barby-0.5.1/0000755000004100000410000000000012147436246012655 5ustar www-datawww-databarby-0.5.1/README0000644000004100000410000000566512147436246013551 0ustar www-datawww-data*** NEW REQUIRE POLICY *** Barcode symbologies are no longer requires automatically, so you'll have to require the ones you need. If you need EAN-13, require 'barby/barcode/ean_13'. Full list of symbologies and filenames below. *** For more information, check out the Barby wiki at https://github.com/toretore/barby/wiki Barby is a Ruby library that generates barcodes in a variety of symbologies. Its functionality is split into barcode and "outputter" objects. Barcode objects turn data into a binary representation for a given symbology. Outputters then take this representation and turns it into images, PDF, etc. You can easily add a symbology without having to worry about graphical representation. If it can be represented as the usual 1D or 2D matrix of lines or squares, outputters will do that for you. Likewise, you can easily add an outputter for a format that doesn't have one yet, and it will work with all existing symbologies. See Barby::Barcode and Barby::Outputter for more information. require 'barby' require 'barby/barcode/code_128' require 'barby/outputter/ascii_outputter' barcode = Barby::Code128B.new('BARBY') puts barcode.to_ascii #Implicitly uses the AsciiOutputter ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## ## # # # # ## # # ## ## # ### # # ## ### ## # ## ### ### ## ### # ## B A R B Y Supported symbologies: Name - filename - dependencies require 'barby/barcode/' * Code 25 - code_25 * Interleaved - code_25_interleaved * IATA - code_25_iata * Code 39 - code_39 * Code 93 - code_93 * Code 128 - code_128 * GS1 128 - gs1_128 * EAN-13 - ean_13 * Bookland - bookland * UPC-A - ean_13 * EAN-8 - ean_8 * UPC/EAN supplemental, 2 & 5 digits - upc_supplemental * QR Code - qr_code - rqrcode * DataMatrix (Semacode) - data_matrix - semacode * PDF417 - pdf_417 - java (JRuby) Formats supported by outputters: * Text (mostly for testing) * PNG, JPEG, GIF * PS, EPS * SVG * PDF * HTML Outputters: filename (dependencies) require 'barby/outputter/_outputter' * ascii * cairo (cairo) * html * pdfwriter * png (chunky_png) * prawn (prawn) * rmagick (RMagick) * svg barby-0.5.1/LICENSE0000644000004100000410000000204012147436246013656 0ustar www-datawww-dataCopyright (c) 2008 Tore Darell 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. barby-0.5.1/vendor/0000755000004100000410000000000012147436246014152 5ustar www-datawww-databarby-0.5.1/vendor/Pdf417lib-java-0.91/0000755000004100000410000000000012147436246017112 5ustar www-datawww-databarby-0.5.1/vendor/Pdf417lib-java-0.91/lib/0000755000004100000410000000000012147436246017660 5ustar www-datawww-databarby-0.5.1/vendor/Pdf417lib-java-0.91/lib/Pdf417lib.java0000755000004100000410000021104412147436246022164 0ustar www-datawww-data/* * Copyright 2003-2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'pdf417lib, a library to generate the bidimensional barcode PDF417'. * * The Initial Developer of the Original Code is Paulo Soares. Portions created by * the Initial Developer are Copyright (C) 2003 by Paulo Soares. * All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://sourceforge.net/projects/pdf417lib * This code is also used in iText (http://www.lowagie.com/iText) */ import java.util.ArrayList; import java.io.UnsupportedEncodingException; /** Generates the 2D barcode PDF417. Supports dimensioning auto-sizing, fixed * and variable sizes, automatic and manual error levels, raw codeword input, * codeword size optimization and bitmap inversion. The output can * be a CCITT G4 Image or a raw bitmap. * @author Paulo Soares (psoares@consiste.pt) */ public class Pdf417lib { /** Auto-size is made based on aspectRatio and yHeight. */ public static final int PDF417_USE_ASPECT_RATIO = 0; /** The size of the barcode will be at least codeColumns*codeRows. */ public static final int PDF417_FIXED_RECTANGLE = 1; /** The size will be at least codeColumns * with a variable number of codeRows. */ public static final int PDF417_FIXED_COLUMNS = 2; /** The size will be at least codeRows * with a variable number of codeColumns. */ public static final int PDF417_FIXED_ROWS = 4; /** The error level correction is set automatically according * to ISO 15438 recomendations. */ public static final int PDF417_AUTO_ERROR_LEVEL = 0; /** The error level correction is set by the user. It can be 0 to 8. */ public static final int PDF417_USE_ERROR_LEVEL = 16; /** No text interpretation is done and the content of codewords * is used directly. */ public static final int PDF417_USE_RAW_CODEWORDS = 64; /** Inverts the output bits of the raw bitmap that is normally * bit one for black. It has only effect for the raw bitmap. */ public static final int PDF417_INVERT_BITMAP = 128; protected int bitPtr; protected int cwPtr; protected SegmentList segmentList; /** Creates a new BarcodePDF417 with the default settings. */ public Pdf417lib() { setDefaultParameters(); } protected boolean checkSegmentType(Segment segment, char type) { if (segment == null) return false; return segment.type == type; } protected int getSegmentLength(Segment segment) { if (segment == null) return 0; return segment.end - segment.start; } /** Set the default settings that correspond to PDF417_USE_ASPECT_RATIO * and PDF417_AUTO_ERROR_LEVEL. */ public void setDefaultParameters() { options = 0; outBits = null; text = new byte[0]; yHeight = 3; aspectRatio = 0.5f; } protected void outCodeword17(int codeword) { int bytePtr = bitPtr / 8; int bit = bitPtr - bytePtr * 8; outBits[bytePtr++] |= codeword >> (9 + bit); outBits[bytePtr++] |= codeword >> (1 + bit); codeword <<= 8; outBits[bytePtr] |= codeword >> (1 + bit); bitPtr += 17; } protected void outCodeword18(int codeword) { int bytePtr = bitPtr / 8; int bit = bitPtr - bytePtr * 8; outBits[bytePtr++] |= codeword >> (10 + bit); outBits[bytePtr++] |= codeword >> (2 + bit); codeword <<= 8; outBits[bytePtr] |= codeword >> (2 + bit); if (bit == 7) outBits[++bytePtr] |= 0x80; bitPtr += 18; } protected void outCodeword(int codeword) { outCodeword17(codeword); } protected void outStopPattern() { outCodeword18(STOP_PATTERN); } protected void outStartPattern() { outCodeword17(START_PATTERN); } protected void outPaintCode() { int codePtr = 0; bitColumns = START_CODE_SIZE * (codeColumns + 3) + STOP_SIZE; int lenBits = ((bitColumns - 1) / 8 + 1) * codeRows; outBits = new byte[lenBits]; for (int row = 0; row < codeRows; ++row) { bitPtr = ((bitColumns - 1) / 8 + 1) * 8 * row; int rowMod = row % 3; int cluster[] = CLUSTERS[rowMod]; outStartPattern(); int edge = 0; switch (rowMod) { case 0: edge = 30 * (row / 3) + ((codeRows - 1) / 3); break; case 1: edge = 30 * (row / 3) + errorLevel * 3 + ((codeRows - 1) % 3); break; default: edge = 30 * (row / 3) + codeColumns - 1; break; } outCodeword(cluster[edge]); for (int column = 0; column < codeColumns; ++column) { outCodeword(cluster[codewords[codePtr++]]); } switch (rowMod) { case 0: edge = 30 * (row / 3) + codeColumns - 1; break; case 1: edge = 30 * (row / 3) + ((codeRows - 1) / 3); break; default: edge = 30 * (row / 3) + errorLevel * 3 + ((codeRows - 1) % 3); break; } outCodeword(cluster[edge]); outStopPattern(); } if ((options & PDF417_INVERT_BITMAP) != 0) { for (int k = 0; k < outBits.length; ++k) outBits[k] ^= 0xff; } } protected void calculateErrorCorrection(int dest) { if (errorLevel < 0 || errorLevel > 8) errorLevel = 0; int A[] = ERROR_LEVEL[errorLevel]; int Alength = 2 << errorLevel; for (int k = 0; k < Alength; ++k) codewords[dest + k] = 0; int lastE = Alength - 1; for (int k = 0; k < lenCodewords; ++k) { int t1 = codewords[k] + codewords[dest]; for (int e = 0; e <= lastE; ++e) { int t2 = (t1 * A[lastE - e]) % MOD; int t3 = MOD - t2; codewords[dest + e] = ((e == lastE ? 0 : codewords[dest + e + 1]) + t3) % MOD; } } for (int k = 0; k < Alength; ++k) codewords[dest + k] = (MOD - codewords[dest + k]) % MOD; } protected int getTextTypeAndValue(int maxLength, int idx) { if (idx >= maxLength) return 0; char c = (char)(text[idx] & 0xff); if (c >= 'A' && c <= 'Z') return (ALPHA + c - 'A'); if (c >= 'a' && c <= 'z') return (LOWER + c - 'a'); if (c == ' ') return (ALPHA + LOWER + MIXED + SPACE); int ms = MIXED_SET.indexOf(c); int ps = PUNCTUATION_SET.indexOf(c); if (ms < 0 && ps < 0) return (ISBYTE + c); if (ms == ps) return (MIXED + PUNCTUATION + ms); if (ms >= 0) return (MIXED + ms); return (PUNCTUATION + ps); } protected void textCompaction(int start, int length) { int dest[] = new int[ABSOLUTE_MAX_TEXT_SIZE * 2]; int mode = ALPHA; int ptr = 0; int fullBytes = 0; int v = 0; int k; int size; length += start; for (k = start; k < length; ++k) { v = getTextTypeAndValue(length, k); if ((v & mode) != 0) { dest[ptr++] = v & 0xff; continue; } if ((v & ISBYTE) != 0) { if ((ptr & 1) != 0) { dest[ptr++] = (mode & PUNCTUATION) != 0 ? PAL : PS; mode = (mode & PUNCTUATION) != 0 ? ALPHA : mode; } dest[ptr++] = BYTESHIFT; dest[ptr++] = v & 0xff; fullBytes += 2; continue; } switch (mode) { case ALPHA: if ((v & LOWER) != 0) { dest[ptr++] = LL; dest[ptr++] = v & 0xff; mode = LOWER; } else if ((v & MIXED) != 0) { dest[ptr++] = ML; dest[ptr++] = v & 0xff; mode = MIXED; } else if ((getTextTypeAndValue(length, k + 1) & getTextTypeAndValue(length, k + 2) & PUNCTUATION) != 0) { dest[ptr++] = ML; dest[ptr++] = PL; dest[ptr++] = v & 0xff; mode = PUNCTUATION; } else { dest[ptr++] = PS; dest[ptr++] = v & 0xff; } break; case LOWER: if ((v & ALPHA) != 0) { if ((getTextTypeAndValue(length, k + 1) & getTextTypeAndValue(length, k + 2) & ALPHA) != 0) { dest[ptr++] = ML; dest[ptr++] = AL; mode = ALPHA; } else { dest[ptr++] = AS; } dest[ptr++] = v & 0xff; } else if ((v & MIXED) != 0) { dest[ptr++] = ML; dest[ptr++] = v & 0xff; mode = MIXED; } else if ((getTextTypeAndValue(length, k + 1) & getTextTypeAndValue(length, k + 2) & PUNCTUATION) != 0) { dest[ptr++] = ML; dest[ptr++] = PL; dest[ptr++] = v & 0xff; mode = PUNCTUATION; } else { dest[ptr++] = PS; dest[ptr++] = v & 0xff; } break; case MIXED: if ((v & LOWER) != 0) { dest[ptr++] = LL; dest[ptr++] = v & 0xff; mode = LOWER; } else if ((v & ALPHA) != 0) { dest[ptr++] = AL; dest[ptr++] = v & 0xff; mode = ALPHA; } else if ((getTextTypeAndValue(length, k + 1) & getTextTypeAndValue(length, k + 2) & PUNCTUATION) != 0) { dest[ptr++] = PL; dest[ptr++] = v & 0xff; mode = PUNCTUATION; } else { dest[ptr++] = PS; dest[ptr++] = v & 0xff; } break; case PUNCTUATION: dest[ptr++] = PAL; mode = ALPHA; --k; break; } } if ((ptr & 1) != 0) dest[ptr++] = PS; size = (ptr + fullBytes) / 2; if (size + cwPtr > MAX_DATA_CODEWORDS) { throw new IndexOutOfBoundsException("The text is too big."); } length = ptr; ptr = 0; while (ptr < length) { v = dest[ptr++]; if (v >= 30) { codewords[cwPtr++] = v; codewords[cwPtr++] = dest[ptr++]; } else codewords[cwPtr++] = v * 30 + dest[ptr++]; } } protected void basicNumberCompaction(int start, int length) { int ret = cwPtr; int retLast = length / 3; int ni, k; cwPtr += retLast + 1; for (k = 0; k <= retLast; ++k) codewords[ret + k] = 0; codewords[ret + retLast] = 1; length += start; for (ni = start; ni < length; ++ni) { // multiply by 10 for (k = retLast; k >= 0; --k) codewords[ret + k] *= 10; // add the digit codewords[ret + retLast] += text[ni] - '0'; // propagate carry for (k = retLast; k > 0; --k) { codewords[ret + k - 1] += codewords[ret + k] / 900; codewords[ret + k] %= 900; } } } protected void numberCompaction(int start, int length) { int full = (length / 44) * 15; int size = length % 44; int k; if (size == 0) size = full; else size = full + size / 3 + 1; if (size + cwPtr > MAX_DATA_CODEWORDS) { throw new IndexOutOfBoundsException("The text is too big."); } length += start; for (k = start; k < length; k += 44) { size = length - k < 44 ? length - k : 44; basicNumberCompaction(k, size); } } protected void byteCompaction6(int start) { int length = 6; int ret = cwPtr; int retLast = 4; int ni, k; cwPtr += retLast + 1; for (k = 0; k <= retLast ; ++k) codewords[ret + k] = 0; length += start; for (ni = start; ni < length; ++ni) { // multiply by 256 for (k = retLast; k >= 0; --k) codewords[ret + k] *= 256; // add the digit codewords[ret + retLast] += (int)text[ni] & 0xff; // propagate carry for (k = retLast; k > 0; --k) { codewords[ret + k - 1] += codewords[ret + k] / 900; codewords[ret + k] %= 900; } } } void byteCompaction(int start, int length) { int k, j; int size = (length / 6) * 5 + (length % 6); if (size + cwPtr > MAX_DATA_CODEWORDS) { throw new IndexOutOfBoundsException("The text is too big."); } length += start; for (k = start; k < length; k += 6) { size = length - k < 44 ? length - k : 6; if (size < 6) { for (j = 0; j < size; ++j) codewords[cwPtr++] = (int)text[k + j] & 0xff; } else { byteCompaction6(k); } } } void breakString() { int textLength = text.length; int lastP = 0; int startN = 0; int nd = 0; char c = 0; int k, ptrS, j; boolean lastTxt, txt; Segment v; Segment vp; Segment vn; for (k = 0; k < textLength; ++k) { c = (char)(text[k] & 0xff); if (c >= '0' && c <= '9') { if (nd == 0) startN = k; ++nd; continue; } if (nd >= 13) { if (lastP != startN) { c = (char)(text[lastP] & 0xff); ptrS = lastP; lastTxt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; for (j = lastP; j < startN; ++j) { c = (char)(text[j] & 0xff); txt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; if (txt != lastTxt) { segmentList.add(lastTxt ? 'T' : 'B', lastP, j); lastP = j; lastTxt = txt; } } segmentList.add(lastTxt ? 'T' : 'B', lastP, startN); } segmentList.add('N', startN, k); lastP = k; } nd = 0; } if (nd < 13) startN = textLength; if (lastP != startN) { c = (char)(text[lastP] & 0xff); ptrS = lastP; lastTxt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; for (j = lastP; j < startN; ++j) { c = (char)(text[j] & 0xff); txt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; if (txt != lastTxt) { segmentList.add(lastTxt ? 'T' : 'B', lastP, j); lastP = j; lastTxt = txt; } } segmentList.add(lastTxt ? 'T' : 'B', lastP, startN); } if (nd >= 13) segmentList.add('N', startN, textLength); //optimize //merge short binary for (k = 0; k < segmentList.size(); ++k) { v = segmentList.get(k); vp = segmentList.get(k - 1); vn = segmentList.get(k + 1);; if (checkSegmentType(v, 'B') && getSegmentLength(v) == 1) { if (checkSegmentType(vp, 'T') && checkSegmentType(vn, 'T') && getSegmentLength(vp) + getSegmentLength(vn) >= 3) { vp.end = vn.end; segmentList.remove(k); segmentList.remove(k); k = -1; continue; } } } //merge text sections for (k = 0; k < segmentList.size(); ++k) { v = segmentList.get(k); vp = segmentList.get(k - 1); vn = segmentList.get(k + 1);; if (checkSegmentType(v, 'T') && getSegmentLength(v) >= 5) { boolean redo = false; if ((checkSegmentType(vp, 'B') && getSegmentLength(vp) == 1) || checkSegmentType(vp, 'T')) { redo = true; v.start = vp.start; segmentList.remove(k - 1); --k; } if ((checkSegmentType(vn, 'B') && getSegmentLength(vn) == 1) || checkSegmentType(vn, 'T')) { redo = true; v.end = vn.end; segmentList.remove(k + 1); } if (redo) { k = -1; continue; } } } //merge binary sections for (k = 0; k < segmentList.size(); ++k) { v = segmentList.get(k); vp = segmentList.get(k - 1); vn = segmentList.get(k + 1);; if (checkSegmentType(v, 'B')) { boolean redo = false; if ((checkSegmentType(vp, 'T') && getSegmentLength(vp) < 5) || checkSegmentType(vp, 'B')) { redo = true; v.start = vp.start; segmentList.remove(k - 1); --k; } if ((checkSegmentType(vn, 'T') && getSegmentLength(vn) < 5) || checkSegmentType(vn, 'B')) { redo = true; v.end = vn.end; segmentList.remove(k + 1); } if (redo) { k = -1; continue; } } } // check if all numbers if (segmentList.size() == 1 && (v = segmentList.get(0)).type == 'T' && getSegmentLength(v) >= 8) { for (k = v.start; k < v.end; ++k) { c = (char)(text[k] & 0xff); if (c < '0' || c > '9') break; } if (k == v.end) v.type = 'N'; } } protected void assemble() { int k; if (segmentList.size() == 0) return; cwPtr = 1; for (k = 0; k < segmentList.size(); ++k) { Segment v = segmentList.get(k); switch (v.type) { case 'T': if (k != 0) codewords[cwPtr++] = TEXT_MODE; textCompaction(v.start, getSegmentLength(v)); break; case 'N': codewords[cwPtr++] = NUMERIC_MODE; numberCompaction(v.start, getSegmentLength(v)); break; case 'B': codewords[cwPtr++] = (getSegmentLength(v) % 6) != 0 ? BYTE_MODE : BYTE_MODE_6; byteCompaction(v.start, getSegmentLength(v)); break; } } } protected static int maxPossibleErrorLevel(int remain) { int level = 8; int size = 512; while (level > 0) { if (remain >= size) return level; --level; size >>= 1; } return 0; } protected void dumpList() { if (segmentList.size() == 0) return; for (int k = 0; k < segmentList.size(); ++k) { Segment v = segmentList.get(k); int len = getSegmentLength(v); char c[] = new char[len]; for (int j = 0; j < len; ++j) { c[j] = (char)(text[v.start + j] & 0xff); if (c[j] == '\r') c[j] = '\n'; } System.out.println("" + v.type + new String(c)); } } protected int getMaxSquare() { if (codeColumns > 21) { codeColumns = 29; codeRows = 32; } else { codeColumns = 16; codeRows = 58; } return MAX_DATA_CODEWORDS + 2; } /** Paints the barcode. If no exception was thrown a valid barcode is available. */ public void paintCode() { int maxErr, lenErr, tot, pad; if ((options & PDF417_USE_RAW_CODEWORDS) != 0) { if (lenCodewords > MAX_DATA_CODEWORDS || lenCodewords < 1 || lenCodewords != codewords[0]) { throw new IllegalArgumentException("Invalid codeword size."); } } else { if (text == null) throw new NullPointerException("Text cannot be null."); if (text.length > ABSOLUTE_MAX_TEXT_SIZE) { throw new IndexOutOfBoundsException("The text is too big."); } segmentList = new SegmentList(); breakString(); //dumpList(); assemble(); segmentList = null; codewords[0] = lenCodewords = cwPtr; } maxErr = maxPossibleErrorLevel(MAX_DATA_CODEWORDS + 2 - lenCodewords); if ((options & PDF417_USE_ERROR_LEVEL) == 0) { if (lenCodewords < 41) errorLevel = 2; else if (lenCodewords < 161) errorLevel = 3; else if (lenCodewords < 321) errorLevel = 4; else errorLevel = 5; } if (errorLevel < 0) errorLevel = 0; else if (errorLevel > maxErr) errorLevel = maxErr; if (codeColumns < 1) codeColumns = 1; else if (codeColumns > 30) codeColumns = 30; if (codeRows < 3) codeRows = 3; else if (codeRows > 90) codeRows = 90; lenErr = 2 << errorLevel; boolean fixedColumn = (options & PDF417_FIXED_ROWS) == 0; boolean skipRowColAdjust = false; tot = lenCodewords + lenErr; if ((options & PDF417_FIXED_RECTANGLE) != 0) { tot = codeColumns * codeRows; if (tot > MAX_DATA_CODEWORDS + 2) { tot = getMaxSquare(); } if (tot < lenCodewords + lenErr) tot = lenCodewords + lenErr; else skipRowColAdjust = true; } else if ((options & (PDF417_FIXED_COLUMNS | PDF417_FIXED_ROWS)) == 0) { double c, b; fixedColumn = true; if (aspectRatio < 0.001) aspectRatio = 0.001f; else if (aspectRatio > 1000) aspectRatio = 1000; b = 73 * aspectRatio - 4; c = (-b + Math.sqrt(b * b + 4 * 17 * aspectRatio * (lenCodewords + lenErr) * yHeight)) / (2 * 17 * aspectRatio); codeColumns = (int)(c + 0.5); if (codeColumns < 1) codeColumns = 1; else if (codeColumns > 30) codeColumns = 30; } if (!skipRowColAdjust) { if (fixedColumn) { codeRows = (tot - 1) / codeColumns + 1; if (codeRows < 3) codeRows = 3; else if (codeRows > 90) { codeRows = 90; codeColumns = (tot - 1) / 90 + 1; } } else { codeColumns = (tot - 1) / codeRows + 1; if (codeColumns > 30) { codeColumns = 30; codeRows = (tot - 1) / 30 + 1; } } tot = codeRows * codeColumns; } if (tot > MAX_DATA_CODEWORDS + 2) { tot = getMaxSquare(); } errorLevel = maxPossibleErrorLevel(tot - lenCodewords); lenErr = 2 << errorLevel; pad = tot - lenErr - lenCodewords; cwPtr = lenCodewords; while (pad-- != 0) codewords[cwPtr++] = TEXT_MODE; codewords[0] = lenCodewords = cwPtr; calculateErrorCorrection(lenCodewords); lenCodewords = tot; outPaintCode(); } /** Gets the raw image bits of the barcode. The image will have to * be scaled in the Y direction by yHeight. * @return The raw barcode image */ public byte[] getOutBits() { return this.outBits; } /** Gets the number of X pixels of outBits. * @return the number of X pixels of outBits */ public int getBitColumns() { return this.bitColumns; } /** Gets the number of Y pixels of outBits. * It is also the number of rows in the barcode. * @return the number of Y pixels of outBits */ public int getCodeRows() { return this.codeRows; } /** Sets the number of barcode rows. This number may be changed * to keep the barcode valid. * @param codeRows the number of barcode rows */ public void setCodeRows(int codeRows) { this.codeRows = codeRows; } /** Gets the number of barcode data columns. * @return he number of barcode data columns */ public int getCodeColumns() { return this.codeColumns; } /** Sets the number of barcode data columns. * This number may be changed to keep the barcode valid. * @param codeColumns the number of barcode data columns */ public void setCodeColumns(int codeColumns) { this.codeColumns = codeColumns; } /** Gets the codeword array. This array is always 928 elements long. * It can be writen to if the option PDF417_USE_RAW_CODEWORDS * is set. * @return the codeword array */ public int[] getCodewords() { return this.codewords; } /** Gets the length of the codewords. * @return the length of the codewords */ public int getLenCodewords() { return this.lenCodewords; } /** Sets the length of the codewords. * @param lenCodewords the length of the codewords */ public void setLenCodewords(int lenCodewords) { this.lenCodewords = lenCodewords; } /** Gets the error level correction used for the barcode. It may different * from the previously set value. * @return the error level correction used for the barcode */ public int getErrorLevel() { return this.errorLevel; } /** Sets the error level correction for the barcode. * @param errorLevel the error level correction for the barcode */ public void setErrorLevel(int errorLevel) { this.errorLevel = errorLevel; } /** Gets the bytes that form the barcode. This bytes should * be interpreted in the codepage Cp437. * @return the bytes that form the barcode */ public byte[] getText() { return this.text; } /** Sets the bytes that form the barcode. This bytes should * be interpreted in the codepage Cp437. * @param text the bytes that form the barcode */ public void setText(byte[] text) { this.text = text; } /** Sets the text that will form the barcode. This text is converted * to bytes using the encoding Cp437. * @param s the text that will form the barcode * @throws UnsupportedEncodingException if the encoding Cp437 is not supported */ public void setText(String s) throws UnsupportedEncodingException { this.text = s.getBytes("Cp437"); } /** Gets the options to generate the barcode. * @return the options to generate the barcode */ public int getOptions() { return this.options; } /** Sets the options to generate the barcode. This can be all * the PDF417_* constants. * @param options the options to generate the barcode */ public void setOptions(int options) { this.options = options; } /** Gets the barcode aspect ratio. * @return the barcode aspect ratio */ public float getAspectRatio() { return this.aspectRatio; } /** Sets the barcode aspect ratio. A ratio or 0.5 will make the * barcode width twice as large as the height. * @param aspectRatio the barcode aspect ratio */ public void setAspectRatio(float aspectRatio) { this.aspectRatio = aspectRatio; } /** Gets the Y pixel height relative to X. * @return the Y pixel height relative to X */ public float getYHeight() { return this.yHeight; } /** Sets the Y pixel height relative to X. It is usually 3. * @param yHeight the Y pixel height relative to X */ public void setYHeight(float yHeight) { this.yHeight = yHeight; } protected static final int START_PATTERN = 0x1fea8; protected static final int STOP_PATTERN = 0x3fa29; protected static final int START_CODE_SIZE = 17; protected static final int STOP_SIZE = 18; protected static final int MOD = 929; protected static final int ALPHA = 0x10000; protected static final int LOWER = 0x20000; protected static final int MIXED = 0x40000; protected static final int PUNCTUATION = 0x80000; protected static final int ISBYTE = 0x100000; protected static final int BYTESHIFT = 913; protected static final int PL = 25; protected static final int LL = 27; protected static final int AS = 27; protected static final int ML = 28; protected static final int AL = 28; protected static final int PS = 29; protected static final int PAL = 29; protected static final int SPACE = 26; protected static final int TEXT_MODE = 900; protected static final int BYTE_MODE_6 = 924; protected static final int BYTE_MODE = 901; protected static final int NUMERIC_MODE = 902; protected static final int ABSOLUTE_MAX_TEXT_SIZE = 5420; protected static final int MAX_DATA_CODEWORDS = 926; static String MIXED_SET = "0123456789&\r\t,:#-.$/+%*=^"; static String PUNCTUATION_SET = ";<>@[\\]_`~!\r\t,:\n-.$/\"|*()?{}'"; static int CLUSTERS[][] = {{ 0x1d5c0, 0x1eaf0, 0x1f57c, 0x1d4e0, 0x1ea78, 0x1f53e, 0x1a8c0, 0x1d470, 0x1a860, 0x15040, 0x1a830, 0x15020, 0x1adc0, 0x1d6f0, 0x1eb7c, 0x1ace0, 0x1d678, 0x1eb3e, 0x158c0, 0x1ac70, 0x15860, 0x15dc0, 0x1aef0, 0x1d77c, 0x15ce0, 0x1ae78, 0x1d73e, 0x15c70, 0x1ae3c, 0x15ef0, 0x1af7c, 0x15e78, 0x1af3e, 0x15f7c, 0x1f5fa, 0x1d2e0, 0x1e978, 0x1f4be, 0x1a4c0, 0x1d270, 0x1e93c, 0x1a460, 0x1d238, 0x14840, 0x1a430, 0x1d21c, 0x14820, 0x1a418, 0x14810, 0x1a6e0, 0x1d378, 0x1e9be, 0x14cc0, 0x1a670, 0x1d33c, 0x14c60, 0x1a638, 0x1d31e, 0x14c30, 0x1a61c, 0x14ee0, 0x1a778, 0x1d3be, 0x14e70, 0x1a73c, 0x14e38, 0x1a71e, 0x14f78, 0x1a7be, 0x14f3c, 0x14f1e, 0x1a2c0, 0x1d170, 0x1e8bc, 0x1a260, 0x1d138, 0x1e89e, 0x14440, 0x1a230, 0x1d11c, 0x14420, 0x1a218, 0x14410, 0x14408, 0x146c0, 0x1a370, 0x1d1bc, 0x14660, 0x1a338, 0x1d19e, 0x14630, 0x1a31c, 0x14618, 0x1460c, 0x14770, 0x1a3bc, 0x14738, 0x1a39e, 0x1471c, 0x147bc, 0x1a160, 0x1d0b8, 0x1e85e, 0x14240, 0x1a130, 0x1d09c, 0x14220, 0x1a118, 0x1d08e, 0x14210, 0x1a10c, 0x14208, 0x1a106, 0x14360, 0x1a1b8, 0x1d0de, 0x14330, 0x1a19c, 0x14318, 0x1a18e, 0x1430c, 0x14306, 0x1a1de, 0x1438e, 0x14140, 0x1a0b0, 0x1d05c, 0x14120, 0x1a098, 0x1d04e, 0x14110, 0x1a08c, 0x14108, 0x1a086, 0x14104, 0x141b0, 0x14198, 0x1418c, 0x140a0, 0x1d02e, 0x1a04c, 0x1a046, 0x14082, 0x1cae0, 0x1e578, 0x1f2be, 0x194c0, 0x1ca70, 0x1e53c, 0x19460, 0x1ca38, 0x1e51e, 0x12840, 0x19430, 0x12820, 0x196e0, 0x1cb78, 0x1e5be, 0x12cc0, 0x19670, 0x1cb3c, 0x12c60, 0x19638, 0x12c30, 0x12c18, 0x12ee0, 0x19778, 0x1cbbe, 0x12e70, 0x1973c, 0x12e38, 0x12e1c, 0x12f78, 0x197be, 0x12f3c, 0x12fbe, 0x1dac0, 0x1ed70, 0x1f6bc, 0x1da60, 0x1ed38, 0x1f69e, 0x1b440, 0x1da30, 0x1ed1c, 0x1b420, 0x1da18, 0x1ed0e, 0x1b410, 0x1da0c, 0x192c0, 0x1c970, 0x1e4bc, 0x1b6c0, 0x19260, 0x1c938, 0x1e49e, 0x1b660, 0x1db38, 0x1ed9e, 0x16c40, 0x12420, 0x19218, 0x1c90e, 0x16c20, 0x1b618, 0x16c10, 0x126c0, 0x19370, 0x1c9bc, 0x16ec0, 0x12660, 0x19338, 0x1c99e, 0x16e60, 0x1b738, 0x1db9e, 0x16e30, 0x12618, 0x16e18, 0x12770, 0x193bc, 0x16f70, 0x12738, 0x1939e, 0x16f38, 0x1b79e, 0x16f1c, 0x127bc, 0x16fbc, 0x1279e, 0x16f9e, 0x1d960, 0x1ecb8, 0x1f65e, 0x1b240, 0x1d930, 0x1ec9c, 0x1b220, 0x1d918, 0x1ec8e, 0x1b210, 0x1d90c, 0x1b208, 0x1b204, 0x19160, 0x1c8b8, 0x1e45e, 0x1b360, 0x19130, 0x1c89c, 0x16640, 0x12220, 0x1d99c, 0x1c88e, 0x16620, 0x12210, 0x1910c, 0x16610, 0x1b30c, 0x19106, 0x12204, 0x12360, 0x191b8, 0x1c8de, 0x16760, 0x12330, 0x1919c, 0x16730, 0x1b39c, 0x1918e, 0x16718, 0x1230c, 0x12306, 0x123b8, 0x191de, 0x167b8, 0x1239c, 0x1679c, 0x1238e, 0x1678e, 0x167de, 0x1b140, 0x1d8b0, 0x1ec5c, 0x1b120, 0x1d898, 0x1ec4e, 0x1b110, 0x1d88c, 0x1b108, 0x1d886, 0x1b104, 0x1b102, 0x12140, 0x190b0, 0x1c85c, 0x16340, 0x12120, 0x19098, 0x1c84e, 0x16320, 0x1b198, 0x1d8ce, 0x16310, 0x12108, 0x19086, 0x16308, 0x1b186, 0x16304, 0x121b0, 0x190dc, 0x163b0, 0x12198, 0x190ce, 0x16398, 0x1b1ce, 0x1638c, 0x12186, 0x16386, 0x163dc, 0x163ce, 0x1b0a0, 0x1d858, 0x1ec2e, 0x1b090, 0x1d84c, 0x1b088, 0x1d846, 0x1b084, 0x1b082, 0x120a0, 0x19058, 0x1c82e, 0x161a0, 0x12090, 0x1904c, 0x16190, 0x1b0cc, 0x19046, 0x16188, 0x12084, 0x16184, 0x12082, 0x120d8, 0x161d8, 0x161cc, 0x161c6, 0x1d82c, 0x1d826, 0x1b042, 0x1902c, 0x12048, 0x160c8, 0x160c4, 0x160c2, 0x18ac0, 0x1c570, 0x1e2bc, 0x18a60, 0x1c538, 0x11440, 0x18a30, 0x1c51c, 0x11420, 0x18a18, 0x11410, 0x11408, 0x116c0, 0x18b70, 0x1c5bc, 0x11660, 0x18b38, 0x1c59e, 0x11630, 0x18b1c, 0x11618, 0x1160c, 0x11770, 0x18bbc, 0x11738, 0x18b9e, 0x1171c, 0x117bc, 0x1179e, 0x1cd60, 0x1e6b8, 0x1f35e, 0x19a40, 0x1cd30, 0x1e69c, 0x19a20, 0x1cd18, 0x1e68e, 0x19a10, 0x1cd0c, 0x19a08, 0x1cd06, 0x18960, 0x1c4b8, 0x1e25e, 0x19b60, 0x18930, 0x1c49c, 0x13640, 0x11220, 0x1cd9c, 0x1c48e, 0x13620, 0x19b18, 0x1890c, 0x13610, 0x11208, 0x13608, 0x11360, 0x189b8, 0x1c4de, 0x13760, 0x11330, 0x1cdde, 0x13730, 0x19b9c, 0x1898e, 0x13718, 0x1130c, 0x1370c, 0x113b8, 0x189de, 0x137b8, 0x1139c, 0x1379c, 0x1138e, 0x113de, 0x137de, 0x1dd40, 0x1eeb0, 0x1f75c, 0x1dd20, 0x1ee98, 0x1f74e, 0x1dd10, 0x1ee8c, 0x1dd08, 0x1ee86, 0x1dd04, 0x19940, 0x1ccb0, 0x1e65c, 0x1bb40, 0x19920, 0x1eedc, 0x1e64e, 0x1bb20, 0x1dd98, 0x1eece, 0x1bb10, 0x19908, 0x1cc86, 0x1bb08, 0x1dd86, 0x19902, 0x11140, 0x188b0, 0x1c45c, 0x13340, 0x11120, 0x18898, 0x1c44e, 0x17740, 0x13320, 0x19998, 0x1ccce, 0x17720, 0x1bb98, 0x1ddce, 0x18886, 0x17710, 0x13308, 0x19986, 0x17708, 0x11102, 0x111b0, 0x188dc, 0x133b0, 0x11198, 0x188ce, 0x177b0, 0x13398, 0x199ce, 0x17798, 0x1bbce, 0x11186, 0x13386, 0x111dc, 0x133dc, 0x111ce, 0x177dc, 0x133ce, 0x1dca0, 0x1ee58, 0x1f72e, 0x1dc90, 0x1ee4c, 0x1dc88, 0x1ee46, 0x1dc84, 0x1dc82, 0x198a0, 0x1cc58, 0x1e62e, 0x1b9a0, 0x19890, 0x1ee6e, 0x1b990, 0x1dccc, 0x1cc46, 0x1b988, 0x19884, 0x1b984, 0x19882, 0x1b982, 0x110a0, 0x18858, 0x1c42e, 0x131a0, 0x11090, 0x1884c, 0x173a0, 0x13190, 0x198cc, 0x18846, 0x17390, 0x1b9cc, 0x11084, 0x17388, 0x13184, 0x11082, 0x13182, 0x110d8, 0x1886e, 0x131d8, 0x110cc, 0x173d8, 0x131cc, 0x110c6, 0x173cc, 0x131c6, 0x110ee, 0x173ee, 0x1dc50, 0x1ee2c, 0x1dc48, 0x1ee26, 0x1dc44, 0x1dc42, 0x19850, 0x1cc2c, 0x1b8d0, 0x19848, 0x1cc26, 0x1b8c8, 0x1dc66, 0x1b8c4, 0x19842, 0x1b8c2, 0x11050, 0x1882c, 0x130d0, 0x11048, 0x18826, 0x171d0, 0x130c8, 0x19866, 0x171c8, 0x1b8e6, 0x11042, 0x171c4, 0x130c2, 0x171c2, 0x130ec, 0x171ec, 0x171e6, 0x1ee16, 0x1dc22, 0x1cc16, 0x19824, 0x19822, 0x11028, 0x13068, 0x170e8, 0x11022, 0x13062, 0x18560, 0x10a40, 0x18530, 0x10a20, 0x18518, 0x1c28e, 0x10a10, 0x1850c, 0x10a08, 0x18506, 0x10b60, 0x185b8, 0x1c2de, 0x10b30, 0x1859c, 0x10b18, 0x1858e, 0x10b0c, 0x10b06, 0x10bb8, 0x185de, 0x10b9c, 0x10b8e, 0x10bde, 0x18d40, 0x1c6b0, 0x1e35c, 0x18d20, 0x1c698, 0x18d10, 0x1c68c, 0x18d08, 0x1c686, 0x18d04, 0x10940, 0x184b0, 0x1c25c, 0x11b40, 0x10920, 0x1c6dc, 0x1c24e, 0x11b20, 0x18d98, 0x1c6ce, 0x11b10, 0x10908, 0x18486, 0x11b08, 0x18d86, 0x10902, 0x109b0, 0x184dc, 0x11bb0, 0x10998, 0x184ce, 0x11b98, 0x18dce, 0x11b8c, 0x10986, 0x109dc, 0x11bdc, 0x109ce, 0x11bce, 0x1cea0, 0x1e758, 0x1f3ae, 0x1ce90, 0x1e74c, 0x1ce88, 0x1e746, 0x1ce84, 0x1ce82, 0x18ca0, 0x1c658, 0x19da0, 0x18c90, 0x1c64c, 0x19d90, 0x1cecc, 0x1c646, 0x19d88, 0x18c84, 0x19d84, 0x18c82, 0x19d82, 0x108a0, 0x18458, 0x119a0, 0x10890, 0x1c66e, 0x13ba0, 0x11990, 0x18ccc, 0x18446, 0x13b90, 0x19dcc, 0x10884, 0x13b88, 0x11984, 0x10882, 0x11982, 0x108d8, 0x1846e, 0x119d8, 0x108cc, 0x13bd8, 0x119cc, 0x108c6, 0x13bcc, 0x119c6, 0x108ee, 0x119ee, 0x13bee, 0x1ef50, 0x1f7ac, 0x1ef48, 0x1f7a6, 0x1ef44, 0x1ef42, 0x1ce50, 0x1e72c, 0x1ded0, 0x1ef6c, 0x1e726, 0x1dec8, 0x1ef66, 0x1dec4, 0x1ce42, 0x1dec2, 0x18c50, 0x1c62c, 0x19cd0, 0x18c48, 0x1c626, 0x1bdd0, 0x19cc8, 0x1ce66, 0x1bdc8, 0x1dee6, 0x18c42, 0x1bdc4, 0x19cc2, 0x1bdc2, 0x10850, 0x1842c, 0x118d0, 0x10848, 0x18426, 0x139d0, 0x118c8, 0x18c66, 0x17bd0, 0x139c8, 0x19ce6, 0x10842, 0x17bc8, 0x1bde6, 0x118c2, 0x17bc4, 0x1086c, 0x118ec, 0x10866, 0x139ec, 0x118e6, 0x17bec, 0x139e6, 0x17be6, 0x1ef28, 0x1f796, 0x1ef24, 0x1ef22, 0x1ce28, 0x1e716, 0x1de68, 0x1ef36, 0x1de64, 0x1ce22, 0x1de62, 0x18c28, 0x1c616, 0x19c68, 0x18c24, 0x1bce8, 0x19c64, 0x18c22, 0x1bce4, 0x19c62, 0x1bce2, 0x10828, 0x18416, 0x11868, 0x18c36, 0x138e8, 0x11864, 0x10822, 0x179e8, 0x138e4, 0x11862, 0x179e4, 0x138e2, 0x179e2, 0x11876, 0x179f6, 0x1ef12, 0x1de34, 0x1de32, 0x19c34, 0x1bc74, 0x1bc72, 0x11834, 0x13874, 0x178f4, 0x178f2, 0x10540, 0x10520, 0x18298, 0x10510, 0x10508, 0x10504, 0x105b0, 0x10598, 0x1058c, 0x10586, 0x105dc, 0x105ce, 0x186a0, 0x18690, 0x1c34c, 0x18688, 0x1c346, 0x18684, 0x18682, 0x104a0, 0x18258, 0x10da0, 0x186d8, 0x1824c, 0x10d90, 0x186cc, 0x10d88, 0x186c6, 0x10d84, 0x10482, 0x10d82, 0x104d8, 0x1826e, 0x10dd8, 0x186ee, 0x10dcc, 0x104c6, 0x10dc6, 0x104ee, 0x10dee, 0x1c750, 0x1c748, 0x1c744, 0x1c742, 0x18650, 0x18ed0, 0x1c76c, 0x1c326, 0x18ec8, 0x1c766, 0x18ec4, 0x18642, 0x18ec2, 0x10450, 0x10cd0, 0x10448, 0x18226, 0x11dd0, 0x10cc8, 0x10444, 0x11dc8, 0x10cc4, 0x10442, 0x11dc4, 0x10cc2, 0x1046c, 0x10cec, 0x10466, 0x11dec, 0x10ce6, 0x11de6, 0x1e7a8, 0x1e7a4, 0x1e7a2, 0x1c728, 0x1cf68, 0x1e7b6, 0x1cf64, 0x1c722, 0x1cf62, 0x18628, 0x1c316, 0x18e68, 0x1c736, 0x19ee8, 0x18e64, 0x18622, 0x19ee4, 0x18e62, 0x19ee2, 0x10428, 0x18216, 0x10c68, 0x18636, 0x11ce8, 0x10c64, 0x10422, 0x13de8, 0x11ce4, 0x10c62, 0x13de4, 0x11ce2, 0x10436, 0x10c76, 0x11cf6, 0x13df6, 0x1f7d4, 0x1f7d2, 0x1e794, 0x1efb4, 0x1e792, 0x1efb2, 0x1c714, 0x1cf34, 0x1c712, 0x1df74, 0x1cf32, 0x1df72, 0x18614, 0x18e34, 0x18612, 0x19e74, 0x18e32, 0x1bef4 }, { 0x1f560, 0x1fab8, 0x1ea40, 0x1f530, 0x1fa9c, 0x1ea20, 0x1f518, 0x1fa8e, 0x1ea10, 0x1f50c, 0x1ea08, 0x1f506, 0x1ea04, 0x1eb60, 0x1f5b8, 0x1fade, 0x1d640, 0x1eb30, 0x1f59c, 0x1d620, 0x1eb18, 0x1f58e, 0x1d610, 0x1eb0c, 0x1d608, 0x1eb06, 0x1d604, 0x1d760, 0x1ebb8, 0x1f5de, 0x1ae40, 0x1d730, 0x1eb9c, 0x1ae20, 0x1d718, 0x1eb8e, 0x1ae10, 0x1d70c, 0x1ae08, 0x1d706, 0x1ae04, 0x1af60, 0x1d7b8, 0x1ebde, 0x15e40, 0x1af30, 0x1d79c, 0x15e20, 0x1af18, 0x1d78e, 0x15e10, 0x1af0c, 0x15e08, 0x1af06, 0x15f60, 0x1afb8, 0x1d7de, 0x15f30, 0x1af9c, 0x15f18, 0x1af8e, 0x15f0c, 0x15fb8, 0x1afde, 0x15f9c, 0x15f8e, 0x1e940, 0x1f4b0, 0x1fa5c, 0x1e920, 0x1f498, 0x1fa4e, 0x1e910, 0x1f48c, 0x1e908, 0x1f486, 0x1e904, 0x1e902, 0x1d340, 0x1e9b0, 0x1f4dc, 0x1d320, 0x1e998, 0x1f4ce, 0x1d310, 0x1e98c, 0x1d308, 0x1e986, 0x1d304, 0x1d302, 0x1a740, 0x1d3b0, 0x1e9dc, 0x1a720, 0x1d398, 0x1e9ce, 0x1a710, 0x1d38c, 0x1a708, 0x1d386, 0x1a704, 0x1a702, 0x14f40, 0x1a7b0, 0x1d3dc, 0x14f20, 0x1a798, 0x1d3ce, 0x14f10, 0x1a78c, 0x14f08, 0x1a786, 0x14f04, 0x14fb0, 0x1a7dc, 0x14f98, 0x1a7ce, 0x14f8c, 0x14f86, 0x14fdc, 0x14fce, 0x1e8a0, 0x1f458, 0x1fa2e, 0x1e890, 0x1f44c, 0x1e888, 0x1f446, 0x1e884, 0x1e882, 0x1d1a0, 0x1e8d8, 0x1f46e, 0x1d190, 0x1e8cc, 0x1d188, 0x1e8c6, 0x1d184, 0x1d182, 0x1a3a0, 0x1d1d8, 0x1e8ee, 0x1a390, 0x1d1cc, 0x1a388, 0x1d1c6, 0x1a384, 0x1a382, 0x147a0, 0x1a3d8, 0x1d1ee, 0x14790, 0x1a3cc, 0x14788, 0x1a3c6, 0x14784, 0x14782, 0x147d8, 0x1a3ee, 0x147cc, 0x147c6, 0x147ee, 0x1e850, 0x1f42c, 0x1e848, 0x1f426, 0x1e844, 0x1e842, 0x1d0d0, 0x1e86c, 0x1d0c8, 0x1e866, 0x1d0c4, 0x1d0c2, 0x1a1d0, 0x1d0ec, 0x1a1c8, 0x1d0e6, 0x1a1c4, 0x1a1c2, 0x143d0, 0x1a1ec, 0x143c8, 0x1a1e6, 0x143c4, 0x143c2, 0x143ec, 0x143e6, 0x1e828, 0x1f416, 0x1e824, 0x1e822, 0x1d068, 0x1e836, 0x1d064, 0x1d062, 0x1a0e8, 0x1d076, 0x1a0e4, 0x1a0e2, 0x141e8, 0x1a0f6, 0x141e4, 0x141e2, 0x1e814, 0x1e812, 0x1d034, 0x1d032, 0x1a074, 0x1a072, 0x1e540, 0x1f2b0, 0x1f95c, 0x1e520, 0x1f298, 0x1f94e, 0x1e510, 0x1f28c, 0x1e508, 0x1f286, 0x1e504, 0x1e502, 0x1cb40, 0x1e5b0, 0x1f2dc, 0x1cb20, 0x1e598, 0x1f2ce, 0x1cb10, 0x1e58c, 0x1cb08, 0x1e586, 0x1cb04, 0x1cb02, 0x19740, 0x1cbb0, 0x1e5dc, 0x19720, 0x1cb98, 0x1e5ce, 0x19710, 0x1cb8c, 0x19708, 0x1cb86, 0x19704, 0x19702, 0x12f40, 0x197b0, 0x1cbdc, 0x12f20, 0x19798, 0x1cbce, 0x12f10, 0x1978c, 0x12f08, 0x19786, 0x12f04, 0x12fb0, 0x197dc, 0x12f98, 0x197ce, 0x12f8c, 0x12f86, 0x12fdc, 0x12fce, 0x1f6a0, 0x1fb58, 0x16bf0, 0x1f690, 0x1fb4c, 0x169f8, 0x1f688, 0x1fb46, 0x168fc, 0x1f684, 0x1f682, 0x1e4a0, 0x1f258, 0x1f92e, 0x1eda0, 0x1e490, 0x1fb6e, 0x1ed90, 0x1f6cc, 0x1f246, 0x1ed88, 0x1e484, 0x1ed84, 0x1e482, 0x1ed82, 0x1c9a0, 0x1e4d8, 0x1f26e, 0x1dba0, 0x1c990, 0x1e4cc, 0x1db90, 0x1edcc, 0x1e4c6, 0x1db88, 0x1c984, 0x1db84, 0x1c982, 0x1db82, 0x193a0, 0x1c9d8, 0x1e4ee, 0x1b7a0, 0x19390, 0x1c9cc, 0x1b790, 0x1dbcc, 0x1c9c6, 0x1b788, 0x19384, 0x1b784, 0x19382, 0x1b782, 0x127a0, 0x193d8, 0x1c9ee, 0x16fa0, 0x12790, 0x193cc, 0x16f90, 0x1b7cc, 0x193c6, 0x16f88, 0x12784, 0x16f84, 0x12782, 0x127d8, 0x193ee, 0x16fd8, 0x127cc, 0x16fcc, 0x127c6, 0x16fc6, 0x127ee, 0x1f650, 0x1fb2c, 0x165f8, 0x1f648, 0x1fb26, 0x164fc, 0x1f644, 0x1647e, 0x1f642, 0x1e450, 0x1f22c, 0x1ecd0, 0x1e448, 0x1f226, 0x1ecc8, 0x1f666, 0x1ecc4, 0x1e442, 0x1ecc2, 0x1c8d0, 0x1e46c, 0x1d9d0, 0x1c8c8, 0x1e466, 0x1d9c8, 0x1ece6, 0x1d9c4, 0x1c8c2, 0x1d9c2, 0x191d0, 0x1c8ec, 0x1b3d0, 0x191c8, 0x1c8e6, 0x1b3c8, 0x1d9e6, 0x1b3c4, 0x191c2, 0x1b3c2, 0x123d0, 0x191ec, 0x167d0, 0x123c8, 0x191e6, 0x167c8, 0x1b3e6, 0x167c4, 0x123c2, 0x167c2, 0x123ec, 0x167ec, 0x123e6, 0x167e6, 0x1f628, 0x1fb16, 0x162fc, 0x1f624, 0x1627e, 0x1f622, 0x1e428, 0x1f216, 0x1ec68, 0x1f636, 0x1ec64, 0x1e422, 0x1ec62, 0x1c868, 0x1e436, 0x1d8e8, 0x1c864, 0x1d8e4, 0x1c862, 0x1d8e2, 0x190e8, 0x1c876, 0x1b1e8, 0x1d8f6, 0x1b1e4, 0x190e2, 0x1b1e2, 0x121e8, 0x190f6, 0x163e8, 0x121e4, 0x163e4, 0x121e2, 0x163e2, 0x121f6, 0x163f6, 0x1f614, 0x1617e, 0x1f612, 0x1e414, 0x1ec34, 0x1e412, 0x1ec32, 0x1c834, 0x1d874, 0x1c832, 0x1d872, 0x19074, 0x1b0f4, 0x19072, 0x1b0f2, 0x120f4, 0x161f4, 0x120f2, 0x161f2, 0x1f60a, 0x1e40a, 0x1ec1a, 0x1c81a, 0x1d83a, 0x1903a, 0x1b07a, 0x1e2a0, 0x1f158, 0x1f8ae, 0x1e290, 0x1f14c, 0x1e288, 0x1f146, 0x1e284, 0x1e282, 0x1c5a0, 0x1e2d8, 0x1f16e, 0x1c590, 0x1e2cc, 0x1c588, 0x1e2c6, 0x1c584, 0x1c582, 0x18ba0, 0x1c5d8, 0x1e2ee, 0x18b90, 0x1c5cc, 0x18b88, 0x1c5c6, 0x18b84, 0x18b82, 0x117a0, 0x18bd8, 0x1c5ee, 0x11790, 0x18bcc, 0x11788, 0x18bc6, 0x11784, 0x11782, 0x117d8, 0x18bee, 0x117cc, 0x117c6, 0x117ee, 0x1f350, 0x1f9ac, 0x135f8, 0x1f348, 0x1f9a6, 0x134fc, 0x1f344, 0x1347e, 0x1f342, 0x1e250, 0x1f12c, 0x1e6d0, 0x1e248, 0x1f126, 0x1e6c8, 0x1f366, 0x1e6c4, 0x1e242, 0x1e6c2, 0x1c4d0, 0x1e26c, 0x1cdd0, 0x1c4c8, 0x1e266, 0x1cdc8, 0x1e6e6, 0x1cdc4, 0x1c4c2, 0x1cdc2, 0x189d0, 0x1c4ec, 0x19bd0, 0x189c8, 0x1c4e6, 0x19bc8, 0x1cde6, 0x19bc4, 0x189c2, 0x19bc2, 0x113d0, 0x189ec, 0x137d0, 0x113c8, 0x189e6, 0x137c8, 0x19be6, 0x137c4, 0x113c2, 0x137c2, 0x113ec, 0x137ec, 0x113e6, 0x137e6, 0x1fba8, 0x175f0, 0x1bafc, 0x1fba4, 0x174f8, 0x1ba7e, 0x1fba2, 0x1747c, 0x1743e, 0x1f328, 0x1f996, 0x132fc, 0x1f768, 0x1fbb6, 0x176fc, 0x1327e, 0x1f764, 0x1f322, 0x1767e, 0x1f762, 0x1e228, 0x1f116, 0x1e668, 0x1e224, 0x1eee8, 0x1f776, 0x1e222, 0x1eee4, 0x1e662, 0x1eee2, 0x1c468, 0x1e236, 0x1cce8, 0x1c464, 0x1dde8, 0x1cce4, 0x1c462, 0x1dde4, 0x1cce2, 0x1dde2, 0x188e8, 0x1c476, 0x199e8, 0x188e4, 0x1bbe8, 0x199e4, 0x188e2, 0x1bbe4, 0x199e2, 0x1bbe2, 0x111e8, 0x188f6, 0x133e8, 0x111e4, 0x177e8, 0x133e4, 0x111e2, 0x177e4, 0x133e2, 0x177e2, 0x111f6, 0x133f6, 0x1fb94, 0x172f8, 0x1b97e, 0x1fb92, 0x1727c, 0x1723e, 0x1f314, 0x1317e, 0x1f734, 0x1f312, 0x1737e, 0x1f732, 0x1e214, 0x1e634, 0x1e212, 0x1ee74, 0x1e632, 0x1ee72, 0x1c434, 0x1cc74, 0x1c432, 0x1dcf4, 0x1cc72, 0x1dcf2, 0x18874, 0x198f4, 0x18872, 0x1b9f4, 0x198f2, 0x1b9f2, 0x110f4, 0x131f4, 0x110f2, 0x173f4, 0x131f2, 0x173f2, 0x1fb8a, 0x1717c, 0x1713e, 0x1f30a, 0x1f71a, 0x1e20a, 0x1e61a, 0x1ee3a, 0x1c41a, 0x1cc3a, 0x1dc7a, 0x1883a, 0x1987a, 0x1b8fa, 0x1107a, 0x130fa, 0x171fa, 0x170be, 0x1e150, 0x1f0ac, 0x1e148, 0x1f0a6, 0x1e144, 0x1e142, 0x1c2d0, 0x1e16c, 0x1c2c8, 0x1e166, 0x1c2c4, 0x1c2c2, 0x185d0, 0x1c2ec, 0x185c8, 0x1c2e6, 0x185c4, 0x185c2, 0x10bd0, 0x185ec, 0x10bc8, 0x185e6, 0x10bc4, 0x10bc2, 0x10bec, 0x10be6, 0x1f1a8, 0x1f8d6, 0x11afc, 0x1f1a4, 0x11a7e, 0x1f1a2, 0x1e128, 0x1f096, 0x1e368, 0x1e124, 0x1e364, 0x1e122, 0x1e362, 0x1c268, 0x1e136, 0x1c6e8, 0x1c264, 0x1c6e4, 0x1c262, 0x1c6e2, 0x184e8, 0x1c276, 0x18de8, 0x184e4, 0x18de4, 0x184e2, 0x18de2, 0x109e8, 0x184f6, 0x11be8, 0x109e4, 0x11be4, 0x109e2, 0x11be2, 0x109f6, 0x11bf6, 0x1f9d4, 0x13af8, 0x19d7e, 0x1f9d2, 0x13a7c, 0x13a3e, 0x1f194, 0x1197e, 0x1f3b4, 0x1f192, 0x13b7e, 0x1f3b2, 0x1e114, 0x1e334, 0x1e112, 0x1e774, 0x1e332, 0x1e772, 0x1c234, 0x1c674, 0x1c232, 0x1cef4, 0x1c672, 0x1cef2, 0x18474, 0x18cf4, 0x18472, 0x19df4, 0x18cf2, 0x19df2, 0x108f4, 0x119f4, 0x108f2, 0x13bf4, 0x119f2, 0x13bf2, 0x17af0, 0x1bd7c, 0x17a78, 0x1bd3e, 0x17a3c, 0x17a1e, 0x1f9ca, 0x1397c, 0x1fbda, 0x17b7c, 0x1393e, 0x17b3e, 0x1f18a, 0x1f39a, 0x1f7ba, 0x1e10a, 0x1e31a, 0x1e73a, 0x1ef7a, 0x1c21a, 0x1c63a, 0x1ce7a, 0x1defa, 0x1843a, 0x18c7a, 0x19cfa, 0x1bdfa, 0x1087a, 0x118fa, 0x139fa, 0x17978, 0x1bcbe, 0x1793c, 0x1791e, 0x138be, 0x179be, 0x178bc, 0x1789e, 0x1785e, 0x1e0a8, 0x1e0a4, 0x1e0a2, 0x1c168, 0x1e0b6, 0x1c164, 0x1c162, 0x182e8, 0x1c176, 0x182e4, 0x182e2, 0x105e8, 0x182f6, 0x105e4, 0x105e2, 0x105f6, 0x1f0d4, 0x10d7e, 0x1f0d2, 0x1e094, 0x1e1b4, 0x1e092, 0x1e1b2, 0x1c134, 0x1c374, 0x1c132, 0x1c372, 0x18274, 0x186f4, 0x18272, 0x186f2, 0x104f4, 0x10df4, 0x104f2, 0x10df2, 0x1f8ea, 0x11d7c, 0x11d3e, 0x1f0ca, 0x1f1da, 0x1e08a, 0x1e19a, 0x1e3ba, 0x1c11a, 0x1c33a, 0x1c77a, 0x1823a, 0x1867a, 0x18efa, 0x1047a, 0x10cfa, 0x11dfa, 0x13d78, 0x19ebe, 0x13d3c, 0x13d1e, 0x11cbe, 0x13dbe, 0x17d70, 0x1bebc, 0x17d38, 0x1be9e, 0x17d1c, 0x17d0e, 0x13cbc, 0x17dbc, 0x13c9e, 0x17d9e, 0x17cb8, 0x1be5e, 0x17c9c, 0x17c8e, 0x13c5e, 0x17cde, 0x17c5c, 0x17c4e, 0x17c2e, 0x1c0b4, 0x1c0b2, 0x18174, 0x18172, 0x102f4, 0x102f2, 0x1e0da, 0x1c09a, 0x1c1ba, 0x1813a, 0x1837a, 0x1027a, 0x106fa, 0x10ebe, 0x11ebc, 0x11e9e, 0x13eb8, 0x19f5e, 0x13e9c, 0x13e8e, 0x11e5e, 0x13ede, 0x17eb0, 0x1bf5c, 0x17e98, 0x1bf4e, 0x17e8c, 0x17e86, 0x13e5c, 0x17edc, 0x13e4e, 0x17ece, 0x17e58, 0x1bf2e, 0x17e4c, 0x17e46, 0x13e2e, 0x17e6e, 0x17e2c, 0x17e26, 0x10f5e, 0x11f5c, 0x11f4e, 0x13f58, 0x19fae, 0x13f4c, 0x13f46, 0x11f2e, 0x13f6e, 0x13f2c, 0x13f26 }, { 0x1abe0, 0x1d5f8, 0x153c0, 0x1a9f0, 0x1d4fc, 0x151e0, 0x1a8f8, 0x1d47e, 0x150f0, 0x1a87c, 0x15078, 0x1fad0, 0x15be0, 0x1adf8, 0x1fac8, 0x159f0, 0x1acfc, 0x1fac4, 0x158f8, 0x1ac7e, 0x1fac2, 0x1587c, 0x1f5d0, 0x1faec, 0x15df8, 0x1f5c8, 0x1fae6, 0x15cfc, 0x1f5c4, 0x15c7e, 0x1f5c2, 0x1ebd0, 0x1f5ec, 0x1ebc8, 0x1f5e6, 0x1ebc4, 0x1ebc2, 0x1d7d0, 0x1ebec, 0x1d7c8, 0x1ebe6, 0x1d7c4, 0x1d7c2, 0x1afd0, 0x1d7ec, 0x1afc8, 0x1d7e6, 0x1afc4, 0x14bc0, 0x1a5f0, 0x1d2fc, 0x149e0, 0x1a4f8, 0x1d27e, 0x148f0, 0x1a47c, 0x14878, 0x1a43e, 0x1483c, 0x1fa68, 0x14df0, 0x1a6fc, 0x1fa64, 0x14cf8, 0x1a67e, 0x1fa62, 0x14c7c, 0x14c3e, 0x1f4e8, 0x1fa76, 0x14efc, 0x1f4e4, 0x14e7e, 0x1f4e2, 0x1e9e8, 0x1f4f6, 0x1e9e4, 0x1e9e2, 0x1d3e8, 0x1e9f6, 0x1d3e4, 0x1d3e2, 0x1a7e8, 0x1d3f6, 0x1a7e4, 0x1a7e2, 0x145e0, 0x1a2f8, 0x1d17e, 0x144f0, 0x1a27c, 0x14478, 0x1a23e, 0x1443c, 0x1441e, 0x1fa34, 0x146f8, 0x1a37e, 0x1fa32, 0x1467c, 0x1463e, 0x1f474, 0x1477e, 0x1f472, 0x1e8f4, 0x1e8f2, 0x1d1f4, 0x1d1f2, 0x1a3f4, 0x1a3f2, 0x142f0, 0x1a17c, 0x14278, 0x1a13e, 0x1423c, 0x1421e, 0x1fa1a, 0x1437c, 0x1433e, 0x1f43a, 0x1e87a, 0x1d0fa, 0x14178, 0x1a0be, 0x1413c, 0x1411e, 0x141be, 0x140bc, 0x1409e, 0x12bc0, 0x195f0, 0x1cafc, 0x129e0, 0x194f8, 0x1ca7e, 0x128f0, 0x1947c, 0x12878, 0x1943e, 0x1283c, 0x1f968, 0x12df0, 0x196fc, 0x1f964, 0x12cf8, 0x1967e, 0x1f962, 0x12c7c, 0x12c3e, 0x1f2e8, 0x1f976, 0x12efc, 0x1f2e4, 0x12e7e, 0x1f2e2, 0x1e5e8, 0x1f2f6, 0x1e5e4, 0x1e5e2, 0x1cbe8, 0x1e5f6, 0x1cbe4, 0x1cbe2, 0x197e8, 0x1cbf6, 0x197e4, 0x197e2, 0x1b5e0, 0x1daf8, 0x1ed7e, 0x169c0, 0x1b4f0, 0x1da7c, 0x168e0, 0x1b478, 0x1da3e, 0x16870, 0x1b43c, 0x16838, 0x1b41e, 0x1681c, 0x125e0, 0x192f8, 0x1c97e, 0x16de0, 0x124f0, 0x1927c, 0x16cf0, 0x1b67c, 0x1923e, 0x16c78, 0x1243c, 0x16c3c, 0x1241e, 0x16c1e, 0x1f934, 0x126f8, 0x1937e, 0x1fb74, 0x1f932, 0x16ef8, 0x1267c, 0x1fb72, 0x16e7c, 0x1263e, 0x16e3e, 0x1f274, 0x1277e, 0x1f6f4, 0x1f272, 0x16f7e, 0x1f6f2, 0x1e4f4, 0x1edf4, 0x1e4f2, 0x1edf2, 0x1c9f4, 0x1dbf4, 0x1c9f2, 0x1dbf2, 0x193f4, 0x193f2, 0x165c0, 0x1b2f0, 0x1d97c, 0x164e0, 0x1b278, 0x1d93e, 0x16470, 0x1b23c, 0x16438, 0x1b21e, 0x1641c, 0x1640e, 0x122f0, 0x1917c, 0x166f0, 0x12278, 0x1913e, 0x16678, 0x1b33e, 0x1663c, 0x1221e, 0x1661e, 0x1f91a, 0x1237c, 0x1fb3a, 0x1677c, 0x1233e, 0x1673e, 0x1f23a, 0x1f67a, 0x1e47a, 0x1ecfa, 0x1c8fa, 0x1d9fa, 0x191fa, 0x162e0, 0x1b178, 0x1d8be, 0x16270, 0x1b13c, 0x16238, 0x1b11e, 0x1621c, 0x1620e, 0x12178, 0x190be, 0x16378, 0x1213c, 0x1633c, 0x1211e, 0x1631e, 0x121be, 0x163be, 0x16170, 0x1b0bc, 0x16138, 0x1b09e, 0x1611c, 0x1610e, 0x120bc, 0x161bc, 0x1209e, 0x1619e, 0x160b8, 0x1b05e, 0x1609c, 0x1608e, 0x1205e, 0x160de, 0x1605c, 0x1604e, 0x115e0, 0x18af8, 0x1c57e, 0x114f0, 0x18a7c, 0x11478, 0x18a3e, 0x1143c, 0x1141e, 0x1f8b4, 0x116f8, 0x18b7e, 0x1f8b2, 0x1167c, 0x1163e, 0x1f174, 0x1177e, 0x1f172, 0x1e2f4, 0x1e2f2, 0x1c5f4, 0x1c5f2, 0x18bf4, 0x18bf2, 0x135c0, 0x19af0, 0x1cd7c, 0x134e0, 0x19a78, 0x1cd3e, 0x13470, 0x19a3c, 0x13438, 0x19a1e, 0x1341c, 0x1340e, 0x112f0, 0x1897c, 0x136f0, 0x11278, 0x1893e, 0x13678, 0x19b3e, 0x1363c, 0x1121e, 0x1361e, 0x1f89a, 0x1137c, 0x1f9ba, 0x1377c, 0x1133e, 0x1373e, 0x1f13a, 0x1f37a, 0x1e27a, 0x1e6fa, 0x1c4fa, 0x1cdfa, 0x189fa, 0x1bae0, 0x1dd78, 0x1eebe, 0x174c0, 0x1ba70, 0x1dd3c, 0x17460, 0x1ba38, 0x1dd1e, 0x17430, 0x1ba1c, 0x17418, 0x1ba0e, 0x1740c, 0x132e0, 0x19978, 0x1ccbe, 0x176e0, 0x13270, 0x1993c, 0x17670, 0x1bb3c, 0x1991e, 0x17638, 0x1321c, 0x1761c, 0x1320e, 0x1760e, 0x11178, 0x188be, 0x13378, 0x1113c, 0x17778, 0x1333c, 0x1111e, 0x1773c, 0x1331e, 0x1771e, 0x111be, 0x133be, 0x177be, 0x172c0, 0x1b970, 0x1dcbc, 0x17260, 0x1b938, 0x1dc9e, 0x17230, 0x1b91c, 0x17218, 0x1b90e, 0x1720c, 0x17206, 0x13170, 0x198bc, 0x17370, 0x13138, 0x1989e, 0x17338, 0x1b99e, 0x1731c, 0x1310e, 0x1730e, 0x110bc, 0x131bc, 0x1109e, 0x173bc, 0x1319e, 0x1739e, 0x17160, 0x1b8b8, 0x1dc5e, 0x17130, 0x1b89c, 0x17118, 0x1b88e, 0x1710c, 0x17106, 0x130b8, 0x1985e, 0x171b8, 0x1309c, 0x1719c, 0x1308e, 0x1718e, 0x1105e, 0x130de, 0x171de, 0x170b0, 0x1b85c, 0x17098, 0x1b84e, 0x1708c, 0x17086, 0x1305c, 0x170dc, 0x1304e, 0x170ce, 0x17058, 0x1b82e, 0x1704c, 0x17046, 0x1302e, 0x1706e, 0x1702c, 0x17026, 0x10af0, 0x1857c, 0x10a78, 0x1853e, 0x10a3c, 0x10a1e, 0x10b7c, 0x10b3e, 0x1f0ba, 0x1e17a, 0x1c2fa, 0x185fa, 0x11ae0, 0x18d78, 0x1c6be, 0x11a70, 0x18d3c, 0x11a38, 0x18d1e, 0x11a1c, 0x11a0e, 0x10978, 0x184be, 0x11b78, 0x1093c, 0x11b3c, 0x1091e, 0x11b1e, 0x109be, 0x11bbe, 0x13ac0, 0x19d70, 0x1cebc, 0x13a60, 0x19d38, 0x1ce9e, 0x13a30, 0x19d1c, 0x13a18, 0x19d0e, 0x13a0c, 0x13a06, 0x11970, 0x18cbc, 0x13b70, 0x11938, 0x18c9e, 0x13b38, 0x1191c, 0x13b1c, 0x1190e, 0x13b0e, 0x108bc, 0x119bc, 0x1089e, 0x13bbc, 0x1199e, 0x13b9e, 0x1bd60, 0x1deb8, 0x1ef5e, 0x17a40, 0x1bd30, 0x1de9c, 0x17a20, 0x1bd18, 0x1de8e, 0x17a10, 0x1bd0c, 0x17a08, 0x1bd06, 0x17a04, 0x13960, 0x19cb8, 0x1ce5e, 0x17b60, 0x13930, 0x19c9c, 0x17b30, 0x1bd9c, 0x19c8e, 0x17b18, 0x1390c, 0x17b0c, 0x13906, 0x17b06, 0x118b8, 0x18c5e, 0x139b8, 0x1189c, 0x17bb8, 0x1399c, 0x1188e, 0x17b9c, 0x1398e, 0x17b8e, 0x1085e, 0x118de, 0x139de, 0x17bde, 0x17940, 0x1bcb0, 0x1de5c, 0x17920, 0x1bc98, 0x1de4e, 0x17910, 0x1bc8c, 0x17908, 0x1bc86, 0x17904, 0x17902, 0x138b0, 0x19c5c, 0x179b0, 0x13898, 0x19c4e, 0x17998, 0x1bcce, 0x1798c, 0x13886, 0x17986, 0x1185c, 0x138dc, 0x1184e, 0x179dc, 0x138ce, 0x179ce, 0x178a0, 0x1bc58, 0x1de2e, 0x17890, 0x1bc4c, 0x17888, 0x1bc46, 0x17884, 0x17882, 0x13858, 0x19c2e, 0x178d8, 0x1384c, 0x178cc, 0x13846, 0x178c6, 0x1182e, 0x1386e, 0x178ee, 0x17850, 0x1bc2c, 0x17848, 0x1bc26, 0x17844, 0x17842, 0x1382c, 0x1786c, 0x13826, 0x17866, 0x17828, 0x1bc16, 0x17824, 0x17822, 0x13816, 0x17836, 0x10578, 0x182be, 0x1053c, 0x1051e, 0x105be, 0x10d70, 0x186bc, 0x10d38, 0x1869e, 0x10d1c, 0x10d0e, 0x104bc, 0x10dbc, 0x1049e, 0x10d9e, 0x11d60, 0x18eb8, 0x1c75e, 0x11d30, 0x18e9c, 0x11d18, 0x18e8e, 0x11d0c, 0x11d06, 0x10cb8, 0x1865e, 0x11db8, 0x10c9c, 0x11d9c, 0x10c8e, 0x11d8e, 0x1045e, 0x10cde, 0x11dde, 0x13d40, 0x19eb0, 0x1cf5c, 0x13d20, 0x19e98, 0x1cf4e, 0x13d10, 0x19e8c, 0x13d08, 0x19e86, 0x13d04, 0x13d02, 0x11cb0, 0x18e5c, 0x13db0, 0x11c98, 0x18e4e, 0x13d98, 0x19ece, 0x13d8c, 0x11c86, 0x13d86, 0x10c5c, 0x11cdc, 0x10c4e, 0x13ddc, 0x11cce, 0x13dce, 0x1bea0, 0x1df58, 0x1efae, 0x1be90, 0x1df4c, 0x1be88, 0x1df46, 0x1be84, 0x1be82, 0x13ca0, 0x19e58, 0x1cf2e, 0x17da0, 0x13c90, 0x19e4c, 0x17d90, 0x1becc, 0x19e46, 0x17d88, 0x13c84, 0x17d84, 0x13c82, 0x17d82, 0x11c58, 0x18e2e, 0x13cd8, 0x11c4c, 0x17dd8, 0x13ccc, 0x11c46, 0x17dcc, 0x13cc6, 0x17dc6, 0x10c2e, 0x11c6e, 0x13cee, 0x17dee, 0x1be50, 0x1df2c, 0x1be48, 0x1df26, 0x1be44, 0x1be42, 0x13c50, 0x19e2c, 0x17cd0, 0x13c48, 0x19e26, 0x17cc8, 0x1be66, 0x17cc4, 0x13c42, 0x17cc2, 0x11c2c, 0x13c6c, 0x11c26, 0x17cec, 0x13c66, 0x17ce6, 0x1be28, 0x1df16, 0x1be24, 0x1be22, 0x13c28, 0x19e16, 0x17c68, 0x13c24, 0x17c64, 0x13c22, 0x17c62, 0x11c16, 0x13c36, 0x17c76, 0x1be14, 0x1be12, 0x13c14, 0x17c34, 0x13c12, 0x17c32, 0x102bc, 0x1029e, 0x106b8, 0x1835e, 0x1069c, 0x1068e, 0x1025e, 0x106de, 0x10eb0, 0x1875c, 0x10e98, 0x1874e, 0x10e8c, 0x10e86, 0x1065c, 0x10edc, 0x1064e, 0x10ece, 0x11ea0, 0x18f58, 0x1c7ae, 0x11e90, 0x18f4c, 0x11e88, 0x18f46, 0x11e84, 0x11e82, 0x10e58, 0x1872e, 0x11ed8, 0x18f6e, 0x11ecc, 0x10e46, 0x11ec6, 0x1062e, 0x10e6e, 0x11eee, 0x19f50, 0x1cfac, 0x19f48, 0x1cfa6, 0x19f44, 0x19f42, 0x11e50, 0x18f2c, 0x13ed0, 0x19f6c, 0x18f26, 0x13ec8, 0x11e44, 0x13ec4, 0x11e42, 0x13ec2, 0x10e2c, 0x11e6c, 0x10e26, 0x13eec, 0x11e66, 0x13ee6, 0x1dfa8, 0x1efd6, 0x1dfa4, 0x1dfa2, 0x19f28, 0x1cf96, 0x1bf68, 0x19f24, 0x1bf64, 0x19f22, 0x1bf62, 0x11e28, 0x18f16, 0x13e68, 0x11e24, 0x17ee8, 0x13e64, 0x11e22, 0x17ee4, 0x13e62, 0x17ee2, 0x10e16, 0x11e36, 0x13e76, 0x17ef6, 0x1df94, 0x1df92, 0x19f14, 0x1bf34, 0x19f12, 0x1bf32, 0x11e14, 0x13e34, 0x11e12, 0x17e74, 0x13e32, 0x17e72, 0x1df8a, 0x19f0a, 0x1bf1a, 0x11e0a, 0x13e1a, 0x17e3a, 0x1035c, 0x1034e, 0x10758, 0x183ae, 0x1074c, 0x10746, 0x1032e, 0x1076e, 0x10f50, 0x187ac, 0x10f48, 0x187a6, 0x10f44, 0x10f42, 0x1072c, 0x10f6c, 0x10726, 0x10f66, 0x18fa8, 0x1c7d6, 0x18fa4, 0x18fa2, 0x10f28, 0x18796, 0x11f68, 0x18fb6, 0x11f64, 0x10f22, 0x11f62, 0x10716, 0x10f36, 0x11f76, 0x1cfd4, 0x1cfd2, 0x18f94, 0x19fb4, 0x18f92, 0x19fb2, 0x10f14, 0x11f34, 0x10f12, 0x13f74, 0x11f32, 0x13f72, 0x1cfca, 0x18f8a, 0x19f9a, 0x10f0a, 0x11f1a, 0x13f3a, 0x103ac, 0x103a6, 0x107a8, 0x183d6, 0x107a4, 0x107a2, 0x10396, 0x107b6, 0x187d4, 0x187d2, 0x10794, 0x10fb4, 0x10792, 0x10fb2, 0x1c7ea }}; static int ERROR_LEVEL[][] = {{ 27, 917 }, { 522, 568, 723, 809 }, { 237, 308, 436, 284, 646, 653, 428, 379 }, { 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65 }, { 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410 }, { 539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612, 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184, 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543 }, { 521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415, 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704, 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776, 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898, 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34, 211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539 }, { 524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720, 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757, 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884, 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521, 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90, 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134, 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, 722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621, 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528, 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, 73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, 609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10 }, { 352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492, 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781, 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41, 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741, 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258, 240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303, 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, 40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785, 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, 283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772, 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45, 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905, 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808, 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249, 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437, 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842, 37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656, 447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433, 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647, 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263 }}; /** Holds value of property outBits. */ private byte[] outBits; /** Holds value of property bitColumns. */ private int bitColumns; /** Holds value of property codeRows. */ private int codeRows; /** Holds value of property codeColumns. */ private int codeColumns; /** Holds value of property codewords. */ private int[] codewords = new int[MAX_DATA_CODEWORDS + 2]; /** Holds value of property lenCodewords. */ private int lenCodewords; /** Holds value of property errorLevel. */ private int errorLevel; /** Holds value of property text. */ private byte[] text; /** Holds value of property options. */ private int options; /** Holds value of property aspectRatio. */ private float aspectRatio; /** Holds value of property yHeight. */ private float yHeight; protected class Segment { public char type; public int start; public int end; public Segment(char type, int start, int end) { this.type = type; this.start = start; this.end = end; } } protected class SegmentList { protected ArrayList list = new ArrayList(); public void add(char type, int start, int end) { list.add(new Segment(type, start, end)); } public Segment get(int idx) { if (idx < 0 || idx >= list.size()) return null; return (Segment)list.get(idx); } public void remove(int idx) { if (idx < 0 || idx >= list.size()) return; list.remove(idx); } public int size() { return list.size(); } } public static void main(String[] args) { if (args.length < 2) { System.out.println("PDF417 barcode postscript generator"); System.out.println("Usage: java Pdf417lib postscript_file_name barcode_text"); return; } try { Pdf417lib pd = new Pdf417lib(); pd.setText(args[1]); pd.setOptions(Pdf417lib.PDF417_INVERT_BITMAP); pd.paintCode(); java.io.PrintWriter pr = new java.io.PrintWriter(new java.io.FileOutputStream(args[0])); int cols = (pd.getBitColumns() - 1) / 8 + 1; pr.println("/Times findfont\n12 scalefont setfont\n100 80 moveto\n(A PDF417 example.)show"); pr.println("stroke\n100 100 translate\n" + pd.getBitColumns()/2.0 + " " + pd.getCodeRows() * 3/2.0 + " scale"); pr.print(pd.getBitColumns() + " " + pd.getCodeRows() + " 1 [" + pd.getBitColumns() + " 0 0 " + (-pd.getCodeRows()) + " 0 " + pd.getCodeRows() + "]{<"); byte out[] = pd.getOutBits(); for (int k = 0; k < out.length; ++k) { if ((k % cols) == 0) pr.println(); pr.print(Integer.toHexString((out[k] & 0xff) | 0x100).substring(1).toUpperCase()); } pr.println("\n>}image\nshowpage"); pr.close(); } catch (Exception e) { e.printStackTrace(); } } }barby-0.5.1/vendor/Pdf417lib-java-0.91/lib/Pdf417lib.jar0000644000004100000410000010104512147436246022013 0ustar www-datawww-dataPKΕÔ: META-INF/þÊPKPKΕÔ:META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ˜éĘ+h8ä¤*xæ%ëiòrñrPKï'0_<<PKÈ•Ô:Pdf417lib$Segment.classMPMOÂ@} ]jK…"‚‚ ’pÀšˆ$&4lbÒ„¨ Æ{ +–”bÚbâÕ¯ÿã¡1ñàðGg9/ï½™y3;?¿_ßzhiÈ¡¢CEUª ›j*¶Tl3(ÉÓƒ``67JH; YŽrɽ·òýëÑÝQï8ð½JŸú¡Ÿœ1”:ÿò¶ãìÝ’¡=‘a±ï‡âr>õDtãzeôÁl Å…/ƒÂ²ï`â>ºVQ0PÄŽhtä ȫإ1Ëâö@Œ§"¤%Õ¥2œ0‘¸q,bSúu7w¯¼‰RE¶#Ó–.hÑT:&Ç‘br₠ɦ)ZÄô˜„%ŠÎ‘'®[û)˜õ‰ŒÕH‘µš)«¢¤à‹ž5ª¬äÏÐø üeþ†'‡2½f°Ž&±NÕ9ÔÑ€òPK›yMaFµPKÈ•Ô:Pdf417lib$SegmentList.classm’ßkÓPÇ¿·ÍmÖ4kÓÎv?Úêæª¦®ÖU|˜¤ ‚ e¾¥k¬i I;Ðÿ@AA}ð>øîîⳔxnµ[}¹7ùÞs>ßsν¿ÿüø  †ëq¨8¯`«2J ¢XÊ—Ä  ¥,–ŠXÖÄrYÆUɱý>CÖØ3÷Íê o;ÕÛžg>3HÞdˆõŸÚ~é*C¸ß~R¯Ýpì–oÚ®ÝßbHêzù!ñ½¶Å2l׺;è¶,ïÙrH‰ší6%êfSÄE;ÙÊÛV§k¹ô¥6]×òŽéû–ÏÓ›åäR&œ=«ÛÛ'ž¤É·Ÿ º^n2(Û½·kݱ…arœ¾.zS¡!­"jfî?ͪH"%£Æžòi×Tä°¡â,ΩX@]EuÜT° 4qâO ÓíTïµö¬Ý~P1•§“ïä,Ã1euãtêfù±Ði>S'X¡kŸ¥7$Ú4M´M '%ƒ90œ ÞL”b€leí¬2B¤rŒèÎÒø!­Šâ/ç/IÉa>L߀L8`¾òü±ÚY¾PAbæÑiÀ+äøkR·HþÅüg$ó‚2Dü+8;ßù!”_ˆŒ1I*ü Rü-Òü©CÔVˆZ:‰’CRb¢œŒ¨š¿'Îhü#ù':¡ YË´3ÚgBÌ·qfLèü 9-ã]ÁRÀ‹ÐÉE,W¥}Ò_PKY+Õ-•PKÈ•Ô:Pdf417lib.classÔ½w|–Eö÷?sæN½o ܇HK0€R"RD‘ŽTÅE‚E@¤£" H·JÇ5î® ¤)EE@DWPÁ‚€ EEl¸«¿y_ Xöûû>¯ç¯g÷Å)3çœkfΙùÌuÝ,ûÞo¬7ÆÔ‰ÌL ÷ ÿ‘`º…ÿL4Ý"&!|_ÄBâ|G$‰Ä†n¸Á¤¸P3S ÅCðMtÆ©ŽvÆþñH1HqH z“J"E!ŠZ ’ìÝŒqF q¦m—%š¦‘ÒHeœI¢# Aâ!@YzËÅEÊÇGRMõH* —Ó“–hnŠT„T‚T¦ã È•¨UªBªAª'DÒ#WÅEj$šá?â#W{© ©©ÍXê \“©¹6.r]|¤^¢iI‹\©ŸhZ#6 pCÂ5‚4†44mÖ¡Ç-þð·…>͵aL¨ÅãžÜðÒD?¡H³È ¡~j±Í¾4ÁðliiÉZÅGZÇGÚÄEnô­á?èº Òrs\ä/q‘v‰&‹…è¹…Æöñ‘ ”kã#bo0gã6ˆÜéˆA§øHgô.ñ‘Ûâ#·ÇGîˆtÅãNzïBº;1rOä^žß Ò=>’Is¸HÏDó`¤W|$+>Ò;.¼ÂgñŸoyòí÷žü4Ê“¾D†ÚÔ“èýhRwO:Ü€T)Í“—èýßcø¾ˆïÇøÃ÷z_Ä÷|ïA}ã=ßñËïÁønì^nìɽ˜¼‚ɽô¾Bo7ÔŸÎxò!nGé8½Þ“çú!¾Gñ}Ž}Xß“›ésŒôÃT†û\¤$Ož'Ên¢%J;¢ÆôæÓ›AGm‹ ¿ ã#kQ ¿ #ó=iÅHóŒ]<£#]ÌH[1ÒVñž´!Àì"@,!À.´Áw ¾mpkñäFŒ—`|#vK°»“i[D€«Á½ž´`‹ˆ²s.*#XD¨ÓPÆ"‚¶`,‹b=iI€EØù9*¾‹ðm‰Û"ÜZâÑãE mÍyÐÂWq»•-œÚ•-œ‚ăN@ AðhŽ]szoXˆGMLÚAÚÐ6Ö“÷HÏ!pŠ<ɪ½ÇB"O2æ÷XC$¥cy’WcOã» ßCøÖÀ÷i|·á[ß§ñ­G fYYxlã&Ƴ0®‰]M»½³è­EG-¤O‰|ãŸIŧD>ÇÏäh9£ú”gœ Àr†ö)O;Q•ú”…}œ([‰r(+Q'ÔVB$ÔJÔÏPO ö'òÄ{œx[‰×u%j"W!ÊÝJШUˆòQ¶e ê*ÔÏ•‘V!À@HU|ŸÀ7©*vO`—´*˜VÕÀR5hƒ|Bäã”ÔÏÔä2†û áSWËé'<ã8…´Œá~ÂB,£T–Q%3 °… ðêLl!@oâU ¢ n!JoÔJ„šI¨ÞH¯!ͤl+´r… [¨â>¨• :“(}^CšI¼>Œ¯2* 2n37¤Ê¤r`z—2´½ÔøqvÅRFµ—j?ήXʨöR÷K™ê^vÅR†¶T<©ˆï |·àÛµ"f` z¢.EÝ»•x 5ƒP=‘–A+jÆ>T¤Š¸ÍÜ–c©x$0¦ãUöåÞ;8›óÕ¨ìÐW'"±M_a¯¦a<ã-g¢¦á1L¤W·£â–I€4|3!iA€½¨Á.s3Ϩ©‚o |QÓnò¤ûÈFÈO£²7Q¢(ÂÇÈê&J´ë÷YÝD–bé#«¥XµR¬ÕeøNÆw¾—á;ßMTñeøNÆ÷2Ü.£Jc<ãÒØMÆ®4&¥ƒ6Ô÷‰r˜*ù‘Ú}†a¼O¨ÃÔË3 ã}â¦hža,ïùô>µ6‰ p€Ï¢N"ÀFÔ#^4ˆ‚º‘(õPŸ%è$BÕ#h”xõ  ÞFJôzT%ÞûŠô,¡&êz¢(Q®‡(n“;$Åîzˆb¬Ad?£:I™ýBíîg@')³_(Ûý è$µ¶Ÿ¤ÖöS¢spÛŽÛaÜÖ Î |©ÄÃø®AÝO¨“æBÍ!Êv¢¬AÚ4‡-T’‰·‘xuQK`"6o(mui›CÛv‚E]ƒºu"ñ†ò º„Ÿ¨H%ƒg~"ã«‹T·‰AÔº¨si RIÔ…” Ü %“@EÚÇž9Éú…-´=s’ݳír’³í²í2ãíÆøuÔÙÇ@T¤}ì£í¸½N€Ùø¾™M€×!I¸M$ÊF¢ÔAMÂw"ÏÍE­ƒ:›P •‹ú:j¡r‰\)‰xu‚ l≠£RƹHu76v.R¤¤“¨}=[|[ü$Û~_+{6½Ûé]½“혬æ(Ø×‰ó`6Æ«9’ð˜ˆGm<’ð˜ˆÇ`ÔÚ¸ÍÆm0ÒêØà;˜(µ 0Rû8R@09yO«ÄÑf_AMª†q_OA¥­vOƳÕ)¸ñì²DÊl<l»'‘ Ï.K¤¸Æ³÷ÃxŒg«m`[…qÏ~ ã6·0áÀ»ñ]`ô¢Nå‘›)ǯÙSyîfÊq*ÜÌFœÊ#7S“SÙˆ xŒÃcåQ7Jt§<êT¢l¦bË*(ãˆRi*R›$Pãð-”€Û¸À-F 1Œ„À#°ƒ$Ôß7Tç/£RzßP˜;¨ºo(ǔުn Æ›1ž‡4ãÍÏCÚAÁmÆc¾Sp›™‚ï@7B-‹:…(ãˆÒuj§Ð§à»Ž(s °O”qD)ƒ[&Ê1¢|L”cDù˜({ˆrŒ(?åe¢ì!Ê1¢¼L”=D9F”—‰²‡(/eQ^&Ê+DÙC”cD¹—(¯eQî%Ê+DÙC”{‰ò Qî%Ê+DéF€W°‡Ýð}ßn¸½‚[7<ºaòJ`ôÒq”§fsž4ò´ÓlÓ3àåQžvš {”§f×eÌGÈÝøÅ÷4;y7¾Gñ=ÍžÞïQ|wã{ßÝøîÆ7ßÝøÅ7ßÝøÅ7ßÝøæã»ß||óñÍÀ7ßÝøfà›ïn|3ðÍÇ7ß||3ðÍÀ#?ðÀ8?0ì“ ƒ¶#œ/§9iÎp©<Âùrš“æçËiŽ¥#œ/G8Zva|„Så4çË.Œp´ìÂøGË.Œwa¼ã]á¤Y‚ñ.Œ—`¼ ã%/ÁøFŒ—`¼ ã1^‚ñ/ÁøFŒo Œ±[Ø&A/ê£Ó`Þ£ÓFG8‚ŽpðìäX:™³“égÎN£F‹èÝÉ´ˆÞA‹è]DoKzÑÛ’ÞEô¶¤·eÐtÐv„Så4§ÊìÇÈNΗ#;9Zvr–,ähÙÉ ²Se!§JsÚr–4§­9mG8Žp(ìäxØÉ¡°ãa!çÆ!jã™þz>Dmœ"Ý¿Qχ¨SäüµqŠÄ¢6QWÛð=„ï)Ša¾‡ð=EYlÃ÷¾Ûð=„ï6|·á; ßmøÂw¾Ûð=„ï,|·á; ßmøÎÂw¾µð…ï6|ká; ßmøÖÂw¾µð…o-|ká1+ðÀxV`Ø&Am?SH¿SÏ÷J!ýN=÷û•jú¢îû/TJêgJê n§pûmpõ`àK¡Ÿ@ú™Z;…ï ¢Ä÷ä N@¶nTç)Ü>CÝŠïA|?C:tŠýŒ([ ðd+>ƒ<¸å E½ õ |·â» é3¤­DYE”'° òVAªnDÙJ”lÔªø>o6Ò*¤'ˆ’M”ªȆT àûDà‹T5pƒT < Uéý™M÷;›.+XbvÞïì¼^Á³ýzAbÄøÆÇÙQ1>…ñq¶ÕÏlÉãl«ƒgom ìØµŸ mÁî vŸ gÓ}‚ÇŒ?Ì ìØ’¯!ÍÄn v¯!}HxÌÄø5HåÀ>H•±›‰]¤× Ê÷ <cHå ò3{ÿwö~`æ=‚™s ¤÷½Ç9~æ<8ÎypÞã [è8HÇ^Ž‚-ôîå(ØBï^΃AçÆR¤½œK1™AïRHE:fÐÑ©"½=!é혽Ÿ9_2ƒArÈD=ÎIsõ8ÇÍÔ½œ9[P÷rðÌ@}•ËÉ ÔW¹§¡fBÒP3!?' r¼ {âyu„'(ÌØy¿òÞx€Âü {€šüýv€š<@MnÂøåølƨÉM &7a¼ ãÉoÂøu:ãMOÆxÆ“1žŒqiŒ'c¼ ãÒOƸ4Æ“1.qéÀ»É]`ô¢þHyÿÆ«àuì…)ïßx¼–Šø‘½p-‹ý#å}ãØ ‡©ºÿÀ^8LÕýH¦ê`|˜ªÛرÞGÚˆÝìÞG:L¾ÇFŒß‡L ì¨Óg‘&a·»g‘Þ$<&aü,D;<®GRì&aw=Ò³„‡b|}àC4è…üÎå}'ðÌüw®ñy,ÉLÿw.ôyü¬˜ÇŒ?²5~ã•ñŒaüÎ%ÿÔkðø…½ð#;å@eCÀívÔa<°ßNRò¿°?`|’º?ŒñIê~c`ÇÛŽÝF‚îGÚŽÝFìö#mÇx?db`G¼9Hé]ƒ4i"&kæ¤d`ÇÞª‹T’Þ¡Hu‘Jb2©n 1äwÞrX¦×ƒeâõ!‡eÊ –‰ÍY'˜>[òGvhn ²/Ð{˜Žtœd‡¦ã$;t#ÛiÛHÛ>¶év:ö±M'Ò1›¶‰´½Ž4›Ž×!I¨u I¨¹Hßód0ƒ ’Íþ ûüÒa¤“löHÛ‘ö±í'"ÍFZÍ/ËIHµ‘CñcÝWìïÙL_±5¾g}ÅúŠ ±êüн°ÂüŠm°ÂÜ@Mާw59žÞ ÔäxzÇÓ¦w<½azÇÓ¦7ô´ý@ÿú±'å¨Ä¨âr¬øðWÔß÷”í×ÔÕWÔß×”ÔW”Þ×TÓ† ƒ‚ÛL l w3Ùß@ïf²?.è Â¦"£w*d½S! AR)ÞòzË&A/ä7ÞCRCóéo¼‘6$= IÏTXÙàâõ*¬Q ò–ú5ô5¥ò5ô eñ5õò e±ŽÍ´m mu°™ŽÔÁ8:¦Ð6޶yHS蘉G- ‰Gm¨ÁA±ŽAŽàGÛuŒt?ÚŽàÇâßÞ󤽿êÉH¤˜Œ fDýýø U÷§ê¾¦Ö¾¡Â¾£®6 nFÝú96u ê\ÔuxÔ2H ÃËZ*q8cÎXê*d¿ ã÷£aüèó%¥ò%ò%µñ6‰ÿ’3ìmrþ6éKòÞ&ÓcIÞXòCÛXòC[LІú=i,Ff¾'ƒ_’·¯HÙ—¤ì+²õ6ùx‡e›|¼Ã²EÀêŽ >,°º!Ôbj1ȯßz’ÊJ¦²ˆß³Ä?°º_²œ_±œ_³œo³tï°Vï²8c‘& Mc…BH¤THl>‹Ó„k‚¥*dô OÖ³j£ù%n=K7š_âFókxã Ò8而â~=«;ŠWøQ¼Â7T^ëGñÊ3ŠQ\ÙßbqÞb]f fú¤…ù~ÉÜÞbZo3­‡™Ç#Œ^ ±Œ¾8ƒ¬À*ðð¦<|OkÊÛòð ÊÃÇð:ò&#ÃëÈ› c ¯#cxitðNÒ4èàÅd Wœ7én7c¸Ø4 Tn2c¸ŒüKðŒË p9¾Íp[ÀͨnÍp»·f¸5ínÿøÒ“²í;ñéߨQqhÝJÇ t|D5u ãßlá$¼ “—09ÃqØ“ñ=Ùx/â{†ÓñŽàoáv†sòzÂí 'æÝ¸ý„ÛÝxü„Ç1ŒÂøv?aw “côî¡÷½{è=Fïz÷Ðû ½{è}…Þ=ô¾Bï_˜å_é‡<²-Sxޱ|Èso¢ã9Fz³|Ž¿‰š<þ¼…Þçƒ ²9Ûáö|0A¶i;ÜÚáqšÍy† ÛãÓìÐöØf›¥÷4{õ(GiÛMÛQÚvÓ¶›¶|ÚvÓ–O[>m­îbž»‹x­ÐbžÛŠá.æá­n+¶ÐöyŒ—ƒd³·Á¸M0HªýÆ`T”üJþ%¿ iÒ¤%H-xÐ"|[ð EhÁƒZb³·¤·e™Mr„ý±“ýÑ…l’æx4Ç£9ê ì™Ø3W‘”§xÆ{,Xufù$ñU£ãIÂW#Ô“<£¡~#)WÓû4n¿‘”¸= I©[ ”Å,cÌŸð ^Lfcþ„§õb –1ð^¬Á2Þ‹5èʼn^ ·™¸õFª„ÛLÜz#½HøV­w0iê¯r07J¯Reìús£ígÊñ ä85¹ò d&¤ã[Jø½fÆ·”gô`|KyFÆ×ƒñUÄnv=‘*b×R»žŠA/$“P¯R虄z•jÏ$T&¡Ò‚HZÐé~¼ÊaÞüè~¤*øÑ¾;|2c~Œ¬n"Q¥X«Ç˜y)Fõ3/ŨJ1 _¹Ë0žŒñ¯ÀÝe_\…È~éà~JâÆ¤qÒ&¤ÉH“‘®#µÏð´÷ p-Ãx†G¾O¨k™ï3<÷Zæû ¿–ù^Ë|£¸M­R·I¸ÕCz6ðâV/8Ыxüþ^¤Ø] œÔþ| €&—!ïC&AÞ`|û ’|ä1ú7ä~”Ço0Òý<-Þ`¸yü(ðcÎãGkˆ2‡(Û‰òê5D™C”Ö Í!ÊÄ»†(@®!Ê’˜H€ºH%ñŠT©$¾C‘ê¤d`  Éaô¯ó´}M£§í£rrýë<2‡Ñ¿Î#s}¿ÔÁm6n¹Hup›[.Òë„oÜr!I×$½HÁ<|5źêÌÃWS±ƒyøjÊv0ÌÃkc7;°CªØAjv$zkSãƒ!ƒ¸(­¦ÚqQZMÉâ¢4ˆ‹Rí ƒ‹Rí ƒ‹Ò n<«¹â âÆ3ˆOí@åÆ3ˆÏ n<‰”Þx )‘µO!%²ì‰¬x˜Žpp· ^ ‚÷ i<¤‰ŸŠÛfòQŽ•œŠo9q*ʱˆåX¿ìÆaW)»òìÊC‚^HCR;x;X熬î<‚î`±²ºóˆÜÕGø†¬nCV·,nSpk„T·)¸5B*‹[#HYÜAâ1. ‰ì5 ëxøç$ê;’2‚/ïëÁç¤l_Þ×1ŒÏÉÛ¾¼¯c,#øò¾ŽàË{¢Ì%Ê¢ŒDm@”¹D‰´i.QF¯QFBe$¤ ¦ R™À©R™À©A Aâ1.C 5€Œ„ g k)©Ï©œáLa-uõ9å3œ)¬¥¸†3…µTØp¦0œêã67pCªÛÜÀ i-¥7ßú¤ Æõ©Î2RýÀ2Œ/†k)ÖÏ©Îa|1\KÅã‹áZÊv_ ‡ñŰ>vs;¾ÖìøvX?°ãbzëSãÃø”8Œ¯k©öa|ýXKÉãëÇ0¾~Ô:øúQ?èàëÇ0¾G¬å{Ø0>E ã+Dý@åD µ;–¡vc(ÛÔbÔÚ*§e6Ê)F™£ÂBA$t@R)i$ï]r”J L#y©dÉK%û©$>‚Ý„À)ØA"$Do„ü¦BšäùäèЄ$Ï'G…&$y>‰jB’瓨&$¹ INÁmZà†”‚Û´À i>yk‚oJà‰`œBj#RJ`YO’¿ yßñ¶ž$AòÖ“ä/HÞz’¼ž$7Æx>ÆËѨñ˜Çh¤õä|>n£ ÐßÑÆ I!À44¦TR_¤Æø¦¾H)šÑÆ)TNc*g4d=åóU²žòù‚*YOù¬§|Ó;ŸÞQ¼`5Æd>&£xËZO5â-«1Æ£xKÁ¸1—ØñJÖ8°ã•l=¥÷µ¶žÒ[Oé5¦m>m£¸ß7¦cWûÆôŽâVŸBocªsúõ|~ZÏ—§ÆH£¸7FÅÍW(B¡þb)¤G(šX )–’@¥|Š“øGÉjqrþ(Y-N΋“îØ ƒ$Ç$¹‰šÎ²¿K’+¨é,{r4¯@Ž*žâØ=ÊŠW )ÓYö ä£x`G>bé-tŠ,ö|Ç\À:Àw̤b«[Þé¬nSR±€%žÎ7%°kJ**`Ü”TǸvÅ;RQT4%_ð!ê;¾Y~Áר/øµ€T|À—Ê7IÅRñ&©X@*Þ$0™N>šbR“1¼$5Å®vcxSjŠñ^—Šc\ä5%ycx™ú‚ÏT_ð…j|“ . ƒo’Á ´5¥­mc¸®6¥c ×Õ/øò´€ÏwoòP©)Òn‡Ž¼9RG!Qqä(Žew¬x+^‚å|”Å.Áb?Êb—`K°~q,] –..øÖªMgÁÞeÁ¦³`ÓY°¬Æ£,Øå¬Æt>ä]ÎB”`!.g â˜~ ¦9Óÿ€ïuð©n:k°€‹úô`!¸£—`æ—3ó̼3¿œ™7cæðõmz0}®É%˜ùå̼Y0s&ã˜G#}„‘Æ1Ò8Fêdã{”<ÊâA FÇJéÛ¸Hk²ú Ș׮_nž5‘¶få´ìŸ™››•ékM\a¿5¥;´jsmë»uéÔº[óNZ·ìÜ­cóÎm3¬±m­)Ö2{`n^æÀ¼Û2ûÉrüÏ䬹¬Ð¥MÛ;Z·êÖÑ»4oc»ÖôZkJ]ÐÛ2£]—[Úw¢O¬)y¡gÆíAGèü(šwéœÑ­uÇŽ»µk}[ëvçÆøŠtà—dM™"½›ßîתõí[qo8?˜¶íokݱs·m;ßÒ¼}YÛ£_^‡¼kbz x8·è¢•nסWoïÛ¿_+Ьf#¿(:7÷Á:4ïܹuÇö~y;uÎèp^-QÐÍPºuj{g°.%­I¬Î6D­q·dø‚5n‘Aóvnjîy»ŒÛ[wôüȨC—ö-;w!>plÛN-ºvníCÁ:ÝÔ¶MgügZ#‚)ë¥vTÞKÍ;yrK ¦ ¶Ã.X˜Tÿðè1:4oŒ§œÚ¹õ»ùAÑàÆù§ó˜ ¡[=šæ>ùœÍx?÷ö]niݱmËsm|Êš·èäÓŽaó;ºQ §\Ú(­šwn~A²Ü|<˜u·N­;{«v÷e>Y«æÀ>µ:ååôØÇ/|‰"ËQ`ß²]—N~ÙýTÝ]wù‚ _Pã-³û0зÄ÷Ìî•Õ1{¨Èç:Іfçô Ü|ÌHÿ¬-Ï·%fåädç´Ëz «¿5¡¼¬ayÈ7•®öŸåبeõ;½qŸ¬¼³õ™5°OžßÝ—]ʸºŸI©Ü¬¼VY½3‡ôÏ뙓9 +/+ǹ˜_¦³¬s½Xµ¶Œï‚æú~jEtkŠ{­S^ö ™y>Ê@? !3'ï\KÄ·tÈì70¯`¢ezföï9¤f^VkV°evNŽ_)¿lÖ¨ŸDg¿’L¶ùÀ^Áiã˳ZÛ¶ »8‹Ü2{À ÌBó Ã0¹Gfn¿žkW´?ià4•è1’dë›ÛÏk­‹&¿Z0¼ø^C *™ý›çôÂyUdB—µø@fÿ~½ÒÎÌi¹ýFdÕ´¦ÂyïöCú÷ïí·YVÎKÁ2ôÌ80;/­GVÚ@oåý’/‰ìŒï¡Høc’±²—|Þy8y$~ŸeÙ^ïë¾å kë^‰Œ‹x¬\pËHë‘™ÃÓeçæåöÌé7(/­O–¿yeæeûÕ¹¾KnfŸ¬†i :íÜŠwëíë°Û@,ŸÔ­]ÎYGÂÇIã)ƱŸqh°ý²kuðKœw{N¿<Qæl+•í«d'³?Ü0Ç ‘ð—á}ÖÜ\«s¿Y¹i½û ìÕ;{`^bkÒrý…’æwTAcíÚiõk§ È~ +/;±Zó´Â¹f Ë0¨VÍê¹}³}Q”ÍÍËɾ?+0çO^NæÀ\ŽúDÊáQ„i‘ðW<6¶à!4Oô›5­NÚ]~9Ójûÿú=_@ïÙ8™ÄL?A©¬‹<‰LŽL‰D¦B¦EFûÛdbÓÑýø5Md ƒ¼‰L?¿(A]œ+†Hd]ek×¹¦îµ×Õ»¾~ƒ*Åj4¬|uÍ+j]uez“{­ImÔ¸é wÝ}O·îc*Ò—H_¥QéÕª79ºêÑã>"q¡½¸’¬¹âìâw˜;dР으¬^­útú=P¤6Cy°Û–~¾Y= ÆäžþpíìíÞ¾=³—o­Ö²íB”½oõ'Ç[Ûê—@yož“E².Ü€Ãsó²üâ< ûòowAÑTž™ƒ#¹úR‡ù4n{ï˜R­åÿÔí1¢epðæeŸ×RÕþÓ¡ÑÅÕ\00¿ ƒÐúû5+^äbœåÅϹ%“«O(w0kªÖªº¿?ǃ¬åsƒ;ÑÎ ô-[íÜrÝ)AøæœwÛÿqÞÁ¸}‘=¶ó²ú°CÃyÙ7e ;»É— ä#$äé‘[hã=ºøüä´ÌÌåjÔ³6¼Ä ‚•ÊìyçœÌžY¦¢éîã/ôuMÙ°+cÃy÷ g{}P}°×sŠè¹^Ï+¢ñúù-¢óúð"ú¯,¢2!×;À+àsx ?|ÞÎD½>¶ˆžäõGŠÄçõñEô ^´ˆ>Ñ듊ø§zý±"z¯O.¢_éõ)Eô*^ŸZD¯ìõiEâO÷úŒ"úL¯?^DÂëO^¤?UDÚë³.ÒgÑçxý™‹ôg‹ès½>¯ˆ>ßë Šè ½¾¨ˆ¾ØëKŠèÏyý¯Eô罞_DÁÄsáðr<×€û;JÀ_¸pË øÒ ÂE&à¯rG øÊB}U!_]è÷z¡î¯G_ð«ýüËÓ7½Vϯ½åÅ8}•±é%ݵ‰+Œ¤¯4n)ßÂoÑÇ¿sdî2¡˜~¦˜¹Û”4÷øªò·–Â×ú¼Ì–ºê]ã^¼j¹ ¥,4q¡|r/ž‹R<°éîcešXÓÃGðWžÂµ}áÓ¹1þOl¯‹½{{ï>Þ»¯oÝtn7ΡBº[aâÒí ŸîÖÆ¯0 éQ?›pz4²Â;?Ÿr>‚1Ù&Æ 2‰f°ŸOŽ)mr} çùQù+daÜÉÞŽ™ßž¾ÜOŠïßž’ß·WS/ŧŒ{wÝòI ©ÝG<4³s‘¦PAKù¤øaƒæómé]‰U²û Süü€*ñoH™¡žó‹=Üo–æz3Ò46£Ì_Ìhs›ã¶åÜÀþV8°ÿóÀÿc`1—Xa[jRÜB£4zSß^Òâ‡;Îw¼î?ÜGÍ­f¢Ïñ$Óß<懽õܰ+f96½üJSâ|¼Ä uªÏÇ4oÿÞ¹¼V.Ìk\z4i¥)y±ÃL¿ {‡m—rˆ^â Oy‡§½Ãö³¢~ýÒÛ¡®qzRI?yíÞ7˜n)¯” õò‹êîÅä¾MÒS(©x×4}±MI/bâ×>µ¯_¤ÔØAõBËÌeÉ¡kÆø]TÚÕ‹Mýƒxmƒs®à?å™ÿS3©Bjlÿ¾ õŠíß½^l¾¹ú\[™Ø¾Ý »]Ñs]Ú=Ô«^lzÙ˜äØš+MYW/.9޿Ŧ¬oô’”gmMúÆÅÙü? ¢Y‘1”-ÃUÍ7µ.1ªòÿmTçÆàg[nœ³ùð½q¾|ÆÌ1 V+~ýbs<•ºúsìÌÎþùÍù=æ‹Ã˜9~pÏø’zÖgr®/³yþh™on2 Ì-f¡éb™®f±?€–ø}òW_`Ï›)æóœßùæf¥yÙ¼i^5ÛÌRó™ç_™åæ_f¥ ›U¶¸yÝ^nÞ°•ÌZÛмi[š·ìfž½Ål°w˜wlO³Ñòü³ÙÈûgKÖ6÷%C±ïgâÏš,)þ9˜¦Ì2Sž†knaÅË kêê…’C©‹ƒm$å“CÝ]ƸŸè‰T¿°!W/&ÔŦÉ15»š~ƒ&‡–˜“ck$‡’ãzÕì[Ò-T/ÞÓäø^õ BÆuÇÌ®.ß?Ûê^39¡;æA²W‹ñôéày~4• ìb°8+ÖìU`ŽáþóièhJyºÕßÞ3É~!+˜í~w¿ojš¦¾çMͦ¥Ùi2Ì.ÓÍ|hú™Ýþ¸úÈŸÿô)øÐ¼äû^3{ÍZó‰ùØó}æS¿œþMºpƒ~áÌÙûHJùEô~8 )”ĘǛ¦&5_dJ¦&ݹĄ£©©Ý“š÷z15)3hA[ß–I[ÚB½üÅe&-u¥©È~«1É¡¹¦XrÌ\­œÚýE¿Ž1 MBô Ÿ ¯<ëÅ+£Uü œ‡–›}Åù ûãçs燨æKs¹¯žªæ€¿Î}m™ƒ¦¹9dZ™Ã¾¿ñ§ñcGM–ùÖqÇš”€ ’R¾{“òõâ“ãSËÆô”äø•¦jA ø]£W'ÇøÌ$DZ0ù2/9.ZÙ··OŽ¡;½°;­âµø¤Ô|“”šqV¢'‡ê… ÌJº™Ä+ùrsÁy ­= ÇÇzÁѰ=Àcç¨dä:ÿø >rZA˜¤òÆ‹V¨Ê·¿y£+‹¥\dt%F1ÓPw?W„„1Á «_ä•Tö"÷*¸?UØ™zag¾åžÊ]*>)ÇOÉ ù&ré9åÛêÿ›ù„þ¯æc6ý—ù˜ÿ+n-œôa0¿ÿm„iÿÓÀjü·é¹‹ÿs\¼ÍÿwズŒœëLöÐ=¦½„dŽ­jþà™ÿœ)¶ÆTïÊ5óª7“cš‡“? »8Õ¤ø“*,2µ8¡¸uT»3äa¸Zr\ÆE-…ù¾ý¶Iúvw÷ý‹Îl¶‡¹Ã˧üáó£ß“§ý5ö'Èýì÷úoþêwƤ™ßMuuÌ¿ý!÷‡iî·D[kM+¦·uf¨1ÛX3ÍÆ™™6Þ»Pf™¯ïKIªÑ?©DߦžâñŒIvp1?1 u§ñ’»©è:]™’Ó+©Æb“ˆ0Ôð+ï÷ch¥©1.¦FþŸŸŸW=¿ ŒgâíxSÜ>jÔN4eíc¦²ljÛ)¦¡fšÚéæF;ÃÜegšž^îgŸðãÿèÜ©Ta¢—'Å6 r÷¿ÎtÑq=›ß2E2bMa‚þG‚9þo3<éâ ?mœåWc¶ ÛgLû¬©äA°†çרy¦žï³¼Ðgy‘¹Ýó{ì“gÿjFÛçÍl›oò½ü’·yÍú·y>Ýfx«¿á‡S’bûÇ÷õÔ_› n‚ÿ%—MSýŠtNI ™à9yŒÅ')v±©Ü2“c›«.:ÿXV©nÎsóü$Ýߌ®çbóÿ|éâÄ¿lŠÙWL9ûª¹Â.3Õìk¦–]îO¾~Š+MG»Êd{>ľaFø¾‡ì:?­Ï¾:Åfø[B y˜ÅS×7vM×ß‚ NrlùÅ6¤*¶àv ¾ö"SƳKLIêÛ›5eæ³äPR±EfWJ곮ȕ°^LЇ…˜¤´E&ѳ Ü‹-ðî1I‰ ‚Æ„³ê%¤pŸò÷ݬàÁñEü¿ ˜œ˜œ°À¤ywŸæfÕ™…oÜÎj%Ç7IN¬—àýùì˜øU¹j&µ÷µ†u¬G¸uþÇOÌn±‰)ßôÿñùd©xá4ý+|­ Õè+MíÅfRàåg_§a¸@ õB‰*ÝQŠ¥— 'µXi®™c:yq¥©ëßfÚ¦—$u›¦—-V(Öõ­+¡Å<í»ÈT*)[l¹‰YabÎ>êÚs‚Ô‹ Ž•ÁjãÿzPV0¨øEfœ«Wœq ¶XÁ`B Lñóƒ­ªW¼l¸ld¹‰]abχ¿ÖŸ2Ìãœk±s®g'W¾Àõ‚é0˜k“‹Ï1 Â+· æSïÂù¼ñ¸Èggѹè,â™"Sûÿ›E碳(p=;µÿõ,n(œ€O6ßj:?Ì® ÃËM(©³³/Xô$üæ²¾1–)#øC®Ú¥ŽåyÎøð Aø ÍšD?óö+LèüÕïyÿ–jì[&Ö¾íÏö ÁßñßF“dßóh·ÍTµÛÍuö}v;Lû¹Áî4-í‡æf»ÛdØÌÝöŸÑ?6“ìó¸ÝkÚOÌ{öSíûÌ|c÷™oí~sÒ÷¶_Ú{À&Û¯ý…ï-oß³í7¶š=bÓíQ‘ûÖ6¶Çl3{Üö³'lŽ=i²ßÙ¿ÛïíRûƒ}מò?Ú¾ï#û³÷øÕ÷üf·ÿ’DûoI¶øëÞŸRKŒ´+÷‹“!’1#J¬<æífHDH1ù»—URB6J’|"%eŸDå_¢ò§”r ’ìJÉe®´”q×KY×PʹVRÞeHªë,Üír¹»S"®»\á²åJ7Bª¸G¥ª{Rª¹RÝ-–t·A®r›¤†û@®vŸJM·_j»K‘kB‰R7”,×…ÊI½Pª\J“+BU¤q(Cš„ºKÓÐ@i%7„ôúxiš.-COûÑ¿þÞ*ªxÌä{ïŽÂ²yÆ'4=Äm¢qùs[á5$ Õ¹¥†¯£àÛøè,™ÆI'=ý8zùqd™¨ô6ÉÒǤH?Ÿ“OÏ}\Ý_x™Y$'EÓ1ò\:‚Y7M]Ó0töTí²¡àÆ“Àª$Ç\QïBëµIÅØ¶! «Kp1Û¹ÌÔ_ct]eF­4IïJÓdiÚµlh•iæ›VšVšæÁ²>t~Yšâ~Jü²ôÓÉ6ed©(ƒMUÉ15$×\'yæ/2Ät‘ÌÝ^ï!ÃÌcÞn†ŒðSý,¼¯pª ¿#söhRòs&šž”ºÂß`“ÒV˜ä|S"=))Pzµ¤[x~QƒŸd´?ûƘò ÁXSA1WÈxo±ÿìb†²ü¥9ìk•5‰KºÁ¿=×àË ¿. ®À)¡E& N©¹š Ì]kL‹®Ñ–«L«7YÆw¹4¶îm³ÊÜ4¬/™\ã‚›dúsSW/µ]aj¦¯47û?á§‘à~ìøv]íÎ&%ßçôZmÚ5“4æÃU>%©úbN÷{™üÂÑ™E´Ä-å‚Ûœ–¸ %>=~E0ø2s}› Ú˜C™ò|/-_Ч!üVÖ|¿ª,o…çLBzR…Á Brlá’ º““î ºýP“ >²2´¸8?ÆÂ[ ÷M†’Òß>âøÁë@¬oÓT?=ž¾ÒÜ|‰öf‹=”Øç›! jN0ïXsz¨O)6µ”i?{®‰¤G;¬0ÅòƒhÅ¢·>5ŸŸ”nõMÑŽ´ÜíÔ{jƒ„2 CËxr´sÐX}<|ßÔž«M—žÑÛ‚ž©Ù âÒËÄ•2·÷œV0ßÿi9’cŸñïE1sL³ôÔP/:ûsÜ$_´L7Ÿ]¦æË„qÒ©’¸ß䂆³H.\ql+œK÷…‹–žz¶:|þ 3šÒ+hôozp¾¼„Æ…þœcÊ^âxÍÿóÐE8­4]Óý–Jñ¹óêqß{B~”“ò»|çŒ|ïBòÿüqø‹ÂC-Õij$1þÕs'V,ò«×¾:ÅÓ„èTO£Ó< G§{‰Îð´Xt¦§Å£{Z"ú„§IÑ'=-}ÊÓhôiO5:ËÓRÑÙž&GçxzYôOKGŸõ´Lt®§e£ó<-ïiùèOS¢ =M.ò´Bt±§—G—xš}ÎÓŠÑ¿zZ)ú¼§•£ùž^}ÁÓ+£ó´JôïžVþÃÓjÑ=­}ÉÓôèËž^}ÅÓÑW=½:ºÔÓšÑežÖоæiíèrOëDWxzMt¥§u£«<½6ºÚÓ뢯{Z/ú†§×G×xZ?ºÖÓÑuž6Œ®÷´QôMOGßò´IômO›F7xÚ,úާ7D7zÚ<ºÉÓÑÍž¶Œ¾ëi«èO[G·zÚ&úž§7F·yzSt»§m£ï{zst‡§‰~ài»èNOo‰îò´}ôCO3¢»=íýÈÓ[£ÿô´côcO;E÷xÚ9º×Ó.ÑO<½-ú©§·G?óôŽè>O»F÷{zgôsOïŠ~áéÝÑ/=½'ú•§÷FxÚ-úµ§Ý£=ÍŒò´Gô°§=£ßxÚ+zÄÓ¬èQO{G¿õ´Oô˜§}£Ç=í=áé}Ñ“žÞýÎÓþÑï=ýÁÓÑSžfGôtPô´§ƒ£?yšýÙÓÜè/žæEõtHô7OˆžñthôwO‡Eÿåéðè¿=ýÃÓ‘Ñ?=¥Öx6Z­õlŒZñìAµ.£«?¡Ô†à«U Dm|œÚxøxµ ð j᪠Ã'ªÀ'©-Lmqødµ%àSÔ&Á§ª- Ÿ¦6 Ÿ®Vá3Ô–‚ÏT› \íeð'Ô–†?©¶ ü)µeáO«-Ÿ¥¶<|¶Úøµ©ðgÔV€?«örø\µiðyj+Âç«­_ ¶2|¡Ú+à‹Ô^ _¬¶ |‰ÚªðçÔVƒÿUmuøójÓáùj¯‚¿ ¶üoj¯†ÿ]mMø?ÔÖ‚¿¨¶6ü%µuà/«½þŠÚºðWÕ^ _ªö:ø2µõ௩½¾\m}ø µ à+Õ6„¯RÛ¾Zmcøëj›ÀßPÛ¾Fm3øZµ7Àשm_¯¶üMµ-áo©m[mkøµmà悔¾QíMðMjÛÂ7«½þ®Ú¿À·¨mߪöø{jÛ÷©Í€oWÛþ¾Ú[á;Ôv„ ¶|§ÚÎð]j»À?T{|·ÚÛ᩽þOµ]᫽¾Gí]ð½jöø§jï…¦¶|ŸÚîðýj3៫íÿBmOø—j{Á¿R›? ¶7ükµ}àÕö…RÛ~Xí}ðoÔÞ?¢¶?ü¨ÚðoÕ„S› ?®vü„ÚÁð“jsàߩͅ¯6þƒÚ!ðSj€ÿ¨v(ü´ÚaðŸÔ‡ÿ¬vüµ#ῪÿMíhøµcà¿«}þ/µÁÿ­öaøjÇÂÿTûˆçÖ¨·jÇÃEí¸Sû(<¤v"DíoðÔžUû;|˜ÚÁ‡«ý7|„Ú?à#Õþ ¥bà£U,|ŒŠÀTÿíC*à¿}Xü·cUÀûˆ øoÇ©€ÿv¼ øo'¨€ÿöQðßNTÿí$ðß>¦þÛÉ*à¿¢þÛ©*࿦þÛé*à¿¡þÛ™*à¿}\ü·O¨€ÿöIðß>¥þÛ§UÀ;Kü·³UÀ;Gü·Ï¨€ÿöYðßÎUÿí<ðßÎWÿíðß.Tÿí"ðß.Vÿíðß>§þÛ¿ª€ÿöyðßæ«€ÿöðßþMü·Wÿí?TÀû¢ øo_RÿíË*à¿}Eü·¯ª€ÿv© øo—©€ÿö5ðß.Wÿí ðß®Tÿí*ðß®Vÿíë*à¿}Cü·kTÀ»Vü·ëTÀ»^ü·oª€ÿö-ðß¾­þÛ *à¿}Gü·UÀ»Iü·›UÀû® øo·¨€ÿv« øoßSÿí6ðßnWÿíû*à¿Ý¡þÛTÀ»Sü·»TÀû¡ øow«€ÿö#ðßþSü·«€ÿv øo÷ª€ÿöðß~ªþÛÏTÀ»Oü·ûUÀû¹ øo¿Pÿí—*à¿ýJü·TÀûµ øoª€ÿö øo«€ÿöðßQÿíQðß~«þÛc*à¿=®þÛ*à¿=©þÛïTÀû½ øoPÿí)ðßþ¨þÛÓ*à¿ýIü·?«€ÿöðßþªþÛßTÀ{Fü·¿«€ÿö_*à¿ý· øoÿPÿíŸ*à¿ð_¬ ø/¢þ‹Sÿ%¤þKŒ ø/±*à¿Ä©€ÿ¯þK‚ ø/‰*à¿„UÀ‰¨€ÿRLü—â*à¿”Pÿ%Iü—’*à¿DUÀQð_J©€ÿ’¬þËe*à¿”Vÿ¥Œ ø/eUÀ)§þKyð_RTÀIUÿ¥‚ ø/—«€ÿ’¦þKEð_*©€ÿRYü—+TÀ¹Rü—**à¿TUÿ¥š ø/ÕUÀIWÿå*ð_j¨€ÿrµ ø/5UÀ©¥þKmð_ꨀÿr ø/uUÀ¹Vü—ëTÀ©§þËõ*à¿ÔWÿ¥ ø/ UÀi¤þKcð_š¨€ÿÒTü—f*à¿Ü þKsð_Z¨€ÿÒRü—V*à¿´Vÿ¥ ø/7ª€ÿr“ ø/mUÀ¹Yü—¿¨€ÿÒNü—[TÀi¯þK† ø/TÀ¹Uü—Ž*à¿tRÿ¥³ ø/]TÀ¹Mü—ÛUÀ¹Cü—®*à¿Ü©þË]*à¿Ü­þË=*à¿Ü«þK7ð_º«€ÿ’©þKð_zª€ÿÒKü—,ð_z«€ÿÒGü—¾*à¿ôSÿå>ð_îWÿ¥¿ ø/TÀ¨þK¶ ø/ƒTÀ¬þKŽ ø/¹*à¿ä©€ÿ2Dü—TÀªþË0ð_†«€ÿ2Bü—‘*࿌RþËhu࿌Qþ˃êÀyHø/«ÿe¬:ð_QþË8u࿌WþËuà¿<ªü—‰êÀ™¤ü—ÇÔÿ2Yø/SÔÿ2Uø/ÓÔÿ2]ø/3Ôÿ2Sø/«ÿå uà¿<©ü—§Ôÿò´:ð_f©ÿe¶:ð_æ¨ÿåuà¿<«ü—¹êÀ™§ü—ùêÀY ü—…êÀY¤ü—ÅêÀY¢ü—çÔÿòWuà¿<¯ü—|u࿼ ü—¿©ÿåïêÀù‡:ð_^TþËKêÀyYø/¯¨ÿåUuà¿,UþË2u࿼¦ü—åêÀY¡ü—•êÀY¥ü—ÕêÀy]ø/o¨ÿe:ð_Öªÿe:ð_Ö«ÿåMu࿼¥ü—·Õÿ²Aø/ï¨ÿe£:ð_6©ÿe³:ð_ÞUþËuà¿lUþË{êÀÙ¦ü—íêÀy_ø/;Ôÿò:ð_vªÿe—:ð_>TþËnuà¿|¤ü—ªÿåcuà¿ìQþË^uà¿|¢ü—OÕÿò™:ð_ö©ÿe¿:ð_>WþËêÀùRø/_©ÿå€:ð_¾VþËAuà¿RþËauà¿|£ü—#êÀ9ªü—oÕÿrLø/ÇÕÿrBø/'Õÿò:ð_¾WþËêÀ9¥ü—ÕÿrZø/?©ÿåguà¿ü¢ü—_Õÿò›:ð_Ψÿåwuà¿üKø/ÿVþËêÀùSøïŒ:ðßYuà¿uà¿sêÀRþ»uà¿‹Uþ»8uà¿‹Wþ»uà¿KTþ»°:ðßEÔÿ®˜:ðßWþ»êÀ—¤üw%Õÿ.ªüwªüw¥Ôÿ.Yøï.Sþ»ÒêÀWFøïʪÿ]9uà¿+¯üw)êÀ—ªüwÔÿîruà¿KSþ»ŠêÀWIøï*«ÿÝêÀw¥:ðßUQþ»ªêÀWMøïª«ÿ]º:ðß]¥üw5Ôÿîjuà¿«©üwµÔÿ®¶:ðßÕQþ»kÔÿ®®:ðß]«üwשÿ]=uà¿»^øïê«ÿ]uà¿k¨üwÔÿ®±:ðß5Qþ»¦êÀ×LøïnPþ»æêÀ×BøïZªÿ]+uà¿k­üwmÔÿîFuà¿»IøïÚªÿÝÍêÀ÷uà¿k§üw·¨ÿ]{uà¿ËPþ»êÀw«:ðßuTþ»NêÀ×Yøïº¨ÿÝmêÀw»:ðßÝ¡üw]ÕÿîNuà¿»KøïîVþ»{Ôÿî^uà¿ë¦üwÝÕÿ.Søïz¨ÿ]Ouà¿ë¥üwYêÀ×[øïú¨ÿ]_uà¿ë§üw÷©ÿÝýêÀ×_øï¨ÿÝ@uà¿ËVþ»AêÀ7XøïrÔÿ.WøïòÔÿnˆ:ðß= üwCÕÿn˜:ðß Wþ»êÀ7RøïFiüw£5þ»1ÿ݃ÿÝCÿÝÃÿÝX ÿî ÿnœ†À7^Cà¿› !ðß=ª!ðßMÔøï&iüwiüw“5þ»)ÿÝT ÿnš†À7]Cà¿›¡!ðßÍÔøï×øïžÐøïžÔøïžÒøïžÖøïfiüw³5þ»9ÿÝ3ÿݳÿÝ\ ÿnžþM°5Å­ûp¦õ@˜fÁÝ‚;wwwwww×!Á=I€„Å!¸»'HpΛýÍ}õ^U§ø¯œ;§g÷ê^_ï5éÿð5¦ÿÃKÕ˜þ/S3ÚënÜŒÑ@5Ý* QÓ­¼šnÔtúÕtêŸÔÌjLPÍlÕÌnTP͆ÕÌi\PÍ\ÕÌmdPÍ<†ÕÌklPÍ|ÕÌotP͆Õ,h|PÍBÕ,l„PÍO ªYÄ¡šE ªYÌ(¡šÅ ªYÂ8¡š% ªYÊH¡š¥ ªYÆX¡še ªYÎh¡šå ªYÁx¡š ªYɈ¡š• ªYŘ¡šU ªYͨ¡šÕ ªYø¡š5 ªYËÈ¡šµ ªYÇØ¡šu ªYÏ衚õ ªÙÀø¡š ªÙÈ¢š !ªÙÄ¢šM "ªÙÌ(¢šÍ #ªÙÂ8¢š- $ªÙÊH¢š­ %ªÙÆX¢šm &ªÙÎh¢ší 'ªÙÁx¢š (ªÙɈ¢š )ªÙŘ¢š] *ªÙͨ¢šÝ +ªÙø¢š= ,ªÙËÈ¢š½ -ªÙÇØ¢š} .ªÙÏ袚ý /ª9Àø¢š 0ª9È£šƒ 1ª9Ä£šC 2ª9Ì(£šÃ 3ª9Â8£š# 4ª9ÊH£š£ 5ª9ÆX£šc 6ª9Îh£šã 7ª9Áx£š 8ª9Ɉ£ƒÕÛ«1Z½ƒÃÕ;ª1^½“Ö;«1b½‹CÖ»ª1f½›ƒÖ»«1j½‡ÃÖ{ª1n½—×{«1r½C×ûª1v½Ÿƒ×û«1z}€Ãת1~}Ø«1‚}ˆC؇ª¹ Ù\‰l®€D6¿‚D6¦À®›‰L]7™»n&2vÝLd 캙ÈØu3‘)°ëf"S`×ÍD¦À®›‰L]7™»n&2vÝLd 캙ÈØu3‘)°ëf"S`×ÍD¦À®›‰L]7™»n&2vÝLd 캙ÈØu3‘)°ëf"S`×ÍD¦À®›‰L]7™»n&2vÝLd 캙ÈØu3‘)°ëf"S`×ÍD¦À®›‰LÝåjLÝjLݯԘ»_«1v¿Qc ì~«ÆØ]©ÆØ]¥ÆØýN)°û½S`÷5¦Àîj5¦Àî5¦ÀîZ5¦ÀîjLÝŸÔ˜»ëÔ˜»?«1v׫1vQc ìþªÆØýM)°û»S`÷5¦ÀîŸjLÝ jLÝjLÝMjLÝÍjLÝ-jLÝ­jLÝmjLÝíjLÝjLݿԘ»;Õ˜»»Ô˜»»Õ˜»{Ô˜»{Õ˜»ûÔ˜»ûÕ˜»Ô˜»Õ˜»‡Ô˜»‡Õ˜»GÔ˜»GÕ˜»ÇÔ˜»ÇÕ˜»'Ô˜»'Õ˜»§Ô˜»§Õ˜»gÔ˜»gÕ˜»çÔ˜»çÕ˜»Ë›»äMÝ‹ò¦Àî%yüËòøWä!ð¯ÊCà_“‡À¿.ÿ<þ yü›òø·ä!ðoËCàÿ+Gÿ®<þ=yüûòøä!ðÊCà?’‡À,ÿDÿ©<þ3yüçòø/ä!ðÿ“‡À)ÿJÿµ<þyü·òøïä!ðßËCàÇwò8ðyøqäqà‡ò8ð<¼—Çò8ðQ>ÉãÀgyø"?’ÇW~ ‰Œ@"ã£Èø$2>‰ŒO@"ã“Èø$2> ‰ŒÏ@"ã³Èø$2>‰Œÿ†DÆ ‘ñEHd| _†DÆW ‘ñUHd| _‡DÆÿ@"ãÈø&$2¾‰ŒoC"ã!‘ñHd|߃DÆ÷!‘ñHdü?‚DÆ!‘ñHdü?ƒDÆÏ!‘ñ Hdü$2~ ‰Œ_A"ã×Èø $2~ ‰ŒßA"ã÷Èø$29Hd@"Ó8È4„D¦™<$2HdŠÈ” ‘)C"SD¦$2 ‰LãA"Ó ‘i|Hdj!‘©B"ÓÈ$Hdš™&‚D¦‰!‘éÇÈ4 $2M ‰L“A"ÓäÈ4$2M ‰LSA"ÓÔÈ4 $2M ‰LÓA"ÓôÈ4$2͉L3A"ÓÌÈ4 $2ý™f…D¦Ù ‘ivHd𙿄D¦¹ ‘inHd𙿅D¦ù ‘i~HdZ™„D¦… ‘iaHdú)$2-‰L‹B"ÓbÈ´8$2-‰LKB"ÓRÈ´4$2-‰LËB"ÓrÈDÜQJôÀ­DÜ1JôÀ«DÜqJôÀ¯DÜ JôÀ¨DÜIJôÀ¬DÜ)JôÀªDÜiJôÀ®DÜÏ”è;C‰¸3•è;K‰¸Ÿ+Ñw¶=p¿P¢î—JôÀ£DܹJôÀ§DÜùJôÀ] DÜ…JôÀ]¤DÜÅJôÀ]¢DÜ¥JôÀ]¦DÜåJôÀ]¡Dܯ”èûµ=p¿Q¢î·JôÀ]©DÜUJôÀýN‰¸ß+Ñ÷%zà®V¢î%zà®U¢îJôÀýI‰¸ë”èû³=p×+Ñ÷%zàþªDÜß”èû»=pÿP¢îŸJôÀÝ DÜJôÀݤDÜÍJ¦Àî%S`w«’)°»MÉØÝ®d ìîP2vÿR2vw*™»»”LÝÝJ¦Àî%S`w¯’)°»OÉØÝ¯d ìP2v*™»‡”LÝÃJ¦Àî%S`÷¨’)°{LÉØ=®d ìžP2vO*™»§”LÝÓJ¦Àî%S`÷¬’)°{NÉØ=¯d ìþ­d ì^P2v/*™»—” ð/+Aà_Q‚À¿ªM ÿºþ?Jø7” ðo*AàßR‚À¿­ÿ¯þ%ü»Jø÷” ðï+Aà?P‚À¨ÿH ÿ±þ%ü§JøÏ” ðŸ+Aà¿P‚ÀÿO ÿ¥þ+%ü×Jøo” ðß*Aà¿S‚À¯ÿA Þ)áÀ”pàÇQÂ*áÀ7J8ð^ >(áÀG%ø¤„Ÿ•pà‹üH ~\%øñ”pऄ?¾|«„_•pà'P—ü„J8ð)áÀO¬„ÿc%øI”pà'UŸL ~r%ø)”pà§TŸJ ~j%øi”pà§UŸN ~z%ø”pàgTŸI ~f%øY”pࢄ?«ülJ8ð³+áÀÏ¡„?§ü\J8ðs+áÀÏ£„?¯ü|J8ðó+áÀ/ „¿ üBJ8ð +áÀÿT ~eøE•qàSÆ_\~ eø%•qà—RÆ_Z~eøe•qà—SÆ_^~eø•qàWRÆ_Y~eøU•qàWSÆ_]~ eø5•qà×RÆ_[~eøu•qà×SÆ__~eø •qà7RÆßX~eøM•qà7SÆß\~ eü–Êø­”!ð[+Cà·Q†Ào« ßN¿½2~eüŽÊø”!ð;+CàwQ†Àïª ßM¿»2~eüžÊø½”!ð{+Cà÷Q†Àï« ßO¿¿2þeüÊøƒ”!ð+CàQ†Àª ?L¸2þeü‘Êø£”!ðG+CàQ†À« ?N¼2þeü‰Êø“”!ð'+CàOQ†ÀŸª ?Mº2þgÊø3”!ðg*CàÏR†Àÿ\¶2þÊø_*CàÏQ†ÀŸ« ?O¾2þeü…Êø‹”!ð+Cà/Q†À_ª ¿L¹2þ eü¯”!ð¿V†ÀÿFÿ[eü•Êø«”!ð¿S†Àÿ^ÿeüÕÊøk”!ð×*Càÿ¨ ÿ“2þ:eüŸ•!ð×+Càÿ¢ ÿ«2þoÊø¿+Càÿ¡ ÿ§2þeüÊø›”!ð7+CàoQ†Àߪ ¿M»2þeü¿”!ðw*CàïR†Àß­ ¿G¯2þ>eüýÊø”!ð*CàR†À?¬ Dÿ¨2þ1eüãÊø'”!ðO*CàŸR†À?­ Fÿ¬2þ9eüóÊø+Cà_P†À¿¨ Iÿ²2þeü«Êø×”!ð¯+Càÿ£ Cÿ¦2þ-eüÛÊøÿ*CàßQ†À¿« Oÿ¾2þeü‡Êø”!ð+Cà?Q†Àª ÿLÿ¹2þ eüÿ”!ð_*Cà¿R†À­ ÿFÿ­2þ;eü÷Êø”qà2ü@~eø¡2|£Œï•qàƒ2|TÆOÊ8ðY¾(ãÀ”qàÇUÆOþGÊ8ðã+ãÀ·Ê8ðU~ex)ãÀO¨Œ?‘2üÄÊ8ð?VÆŸD~ReøÉ”qà'WÆŸB~Jeø©”qà§VÆŸF~Zeøé”qà§WÆŸA~Feø™”qàgVÆŸEþ'Ê8ð³*ãÀϦŒ?»2üÊ8ðs*ãÀÏ¥Œ?·2ü<Ê8ðó*ãÀϧŒ?¿2üÊ8ð *ãÀ/¤Œ¿°2üO•qàQÁ_T~1øÅUpà—PÁ_R~)ø¥Upà—QÁ_V~9øåUpàWPÁ_Q~%ø•UpàWQÁ_U~5øÕUpà×PÁ_S~-øµUpà×QÁ_W~=øõUpà7PÁßP~#øUpà7QÁßT~3øÍUpà·PÀo©ßJ¿µ ~ü¶*øíT ðÛ«@àwPÀï¨ßI¿³ ~ü®*øÝT ð»«@à÷PÀï©ßK¿· ~ü¾*øýT ðû«@àPÀ¨?H° þü¡*øÃT ð‡«@àPÀ©?J´ þü±*øãT ðÇ«@àOPÀŸ¨?I² þü©*øÓT ð§«@à¦?C¦ þ,üÏU ðg«@à¡ÿ¥ þü¹*øóT ðç«@à/PÀ_¨¿H± þü¥*øËT ð—«@à¯PÀÿJÿküoT ð¿UÀ_©¿Jÿ;üïU ðPÀ_­¿F­ þ*ø?©@à¯SÀÿY½ þ/*ø¿ª@àÿ¦ÿ» þ*øª@àoPÀߨ¿I³ þü­*øÛT ð·«@àïPÀÿK§ þ.üÝ*ø{T ð÷ª@àïSÀ߯@ÿ  þ!üÃ*øGT ðª@àSÀ?®Bÿ¤ þ)üÓ*øgT ðϪ@àŸSÀ?¯ÿ· þü‹*ø—T ð/«@à_QÀ¿ªMÿº þ?*ø7T ðoª@àßRÀ¿­ÿ¯ þü»*ø÷T ðï«@à?PÀ¨ÿHÿ± þü§*øÏT ðŸ«@à¿PÀÿOÿ¥ þ+ü×*øoT ðߪ@à¿SÀ¯ÿA…8§BÜ@…¸qTèªÐרÐçUè *ôÀEzà’ =pY…¸¢BÜH…¸qUèO…¸©Ð7¾ =p­ =pU…¸ Tè“ =pªÐ7‘ =p«Ð÷czà&Q¡nRzà&S¡nrzà¦P¡nJzà¦R¡njzà¦Q¡nZzà¦S¡nzzàfP¡nFzàfR¡nfzàfQ¡î'*ôÀͪBÜl*ôÀÍ®BÜ*ôÀÍ©BÜ\*ôÀÍ­BÜ<*ôÀÍ«BÜ|*ôÀͯBÜ*ôÀ-¨BÜB*ôÀ-¬BÜOUè[D#zàÕˆ¸Å4¢nqè[B#zà–Ôˆ¸¥4¢niè[F#zà–Õˆ¸å4¢nyè[A#zàVÔˆ¸•4¢neè[E#zàVÕˆ¸Õ4¢nuè[C#zàÖÔˆ¸µ4¢nmè[G#zàÖÕˆ¸õ4¢n}èÛ@#zà6Ôˆ¸4¢ncèÛD#zà6Õˆ¸Í4¢nsèÛB#ü–Aà·Ò¿µFøm4‚Ào«~; ðÛkßA#üŽAàwÒ¿³Fø]4‚Àïª~7 ð»kßC#üžAà÷Ò¿·Fø}4‚Àï«~? ðûk?@#üAàÒ°FøC4‚Àªþ0 ð‡k?B#ü‘AàÒ´Føc4‚À«þ8 ðÇk?A#ü‰AàOÒ²FøS4‚ÀŸªþ4 ð§kÿ™Fø34‚ÀŸ©þ, ð?×¶Fø_hÿ¥Føs4‚ÀŸ«þ< ðçk¿@#ü…Aà/Ò±FøK4‚À_ªþ2vXsÝëÝÄm&)Õl»[­éÞÓš%£ýCµ ¨¦Z<‘¯æºŠ7€Ù&¾ìÞ·/[º¡¯–qª%5Æjù2©ZZLÛý“E’Æ:8´ûÁжü Dv¿w^ûA÷¶ý Eet?¸!?8.?hiÝ:kKÕ²ÛÜZ_^©ÖŽú_=nÿ¥ñZ£R?ªÎ’NÇo—îÞ-¶Óôï¶3ﶤ½›µ–wï6ž½›}k÷n«ðn–¡cæÒ¼›%Rµ¹ZPH÷v–Ó½ÿ7nµÔ—v<.ÕÞÏ2Oǯ­Õ¶Õ0ÛZ- ¬ Z¾f«ê¬çnÂjéHíDÕÂ*Ú‰ë84|V‹nl'©–TÑNZõÿMVQÓÉ«ÅôµSTKi§¬ÊØNÕ蚺.è®/µKõ£Ä¸Y¨o»Y-´›ÛÕYHBªbƒ` ¬±Ý¥¿¸m¸8KÏlK»kÿQ~Õ_Û‹\›t×fyƒvmÛqmvص½Ð_ÛÃýµ]͵Y"^wmÀÔ]›å7t×f1ݵYJWwmrØ]›e–ÙµÙ_¹·ÕOÚ©ªå}vç,|všj©xí´­}2ÓU‹*k§oíWÍP-®±ZÌT;SuF£g®&ÖÎÒÄOªEB¶³VKŒjg«Îg¯–gÔÎQÅÎÎY-õ­«Z[;wµ ¤vžþ˜·ZÒM;_kÍ®óW‹/lhíÚ¬–UÚ.Ô® WKÎhZ-Ø©]ÄþÄEûm±jÙíâÕ"¢Ú%ª%¬¶KÚG±® ‡;ª¸ÌÀ-ȹ7æô Ý&ܘËõC7Ëÿ­ŸnìÚ: féîKË{°±»©/ƒ3û±»˜±³¬šnì,"±;†¢ÚÑ {®ºG: Oè†Î}Öß–+2t–xÕ û¢¿-ÑÝ­ ¥VuCg¡ªÝÐY6„ Ý; %uCgsí´•ÚéªÅ ¶ÓWK“èQ›±¿›fªÕÔ ¿l–jA²íOÚ±±»š±³pE»k;‹þêÆÎAº±³À´nì¨Áyªû7cçìS™¯ºK8ì†Ï&´nø,'§]ª:‹Z^ºZ:`»LµÐØvÙjY=írÕYƒìòÕ‹ÚZkl^±Z\n»Rÿñ­ÜZm¬R-Ú¯]µ5>¾Zuvtbõjñ0íÕÒhÚ5«…x´kUËÖi×®•Õ®S-Q¬]·Z@h»^µÐvýjq¾íÕRBÛ «…§µUË j7®ÍÚnÒZ/ö¦ÕrÏÚÍZkÓÞ¼ÿ\·¨–¥ÕnY-­Ýª:»y¶®PÚnSýŽm«Å5µÛUKik·¯ÜîP-»´Ý±ÿ+wª– Óî\-X²Ý¥Zþj»kuöµÝª¥å´»W “k÷¨–ÅÓîÙÚу½ª³›`ï~jÛ‡y¬Ý·ÿ@÷«~Óî_-Ó¥= µS öÅ}Pµ|›öàjñ¸í!ÕÒüÚC[ëA?¬Ãmxhí>Ò~ëºëkn\Dî›,W¥ä¾§äöa¶´Ï)´«PqîA*n*•è”àN*Î}MÅY^ŠUÜTœ;…г0,«8†Zݔ܀Ö{ü/³¥ú’»…’ã“ìfËu(9ËíJŽyh²þÇ'ï')ú‰kÊþÿ¦ª– d%÷y_rwSr|ØÓUKVé¦K»œÚåú‚³Z™©Qo\Û,Õ‚•ºÉ’Y²+¸)(8þÈÙûO²+¸›ú‚›š‚s'Sp\Úœå¬Úd¹g)m6[nMÁYvM—ûPp–xf·|_pv¬g‘êží+ŽÓ6½žvæŒTœ{¬¯¸ý¨8Fzév…¾àV¦à,,ª+8&žåYQ´+ôµbuWPqÌ+W‹oêJŽùdÕj!¦]ÍY†qWs¨RWskSs6!w5g¹Í]ÍY|tWshóºýŒ°^«¾ävèKî JŽ9p£vǾâ~ âìWlÚÚ„±YÛnÞ ÕÕRª»Š³Ô®â,Ó¯«8‹:k·i—¡àÜœÅåü÷H_pKPp‘fwgL]ÁY~cWpà&ë î Înǽ|_nÓõåöåæî¡Ü,ËÏÊÍ2è?ãÛyúr›ŽrC©ªÜZ-²«7g·Çáýjàˆ¶PqŽ£GUbÝѵ§>¦×êŽe^è–u•x6w|Ë œjŸF~bíÓ­Oª}JòÉ•THw swu§r·VwZuœÀ8½’úç~ƺ¬º3ª£wüÌJ ;«öéÈ?¯Ž“ gWÒÚÜ/*é‘î—¬üª;§’†ëÎEMª;¯’æçί¤è¹ *éaîÂJÊ¢»¨%ôûâ–lîK˜ñ«»´’é.«d3¹Ë+Ù¤îŠÚg¯ÿª’…å~Íç]ÝojŸ þÛJöŸ»’…puWU2ãÜïú_ÿ{–„ðT"ÜÜÕ•ˆawM%ÒØ]Ë]Ý+Q¬îO•hYw]Ëgøç–`òë+jî/-Ó_»É^ÿVɧu¯Ž®úTòÂÜ?+9Ðî†Úç³ßXÉ-u7Õ>wüæ–fõ[*1’îV&ân”ZNPÝ^IrwÔ>íû_-vîìßû®JÖ¢»»öã÷T2àܽ¬<º‰®¿îûYQV÷@%Ù=ØýñöúP%:Î=\‰Är wÝŠfìæx¬öÑØ#­Ì0T÷d%jÏ=Õýg¯O·\Ñ3µO~vìÖ}®ÿççšnYQû øØ=T÷bw±öúR%˽\ ¸u¯Œýµ¯V‚ÚÜkÝgd¯¯·|ù?ÝðÚë-MôoVbÇÜ[•Øf÷vËI±ÿVÒ³Ý;-Ò»•pM÷+ônÇU uuTŽ݇¬^º•UjuWGdÁ'•PJ÷iË]þY%›Ø}^É´u_T2BÝÿXW÷eí³ê¿êna{ýº’¹å¾©dݺoYW÷]Kdý÷c¿î‡®â×eKÑ‹«­º›vuöƒû³ì>îhKøÄÞîÿmÍfÝ®îü^]mR+v³ÚröÄÕÂþm›uâj‘ï¶œ}quw!®ö¼‚N\->ÌÖ³"®vÛuâjCÖ‰«{qµ$T×™WË}³õ¬Gœ¼µeÍ,ЦìW’Sõ»‡©«åvÒjqwÝFdU”u@¨NµÈdÛ‰\ßk«©c·yqµøÒN\ÝWˆ«…ÙwâÊïšéÁV³G!®ö`×ÉW‹E¶Èäˆ+?0oµlôN\Ù Î_-ɵۊìÐkë h«¥L›¶N‡¶Z–l§­…Ü.ʲi±~-²xµ6[ÌÚúrI»½:eµ(e[ËÚ·/Ó‚²² _Žꔕýê Õ²³ÛÛmzaýaµÜnV»ÐUÙH®Ö¯WWïèkTK‚5]}£×ÕéÐUë0ØZÖ–*ëUËl×o-PhƒÖ$fÃÖnŠª…y·Sø¬Ú¡ØMû%âfÕòÍ;]ec½E¿nÙYèt•UôÖ½èoÓ/ÿ·í·õÝJÖtmûv5t›¢ÓÕc{]}]µdæNW-´ÓU>üݪÅkwºÊb~³g¿ÇÙ«_Òì]-Y»“V´[ÉžŠ´Z<§I«‰ô, ì÷à¡M´º«V„‡V‹ì¤ÕžÊÐI«…'·Gô‹Ì#kÿȉN[ÓÖÃÇ´õÒ^[{q:Ž}H§­X4&®îÜ1q½¦W¢¹;quôâJD®‰+Á4§µ÷Úê®êµµÂÅcsÓ™í,½´,ÛI+AÔ´º+zi%±“VGÜË9íÒ½²û³«•œISV×+«ûu¯¬ä»»‹º¶—ÖÍzií×pi%^´“Öþq—×þqW°rFZ—륕ØÌNZ‰…5iEÀ¯l91{UKÔÊïðh:em÷é…•ìswµ“ÕO{Y%ÁÒduê^V§4¯ã6ét Ö~’ýK7öÂÚ?Hâo• îNXûqtºQ/¬™š°—rc;_¯«ä »›+ùù&¬õÂJ~¨»­’ìnoçè…•G÷¯J¼¿»sL^îÜ»ÙÒ›´ö qoKË},$‘VN¶>пùƒ•°áNY õÿ­Œ]ã-«ŸÇÚÃz]í‘òDí ò$“J'ª-êòtåÉ î™öÀ^V |vÏUf;]%Ø¿ÓÕ~ä^¨ÜvºÚ?h㥱÷|¹0Ùéjÿ ˜W+Å®òÀ÷zåÁ&¬Äú¼1vg¼‰Ç€²²€y›59ÒÊRóJy§­ýßóÞØµ¿?¦™ôWñ!s¯I+y¨´ö‹ŠNZIYútìžù¬’ÿnÚzܘ¶Þ?¦­ë—ícÒzÖ˜´î<&­çŽI+¡OßIï÷˜b¶ö7ÙÀÕ>^|Ðrnœ~}:èÄ–“> æV·¼dËT݆–w±ö©óÆr¬YNÞ”–\£Ú‡¦;öíÐòïÝ6–o¿éÅkÿ†%úÛg°$¶B·iªÄ%–îïòA·ñåhå²ýZx°\?wº½/G3»Í/GäVìç¿ÁJÝüm¯+×þ± «ôZ1Xµ¯ÆÁjµ\Äê-'/×èîD{]³ò”žÁZ¸?u°v?Y º}0'&×­¤ÖÃèè¾¹«O{Ý _A6¬}ªýF-57n¹û6ékd°éØm´Y¿¿tâÍy·nWÌ»%ºÝ­¿ú™w°u¿?t N1lÛoaÛau Ðrüu‡~2èdœãv;ÕþÑ%;W¢ž’s\sWöÙÝ4SûG½ìŽQšs 'Ascii', :outputter_method => 'to_ascii', :barcode => 'Code128B' } ARGV.options do |o| o.banner = " Usage: #{File.basename(__FILE__)} [OPTIONS] data" o.define_head ' Generates barcodes and prints the generated output to STDOUT' o.separator '' o.separator ' EXPERIMENTAL' o.separator '' o.on('-b', '--barcode=ClassName', String, 'Barcode type (Code128B)'){|v| options[:barcode] = v } o.on('-o', '--outputter=ClassName', String, 'Outputter (Ascii)'){|v| options[:outputter] = v } o.on('-m', '--method=method_name', String, 'Outputter method (to_ascii)'){|v| options[:outputter_method] = v } o.on_tail("-h", "--help", "Show this help message.") { puts o; exit } o.parse! end #p STDIN.read #exit require "barby/outputter/#{options[:outputter].gsub(/[A-Z]/){|c| '_'+c.downcase }[1..-1]}_outputter" barcode_class = Barby.const_get(options[:barcode]) barcode = barcode_class.new($*.empty? ? STDIN.read.chomp : $*[0]) outputter_class = Barby.const_get("#{options[:outputter]}Outputter") outputter = outputter_class.new(barcode) print eval("outputter.#{options[:outputter_method]}(#{ENV['OPTIONS']})") barby-0.5.1/metadata.yml0000644000004100000410000000441612147436246015165 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: barby version: !ruby/object:Gem::Version version: 0.5.1 prerelease: platform: ruby authors: - Tore Darell autorequire: bindir: bin cert_chain: [] date: 2013-03-12 00:00:00.000000000 Z dependencies: [] description: Barby creates barcodes. email: toredarell@gmail.com executables: [] extensions: [] extra_rdoc_files: - README files: - CHANGELOG - README - LICENSE - lib/barby/barcode/bookland.rb - lib/barby/barcode/code_128.rb - lib/barby/barcode/code_25.rb - lib/barby/barcode/code_25_iata.rb - lib/barby/barcode/code_25_interleaved.rb - lib/barby/barcode/code_39.rb - lib/barby/barcode/code_93.rb - lib/barby/barcode/data_matrix.rb - lib/barby/barcode/ean_13.rb - lib/barby/barcode/ean_8.rb - lib/barby/barcode/gs1_128.rb - lib/barby/barcode/pdf_417.rb - lib/barby/barcode/qr_code.rb - lib/barby/barcode/upc_supplemental.rb - lib/barby/barcode.rb - lib/barby/outputter/ascii_outputter.rb - lib/barby/outputter/cairo_outputter.rb - lib/barby/outputter/html_outputter.rb - lib/barby/outputter/pdfwriter_outputter.rb - lib/barby/outputter/png_outputter.rb - lib/barby/outputter/point_matrix.rb - lib/barby/outputter/prawn_outputter.rb - lib/barby/outputter/rmagick_outputter.rb - lib/barby/outputter/svg_outputter.rb - lib/barby/outputter.rb - lib/barby/vendor.rb - lib/barby/version.rb - lib/barby.rb - vendor/Pdf417lib-java-0.91/lib/Pdf417lib.jar - vendor/Pdf417lib-java-0.91/lib/Pdf417lib.java - bin/barby homepage: http://toretore.github.com/barby licenses: [] post_install_message: ! ' *** NEW REQUIRE POLICY ***" Barby no longer require all barcode symbologies by default. You''ll have to require the ones you need. For example, if you need EAN-13, require ''barby/barcode/ean_13''; For a full list of symbologies and their filenames, see README. *** ' rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: barby rubygems_version: 1.8.23 signing_key: specification_version: 3 summary: The Ruby barcode generator test_files: [] barby-0.5.1/CHANGELOG0000644000004100000410000000301712147436246014070 0ustar www-datawww-data* 0.5.1 * Fix some encoding issues (ruby 2.0 & 1.9) * Rewrite HtmlOutputter. Not entirely backwards compatible with the previous version. * 0.5.0 * Require requirement of barcode symbologies in the same way outputters must be required before being used * 0.4.4 * Use Gemfile for dependency management [Ken Collins] * Move to MiniTest [Ken Collins] * HTML outputter [Ken Collins] * Various 1.9 fixes [Ken Collins, Dominique Ribaut] * 0.4.3 * 2- and 5-digit UPC supplements * Use ChunkyPNG for PngOutputter * 0.4.2 * ChunkyPngOutputter now renders 2D barcodes not upside down [Thanks Scient] * 0.4.1 * ChunkyPngOutputter - ChunkyPNG is a pure-Ruby PNG library * 0.4.0 * Can you tell I'm just making up version numbers as I go along? * DataMatrix (not required automatically, requires the 'semacode' gem) * Refactored PrawnOutputter a little. No more stupid options hashes + unbleed attribute * 0.3.2 * Fix bug where Code128 extras choke on newlines [Wayne Conrad] * Don't allow Code128 with empty data strings [Wayne Conrad] * Allow custom :size for QrCodes * 0.3.1 * Add support for PDF417, using Pdf417lib (JRuby only) [Aslak Hellesøy] * 0.3.0 * Make compatible with Ruby 1.9 [Chris Mowforth] * Add SvgOutputter for outputting SVGs without dependencies [Peter H. Li] * 0.2.1 * Allow QR Codes with sizes up to 40 * 0.2.0 * Added support for 2D barcodes * Updated all outputters to support 2D barcodes * Added support for QR Code * 0.1.2 * Added CairoOutputter [Kouhei Sutou] * 0.1.1 * Added PngOutputter that uses "png" gem barby-0.5.1/lib/0000755000004100000410000000000012147436246013423 5ustar www-datawww-databarby-0.5.1/lib/barby.rb0000644000004100000410000000014112147436246015043 0ustar www-datawww-datarequire 'barby/vendor' require 'barby/version' require 'barby/barcode' require 'barby/outputter' barby-0.5.1/lib/barby/0000755000004100000410000000000012147436246014522 5ustar www-datawww-databarby-0.5.1/lib/barby/version.rb0000644000004100000410000000022112147436246016527 0ustar www-datawww-datamodule Barby #:nodoc: module VERSION #:nodoc: MAJOR = 0 MINOR = 5 TINY = 1 STRING = [MAJOR, MINOR, TINY].join('.') end end barby-0.5.1/lib/barby/vendor.rb0000644000004100000410000000014012147436246016337 0ustar www-datawww-dataDir["#{File.dirname(__FILE__)}/../../vendor/*/lib"].each do |d| $: << File.expand_path(d) end barby-0.5.1/lib/barby/outputter/0000755000004100000410000000000012147436246016575 5ustar www-datawww-databarby-0.5.1/lib/barby/outputter/pdfwriter_outputter.rb0000644000004100000410000000333012147436246023262 0ustar www-datawww-datarequire 'barby/outputter' module Barby #Annotates a PDFWriter document with the barcode # #Registers the annotate_pdf method class PDFWriterOutputter < Outputter register :annotate_pdf attr_accessor :x, :y, :height, :xdim #Annotate a PDFWriter document with the barcode # #Valid options are: # #x, y - The point in the document to start rendering from #height - The height of the bars in PDF units #xdim - The X dimension in PDF units def annotate_pdf(pdf, options={}) with_options options do xpos, ypos = x, y orig_xpos = xpos if barcode.two_dimensional? boolean_groups.reverse_each do |groups| groups.each do |bar,amount| if bar pdf.move_to(xpos, ypos). line_to(xpos, ypos+xdim). line_to(xpos+(xdim*amount), ypos+xdim). line_to(xpos+(xdim*amount), ypos). line_to(xpos, ypos). fill end xpos += (xdim*amount) end xpos = orig_xpos ypos += xdim end else boolean_groups.each do |bar,amount| if bar pdf.move_to(xpos, ypos). line_to(xpos, ypos+height). line_to(xpos+(xdim*amount), ypos+height). line_to(xpos+(xdim*amount), ypos). line_to(xpos, ypos). fill end xpos += (xdim*amount) end end end pdf end def x @x || 10 end def y @y || 10 end def height @height || 50 end def xdim @xdim || 1 end end end barby-0.5.1/lib/barby/outputter/cairo_outputter.rb0000644000004100000410000001103412147436246022351 0ustar www-datawww-datarequire 'barby/outputter' require 'cairo' require 'stringio' module Barby #Uses Cairo to render a barcode to a number of formats: PNG, PS, EPS, PDF and SVG # #Registers methods render_to_cairo_context, to_png, to_ps, to_eps, to_pdf and to_svg class CairoOutputter < Outputter register :render_to_cairo_context register :to_png if Cairo.const_defined?(:PSSurface) register :to_ps register :to_eps if Cairo::PSSurface.method_defined?(:eps=) end register :to_pdf if Cairo.const_defined?(:PDFSurface) register :to_svg if Cairo.const_defined?(:SVGSurface) attr_writer :x, :y, :xdim, :height, :margin #Render the barcode onto a Cairo context def render_to_cairo_context(context, options={}) if context.respond_to?(:have_current_point?) and context.have_current_point? current_x, current_y = context.current_point else current_x = x(options) || margin(options) current_y = y(options) || margin(options) end _xdim = xdim(options) _height = height(options) original_current_x = current_x context.save do context.set_source_color(:black) context.fill do if barcode.two_dimensional? boolean_groups.each do |groups| groups.each do |bar,amount| current_width = _xdim * amount if bar context.rectangle(current_x, current_y, current_width, _xdim) end current_x += current_width end current_x = original_current_x current_y += _xdim end else boolean_groups.each do |bar,amount| current_width = _xdim * amount if bar context.rectangle(current_x, current_y, current_width, _height) end current_x += current_width end end end end context end #Render the barcode to a PNG image def to_png(options={}) output_to_string_io do |io| Cairo::ImageSurface.new(options[:format], full_width(options), full_height(options)) do |surface| render(surface, options) surface.write_to_png(io) end end end #Render the barcode to a PS document def to_ps(options={}) output_to_string_io do |io| Cairo::PSSurface.new(io, full_width(options), full_height(options)) do |surface| surface.eps = options[:eps] if surface.respond_to?(:eps=) render(surface, options) end end end #Render the barcode to an EPS document def to_eps(options={}) to_ps(options.merge(:eps => true)) end #Render the barcode to a PDF document def to_pdf(options={}) output_to_string_io do |io| Cairo::PDFSurface.new(io, full_width(options), full_height(options)) do |surface| render(surface, options) end end end #Render the barcode to an SVG document def to_svg(options={}) output_to_string_io do |io| Cairo::SVGSurface.new(io, full_width(options), full_height(options)) do |surface| render(surface, options) end end end def x(options={}) @x || options[:x] end def y(options={}) @y || options[:y] end def width(options={}) (barcode.two_dimensional? ? encoding.first.length : encoding.length) * xdim(options) end def height(options={}) if barcode.two_dimensional? encoding.size * xdim(options) else @height || options[:height] || 50 end end def full_width(options={}) width(options) + (margin(options) * 2) end def full_height(options={}) height(options) + (margin(options) * 2) end def xdim(options={}) @xdim || options[:xdim] || 1 end def margin(options={}) @margin || options[:margin] || 10 end private def output_to_string_io io = StringIO.new yield(io) io.rewind io.read end def render(surface, options) context = Cairo::Context.new(surface) yield(context) if block_given? context.set_source_color(options[:background] || :white) context.paint render_to_cairo_context(context, options) context end end end barby-0.5.1/lib/barby/outputter/rmagick_outputter.rb0000644000004100000410000000524212147436246022675 0ustar www-datawww-datarequire 'barby/outputter' require 'RMagick' module Barby #Renders images from barcodes using RMagick # #Registers the to_png, to_gif, to_jpg and to_image methods class RmagickOutputter < Outputter register :to_png, :to_gif, :to_jpg, :to_image attr_accessor :height, :xdim, :ydim, :margin #Returns a string containing a PNG image def to_png(*a) to_blob('png', *a) end #Returns a string containint a GIF image def to_gif(*a) to_blob('gif', *a) end #Returns a string containing a JPEG image def to_jpg(*a) to_blob('jpg', *a) end def to_blob(format, *a) img = to_image(*a) blob = img.to_blob{|i| i.format = format } #Release the memory used by RMagick explicitly. Ruby's GC #isn't aware of it and can't clean it up automatically img.destroy! if img.respond_to?(:destroy!) blob end #Returns an instance of Magick::Image def to_image(opts={}) with_options opts do canvas = Magick::Image.new(full_width, full_height) bars = Magick::Draw.new x = margin y = margin if barcode.two_dimensional? encoding.each do |line| line.split(//).map{|c| c == '1' }.each do |bar| if bar bars.rectangle(x, y, x+(xdim-1), y+(ydim-1)) end x += xdim end x = margin y += ydim end else booleans.each do |bar| if bar bars.rectangle(x, y, x+(xdim-1), y+(height-1)) end x += xdim end end bars.draw(canvas) canvas end end #The height of the barcode in px #For 2D barcodes this is the number of "lines" * ydim def height barcode.two_dimensional? ? (ydim * encoding.length) : (@height || 100) end #The width of the barcode in px def width length * xdim end #Number of modules (xdims) on the x axis def length barcode.two_dimensional? ? encoding.first.length : encoding.length end #X dimension. 1X == 1px def xdim @xdim || 1 end #Y dimension. Only for 2D codes def ydim @ydim || xdim end #The margin of each edge surrounding the barcode in pixels def margin @margin || 10 end #The full width of the image. This is the width of the #barcode + the left and right margin def full_width width + (margin * 2) end #The height of the image. This is the height of the #barcode + the top and bottom margin def full_height height + (margin * 2) end end end barby-0.5.1/lib/barby/outputter/prawn_outputter.rb0000644000004100000410000000527712147436246022417 0ustar www-datawww-datarequire 'barby/outputter' require 'prawn' module Barby class PrawnOutputter < Outputter register :to_pdf, :annotate_pdf attr_accessor :xdim, :ydim, :x, :y, :height, :margin, :unbleed def to_pdf(opts={}) doc_opts = opts.delete(:document) || {} doc_opts[:page_size] ||= 'A4' annotate_pdf(Prawn::Document.new(doc_opts), opts).render end def annotate_pdf(pdf, opts={}) with_options opts do xpos, ypos = x, y orig_xpos = xpos if barcode.two_dimensional? boolean_groups.reverse_each do |groups| groups.each do |bar,amount| if bar pdf.move_to(xpos+unbleed, ypos+unbleed) pdf.line_to(xpos+unbleed, ypos+ydim-unbleed) pdf.line_to(xpos+(xdim*amount)-unbleed, ypos+ydim-unbleed) pdf.line_to(xpos+(xdim*amount)-unbleed, ypos+unbleed) pdf.line_to(xpos+unbleed, ypos+unbleed) pdf.fill end xpos += (xdim*amount) end xpos = orig_xpos ypos += ydim end else boolean_groups.each do |bar,amount| if bar pdf.move_to(xpos+unbleed, ypos) pdf.line_to(xpos+unbleed, ypos+height) pdf.line_to(xpos+(xdim*amount)-unbleed, ypos+height) pdf.line_to(xpos+(xdim*amount)-unbleed, ypos) pdf.line_to(xpos+unbleed, ypos) pdf.fill end xpos += (xdim*amount) end end end pdf end def length two_dimensional? ? encoding.first.length : encoding.length end def width length * xdim end def height two_dimensional? ? (ydim * encoding.length) : (@height || 50) end def full_width width + (margin * 2) end def full_height height + (margin * 2) end #Margin is used for x and y if not given explicitly, effectively placing the barcode # points from the [left,bottom] of the page. #If you define x and y, there will be no margin. And if you don't define margin, it's 0. def margin @margin || 0 end def x @x || margin end def y @y || margin end def xdim @xdim || 1 end def ydim @ydim || xdim end #Defines an amount to reduce black bars/squares by to account for "ink bleed" #If xdim = 3, unbleed = 0.2, a single/width black bar will be 2.6 wide #For 2D, both x and y dimensions are reduced. def unbleed @unbleed || 0 end private def page_size(xdim, height, margin) [width(xdim,margin), height(height,margin)] end end end barby-0.5.1/lib/barby/outputter/ascii_outputter.rb0000644000004100000410000000161712147436246022352 0ustar www-datawww-datarequire 'barby/outputter' module Barby #Outputs an ASCII representation of the barcode. This is mostly useful for printing #the barcode directly to the terminal for testing. # #Registers to_ascii class AsciiOutputter < Outputter register :to_ascii def to_ascii(opts={}) default_opts = {:height => 10, :xdim => 1, :bar => '#', :space => ' '} default_opts.update(:height => 1, :bar => ' X ', :space => ' ') if barcode.two_dimensional? opts = default_opts.merge(opts) if barcode.two_dimensional? booleans.map do |bools| line_to_ascii(bools, opts) end.join("\n") else line_to_ascii(booleans, opts) end end private def line_to_ascii(booleans, opts) Array.new( opts[:height], booleans.map{|b| (b ? opts[:bar] : opts[:space]) * opts[:xdim] }.join ).join("\n") end end end barby-0.5.1/lib/barby/outputter/png_outputter.rb0000644000004100000410000000453212147436246022045 0ustar www-datawww-datarequire 'barby/outputter' require 'chunky_png' module Barby #Renders the barcode to a PNG image using chunky_png (gem install chunky_png) # #Registers the to_png, to_datastream and to_canvas methods class PngOutputter < Outputter register :to_png, :to_image, :to_datastream attr_accessor :xdim, :ydim, :width, :height, :margin #Creates a PNG::Canvas object and renders the barcode on it def to_image(opts={}) with_options opts do canvas = ChunkyPNG::Image.new(full_width, full_height, ChunkyPNG::Color::WHITE) if barcode.two_dimensional? x, y = margin, margin booleans.each do |line| line.each do |bar| if bar x.upto(x+(xdim-1)) do |xx| y.upto y+(ydim-1) do |yy| canvas[xx,yy] = ChunkyPNG::Color::BLACK end end end x += xdim end y += ydim x = margin end else x, y = margin, margin booleans.each do |bar| if bar x.upto(x+(xdim-1)) do |xx| y.upto y+(height-1) do |yy| canvas[xx,yy] = ChunkyPNG::Color::BLACK end end end x += xdim end end canvas end end #Create a ChunkyPNG::Datastream containing the barcode image # # :constraints - Value is passed on to ChunkyPNG::Image#to_datastream # E.g. to_datastream(:constraints => {:color_mode => ChunkyPNG::COLOR_GRAYSCALE}) def to_datastream(*a) constraints = a.first && a.first[:constraints] ? [a.first[:constraints]] : [] to_image(*a).to_datastream(*constraints) end #Renders the barcode to a PNG image def to_png(*a) to_datastream(*a).to_s end def width length * xdim end def height barcode.two_dimensional? ? (ydim * encoding.length) : (@height || 100) end def full_width width + (margin * 2) end def full_height height + (margin * 2) end def xdim @xdim || 1 end def ydim @ydim || xdim end def margin @margin || 10 end def length barcode.two_dimensional? ? encoding.first.length : encoding.length end end end barby-0.5.1/lib/barby/outputter/point_matrix.rb0000644000004100000410000000702012147436246021636 0ustar www-datawww-datarequire 'barby/outputter' module Barby class Outputter #A collection of rows - an array of arrays class PointMatrix < Array DEFAULT_XDIM = 1.0 DEFAULT_YDIM = 1.0 attr_writer :xdim, :ydim def initialize(*a, &b) # new([[t,f,t,f], [f,t,f,t], ...]) if a[0].is_a?(Array) && a[0][0].is_a?(Array) && [true,false].include?(a[0][0][0]) a[0] = a[0].map{|r| PointRow.new(self, r) } # new(['1010', '0101', ...]) elsif a[0].is_a?(Array) && a[0][0].is_a?(String) a[0] = a[0].map{|s| PointRow.new(self, s) } end super(*a, &b) end def xdim @xdim || DEFAULT_XDIM end def ydim @ydim || DEFAULT_YDIM end def width inject(0){|m,r| r.width > m ? r.width : m } end def height inject(0){|s,r| s + r.height } end def to_s map{|r| r.to_s } end def inspect to_s end def dup self.class.new(map{|r| r.dup }) end end class PointRow < Array attr_reader :matrix attr_accessor :xdim, :ydim def initialize(*a, &b) raise ArgumentError, 'PointRow must belong to a PointMatrix' unless a[0].is_a?(PointMatrix) @matrix = a.shift #Assume called with [t,f,t,f,..] if a[0].is_a?(Array) && [true, false].include?(a[0][0]) a[0] = a[0].map{|b| Point.new(self, b) } #Assume called with '1010..' elsif a[0].is_a?(String) a[0] = a[0].split(//).map{|s| Point.new(self, s == '1') } end super(*a, &b) end def booleans map{|p| p.active? } end def xdim @xdim || matrix.xdim end def ydim @ydim || matrix.ydim end def width inject(0){|s,p| s + p.width } end def height inject(0){|m,p| p.height > m ? p.height : m } end def to_s inject(''){|s,p| s << (p.active ? '1' : '0') } end def inspect to_s end def ==(other) super #Just to say explicitly that equality should behave like in an array end def dup self.class.new(matrix, map{|p| p.dup }) end end class Point attr_reader :row, :active attr_writer :width, :height, :color, :active alias active? active def initialize(row, active, opts={}) @row = row self.active = active end def color @color || (active ? Color.new(0,0,0) : nil) end def width @width || row.xdim end def height @height || row.ydim end def ==(other) active == other.active && width == other.width && height == other.height && color == other.color end end #TODO Add alpha class Color MIN_VALUE = 0 MAX_VALUE = 255 attr_reader :red, :blue, :green def initialize(r, b, g) self.red, self.blue, self.green = r, b, g end def red=(r) set_color(:red, r) end def blue=(b) set_color(:blue, b) end def green=(g) set_color(:green, g) end def ==(other) other.red == red && other.blue == blue && other.green == green end private def set_color(name, value) raise ArgumentError, "Value must be between 0-255" if value < MIN_VALUE || value > MAX_VALUE instance_variable_set("@#{name}", value) end end end end barby-0.5.1/lib/barby/outputter/html_outputter.rb0000644000004100000410000000421612147436246022224 0ustar www-datawww-datarequire 'barby/outputter' module Barby # Outputs an HTML containing cells for each module in the barcode. # # This does NOT include any styling, you're expected to add the relevant # CSS yourself. The markup is simple: One
with class 'barby-barcode', # one or more inside a each containing #
for each module with the additional class "on" or "off". # # Example, let's say the barcode.encoding == ['101', '010'] : # # # # # # # # # # # # # # #
# # You could then style this with: # # table.barby-barcode { border-spacing: 0; } # tr.barby-row {} # td.barby-cell { width: 3px; height: 3px; } # td.barby-cell.on { background: #000; } # # Options: # # :class_name - A class name that will be added to the in addition to barby-barcode class HtmlOutputter < Outputter register :to_html attr_accessor :class_name def to_html(options = {}) with_options options do start + rows.join + stop end end def rows if barcode.two_dimensional? rows_for(booleans) else rows_for([booleans]) end end def rows_for(boolean_groups) boolean_groups.map{|g| row_for(cells_for(g)) } end def cells_for(booleans) booleans.map{|b| b ? on_cell : off_cell } end def row_for(cells) "#{cells.join}" end def on_cell '' end def off_cell '' end def start '
' end def stop '
' end end end barby-0.5.1/lib/barby/outputter/svg_outputter.rb0000644000004100000410000001152712147436246022062 0ustar www-datawww-datarequire 'barby/outputter' module Barby #Renders the barcode to a simple SVG image using pure ruby # #Registers the to_svg, bars_to_path, and bars_to_rects method # #Bars can be rendered as a stroked path or as filled rectangles. Path #generally yields smaller files, but this doesn't render cleanly in Firefox #3 for odd xdims. My guess is that the renderer tries to put half a pixel #on one side of the path and half on the other, leading to fuzzy dithering #instead of sharp, clean b&w. # #Therefore, default behavior is to use a path for even xdims, and #rectangles for odd. This can be overridden by calling with explicit #:use => 'rects' or :use => 'path' options. class SvgOutputter < Outputter register :to_svg, :bars_to_rects, :bars_to_path attr_writer :title, :xdim, :ydim, :height, :rmargin, :lmargin, :tmargin, :bmargin, :xmargin, :ymargin, :margin def to_svg(opts={}) with_options opts do case opts[:use] when 'rects' then bars = bars_to_rects when 'path' then bars = bars_to_path else xdim_odd = (xdim % 2 == 1) bars = xdim_odd ? bars_to_rects : bars_to_path end <<-"EOT" #{escape title} #{bars} EOT end end def bars_to_rects(opts={}) rects = '' with_options opts do x, y = lmargin, tmargin if barcode.two_dimensional? boolean_groups.each do |line| line.each do |bar, amount| bar_width = xdim * amount if bar rects << %Q|\n| end x += bar_width end y += ydim x = lmargin end else boolean_groups.each do |bar, amount| bar_width = xdim * amount if bar rects << %Q|\n| end x += bar_width end end end # with_options rects end def bars_to_path(opts={}) with_options opts do %Q|| end end def bars_to_path_data(opts={}) path_data = '' with_options opts do x, y = lmargin+(xdim/2), tmargin if barcode.two_dimensional? booleans.each do |line| line.each do |bar| if bar path_data << "M#{x} #{y}V #{y+ydim}" end x += xdim end y += ydim x = lmargin+(xdim/2) end else booleans.each do |bar| if bar path_data << "M#{x} #{y}V#{y+height}" end x += xdim end end end # with_options path_data end def title @title || barcode.to_s end def width length * xdim end def height barcode.two_dimensional? ? (ydim * encoding.length) : (@height || 100) end def full_width width + lmargin + rmargin end def full_height height + tmargin + bmargin end def xdim @xdim || 1 end def ydim @ydim || xdim end def lmargin @lmargin || _xmargin end def rmargin @rmargin || _xmargin end def tmargin @tmargin || _ymargin end def bmargin @bmargin || _ymargin end def xmargin return nil if @lmargin || @rmargin _margin end def ymargin return nil if @tmargin || @bmargin _margin end def margin return nil if @ymargin || @xmargin || @tmargin || @bmargin || @lmargin || @rmargin _margin end def length barcode.two_dimensional? ? encoding.first.length : encoding.length end def svg_width(opts={}) opts[:rot] ? full_height : full_width end def svg_height(opts={}) opts[:rot] ? full_width : full_height end def transform(opts={}) opts[:rot] ? %Q|transform="rotate(-90) translate(-#{full_width}, 0)"| : nil end private def _xmargin @xmargin || _margin end def _ymargin @ymargin || _margin end def _margin @margin || 10 end #Escape XML special characters <, & and > def escape(str) str.gsub('&', '&').gsub('<', '<').gsub('>', '>') end end end barby-0.5.1/lib/barby/barcode/0000755000004100000410000000000012147436246016121 5ustar www-datawww-databarby-0.5.1/lib/barby/barcode/pdf_417.rb0000644000004100000410000000322712147436246017616 0ustar www-datawww-datarequire 'barby/barcode' require 'java' require 'Pdf417lib' import 'Pdf417lib' module Barby class Pdf417 < Barcode2D DEFAULT_OPTIONS = { :options => 0, :y_height => 3, :aspect_ratio => 0.5, :error_level => 0, :len_codewords => 0, :code_rows => 0, :code_columns => 0 } # Creates a new Pdf417 barcode. The +options+ argument # can use the same keys as DEFAULT_OPTIONS. Please consult # the source code of Pdf417lib.java for details about values # that can be used. def initialize(data, options={}) @pdf417 = Java::Pdf417lib.new self.data = data DEFAULT_OPTIONS.merge(options).each{|k,v| send("#{k}=", v) } end def options=(options) @options = options end def y_height=(y_height) @pdf417.setYHeight(y_height) end def aspect_ratio=(aspect_ratio) @pdf417.setAspectRatio(aspect_ratio) end def error_level=(error_level) @pdf417.setErrorLevel(error_level) end def len_codewords=(len_codewords) @pdf417.setLenCodewords(len_codewords) end def code_rows=(code_rows) @pdf417.setCodeRows(code_rows) end def code_columns=(code_columns) @pdf417.setCodeColumns(code_columns) end def data=(data) @pdf417.setText(data) end def encoding @pdf417.paintCode() cols = (@pdf417.getBitColumns() - 1) / 8 + 1 enc = [] row = nil @pdf417.getOutBits.each_with_index do |byte, n| if n%cols == 0 row = "" enc << row end row << sprintf("%08b", (byte & 0xff) | 0x100) end enc end end endbarby-0.5.1/lib/barby/barcode/code_25.rb0000644000004100000410000000734112147436246017673 0ustar www-datawww-datarequire 'barby/barcode' module Barby #Standard/Industrial 2 of 5, non-interleaved # #Checksum not included by default, to include it, #set include_checksum = true class Code25 < Barcode1D WIDE = W = true NARROW = N = false START_ENCODING = [W,W,N] STOP_ENCODING = [W,N,W] ENCODINGS = { 0 => [N,N,W,W,N], 1 => [W,N,N,N,W], 2 => [N,W,N,N,W], 3 => [W,W,N,N,N], 4 => [N,N,W,N,W], 5 => [W,N,W,N,N], 6 => [N,W,W,N,N], 7 => [N,N,N,W,W], 8 => [W,N,N,W,N], 9 => [N,W,N,W,N] } attr_accessor :data, :narrow_width, :wide_width, :space_width, :include_checksum def initialize(data) self.data = data end def data_encoding digit_encodings.join end def data_encoding_with_checksum digit_encodings_with_checksum.join end def encoding start_encoding+(include_checksum? ? data_encoding_with_checksum : data_encoding)+stop_encoding end def characters data.split(//) end def characters_with_checksum characters.push(checksum.to_s) end def digits characters.map{|c| c.to_i } end def digits_with_checksum digits.push(checksum) end def even_and_odd_digits alternater = false digits.reverse.partition{ alternater = !alternater } end def digit_encodings raise_invalid unless valid? digits.map{|d| encoding_for(d) } end alias character_encodings digit_encodings def digit_encodings_with_checksum raise_invalid unless valid? digits_with_checksum.map{|d| encoding_for(d) } end alias character_encodings_with_checksum digit_encodings_with_checksum #Returns the encoding for a single digit def encoding_for(digit) encoding_for_bars(ENCODINGS[digit]) end #Generate encoding for an array of W,N def encoding_for_bars(*bars) wide, narrow, space = wide_encoding, narrow_encoding, space_encoding bars.flatten.inject '' do |enc,bar| enc + (bar == WIDE ? wide : narrow) + space end end def encoding_for_bars_without_end_space(*a) encoding_for_bars(*a).gsub(/0+$/, '') end #Mod10 def checksum evens, odds = even_and_odd_digits sum = odds.inject(0){|sum,d| sum + d } + evens.inject(0){|sum,d| sum + (d*3) } sum %= 10 sum.zero? ? 0 : 10-sum end def checksum_encoding encoding_for(checksum) end #The width of a narrow bar in xdims def narrow_width @narrow_width || 1 end #The width of a wide bar in xdims #By default three times as wide as a narrow bar def wide_width @wide_width || narrow_width*3 end #The width of the space between the bars in xdims #By default the same width as a narrow bar # #A space serves only as a separator for the bars, #there is no encoded meaning in them def space_width @space_width || narrow_width end #2 of 5 doesn't require a checksum, but you can include a Mod10 checksum #by setting +include_checksum+ to true def include_checksum? include_checksum end def data=(data) @data = "#{data}" end def start_encoding encoding_for_bars(START_ENCODING) end def stop_encoding encoding_for_bars_without_end_space(STOP_ENCODING) end def narrow_encoding '1' * narrow_width end def wide_encoding '1' * wide_width end def space_encoding '0' * space_width end def valid? data =~ /^[0-9]*$/ end def to_s (include_checksum? ? characters_with_checksum : characters).join end private def raise_invalid raise ArgumentError, "data not valid" end end end barby-0.5.1/lib/barby/barcode/code_39.rb0000644000004100000410000001774412147436246017710 0ustar www-datawww-data#encoding: ASCII require 'barby/barcode' module Barby class Code39 < Barcode1D WIDE = W = true NARROW = N = false ENCODINGS = { ' ' => [N,W,W,N,N,N,W,N,N], '$' => [N,W,N,W,N,W,N,N,N], '%' => [N,N,N,W,N,W,N,W,N], '+' => [N,W,N,N,N,W,N,W,N], '-' => [N,W,N,N,N,N,W,N,W], '.' => [W,W,N,N,N,N,W,N,N], '/' => [N,W,N,W,N,N,N,W,N], '0' => [N,N,N,W,W,N,W,N,N], '1' => [W,N,N,W,N,N,N,N,W], '2' => [N,N,W,W,N,N,N,N,W], '3' => [W,N,W,W,N,N,N,N,N], '4' => [N,N,N,W,W,N,N,N,W], '5' => [W,N,N,W,W,N,N,N,N], '6' => [N,N,W,W,W,N,N,N,N], '7' => [N,N,N,W,N,N,W,N,W], '8' => [W,N,N,W,N,N,W,N,N], '9' => [N,N,W,W,N,N,W,N,N], 'A' => [W,N,N,N,N,W,N,N,W], 'B' => [N,N,W,N,N,W,N,N,W], 'C' => [W,N,W,N,N,W,N,N,N], 'D' => [N,N,N,N,W,W,N,N,W], 'E' => [W,N,N,N,W,W,N,N,N], 'F' => [N,N,W,N,W,W,N,N,N], 'G' => [N,N,N,N,N,W,W,N,W], 'H' => [W,N,N,N,N,W,W,N,N], 'I' => [N,N,W,N,N,W,W,N,N], 'J' => [N,N,N,N,W,W,W,N,N], 'K' => [W,N,N,N,N,N,N,W,W], 'L' => [N,N,W,N,N,N,N,W,W], 'M' => [W,N,W,N,N,N,N,W,N], 'N' => [N,N,N,N,W,N,N,W,W], 'O' => [W,N,N,N,W,N,N,W,N], 'P' => [N,N,W,N,W,N,N,W,N], 'Q' => [N,N,N,N,N,N,W,W,W], 'R' => [W,N,N,N,N,N,W,W,N], 'S' => [N,N,W,N,N,N,W,W,N], 'T' => [N,N,N,N,W,N,W,W,N], 'U' => [W,W,N,N,N,N,N,N,W], 'V' => [N,W,W,N,N,N,N,N,W], 'W' => [W,W,W,N,N,N,N,N,N], 'X' => [N,W,N,N,W,N,N,N,W], 'Y' => [W,W,N,N,W,N,N,N,N], 'Z' => [N,W,W,N,W,N,N,N,N] } #In extended mode, each character is replaced with two characters from the "normal" encoding EXTENDED_ENCODINGS = { "\000" => '%U', " " => " ", "@" => "%V", "`" => "%W", "\001" => '$A', "!" => "/A", "A" => "A", "a" => "+A", "\002" => '$B', '"' => "/B", "B" => "B", "b" => "+B", "\003" => '$C', "#" => "/C", "C" => "C", "c" => "+C", "\004" => '$D', "$" => "/D", "D" => "D", "d" => "+D", "\005" => '$E', "%" => "/E", "E" => "E", "e" => "+E", "\006" => '$F', "&" => "/F", "F" => "F", "f" => "+F", "\007" => '$G', "'" => "/G", "G" => "G", "g" => "+G", "\010" => '$H', "(" => "/H", "H" => "H", "h" => "+H", "\011" => '$I', ")" => "/I", "I" => "I", "i" => "+I", "\012" => '$J', "*" => "/J", "J" => "J", "j" => "+J", "\013" => '$K', "+" => "/K", "K" => "K", "k" => "+K", "\014" => '$L', "," => "/L", "L" => "L", "l" => "+L", "\015" => '$M', "-" => "-", "M" => "M", "m" => "+M", "\016" => '$N', "." => ".", "N" => "N", "n" => "+N", "\017" => '$O', "/" => "/O", "O" => "O", "o" => "+O", "\020" => '$P', "0" => "0", "P" => "P", "p" => "+P", "\021" => '$Q', "1" => "1", "Q" => "Q", "q" => "+Q", "\022" => '$R', "2" => "2", "R" => "R", "r" => "+R", "\023" => '$S', "3" => "3", "S" => "S", "s" => "+S", "\024" => '$T', "4" => "4", "T" => "T", "t" => "+T", "\025" => '$U', "5" => "5", "U" => "U", "u" => "+U", "\026" => '$V', "6" => "6", "V" => "V", "v" => "+V", "\027" => '$W', "7" => "7", "W" => "W", "w" => "+W", "\030" => '$X', "8" => "8", "X" => "X", "x" => "+X", "\031" => '$Y', "9" => "9", "Y" => "Y", "y" => "+Y", "\032" => '$Z', ":" => "/Z", "Z" => "Z", "z" => "+Z", "\033" => '%A', ";" => "%F", "[" => "%K", "{" => "%P", "\034" => '%B', "<" => "%G", "\\" => "%L", "|" => "%Q", "\035" => '%C', "=" => "%H", "]" => "%M", "}" => "%R", "\036" => '%D', ">" => "%I", "^" => "%N", "~" => "%S", "\037" => '%E', "?" => "%J", "_" => "%O", "\177" => "%T" } CHECKSUM_VALUES = { '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'N' => 23, 'M' => 22, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, '-' => 36, '.' => 37, ' ' => 38, '$' => 39, '/' => 40, '+' => 41, '%' => 42 } START_ENCODING = [N,W,N,N,W,N,W,N,N] # * STOP_ENCODING = [N,W,N,N,W,N,W,N,N] # * attr_accessor :data, :spacing, :narrow_width, :wide_width, :extended, :include_checksum # Do not surround "data" with the mandatory "*" as is this is done automically for you. # So instead of passing "*123456*" as "data", just pass "123456". def initialize(data, extended=false) self.data = data self.extended = extended raise(ArgumentError, "data is not valid (extended=#{extended?})") unless valid? yield self if block_given? end #Returns the characters that were passed in, no matter it they're part of #the extended charset or if they're already encodable, "normal" characters def raw_characters data.split(//) end #Returns the encodable characters. If extended mode is enabled, each character will #first be replaced by two characters from the encodable charset def characters chars = raw_characters extended ? chars.map{|c| EXTENDED_ENCODINGS[c].split(//) }.flatten : chars end def characters_with_checksum characters + [checksum_character] end def encoded_characters characters.map{|c| encoding_for(c) } end def encoded_characters_with_checksum encoded_characters + [checksum_encoding] end #The data part of the encoding (no start+stop characters) def data_encoding encoded_characters.join(spacing_encoding) end def data_encoding_with_checksum encoded_characters_with_checksum.join(spacing_encoding) end def encoding return encoding_with_checksum if include_checksum? start_encoding+spacing_encoding+data_encoding+spacing_encoding+stop_encoding end def encoding_with_checksum start_encoding+spacing_encoding+data_encoding_with_checksum+spacing_encoding+stop_encoding end #Checksum is optional def checksum characters.inject(0) do |sum,char| sum + CHECKSUM_VALUES[char] end % 43 end def checksum_character CHECKSUM_VALUES.invert[checksum] end def checksum_encoding encoding_for(checksum_character) end #Set include_checksum to true to make +encoding+ include the checksum def include_checksum? include_checksum end #Takes an array of WIDE/NARROW values and returns the string representation for #those bars and spaces, using wide_width and narrow_width def encoding_for_bars(*bars_and_spaces) bar = false bars_and_spaces.flatten.map do |width| bar = !bar (bar ? '1' : '0') * (width == WIDE ? wide_width : narrow_width) end.join end #Returns the string representation for a single character def encoding_for(character) encoding_for_bars(ENCODINGS[character]) end #Spacing between the characters in xdims. Spacing will be inserted #between each character in the encoding def spacing @spacing ||= 1 end def spacing_encoding '0' * spacing end def narrow_width @narrow_width ||= 1 end def wide_width @wide_width ||= 2 end def extended? extended end def start_encoding encoding_for_bars(START_ENCODING) end def stop_encoding encoding_for_bars(STOP_ENCODING) end def valid? if extended? raw_characters.all?{|c| EXTENDED_ENCODINGS.include?(c) } else raw_characters.all?{|c| ENCODINGS.include?(c) } end end def to_s data end end end barby-0.5.1/lib/barby/barcode/code_25_iata.rb0000644000004100000410000000076712147436246020676 0ustar www-datawww-datarequire 'barby/barcode/code_25' module Barby #The IATA version of 2 of 5 is identical to its parent except for different #start and stop codes. This is the one used on the tags they put on your #luggage when you check it in at the airport. class Code25IATA < Code25 START_ENCODING = [N,N] STOP_ENCODING = [W,N] def start_encoding encoding_for_bars(START_ENCODING) end def stop_encoding encoding_for_bars_without_end_space(STOP_ENCODING) end end end barby-0.5.1/lib/barby/barcode/bookland.rb0000644000004100000410000000161312147436246020240 0ustar www-datawww-data#encoding: ASCII require 'barby/barcode/ean_13' module Barby #Bookland barcodes are EAN-13 barcodes with number system #978 (hence "Bookland"). The data they encode is an ISBN #with its check digit removed. This is a convenience class #that takes an ISBN no instead of "pure" EAN-13 data. class Bookland < EAN13 BOOKLAND_NUMBER_SYSTEM = '978' attr_accessor :isbn def initialize(isbn) self.isbn = isbn raise ArgumentError, 'data not valid' unless valid? end def data BOOKLAND_NUMBER_SYSTEM+isbn_only end #Removes any non-digit characters, number system and check digit #from ISBN, so "978-82-92526-14-9" would result in "829252614" def isbn_only s = isbn.gsub(/[^0-9]/, '') if s.size > 10#Includes number system s[3,9] else#No number system, may include check digit s[0,9] end end end end barby-0.5.1/lib/barby/barcode/upc_supplemental.rb0000644000004100000410000000475012147436246022034 0ustar www-datawww-datarequire 'barby/barcode' require 'barby/barcode/ean_13' module Barby class UPCSupplemental < Barby::Barcode1D attr_accessor :data FORMAT = /^\d\d\d\d\d$|^\d\d$/ START = '1011' SEPARATOR = '01' ODD = :odd EVEN = :even PARITY_MAPS = { 2 => { 0 => [ODD, ODD], 1 => [ODD, EVEN], 2 => [EVEN, ODD], 3 => [EVEN, EVEN] }, 5 => { 0 => [EVEN, EVEN, ODD, ODD, ODD], 1 => [EVEN, ODD, EVEN, ODD, ODD], 2 => [EVEN, ODD, ODD, EVEN, ODD], 3 => [EVEN, ODD, ODD, ODD, EVEN], 4 => [ODD, EVEN, EVEN, ODD, ODD], 5 => [ODD, ODD, EVEN, EVEN, ODD], 6 => [ODD, ODD, ODD, EVEN, EVEN], 7 => [ODD, EVEN, ODD, EVEN, ODD], 8 => [ODD, EVEN, ODD, ODD, EVEN], 9 => [ODD, ODD, EVEN, ODD, EVEN] } } ENCODINGS = { ODD => EAN13::LEFT_ENCODINGS_ODD, EVEN => EAN13::LEFT_ENCODINGS_EVEN } def initialize(data) self.data = data end def size data.size end def two_digit? size == 2 end def five_digit? size == 5 end def characters data.split(//) end def digits characters.map{|c| c.to_i } end #Odd and even methods are only useful for 5 digits def odd_digits alternater = false digits.reverse.select{ alternater = !alternater } end def even_digits alternater = true digits.reverse.select{ alternater = !alternater } end def odd_sum odd_digits.inject(0){|s,d| s + d * 3 } end def even_sum even_digits.inject(0){|s,d| s + d * 9 } end #Checksum is different for 2 and 5 digits #2-digits don't really have a checksum, just a remainder to look up the parity def checksum if two_digit? data.to_i % 4 elsif five_digit? (odd_sum + even_sum) % 10 end end #Parity maps are different for 2 and 5 digits def parity_map PARITY_MAPS[size][checksum] end def encoded_characters parity_map.zip(digits).map do |parity, digit| ENCODINGS[parity][digit] end end def encoding START + encoded_characters.join(SEPARATOR) end def valid? data =~ FORMAT end def to_s data end NO_PRICE = new('90000') #The book doesn't have a suggested retail price COMPLIMENTARY = new('99991') #The book is complimentary (~free) USED = new('99990') #The book is marked as used end end barby-0.5.1/lib/barby/barcode/qr_code.rb0000644000004100000410000000541712147436246020071 0ustar www-datawww-datarequire 'rqrcode' require 'barby/barcode' module Barby #QrCode is a thin wrapper around the RQRCode library class QrCode < Barcode2D #Maximum sizes for each correction level for binary data #It's an array SIZES = { #L M Q H 1 => [17, 14, 11, 7], 2 => [32, 26, 20, 14], 3 => [53, 42, 32, 24], 4 => [78, 62, 46, 34], 5 => [106, 84, 60, 44], 6 => [134, 106, 74, 58], 7 => [154, 122, 86, 64], 8 => [192, 152, 108, 84], 9 => [230, 180, 130, 98], 10 => [271, 213, 151, 119], 11 => [321, 251, 177, 137], 12 => [367, 287, 203, 155], 13 => [425, 331, 241, 177], 14 => [458, 362, 258, 194], 15 => [520, 412, 292, 220], 16 => [586, 450, 322, 250], 17 => [644, 504, 364, 280], 18 => [718, 560, 394, 310], 19 => [792, 624, 442, 338], 20 => [858, 666, 482, 382], 21 => [929, 711, 509, 403], 22 => [1003, 779, 565, 439], 23 => [1091, 857, 611, 461], 24 => [1171, 911, 661, 511], 25 => [1273, 997, 715, 535], 26 => [1367, 1059, 751, 593], 27 => [1465, 1125, 805, 625], 28 => [1528, 1190, 868, 658], 29 => [1628, 1264, 908, 698], 30 => [1732, 1370, 982, 742], 31 => [1840, 1452, 1030, 790], 32 => [1952, 1538, 1112, 842], 33 => [2068, 1628, 1168, 898], 34 => [2188, 1722, 1228, 958], 35 => [2303, 1809, 1283, 983], 36 => [2431, 1911, 1351, 1051], 37 => [2563, 1989, 1423, 1093], 38 => [2699, 2099, 1499, 1139], 39 => [2809, 2213, 1579, 1219], 40 => [2953, 2331, 1663, 1273] }.sort LEVELS = { :l => 0, :m => 1, :q => 2, :h => 3 } attr_reader :data attr_writer :level, :size def initialize(data, options={}) self.data = data options.each{|k,v| send("#{k}=", v) } raise(ArgumentError, "data too large") unless size end def data=(data) @data = data end def encoding rqrcode.modules.map{|r| r.inject(''){|s,m| s << (m ? '1' : '0') } } end #Error correction level #Can be one of [:l, :m, :q, :h] (7%, 15%, 25%, 30%) def level @level || :l end def size #@size is only used for manual override, if it's not set #manually the size is always dynamic, calculated from the #length of the data return @size if @size level_index = LEVELS[level] length = data.length found_size = nil SIZES.each do |size,max_values| if max_values[level_index] >= length found_size = size break end end found_size end def to_s data[0,20] end private #Generate an RQRCode object with the available values def rqrcode RQRCode::QRCode.new(data, :level => level, :size => size) end end end barby-0.5.1/lib/barby/barcode/data_matrix.rb0000644000004100000410000000127512147436246020750 0ustar www-datawww-datarequire 'semacode' #Ruby 1.8: gem install semacode - Ruby 1.9: gem install semacode-ruby19 require 'barby/barcode' module Barby #Uses the semacode library (gem install semacode) to encode DataMatrix barcodes class DataMatrix < Barcode2D attr_accessor :data def initialize(data) self.data = data end def data=(data) @data = data @encoder = nil end def encoder @encoder ||= ::DataMatrix::Encoder.new(data) end def encoding encoder.data.map{|a| a.map{|b| b ? '1' : '0' }.join } end def semacode? #TODO: Not sure if this is right data =~ /^http:\/\// end def to_s data end end end barby-0.5.1/lib/barby/barcode/code_25_interleaved.rb0000644000004100000410000000344712147436246022260 0ustar www-datawww-datarequire 'barby/barcode/code_25' module Barby #Code 2 of 5 interleaved. Same as standard 2 of 5, but spaces are used #for encoding as well as the bars. Each pair of numbers get interleaved, #that is, the first is encoded in the bars and the second is encoded #in the spaced. This means an interleaved 2/5 barcode must have an even #number of digits. class Code25Interleaved < Code25 START_ENCODING = [N,N,N,N] STOP_ENCODING = [W,N,N] def digit_pairs(d=nil) (d || digits).inject [] do |ary,d| ary << [] if !ary.last || ary.last.size == 2 ary.last << d ary end end def digit_pairs_with_checksum digit_pairs(digits_with_checksum) end def digit_encodings raise_invalid unless valid? digit_pairs.map{|p| encoding_for_pair(p) } end def digit_encodings_with_checksum digit_pairs_with_checksum.map{|p| encoding_for_pair(p) } end def encoding_for_pair(pair) bars, spaces = ENCODINGS[pair.first], ENCODINGS[pair.last] encoding_for_interleaved(bars.zip(spaces)) end #Encodes an array of interleaved W or N bars and spaces #ex: [W,N,W,W,N,N] => "111011100010" def encoding_for_interleaved(*bars_and_spaces) bar = false#starts with bar bars_and_spaces.flatten.inject '' do |enc,bar_or_space| bar = !bar enc << (bar ? '1' : '0') * (bar_or_space == WIDE ? wide_width : narrow_width) end end def start_encoding encoding_for_interleaved(START_ENCODING) end def stop_encoding encoding_for_interleaved(STOP_ENCODING) end def valid? # When checksum is included, it's included when determining "evenness" super && digits.size % 2 == (include_checksum? ? 1 : 0) end end end barby-0.5.1/lib/barby/barcode/code_93.rb0000644000004100000410000001667612147436246017713 0ustar www-datawww-data#encoding: ASCII require 'barby/barcode' module Barby class Code93 < Barcode1D SHIFT_DOLLAR = "\301" # ($) SHIFT_PERCENT = "\302" # (%) SHIFT_SLASH = "\303" # (/) SHIFT_PLUS = "\304" # (+) SHIFT_CHARACTERS = [SHIFT_DOLLAR, SHIFT_PERCENT, SHIFT_SLASH, SHIFT_PLUS] ENCODINGS = { "0" => "100010100", "1" => "101001000", "2" => "101000100", "3" => "101000010", "4" => "100101000", "5" => "100100100", "6" => "100100010", "7" => "101010000", "8" => "100010010", "9" => "100001010", "A" => "110101000", "B" => "110100100", "C" => "110100010", "D" => "110010100", "E" => "110010010", "F" => "110001010", "G" => "101101000", "H" => "101100100", "I" => "101100010", "J" => "100110100", "K" => "100011010", "L" => "101011000", "M" => "101001100", "N" => "101000110", "O" => "100101100", "P" => "100010110", "Q" => "110110100", "R" => "110110010", "S" => "110101100", "T" => "110100110", "U" => "110010110", "V" => "110011010", "W" => "101101100", "X" => "101100110", "Y" => "100110110", "Z" => "100111010", "-" => "100101110", "." => "111010100", " " => "111010010", "$" => "111001010", "/" => "101101110", "+" => "101110110", "%" => "110101110", SHIFT_DOLLAR => "100100110", SHIFT_PERCENT => "111011010", SHIFT_SLASH => "111010110", SHIFT_PLUS => "100110010" } EXTENDED_MAPPING = { "\000" => "\302U", " " => " ", "@" => "\302V", "`" => "\302W", "\001" => "\301A", "!" => "\303A", "A" => "A", "a" => "\304A", "\002" => "\301B", '"' => "\303B", "B" => "B", "b" => "\304B", "\003" => "\301C", "#" => "\303C", "C" => "C", "c" => "\304C", "\004" => "\301D", "$" => "\303D", "D" => "D", "d" => "\304D", "\005" => "\301E", "%" => "\303E", "E" => "E", "e" => "\304E", "\006" => "\301F", "&" => "\303F", "F" => "F", "f" => "\304F", "\007" => "\301G", "'" => "\303G", "G" => "G", "g" => "\304G", "\010" => "\301H", "(" => "\303H", "H" => "H", "h" => "\304H", "\011" => "\301I", ")" => "\303I", "I" => "I", "i" => "\304I", "\012" => "\301J", "*" => "\303J", "J" => "J", "j" => "\304J", "\013" => "\301K", "/" => "\303K", "K" => "K", "k" => "\304K", "\014" => "\301L", "," => "\303L", "L" => "L", "l" => "\304L", "\015" => "\301M", "-" => "-", "M" => "M", "m" => "\304M", "\016" => "\301N", "." => ".", "N" => "N", "n" => "\304N", "\017" => "\301O", "+" => "\303O", "O" => "O", "o" => "\304O", "\020" => "\301P", "0" => "0", "P" => "P", "p" => "\304P", "\021" => "\301Q", "1" => "1", "Q" => "Q", "q" => "\304Q", "\022" => "\301R", "2" => "2", "R" => "R", "r" => "\304R", "\023" => "\301S", "3" => "3", "S" => "S", "s" => "\304S", "\024" => "\301T", "4" => "4", "T" => "T", "t" => "\304T", "\025" => "\301U", "5" => "5", "U" => "U", "u" => "\304U", "\026" => "\301V", "6" => "6", "V" => "V", "v" => "\304V", "\027" => "\301W", "7" => "7", "W" => "W", "w" => "\304W", "\030" => "\301X", "8" => "8", "X" => "X", "x" => "\304X", "\031" => "\301Y", "9" => "9", "Y" => "Y", "y" => "\304Y", "\032" => "\301Z", ":" => "\303Z", "Z" => "Z", "z" => "\304Z", "\033" => "\302A", ";" => "\302F", "[" => "\302K", "{" => "\302P", "\034" => "\302B", "<" => "\302G", "\\" => "\302L", "|" => "\302Q", "\035" => "\302C", "=" => "\302H", "]" => "\302M", "}" => "\302R", "\036" => "\302D", ">" => "\302I", "^" => "\302N", "~" => "\302S", "\037" => "\302E", "?" => "\302J", "_" => "\302O", "\177" => "\302T" } EXTENDED_CHARACTERS = EXTENDED_MAPPING.keys - ENCODINGS.keys CHARACTERS = { 0 => "0", 1 => "1", 2 => "2", 3 => "3", 4 => "4", 5 => "5", 6 => "6", 7 => "7", 8 => "8", 9 => "9", 10 => "A", 11 => "B", 12 => "C", 13 => "D", 14 => "E", 15 => "F", 16 => "G", 17 => "H", 18 => "I", 19 => "J", 20 => "K", 21 => "L", 22 => "M", 23 => "N", 24 => "O", 25 => "P", 26 => "Q", 27 => "R", 28 => "S", 29 => "T", 30 => "U", 31 => "V", 32 => "W", 33 => "X", 34 => "Y", 35 => "Z", 36 => "-", 37 => ".", 38 => " ", 39 => "$", 40 => "/", 41 => "+", 42 => "%", 43 => SHIFT_DOLLAR, 44 => SHIFT_PERCENT, 45 => SHIFT_SLASH, 46 => SHIFT_PLUS } VALUES = CHARACTERS.invert START_ENCODING = '101011110' # * STOP_ENCODING = '101011110' TERMINATE_ENCODING = '1' attr_accessor :data def initialize(data) self.data = data end def extended? raw_characters.any?{|c| EXTENDED_CHARACTERS.include?(c) } end def raw_characters data.split(//) end def characters raw_characters.map{|c| EXTENDED_MAPPING[c].split(//) }.flatten end def encoded_characters characters.map{|c| ENCODINGS[c] } end alias character_encodings encoded_characters def start_encoding START_ENCODING end #The stop encoding includes the termination bar def stop_encoding STOP_ENCODING+TERMINATE_ENCODING end def encoding start_encoding+data_encoding_with_checksums+stop_encoding end def data_encoding character_encodings.join end def data_encoding_with_checksums (character_encodings + checksum_encodings).join end def checksum_encodings checksum_characters.map{|c| ENCODINGS[c] } end def checksum_encoding checksum_encodings.join end def checksums [c_checksum, k_checksum] end def checksum_characters checksums.map{|s| CHARACTERS[s] } end #Returns the values used for computing the C checksum #in the "right" order (i.e. reversed) def checksum_values characters.map{|c| VALUES[c] }.reverse end #Returns the normal checksum plus the c_checksum #This is used for calculating the k_checksum def checksum_values_with_c_checksum [c_checksum] + checksum_values end #Calculates the C checksum based on checksum_values def c_checksum sum = 0 checksum_values.each_with_index do |value, index| sum += ((index % 20) + 1) * value end sum % 47 end def c_checksum_character CHARACTERS[c_checksum] end def c_checksum_encoding ENCODINGS[c_checksum_character] end #Calculates the K checksum based on checksum_values_with_c_checksum def k_checksum sum = 0 checksum_values_with_c_checksum.each_with_index do |value, index| sum += ((index % 15) + 1) * value end sum % 47 end def k_checksum_character CHARACTERS[k_checksum] end def k_checksum_encoding ENCODINGS[k_checksum_character] end def valid? characters.all?{|c| ENCODINGS.include?(c) } end def to_s data end end end barby-0.5.1/lib/barby/barcode/ean_13.rb0000644000004100000410000000767112147436246017527 0ustar www-datawww-datarequire 'barby/barcode' module Barby #EAN-13, aka UPC-A, barcodes are the ones you can see at your local #supermarket, in your house and, well, everywhere.. # #To use this for a UPC barcode, just add a 0 to the front class EAN13 < Barcode1D LEFT_ENCODINGS_ODD = { 0 => '0001101', 1 => '0011001', 2 => '0010011', 3 => '0111101', 4 => '0100011', 5 => '0110001', 6 => '0101111', 7 => '0111011', 8 => '0110111', 9 => '0001011' } LEFT_ENCODINGS_EVEN = { 0 => '0100111', 1 => '0110011', 2 => '0011011', 3 => '0100001', 4 => '0011101', 5 => '0111001', 6 => '0000101', 7 => '0010001', 8 => '0001001', 9 => '0010111' } RIGHT_ENCODINGS = { 0 => '1110010', 1 => '1100110', 2 => '1101100', 3 => '1000010', 4 => '1011100', 5 => '1001110', 6 => '1010000', 7 => '1000100', 8 => '1001000', 9 => '1110100' } #Describes whether the left-hand encoding should use #LEFT_ENCODINGS_ODD or LEFT_ENCODINGS_EVEN, based on the #first digit in the number system (and the barcode as a whole) LEFT_PARITY_MAPS = { 0 => [:odd, :odd, :odd, :odd, :odd, :odd], #UPC-A 1 => [:odd, :odd, :even, :odd, :even, :even], 2 => [:odd, :odd, :even, :even, :odd, :even], 3 => [:odd, :odd, :even, :even, :even, :odd], 4 => [:odd, :even, :odd, :odd, :even, :even], 5 => [:odd, :even, :even, :odd, :odd, :even], 6 => [:odd, :even, :even, :even, :odd, :odd], 7 => [:odd, :even, :odd, :even, :odd, :even], 8 => [:odd, :even, :odd, :even, :even, :odd], 9 => [:odd, :even, :even, :odd, :even, :odd] } #These are the lines that "stick down" in the graphical representation START = '101' CENTER = '01010' STOP = '101' #EAN-13 barcodes have 12 digits + check digit FORMAT = /^\d{12}$/ attr_accessor :data def initialize(data) self.data = data raise ArgumentError, 'data not valid' unless valid? end def characters data.split(//) end def numbers characters.map{|s| s.to_i } end def odd_and_even_numbers alternater = false numbers.reverse.partition{ alternater = !alternater } end #Numbers that are encoded to the left of the center #The first digit is not included def left_numbers numbers[1,6] end #Numbers that are encoded to the right of the center #The checksum is included here def right_numbers numbers_with_checksum[7,6] end def numbers_with_checksum numbers + [checksum] end def data_with_checksum data + checksum.to_s end def left_encodings left_parity_map.zip(left_numbers).map do |parity,number| parity == :odd ? LEFT_ENCODINGS_ODD[number] : LEFT_ENCODINGS_EVEN[number] end end def right_encodings right_numbers.map{|n| RIGHT_ENCODINGS[n] } end def left_encoding left_encodings.join end def right_encoding right_encodings.join end def encoding start_encoding+left_encoding+center_encoding+right_encoding+stop_encoding end #The parities to use for encoding left-hand numbers def left_parity_map LEFT_PARITY_MAPS[numbers.first] end def weighted_sum odds, evens = odd_and_even_numbers odds.map!{|n| n * 3 } sum = (odds+evens).inject(0){|s,n| s+n } end #Mod10 def checksum mod = weighted_sum % 10 mod.zero? ? 0 : 10-mod end def checksum_encoding RIGHT_ENCODINGS[checksum] end def valid? data =~ FORMAT end def to_s data_with_checksum end #Is this a UPC-A barcode? #UPC barcodes are EAN codes that start with 0 def upc? numbers.first.zero? end def start_encoding START end def center_encoding CENTER end def stop_encoding STOP end end class UPCA < EAN13 def data '0' + super end end end barby-0.5.1/lib/barby/barcode/code_128.rb0000644000004100000410000003425412147436246017762 0ustar www-datawww-data#encoding: ASCII require 'barby/barcode' module Barby #Code 128 barcodes # #Note that you must provide a type for each object, either by passing a string #as a second parameter to Code128.new or by instantiating one of the child classes. # #You can switch type by using the CODEA, CODEB and CODEC characters: # # "\305" => A # "\306" => B # "\307" => C # #As an example, here's one that starts out as type A and then switches to B and then C: # # Code128A.new("ABC123\306def\3074567") class Code128 < Barcode1D ENCODINGS = { 0 => "11011001100", 1 => "11001101100", 2 => "11001100110", 3 => "10010011000", 4 => "10010001100", 5 => "10001001100", 6 => "10011001000", 7 => "10011000100", 8 => "10001100100", 9 => "11001001000", 10 => "11001000100", 11 => "11000100100", 12 => "10110011100", 13 => "10011011100", 14 => "10011001110", 15 => "10111001100", 16 => "10011101100", 17 => "10011100110", 18 => "11001110010", 19 => "11001011100", 20 => "11001001110", 21 => "11011100100", 22 => "11001110100", 23 => "11101101110", 24 => "11101001100", 25 => "11100101100", 26 => "11100100110", 27 => "11101100100", 28 => "11100110100", 29 => "11100110010", 30 => "11011011000", 31 => "11011000110", 32 => "11000110110", 33 => "10100011000", 34 => "10001011000", 35 => "10001000110", 36 => "10110001000", 37 => "10001101000", 38 => "10001100010", 39 => "11010001000", 40 => "11000101000", 41 => "11000100010", 42 => "10110111000", 43 => "10110001110", 44 => "10001101110", 45 => "10111011000", 46 => "10111000110", 47 => "10001110110", 48 => "11101110110", 49 => "11010001110", 50 => "11000101110", 51 => "11011101000", 52 => "11011100010", 53 => "11011101110", 54 => "11101011000", 55 => "11101000110", 56 => "11100010110", 57 => "11101101000", 58 => "11101100010", 59 => "11100011010", 60 => "11101111010", 61 => "11001000010", 62 => "11110001010", 63 => "10100110000", 64 => "10100001100", 65 => "10010110000", 66 => "10010000110", 67 => "10000101100", 68 => "10000100110", 69 => "10110010000", 70 => "10110000100", 71 => "10011010000", 72 => "10011000010", 73 => "10000110100", 74 => "10000110010", 75 => "11000010010", 76 => "11001010000", 77 => "11110111010", 78 => "11000010100", 79 => "10001111010", 80 => "10100111100", 81 => "10010111100", 82 => "10010011110", 83 => "10111100100", 84 => "10011110100", 85 => "10011110010", 86 => "11110100100", 87 => "11110010100", 88 => "11110010010", 89 => "11011011110", 90 => "11011110110", 91 => "11110110110", 92 => "10101111000", 93 => "10100011110", 94 => "10001011110", 95 => "10111101000", 96 => "10111100010", 97 => "11110101000", 98 => "11110100010", 99 => "10111011110", 100 => "10111101110", 101 => "11101011110", 102 => "11110101110", 103 => "11010000100", 104 => "11010010000", 105 => "11010011100" } VALUES = { 'A' => { 0 => " ", 1 => "!", 2 => "\"", 3 => "#", 4 => "$", 5 => "%", 6 => "&", 7 => "'", 8 => "(", 9 => ")", 10 => "*", 11 => "+", 12 => ",", 13 => "-", 14 => ".", 15 => "/", 16 => "0", 17 => "1", 18 => "2", 19 => "3", 20 => "4", 21 => "5", 22 => "6", 23 => "7", 24 => "8", 25 => "9", 26 => ":", 27 => ";", 28 => "<", 29 => "=", 30 => ">", 31 => "?", 32 => "@", 33 => "A", 34 => "B", 35 => "C", 36 => "D", 37 => "E", 38 => "F", 39 => "G", 40 => "H", 41 => "I", 42 => "J", 43 => "K", 44 => "L", 45 => "M", 46 => "N", 47 => "O", 48 => "P", 49 => "Q", 50 => "R", 51 => "S", 52 => "T", 53 => "U", 54 => "V", 55 => "W", 56 => "X", 57 => "Y", 58 => "Z", 59 => "[", 60 => "\\", 61 => "]", 62 => "^", 63 => "_", 64 => "\000", 65 => "\001", 66 => "\002", 67 => "\003", 68 => "\004", 69 => "\005", 70 => "\006", 71 => "\a", 72 => "\b", 73 => "\t", 74 => "\n", 75 => "\v", 76 => "\f", 77 => "\r", 78 => "\016", 79 => "\017", 80 => "\020", 81 => "\021", 82 => "\022", 83 => "\023", 84 => "\024", 85 => "\025", 86 => "\026", 87 => "\027", 88 => "\030", 89 => "\031", 90 => "\032", 91 => "\e", 92 => "\034", 93 => "\035", 94 => "\036", 95 => "\037", 96 => "\303", 97 => "\302", 98 => "SHIFT", 99 => "\307", 100 => "\306", 101 => "\304", 102 => "\301", 103 => "STARTA", 104 => "STARTB", 105 => "STARTC" }.invert, 'B' => { 0 => " ", 1 => "!", 2 => "\"", 3 => "#", 4 => "$", 5 => "%", 6 => "&", 7 => "'", 8 => "(", 9 => ")", 10 => "*", 11 => "+", 12 => ",", 13 => "-", 14 => ".", 15 => "/", 16 => "0", 17 => "1", 18 => "2", 19 => "3", 20 => "4", 21 => "5", 22 => "6", 23 => "7", 24 => "8", 25 => "9", 26 => ":", 27 => ";", 28 => "<", 29 => "=", 30 => ">", 31 => "?", 32 => "@", 33 => "A", 34 => "B", 35 => "C", 36 => "D", 37 => "E", 38 => "F", 39 => "G", 40 => "H", 41 => "I", 42 => "J", 43 => "K", 44 => "L", 45 => "M", 46 => "N", 47 => "O", 48 => "P", 49 => "Q", 50 => "R", 51 => "S", 52 => "T", 53 => "U", 54 => "V", 55 => "W", 56 => "X", 57 => "Y", 58 => "Z", 59 => "[", 60 => "\\", 61 => "]", 62 => "^", 63 => "_", 64 => "`", 65 => "a", 66 => "b", 67 => "c", 68 => "d", 69 => "e", 70 => "f", 71 => "g", 72 => "h", 73 => "i", 74 => "j", 75 => "k", 76 => "l", 77 => "m", 78 => "n", 79 => "o", 80 => "p", 81 => "q", 82 => "r", 83 => "s", 84 => "t", 85 => "u", 86 => "v", 87 => "w", 88 => "x", 89 => "y", 90 => "z", 91 => "{", 92 => "|", 93 => "}", 94 => "~", 95 => "\177", 96 => "\303", 97 => "\302", 98 => "SHIFT", 99 => "\307", 100 => "\304", 101 => "\305", 102 => "\301", 103 => "STARTA", 104 => "STARTB", 105 => "STARTC", }.invert, 'C' => { 0 => "00", 1 => "01", 2 => "02", 3 => "03", 4 => "04", 5 => "05", 6 => "06", 7 => "07", 8 => "08", 9 => "09", 10 => "10", 11 => "11", 12 => "12", 13 => "13", 14 => "14", 15 => "15", 16 => "16", 17 => "17", 18 => "18", 19 => "19", 20 => "20", 21 => "21", 22 => "22", 23 => "23", 24 => "24", 25 => "25", 26 => "26", 27 => "27", 28 => "28", 29 => "29", 30 => "30", 31 => "31", 32 => "32", 33 => "33", 34 => "34", 35 => "35", 36 => "36", 37 => "37", 38 => "38", 39 => "39", 40 => "40", 41 => "41", 42 => "42", 43 => "43", 44 => "44", 45 => "45", 46 => "46", 47 => "47", 48 => "48", 49 => "49", 50 => "50", 51 => "51", 52 => "52", 53 => "53", 54 => "54", 55 => "55", 56 => "56", 57 => "57", 58 => "58", 59 => "59", 60 => "60", 61 => "61", 62 => "62", 63 => "63", 64 => "64", 65 => "65", 66 => "66", 67 => "67", 68 => "68", 69 => "69", 70 => "70", 71 => "71", 72 => "72", 73 => "73", 74 => "74", 75 => "75", 76 => "76", 77 => "77", 78 => "78", 79 => "79", 80 => "80", 81 => "81", 82 => "82", 83 => "83", 84 => "84", 85 => "85", 86 => "86", 87 => "87", 88 => "88", 89 => "89", 90 => "90", 91 => "91", 92 => "92", 93 => "93", 94 => "94", 95 => "95", 96 => "96", 97 => "97", 98 => "98", 99 => "99", 100 => "\306", 101 => "\305", 102 => "\301", 103 => "STARTA", 104 => "STARTB", 105 => "STARTC" }.invert } FNC1 = "\xc1" FNC2 = "\xc2" FNC3 = "\xc3" FNC4 = "\xc4" CODEA = "\xc5" CODEB = "\xc6" CODEC = "\xc7" STOP = '11000111010' TERMINATE = '11' attr_reader :type def initialize(data, type) self.type = type self.data = "#{data}" raise ArgumentError, 'Data not valid' unless valid? end def type=(type) type.upcase! raise ArgumentError, 'type must be A, B or C' unless type =~ /^[ABC]$/ @type = type end def to_s full_data end def data @data end #Returns the data for this barcode plus that for the entire extra chain, #excluding all change codes def full_data data + full_extra_data end #Returns the data for this barcode plus that for the entire extra chain, #including all change codes prefixing each extra def full_data_with_change_codes data + full_extra_data_with_change_code end #Returns the full_data for the extra or an empty string if there is no extra def full_extra_data return '' unless extra extra.full_data end #Returns the full_data for the extra with the change code for the extra #prepended. If there is no extra, an empty string is returned def full_extra_data_with_change_code return '' unless extra change_code_for(extra) + extra.full_data_with_change_codes end #Set the data for this barcode. If the barcode changes #character set, an extra will be created. def data=(data) data, *extra = data.split(/([#{CODEA+CODEB+CODEC}])/n) @data = data || '' self.extra = extra.join unless extra.empty? end #An "extra" is present if the barcode changes character set. If #a 128A barcode changes to C, the extra will be an instance of #Code128C. Extras can themselves have an extra if the barcode #changes character set again. It's like a linked list, and when #there are no more extras, the barcode ends with that object. #Most barcodes probably don't change charsets and don't have extras. def extra @extra end #Set the extra for this barcode. The argument is a string starting with the #"change character set" symbol. The string may contain several character #sets, in which case the extra will itself have an extra. def extra=(extra) raise ArgumentError, "Extra must begin with \\305, \\306 or \\307" unless extra =~ /^[#{CODEA+CODEB+CODEC}]/n type, data = extra[0,1], extra[1..-1] @extra = class_for(type).new(data) end #Get an array of the individual characters for this barcode. Special #characters like FNC1 will be present. Characters from extras are not #present. def characters chars = data.split(//n) if type == 'C' result = [] count = 0 while count < chars.size if chars[count] =~ /^\d$/ #If encountering a digit, next char/byte *must* be second digit in pair. I.e. if chars[count] is 5, #chars[count+1] must be /[0-9]/, otherwise it's not valid result << "#{chars[count]}#{chars[count+1]}" count += 2 else result << chars[count] count += 1 end end result else chars end end #Return the encoding of this barcode as a string of 1 and 0 def encoding start_encoding+data_encoding+extra_encoding+checksum_encoding+stop_encoding end #Returns the encoding for the data part of this barcode, without any extras def data_encoding characters.map do |char| encoding_for char end.join end #Returns the data encoding of this barcode and extras. def data_encoding_with_extra_encoding data_encoding+extra_encoding end #Returns the data encoding of this barcode's extra and its #extra until the barcode ends. def extra_encoding return '' unless extra change_code_encoding_for(extra) + extra.data_encoding + extra.extra_encoding end #Calculate the checksum for the data in this barcode. The data includes #data from extras. def checksum pos = 0 (numbers+extra_numbers).inject(start_num) do |sum,number| pos += 1 sum + (number * pos) end % 103 end #Get the encoding for the checksum def checksum_encoding encodings[checksum] end #protected #Returns the numeric values for the characters in the barcode in an array def numbers characters.map do |char| values[char] end end #Returns the numeric values for extras def extra_numbers return [] unless extra [change_code_number_for(extra)] + extra.numbers + extra.extra_numbers end def encodings ENCODINGS end #The start encoding starts the barcode def stop_encoding STOP+TERMINATE end #Find the encoding for the specified character for this barcode def encoding_for(char) encodings[values[char]] end def change_code_for_class(klass) {Code128A => CODEA, Code128B => CODEB, Code128C => CODEC}[klass] end #Find the character that changes the character set to the one #represented in +barcode+ def change_code_for(barcode) change_code_for_class(barcode.class) end #Find the numeric value for the character that changes the character #set to the one represented in +barcode+ def change_code_number_for(barcode) values[change_code_for(barcode)] end #Find the encoding to change to the character set in +barcode+ def change_code_encoding_for(barcode) encodings[change_code_number_for(barcode)] end def class_for(character) case character when 'A' then Code128A when 'B' then Code128B when 'C' then Code128C when CODEA then Code128A when CODEB then Code128B when CODEC then Code128C end end #Is the data in this barcode valid? Does a lookup of every character #and checks if it exists in the character set. An empty data string #will also be reported as invalid. def valid? characters.any? && characters.all?{|c| values.include?(c) } end def values VALUES[type] end def start_num values["START#{type}"] end def start_encoding encodings[start_num] end end class Code128A < Code128 def initialize(data) super(data, 'A') end end class Code128B < Code128 def initialize(data) super(data, 'B') end end class Code128C < Code128 def initialize(data) super(data, 'C') end end end barby-0.5.1/lib/barby/barcode/gs1_128.rb0000644000004100000410000000123012147436246017526 0ustar www-datawww-datarequire 'barby/barcode/code_128' module Barby #AKA EAN-128, UCC-128 class GS1128 < Code128 attr_accessor :application_identifier def initialize(data, type, ai) self.application_identifier = ai super(data, type) end #TODO: Not sure this is entirely right def data FNC1+application_identifier+super end def partial_data @data end def application_identifier_number values[application_identifier] end def application_identifier_encoding encodings[application_identifier_number] end def to_s "(#{application_identifier}) #{partial_data}" end end end barby-0.5.1/lib/barby/barcode/ean_8.rb0000644000004100000410000000066712147436246017451 0ustar www-datawww-datarequire 'barby/barcode/ean_13' module Barby #EAN-8 is a sub-set of EAN-13, with only 7 (8) digits class EAN8 < EAN13 FORMAT = /^\d{7}$/ def left_numbers numbers[0,4] end def right_numbers numbers_with_checksum[4,4] end #Left-hand digits are all encoded using odd parity def left_parity_map [:odd, :odd, :odd, :odd] end def valid? data =~ FORMAT end end end barby-0.5.1/lib/barby/outputter.rb0000644000004100000410000000735512147436246017134 0ustar www-datawww-datarequire 'barby/barcode' module Barby #An Outputter creates something from a barcode. That something can be #anything, but is most likely a graphical representation of the barcode. #Outputters can register methods on barcodes that will be associated with #them. # #The basic structure of an outputter class: # # class FooOutputter < Barby::Outputter # register :to_foo # def to_too # do_something_with(barcode.encoding) # end # end # #Barcode#to_foo will now be available to all barcodes class Outputter attr_accessor :barcode #An outputter instance will have access to a Barcode def initialize(barcode) self.barcode = barcode end #Register one or more handler methods with this outputter #Barcodes will then be able to use these methods to get the output #from the outputter. For example, if you have an ImageOutputter, #you could do: # #register :to_png, :to_gif # #You could then do aBarcode.to_png and get the result of that method. #The class which registers the method will receive the barcode as the only #argument, and the default implementation of initialize puts that into #the +barcode+ accessor. # #You can also have different method names on the barcode and the outputter #by providing a hash: # #register :to_png => :create_png, :to_gif => :create_gif def self.register(*method_names) if method_names.first.is_a? Hash method_names.first.each do |name, method_name| Barcode.register_outputter(name, self, method_name) end else method_names.each do |name| Barcode.register_outputter(name, self, name) end end end def two_dimensional? barcode.respond_to?(:two_dimensional?) && barcode.two_dimensional? end #Converts the barcode's encoding (a string containing 1s and 0s) #to true and false values (1 == true == "black bar") # #If the barcode is 2D, each line will be converted to an array #in the same way def booleans(reload=false)#:doc: if two_dimensional? encoding(reload).map{|l| l.split(//).map{|c| c == '1' } } else encoding(reload).split(//).map{|c| c == '1' } end end #Returns the barcode's encoding. The encoding #is cached and can be reloaded by passing true def encoding(reload=false)#:doc: @encoding = barcode.encoding if reload @encoding ||= barcode.encoding end #Collects continuous groups of bars and spaces (1 and 0) #into arrays where the first item is true or false (1 or 0) #and the second is the size of the group # #For example, "1100111000" becomes [[true,2],[false,2],[true,3],[false,3]] def boolean_groups(reload=false) if two_dimensional? encoding(reload).map do |line| line.scan(/1+|0+/).map do |group| [group[0,1] == '1', group.size] end end else encoding(reload).scan(/1+|0+/).map do |group| [group[0,1] == '1', group.size] end end end private #Takes a hash and temporarily sets properties on self (the outputter object) #corresponding with the keys to their values. When the block exits, the #properties are reset to their original values. Returns whatever the block returns. def with_options(options={}) original_options = options.inject({}) do |origs,pair| if respond_to?(pair.first) && respond_to?("#{pair.first}=") origs[pair.first] = send(pair.first) send("#{pair.first}=", pair.last) end origs end rv = yield original_options.each do |attribute,value| send("#{attribute}=", value) end rv end end end barby-0.5.1/lib/barby/barcode.rb0000644000004100000410000000545112147436246016453 0ustar www-datawww-datamodule Barby #The base class for all barcodes. It includes some method_missing magic #that is used to find registered outputters. # #The only interface requirement of a barcode class is that is has an encoding #method that returns a string consisting of 1s and 0s representing the barcode's #"black" and "white" parts. One digit is the width of the "X dimension"; that is, #"101100" represents a single-width bar followed by a single-width space, then #a bar and a space twice that width. # #Example implementation: # # class StaticBarcode < Barby::Barcode1D # def encoding # '101100111000111100001' # end # end # # require 'barby/outputter/ascii_outputter' # puts StaticBarcode.new.to_ascii(:height => 3) # # # ## ### #### # # # ## ### #### # # # ## ### #### # # #2D implementation: # # class Static2DBarcode < Barby::Barcode2D # def encoding # ['1010101', '010101110', '0001010100'] # end # end class Barcode #Every barcode must have an encoding method. This method returns #a string containing a series of 1 and 0, representing bars and #spaces. One digit is the width of one "module" or X dimension. # #If the barcode is 2D, it returns an array of strings representing #each line in the barcode def encoding raise NotImplementedError, 'Every barcode should implement this method' end #Is this barcode valid? def valid? false end def to_s self.class.name.split('::').last end #Is this barcode 2D? def two_dimensional? is_a? Barcode2D end def method_missing(name, *args, &b)#:nodoc: #See if an outputter has registered this method if self.class.outputters.include?(name) klass, method_name = self.class.outputters[name] klass.new(self).send(method_name, *args, &b) else super end end #Returns an instantiated outputter for +name+ if any outputter #has registered that name def outputter_for(name, *a, &b) outputter_class_for(name).new(self, *a, &b) end #Get the outputter class object for +name+ def outputter_class_for(name) self.class.outputters[name].first end class << self def outputters @@outputters ||= {} end #Registers an outputter with +name+ so that a call to #+name+ on a Barcode instance will be delegated to this outputter def register_outputter(name, klass, method_name) outputters[name] = [klass, method_name] end end end #Most barcodes are one-dimensional. They have bars. class Barcode1D < Barcode end #2D barcodes are 1D barcodes stacked on top of each other. #Their encoding method must return an array of strings class Barcode2D < Barcode end end