Copy link to clipboard
Copied
After seeing Marc Autret's marvellous pngswatch script, I spent several hours creating PNGs with Photoshop, copying its hex data into Javascript compatible format, finding the relevant color bytes to change ... and all the while I was thinking, "there was an uncompressed PNG format, wasn't there?"
That's not because I have a bad memory.
Sure, Marc created his PNG in some other program, saved it as a compressed file, and 'only' changed the palette part in his script -- which involves delving quite deeply into the actual PNG format --, and that's a feasible way of doing the stuff he intended to: change jsut the color. But if you want to actually create a dropdown or listbox image on the fly -- say, for a line widths dropdown --, you have to be able to create an entire image a-new. And PNGs are notoriously difficult to create, because the image pixels themselves are compressed using the very advanced zlib compression.
But (as I was thinking) ... zlib also allows a "non-compressed" format!
With some sleuthing I found a couple of hints to get me started, and found a totally useful utility as well: pngcheck, which can take a PNG to bits and tell you what's wrong with it. So, here you have it: a lightweight PNGLIB Javascript, that can create any PNG right out of nothing!
Any image, apart from the limitations, that is.
Its main limitation is that you can only create 8-bit palettized PNGs with it. I see no reason to add umpteen functions to cater for the occasional 1-, 2-, or 4-bit or true color PNG, or to add total support for all the different types of transparency that PNG supports. But, hey, its main use is for icons, and you'll have to do with the limits of "just" 256 colors -- or even less than that, if you reserve one or more colors for transparency. On the plus side again, it's total real pixel alpha-level transparency we're talking about (overall that can make your graphics still better than the average '90s DOS game).
Using the function is easy; at the bottom of the script is an example, but it boils down to:
Tips: hmm. I dunno. Don't use this function to create super-huge PNGs, I guess. The non-compression format uses a couple of checksums on its own, and they are sure to fail on very large images. But, come on, be realistic: it's not a Photoshop replacement we're talking about, it's for icons!
And Be Kind to Your Users: it's rather overkill to include all of the data for a static PNG image, such as a logo or something. Just create that once, and include the binary data in your script! This function is designed to create PNGs on the fly, from variable rather than static data.
Before I forget: here it is. Enjoy!
/****** PngLib.jsx ******/
/* A Jongware Product -- based *very* heavily, however, upon Marc Autret's pngswatch
/* script (http://forums.adobe.com/thread/780105?tstart=0), and with further
/* help from the pages of David "Code Monk" Jones (http://drj11.wordpress.com/2007/11/20/a-use-for-uncompressed-pngs/)
/* and Christian Fröschlin (http://www.chrfr.de/software/midp_png.html)
/* Any errors, of course, must have crept in while I wasn't paying attention.
/* [Jw] 26-Jan-2010
*************************/
var makePng = (function()
{
// Table of CRCs of 8-bit messages
var CRC_256 = [0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d];
// PNG Cyclic Redundancy Code algorithm -- http://www.w3.org/TR/PNG/#D-CRCAppendix
var crc32s = function(/*uint[]*/buf)
{
var c = 0xffffffff, i;
for( i=0 ; i < buf.length; i++ )
c = CRC_256[(c ^ buf.charCodeAt(i)) & 0xff] ^ (c >>> 8);
return (c ^ 0xffffffff);
};
var header = function ()
{
return "\x89PNG\x0D\x0A\x1A\x0A";
};
var i2s = function (/*int32*/i)
{
return String.fromCharCode(i>>>24) + String.fromCharCode(i>>>16) + String.fromCharCode(i>>>8) + String.fromCharCode(i);
}
var chunk = function (/*4 Char PNG code*/chunkType, /*data*/data)
{
var buf = chunkType + data;
var crc = crc32s(buf);
buf = i2s (data.length) + buf + i2s (crc);
return buf;
};
var adler32 = function (/*string*/buf)
{
var i, a = 1, b = 0;
for (i=0; i<buf.length; i++)
{
a += buf.charCodeAt(i); s1 %= 65521;
b += a; b %= 65521;
}
return (b<<16)+a;
}
return function(/*int*/wide, /*int*/high, /*string*/ pal, /*string*/image, /*string*/transpIndex)
{
var t, bits;
if (pal.length % 3)
{
alert ("Bad Palette length -- not a multiple of 3");
return null;
}
if (image.length != high*wide)
{
alert ("Size error: expected "+(high*wide)+" bytes, got "+image.length);
return null;
}
bits = '';
for (t=0; t<high; t++)
bits += "\x00"+image.substr(t*wide, wide);
t = bits.length;
bits += i2s (adler32(bits));
var r = header() + chunk ('IHDR', i2s (wide)+i2s(high)+"\x08\x03\x00\x00\x00");
r += chunk ('PLTE', pal);
if (transpIndex != null)
r += chunk ('tRNS', transpIndex);
r += chunk ('IDAT', "\x78\x9c\x01"+ String.fromCharCode (t & 0xff)+String.fromCharCode((t>>>8) & 0xff)+String.fromCharCode ((~t) & 0xff)+String.fromCharCode(~(t>>>8) & 0xff)+bits);
r += chunk ('IEND', '');
return r;
};
})();
/* Sample usage. Remove when #including the above in _your_ script! */
var pngPal = "\x00\x00\x00"+"\xff\x00\x00"+"\x00\xff\x00"+"\x00\x00\xff"+"\xff\xff\x00"+"\x40\x40\x40";
var pngData = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+
"\x00\x01\x01\x02\x02\x03\x03\x04\x04\x00"+
"\x00\x01\x01\x02\x02\x03\x03\x04\x04\x00"+
"\x05\x01\x01\x02\x02\x03\x03\x04\x04\x05"+
"\x05\x01\x01\x02\x02\x03\x03\x04\x04\x05"+
"\x05\x01\x01\x02\x02\x03\x03\x04\x04\x05"+
"\x05\x01\x01\x02\x02\x03\x03\x04\x04\x05"+
"\x05\x01\x01\x02\x02\x03\x03\x04\x04\x05"+
"\x05\x01\x01\x02\x02\x03\x03\x04\x04\x05"+
"\x05\x01\x01\x02\x02\x03\x03\x04\x04\x05"+
"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05";
img = makePng (10,11, pngPal, pngData, "\x40");
var w = new Window("dialog", "Image test");
w.add ('image', undefined, img);
var f = new File(Folder.myDocuments+"/test-me2.png");
if (f.open('w'))
{
f.encoding = "BINARY";
f.write (img);
f.close();
} else
alert ("eh -- couldn't write test file...");
w.show();
Copy link to clipboard
Copied
Wow - pretty cool! I never cease to be amazed at how far ExtendScript can be stretched, eh - you'd expect this to be something in the realm of C/C++/Java.
Copy link to clipboard
Copied
Coming from you, Kris, that's a huge compliment!
(Even though this is your Very First Post. Gremlins about -- I don't longer care, past-midnight or not.)
Copy link to clipboard
Copied
Yes.
Truly amazing!
Theun, I'm waiting to play space invaders...
Harbs
Copy link to clipboard
Copied
Here is a more complicated (and useful ) example. (--Its actual usefulness is not as, erm, useful as I hoped, because it seems you don't have access to the built-in stroke styles! If anyone knows a work-around that, let me know ...)
First, create a few custom Striped and/or Dashed stroke styles; then call this Javascript to see them created "live" in the drop down. Make sure you removed the sample code from the end of "pnglib.jsx", otherwise that dialog with interfere and mess up my nice program.
#include "pnglib.jsx"
function createStripeImg (styleIndex)
{
var pngPal = "\x00\x00\x00"+"\xff\xff\xff";
var pngData = '';
var x,y, ystart;
var stripes = [];
var i;
for (y=0; y<app.activeDocument.stripedStrokeStyles[styleIndex].stripeArray.length; y++)
stripes.push (Math.round (11*app.activeDocument.stripedStrokeStyles[styleIndex].stripeArray
/100)); i = 0;
for (y=0; y<11; y++)
{
if (y >= stripes)
{
if (y <= stripes[i+1])
{
for (x=0; x<48; x++)
pngData += "\x00";
continue;
}
i += 2;
}
for (x=0; x<48; x++)
pngData += "\x01";
}
return makePng (48,11, pngPal, pngData, "\xff\x00");
}
function createDashImg (styleIndex)
{
var pngPal = "\x00\x00\x00"+"\xff\xff\xff";
var pngData = '';
var x,y, xstart;
var dashes = [];
var i, len;
len = 0;
for (y=0; y<app.activeDocument.dashedStrokeStyles[styleIndex].dashArray.length; y++)
len += app.activeDocument.dashedStrokeStyles[styleIndex].dashArray
; xstart = 0;
for (y=0; y<app.activeDocument.dashedStrokeStyles[styleIndex].dashArray.length; y++)
{
dashes.push (xstart);
xstart += Math.round (48*app.activeDocument.dashedStrokeStyles[styleIndex].dashArray
/len); }
dashes.push (47);
i = 0;
for (y=0; y<11; y++)
{
if (y < 3 || y > 8)
{
for (x=0; x<48; x++)
pngData += "\x01";
} else
{
xstart = 0;
for (x=0; x<48; x++)
{
if (x >= dashes[xstart])
{
if (x >= dashes[xstart+1])
xstart += 2;
pngData += "\x00";
} else
{
pngData += "\x01";
}
}
}
}
return makePng (48,11, pngPal, pngData, "\xff\x00");
}
if (app.activeDocument.stripedStrokeStyles.length+app.activeDocument.dashedStrokeStyles.length < 1)
{
alert ("This example needs a few custom stripe or dash stroke styles to play with");
exit (0);
}
var w = new Window("dialog", "Select a stripe type");
var ddl = w.add("dropdownlist");
for( i=0; i < app.activeDocument.stripedStrokeStyles.length; i++)
(ddl.add('item', " "+app.activeDocument.stripedStrokeStyles.name)).image = createStripeImg (i);
for( i=0; i < app.activeDocument.dashedStrokeStyles.length; i++)
(ddl.add('item', " "+app.activeDocument.dashedStrokeStyles.name)).image = createDashImg (i);
ddl.selection = 0;
g = w.add ("group");
g.orientation = 'row';
g.add ("button", undefined, "OK");
g.add ("button", undefined, "Cancel");
w.show();
Copy link to clipboard
Copied
Nice work, Theunis!
P.
Copy link to clipboard
Copied
My God. You guys are amazing!!!
Still no way to access the built-in stroke types?
Copy link to clipboard
Copied
As the standard strokes are "standard" and haven't changed in years. Even the weird ones like Happy see What is the direction of the curve points returned by entirePath()? [See description for details] There's an InDesign Secrets on post that list the weird one's wouldn't be surprised if it was written by Jongware 🙂 You could just make a document with the lines and export the lines as PNGs and convert them to embed code if you need.
Marc has a selection to PNG script that if I remember correctly makes an SUI image from the current document selection. You might find that useful.
In short don't bother trying to do it on the fly just do a bit of prep work and you have a work around.
Copy link to clipboard
Copied
Thank you so much, Trevor!
Copy link to clipboard
Copied
lf.corullon wrote
My God. You guys are amazing!!!
Still no way to access the built-in stroke types?
Hi,
what do you mean by "there is no way to access the built-in stroke types" ?
You can access them by using their appropriate strings as value.
Here some sample code:
var newDoc = app.documents.add();
var newRectangle = newDoc.rectangles.add
(
{
geometricBounds : [ 0, 0 , "50 mm" , "50 mm" ] ,
strokeWeight : "3 mm",
strokeColor : "Black" ,
strokeTint : -1 ,
strokeAlignment : StrokeAlignment.OUTSIDE_ALIGNMENT ,
strokeType :"$ID/Solid"
}
);
Now set the string for strokeType differently.
I gathered some with their locale independent names.
German name > locale independent name
// StrokeType
/*
Strings:
"$ID/Canned Dotted" => German "Gepunktet"
Durchgezogen $ID/Solid
Breit - Breit $ID/ThickThick
Breit - Schmal $ID/ThickThin
Breit - Schmal - Breit $ID/ThickThinThick
Schmal - Breit $ID/ThinThick
Schmal - Breit - Schmal $ID/ThinThickThin
Schmal - Schmal $ID/ThinThin
Dreifach $ID/Triple_Stroke
Weiße Rauten $ID/White Diamond
Japanische Punkte $ID/Japanese Dots
Gestrichelt (3 und 2) $ID/Canned Dashed 3x2
Gestrichelt (4 und 4) $ID/Canned Dashed 4x4
Schraffiert (nach links geneigt) $ID/Left Slant Hash
Schraffiert (gerade) $ID/Straight Hash
Gepunktet $ID/Canned Dotted
Gestrichelt $ID/Dashed
Wellenlinie $ID/Wavy
Schraffiert (nach rechts geneigt) $ID/Right Slant Hash
*/
So used like that:
var newDoc = app.documents.add();
var newRectangle = newDoc.rectangles.add
(
{
geometricBounds : [ 0, 0 , "50 mm" , "50 mm" ] ,
strokeWeight : "3 mm",
strokeColor : "Black" ,
strokeTint : -1 ,
strokeAlignment : StrokeAlignment.OUTSIDE_ALIGNMENT ,
strokeType :"$ID/Canned Dashed 3x2"
}
);
The result is this:
Regards,
Uwe
Copy link to clipboard
Copied
Here's the link to the other ones
https://indesignsecrets.com/easter-egg-stroke-styles.php
Woof, Happy, Feet, Lights and Rasta
Not too commonly used.
Copy link to clipboard
Copied
Great, Uwe!
var myTypes = ["$ID/Solid" , "$ID/ThickThick" , "$ID/ThickThin" , "$ID/ThickThinThick" , "$ID/ThinThick" , "$ID/ThinThickThin" , "$ID/ThinThin" , "$ID/Triple_Stroke" , "$ID/White Diamond" , "$ID/Japanese Dots" , "$ID/Canned Dashed 3x2" , "$ID/Canned Dashed 4x4" , "$ID/Left Slant Hash" , "$ID/Straight Hash" , "$ID/Canned Dotted" , "$ID/Dashed" , "$ID/Wavy" , "$ID/Right Slant Hash"];
var newDoc = app.documents.add();
var myPoint = 5.767;
for (var i=0; i<myTypes.length; i++)
{
var newRectangle = newDoc.graphicLines.add
(
{
geometricBounds : [ myPoint+4.233, 0 , myPoint+4.233 , "50 mm" ] ,
strokeWeight : "3 mm",
strokeColor : "Black" ,
strokeTint : -1 ,
strokeAlignment : StrokeAlignment.OUTSIDE_ALIGNMENT ,
strokeType : myTypes,
}
);
myPoint = myPoint+4.233;
}
Now it's easier!
Thank you all!!!
Copy link to clipboard
Copied
Just posting if someone else needs it...
//=============================================================
// BUILT-IN STROKE TYPES AS IMAGES WITH 13PX HEIGHT
var myDashed32 = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x01<IDATx\u00DA\u00ED\u0097\u00BBN\u0085@\x10\u0086g7PXh\x0F\u008D/`a\t\u00BD\u008FaqJ;\b\x05Pp\u00BFT\u00E4<\u0088\u008D\u00B7\x07\u00B3\u00D3hu\u009C\u00C1%NN\x0E\nKe\u00B2$\x7F\u00B6`\u0096\u00FF\u00DB\x7F'\u00B0@UU`\u00F4-(\u00CBr\u0093\u00E8!\u00D3x,~\u00FF?\u00F8@\u00D7u\u00DAj\u00DBv\x16\u0090\u00836M\u00B3\u00C9\u00E7\u00B7 \u00B8\x0F\u00F1l\u00F1\u0081 \b\u00B4\x15E\u00D1\u009F;V\u00D75\u00C4q\u00AC\u00ED\x11\u0086!\x14E\u00B1\u00A83\u0088g\u00CBz\u00E8z\u00D6\u00D0\x03\u00EA\u00C5q\u009C\u009B\u00BE\u00EF!\u00CFsq\n2\u00CB21\f\x03x\u009Ew\u0089\u00F5\u008FB\b\u009A\u00FB\u00B4\u00D0c\u00AC\u00B3,\u00EB>I\u00923\u00EA\u00AE)\u0094c\u0091?q \u00CF-q)>\u009Du\u00C1a\u00ADpQ\u00E3\u00E8\u00BA\u00EE\x1DA \u00A4\u009C\u0081\u0094\x14\u0086\u00EF\u00FB\u00D7T/\u00A5\\\u00EDe\u00DB\u00F6!M\u00D3\x0B\n\x03;\u00E0d\u00E8\u00E4O\x1C\u00C8\u00B3\u00E7|\x1A\u0082\u00CF\u00B5B\u00B37\x1A\u00D1|\u00A7\u00C2\x10s;\u00A6\u00C2\u00B8\u00C2\u00FAw\f\u0083\u00E6\x7F,\u00F4\x19\u00EB0\u008CW\f\u00E3\\\u0085\x013a\b\x15F\u00C3\u00F94d:\u0083w\u0086ygL2_\x13\u00F651\u00E7\fv\u00CE0'Pv\x025\u00FF$?\u00FA\x02\u0081\u008Fr\u0085\u00AB\u008AP\u00F6\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myDashed44 = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x00\u00B6IDATx\u00DA\u00ED\u0097A\x0E\x02!\fE\u00CBx\r\u00B8\u0097\u00B7`\u00C1v`H r\x1C\u00A3\u00873q\u00A5\u00F3\u0095\u0089\u00DD\u00DB\u00EEJ\u00F2\u00D2\u00DD\u00EF\u00CFO\x03\u0085j\u00ADd|\u00A1m\u00DB\u00D4@\u0083\u00A3\u00FE\x0B\u00D7\u00D3\u0082z\u00EF*\u00B4\u00D6\u00C4\u0082\u00E0\u0081@W\u00CB3\u00C5\x18UH)\u00A9L\x06t\u00B5<\u00E3\u00DC\u0084\u00B9\u00EE\u00DC\u00BD\u00F7\u00E71\x06\u00E5\u009C\u009DD\x18\u00D0\u0081\x1Et\u00A1?\u00FBH{\u00A7\u0097$\u00CE\u00B9O\r!\\`\u00BE\u0094r\u0092\b\x03:\u00D0\u0083.\u00EF#\f=%\u00D9M>Pw\u00D3\u00EB\fc\x11\nc\u0099a\u00AC\u00BC\u008F06\x19|2\u00EC\u00CE8\u00B0\u00D7\u0084\u00BD&\u00B6g\u00B0=\u00C36P\u00B6\u0081\u00DA\u009F\u00E4\u00C7\x1B\u00C8\u00DBza\x15q\x15n\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myDotted = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x02]IDATx\u00DA\u00EDV\u00CF\u00AB\x12Q\x14\u00BE\u00F7\u008E\x0B\u0095\x02E\x05\x03\u00C9\u009Dh\u00AB\\\u00E4\u00C6\x10\u00DA*\x04\u00BA\u00B1\u00AD\u0098\u0089n\u00D4\u0087\u00E2\x0F\u00FC=\u00FEvQ\u009B\u00B6\u00B5\u008C z\u00B4j\u00D5\x1F\u00D0\x7F\x10\u00FD\tE\u00D0\u0083\u00A2\u009E\x04\u00AF\u00F3M3\u008F\u0099q|\u00EF\u00D1\u00A6E\u00B38\u00DC{\u00E7\u009E\u00EF|\u00E7|\u00F7\u00DC\u0099a\u00E3\u00F1\u0098\u00D9\u00F6\u00C7\f\u008B\u00D1ht>j\u00A6\x7Fne\x7F\u0083\u00F9\u00D7\\\u00870{\u0080\u00E1p\u0088Q\u00CCf3<\x13\u00EA\u00DA\x12\u00AC\x0FL~\u009C0|:\u009D\u00F2\u00C1`\u00C0\u00CD\u00E4V8\u00C4\u009EL&\n\x17\u00CD\u00C5E\u0089\u009A\n\x02\x06\x1C\u00C8\u00EF\u00CA\\\u00B2,+8\u00CA\u00CF\u0092k\x0F0\u009F\u00CF\u0095u\u00ADVcHR[_\u00A4\u00B8\u0086\x03\u00A6\u00D3\u00E9\u00B0\u00F5z}%\f\u00E2\u00F7z=\x05\u00B7Z\u00AD\u0090,\u00BBL\x10\x18\u00FC\u0080A\f\u00E0\u00B4\x03\u00BB,\u00BFV\u00AB\u00C5\x1A\u008D\x06\u00DBl68\u0084=\u00AEs \u00A9\u00C5\x16\u008B\x05+\u0095J\"\x1C\x0E\u00D79\u00E7\u00C7\u00B1XL.\u0097\u00CB.\u0090\x1F\"D\x17 x6\u009BM0\u00C6^x\u00BD\u00DE\u0097\u0099L\u00E6\u00AE\u00B9\u0095\u00F5\u00A6\t\u00D1n\u00B7\u009D~\u00BF_&\u00DCq<\x1E?B\u00A2\u0087\u00B8\u00B4\u00EEC\u00F1\u00A9T\u00EA>a^\u0085B\u00A1g\u00F9|\u00FE\u0096\u00DAY\u0096\\\u00A8k\u00B9\\\u00B2j\u00B5\u00EAs\u00BB\u00DD\u008F\x1D\x0E\u00C7\u00EBd2\u00F9\u00A8\u00DB\u00ED\x1A\x041t\x06\x19\u00C7&\x11\u00B4\u0088\u00E8L\u0092\u00A43\u008C\u0081@\u00E0)\u00C8\u00B4\u00D67\x13A\u00C0\\.w\u0083|?\u00C3_\u00B5/\u00C5b\u00F1&\u00F6\u00B46\u00D6\x0B\u0081\u00ABAB0\u009F\u00CF\u00F7\x04\u00FEB\b\x05\x17\u008DF\u008F\u0080\u00D1\u00B7\u00B1\x0E'\u00B0GB\u00DC!\u00DF\u009D\u008E\u00EBc\u00BD^\u00BFf%\u00A2z58\t\u00C1\u009DN\u00E7\x1B\u00F8\u00D3!+8\u008A\u00F3\x00\u00C2\u00A2.Cg\x00Dw\u009D5\u009BM\u00F2co)\u00B9\x1D\u0081NH\u0090\u00D3`0\u00F8A%\x12f1\u00FA\u00FD\u00BE\u00D8n\u00B7,\x12\u0089\u00A4U\u00A2\x1F\u0084\u00FD\u008E\u00E2\n\u0085\u00C2=\u009C\b\u0091IV\x02\u00D2>\u00B8\u00DE\u0093\u00EF)\u008D'tb;\u009A\u00BF\u00ABT*\u00E8\x1A\u00C9\\\x18\u00E2 \u009E\u00C7\u00E3y\u0088\u0082\u00C8\u00BEQ~?1O$\x12\u00B7q5\x11\u00DB\u00CC\u0085\u00AEM\u00A7\u00D3\u00D7\u0089\u00E3\x13\u00EA\u00A1\u00F1+\u008D\u00BF\\.\u00D7s\u00B5;\u008Cb\u00D8\u009Da\u00BF3\x0E\u00BF3\u00EC\u00AF\u0089\u00FD\u009F\u00B1\u00DF\x19\u00F6\x1F\u00A8\u0085\x18\u00FF\u00BB\u00FD\x06\u00C1\u00AD\u00D5\u00B6;\u0093|\x13\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myJapDots = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x02\u00E0IDATx\u00DA\u00EDW=lRQ\x14\u00BE\u00EF=l\r\rj\n\x11cY\u00AA1!\u0081\u0085\u00B8\x00\tq\u00C1\u00CD0 \u0096\u00B0@\u00E8$q\x00\u00D2\x12H\u00F9\u00FF\u0087\x12\x17w\x13\u00A3C\x1DZuvt\u00D1\u00C1\u00C9\u00CD\u00D18\x18\u00E3\u00A41\u00C6j\u0093\u00FA}\u00D7\u00F7\u00EA\u00F3Q\u00A315q\u0080\u00E4p\u00EF=\u00F7;\u00E7|\u00E7'\u008F\u0087h\u00B5Zb&\u00DFE~5\u009B\u00CD\x031\u00CE\x06\u00C0\u00AC;J\u008C\u00F5\u00FEO0\u00FF\u008A\u008Bq\x16\u008DF\u0083\x07\u00B5\u00D7\u00EB)P\u00A8<[\tQ\u00D7n\u00B7%\x06{\u00F50\u00D2\u00D0K{b\u00E8\u00EF0\x12\u00F5z]\u00E9v\u00BBR\u00B8\u00B7b\u00B8B\u00AF\u00EA\x18U\u00F79\u0095\u00D4\u00EF\u00F8r%O`$\u00EF_\u00E5d\u00E5+F\u00A3\u0091\u00E8\u00F7\u00FB\"\u009F\u00CFK\u00C0`00\u0080\x07F\u00C3\u00E1PlllH\f\u00F1 :Ui\u00EA\u0089%\u0086\u00FE@\u00E2'\f\u00EF\u00C6\u00E3\u00B1(\x16\u008B\u00A2T*\u0089\u00CD\u00CD\u00CD\u00A9Bp\u00A5~}}]\u00E2\u00AC\\\u0088a\u0082f\u00BE\u008Ck\u00E5B~\u00D4\x13C\u00DE\u00B4\u00B1\u00FA\u00B1\u00F2eQD*\u0095:\u00E9\u00F3\u00F9\u00CAB\u0088\x1D\u008F\u00C7S\u00CDf\u00B3sL\x1E\x1D\u0092\u009D\u00E4~ee\u00E5\u0094\u00CB\u00E5\u009A\x10\x13\b\x04r\u0085BAt:\x1D\u00E9\u008C\u00DDc\u00F0d2\u00B9\f\u00FB\u00DB\u00C0l\u00FB\u00FD\u00FE\u00ABL\u0098z}\u00F2$>\x12\u0089\x045M\u00DB\u00B2\u00DB\u00ED\u00F7\u00A3\u00D1h\u00B8V\u00ABMu\x0B\u00FA+\u00B8\u00DF\x06\u00EEN:\u009D\u00BE`\u0090\u00A6\u00D0_.\u0097\x13\u00F0\u00BF\u00AA\u00F3\u00BD\u0085\u00B8\u00A7\u00F58\u008A\u0081A!5\u00F0,\x01\u00F3\x10\u00BC[\u00E5ry\u009E\x05aN&\u00BE.\u00D8\u008F\u0080y\x00\x7F7\u00E8\u0097\u009F\u00C7\u0090}EQ\u00F6\u00B9\u00BA\u00DD\u00EE\u00A1>f\x1A\b*\u0095JEu8\x1C[\u00BC\x03A\u0089A\u00F1\u00D2\u00ECr\u00B5Z\u00D5\u0098$\x12?\x0E\u00FDs\u00B3\u009Fp8|\u0089\u0085D\u00C2\x1A+\u008F\u00C4\u00CEB\u00FF\u0096w\u00BA\u00BCK$\x12\u00CBL\x16\x18\x1B\u00D7X,v\x11\u00FA]\x03\x03_/2\u0099\u00CC\x02\u00ED\u0081Q\u00E9oii)e\u008E\x03y\u0084\u00F8\u00E4\u00A10\x16\u00A7\u00C9\u00EB\u00F56x\u00A7\u00AA\u00AA\u00C48\u009D\u00CE\u009B(\b\x0B\u00AEab\x156\n\u009F{&.\u0094\u00BC\u00A0S$\u00F9\x05\u0087O0\u00E6\u00FA\u0094\u00A3\u00C31\u00A7cL\u00CA\t\u00E8^\u00E1n\x17\u00D8\x0F\u00C0~E1v\u00F4$\u00E6X\u00E5\u00B5\u00B5\u00B53,\x140\u009F\u0081\u00FD\u00C8\u00FD\u00E2\u00E2b\u009D\u00F6(\u00D8\u00B1\u00C9d\"B\u00A1\u00D0e\u00C6\"\x06\"1\u00F1x\u00FC\x1A\u008B\u008A\u008E\u00CD3\x1E\u00BAx\u009Dz\u00C6\u00D1}\u00ED\x05\u0083\u00C1\u00F3\u00B4\u0087\x1F\x1B\u00FD\u00A1\u009Bw\u0081\u00D9c\x1Cr\u00C2\u00FE\r\u00E2/\u00D0\x1E\u00DDW\u00D9a\u00E8\u009F\u00D8l6\u00E6\u00F2^\u00CF\u00E9\x19\u00F2`>\u00F2\x19\x04\u00BC\x1Dv\u00AFi\u00CF\u00BC\u0099\x13\u00D6\u0097\x7F;\x19\u00ABG4\x19\u00E7\u00FE\u00AB\u00C9\u0098=3L\u00CF\u008C\u00D9\u00AF\u0089\u00E9\u00D7d\u00F6\u009Eaz\u00CF\u0098\u00BD\u0081\u009A\u00DE@g\u00FFI~\u00C87V\u00BF\u00A9\x1D\x11\u00DF\x15\u0095\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myLeftSlant = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x05\x15IDATx\u00DA\u00ED\u0097\u00E9O\u009CU\x14\u00C6\u00EF\f\u00FB\u00BE\u00EF\u00A8\u0080\x10!a\x0B\x10V1A\u0098\u00B4@a\n\u009D\u00A1,\x03\u00C8P\u00D9J\u0090}\x1D`X\u0086\u00CDX\u00A3&j\u00EC\x07\u008D5\u00D1\x18SS5MP\u00A3]l\x0B\x01?\u009A\u00F8M\u00FF\x14\x7Fg\u009C\u0097L\u00E9\u00D0\u00D2F\u00BF\u0095\u00E4\u00C9y\u00E7<\u00F79\u00F7\u009Cs\u00EF{\u00EF\u008B\u00B2\u00DB\u00ED\u00EA9\u00FE\u0085Z^^v>\u0088u\x7F>n\u00DD\u00F1\u00B81\u00CF\u00CA=\u008B\u00FE\u00B4\u00BA\u00D3\u00EA\u00D5\u00CA\u00CA\u008A~iiI\u00AD\u00AD\u00AD\u00E9x\u00D6\u00C9\u00B3\u00E6s\u00B3:\x04\x02\u008F\x1CV\u00B7\u00BA\u00BA\u00EA\u0084'\u00FD\u0093b\u00BB\u00F4\n<5wBn\x0FqX\u00C9\u00C1cM\x12[\u00E3\u0094\u00CDfS\x0E\u0087CMLL8\u009F766\u00D4\u00C2\u00C2\u0082\u00DA\u00DC\u00DCT\u00F3\u00F3\u00F3G\u00BF\u00D7\u00D7\u00D7%\u0080Z\\\\<\u00F2\u0089N\x1B399\u00A9\u00E6\u00E6\u00E6\u009C:M\u00AF\u008D\x11N\u00C6y\u00E24;==\u00ADfff\u00D4\u00D6\u00D6\u00D6QL\u00B1\u009E8w\u00BD\u00E4\u00EC*\u00E8\u0091\u00D8Zm\u00B3\u00B3\u00B3jjjJmoo;9\u0089-uHM\x1A\u0087N\u00AFBBB\u00AE\u008D\u008D\u008DEfgg\x1B\x13\x13\x13\u009BL&Sb\\\\\u00DCB[[\u009B\u008A\u0089\u0089\u00D9\u00E8\u00E9\u00E9\u00F1\u00C3\x7F\u00D9b\u00B1\x14\u00B6\u00B7\u00B7g\u00C4\u00C6\u00C6\u00CE\t\u0087\x15\u00CE;>>\u00FE\u00AD\u00DE\u00DE\u00DE\u00EC\u00CA\u00CA\u00CAW\u00C3\u00C3\u00C3\u00AD\u008C\t\u0086[\u00C3\u00CA\x18\u00FB\u00C0\u00C0@DII\u0089!22\u00B2\x13]8\u00BE\u00D5\u008E\u008E\x0E\u00E1V;;;\u00C3\u0092\u0093\u0093\u00BB[ZZ^khh\u00C8\u00F2\u00F7\u00F7\x1F\u00EF\u00EA\u00EA\u00D21\u00EF\u00C7X\u00BF\u00A4\u00A4\u00A4Kh\u00CAjkks\x02\x03\x03G\x18\u00EF\x03\u00E7\u0090\u00D8\u00E48\u0087\u00EE\u0085\u008C\u008C\u008C\u0086\u00EA\u00EAj\u00D3\u00E8\u00E8\u00A8ODD\u00C4&y\ngC\u0097\u0090\u0096\u0096\u00D6\\__\x7F\u00AE\u00B5\u00B55\u00D9\u00DB\u00DB{\u00A1\u00BB\u00BB\u00DB\u00997:_j\x1Aonn6P\u00EFK>>>\u00CB\u00E3\u00E3\u00E3Jeee\u00ED\x04\x05\x05\u00DD)//7zyy\u00DDSJ]\x02\u00D7\u00C0\u00BB`\x12n\u00B7\u00B0\u00B0\u00F0\x02\u00C1~/**:ORw\u00F0\u00EF\u0080Y\u00B8\u009Bpf\u00B8\u00C3\u00B2\u00B2\u00B2\x0Bp?\u00E1'\u00AAz\x0F|\x06\u00DE\u00A4\u00C0\u00FB\x15\x15\x15e\u00D8\u00BB\u00FC\x1E\x01\x1F\u0082\u00AB`\u00D0\u00CF\u00CF\u00EF61\u008D\u00E8\x0F\u008A\u008B\u008B\u00DB)\u00E6[\u00FC\u00AB`\u0085\u00F1\u00FBp\r2/\\kXX\u00D8w\u00F8\u00D9\u00CB\u00CA\x01\u00BE\x01\x16\u00F2\u00DDg\u00FEF\u00C6\u00EE\u00E5\u00E6\u00E6v\u00D0\u00A8m\u00FC_\u0083nt{\u00E8\x1B}}}\u00F7\x18c\u00A5\tG5\u0081\x1FA\x13\u00F8\u00BB\u00B4\u00B4\u00B4#**\u00EAs\u009E\u00BFR999g\u00F2\u00F3\u00F3[\u00A5!\x14T\x13\x1C\x1C\u00FC\x0BD\u009BN\u00A7\u00BB\nd\u00E2\u00CB\u00AC\u00EA\rDgI\u00FE\x1EVVY\u0082\u00ADHq\x04\u00BA\u00CE\u00CA\u00D73\u00E9o2\u0086\u0082~\u00C0\u00DF\u008Fv\x07H\u00E1\x16\u009At\u008B\u0086\u00E4\u00B0\x0B\x7F\u00E6w/\u00FE+\u00E0}\u009E\u00DF\b\r\r\u00DDe!\f\u00C4\u00BEK\u00D1F\u0092\u00FE\x12\u00FF\u008C\u0080\x06HN\u00AFKl\u00E6h\u00A0X)t\x12\u00AD\rHq\u00A6\u0080\u0080\u0080[\u00E8\u00AB\u00C9\u00FBvAAA\x13\u00BB\u00C9.\x0B\x01of\u00DE_\u0085\x13KC.\u00B2\x1Bd\x11\x1Cp\u00C3\u00E0\x060\u00E8\u00F5\u00FA?\u0099\u00C3\u00C4\x0E\u0095F\u00A9?\u00A2\u00A3\u00A3\x1D4\u00C4\u00CCv9\u0090nb\u00EF\u00E3\u00B7\u0082/\u00C0;`\u009A\u00C9vE$+E`m\u0087\u00BC\r\u00E6(\u00E8&\u008Dha\u00A5\x0E\u00D17\u00C1I\u00D1c\u00E0\x03\u00F0\u00A94\u0087\u0098{\u00B2C\\\u00BAa\u00F0\x11\u00F8D\u009A-;\u0084\u00A4\u00CFS\u00F4\x01\x05\u00B5\x11Ov\u0088\x14e\u00A7\u00D8}\u00E65\u00A2?\u0094\u0082h\u00E8\u00F7\u00F8m`\u00C3\u00B5\x0B\u00BA(j\x0F}#\u00B1\u00F7\u00D9!\x16\x16h\x0B\u00BF4\u00B5\u0087b\x1F\u00C8\u00AE'\u00CE\u0083\u00BC\u00BC<+\u008B%5]\u0091\u009A\u00C0.0\u0082\u00BF\u00C8\u00BFK\u00F1\u008E\u00F9\u00B0\u00D2kCCC\u00C1uuu\u00F5)))f\u00DEI\x16(v\u00C9\u00F5n;\u00B0\u0081$\u00D1_UUU\u00C29\u0091\u0097\u0090\u00900\u008C\u00D5\u00CB\u00BB-z\x1A5d0\x18\nx.\u00A2\u00FB\u00FD\u00BC\u009B\x01\u00E8\u00D6]\u00EF\u00F6\u0092\u00D9l\u008E\u00C5\u009AH\u00C6822\x12\u0080n]b\u00E3\u00B3\u00F3>G\u00B2\x18\u00ED\x14j\x18\x1C\x1C|\x19\u00DD\x14g\u0090\u00CC\u00BB)g\x13\u00B9\u00CD\u0090hU__\u00DF+\u008C\x1Fg^/\u00E1\u00D0)\u00F2\u00986\x1A\u008Di\u00A9\u00A9\u00A9g\u00D3\u00D3\u00D3/rPG\x11k\u009D1\u008A\u00B3\u00CC\u00C6\u0099\u00F0\"\x7F\u00E7233\u009B9\x17\u00E3\u00E1\u0096\u00ACV\u00AB\u00CC\u00EB\u0080\u00F3\u00A7\u00D6\u00FE\u009A\u009A\x1A6dq\x06\r\u00B9\u00EE<}\u00DDOd\u00ED\x04v?\u0099\u00E5\x14\u00D7N]\u00ED\u0094\u00D7\u00AC'\u00EE\u00B8^\u00FC\x12Wn,\u00ED\x06:~\u00B3\b\u00E7I/\u00BF\u00E56\u00F2\u00C4i\u00B9\u00CA\u00B5(\x07\u00A0\u00C6qK\u00E8\u00B4\u009BQn\r\u00E1\u008E\u00EB\u00E5\u00B7\u00EB\u00DAw\u00DE\u00924K)\u00ED\u00EEu}|\u00B8\x7F\x0F<\u00F4] \u00F7\u00BC\u00EB;Bw\x02\u00A7<q\u00EE\u00F7\u00BA|o<\u0081\u00F3\u00A4\x7F,'\u0096\x0F\u00A6\u00D3\u00C4~\u00A4&\u00D1I\u00CDbi\u00A0\u00FE?\u00FD\u008A<\u0089\u00FB?c?\u00CD\x17\u00E6I\u009C\u0086\u00E7\u00FF\u0093\u00B8\u00E1\x1F\u00F5\u00AD4\u008F\u00AD\x10dc\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myRightSlant = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x05\x0EIDATx\u00DA\u00ED\u0097\u00E9O\u009CU\x14\u00C6\u00EF\f\u00FB\u00BE\u0097U\x05\u0084\b\t[\u0080\u00C8&&\b\x13\x0B\x14\u00A6\u00D0\x19\u00CA\u008E\f\u0095\u00AD\x04a\u00D8a\x18\u00D6a3\u00B6Q\x135\u00F6\u0083\u00C6\u009Ah\u008C\u00A9\u00A9\u009A&\u00A8\u00D1.\u00B6\u0085\u0080\x1FM\u00FC\u00A6\x7F\u008A\u00BF3\u00CE;\x19aJ\u00D1\u00B4\u00DF:\u00C9\u00C3y\u00DF\u00F3\u00DCs\u00EE9\u00E7\u00DE\u00F7\u00DC\u008BZ^^V\u00CF\u00F0\x0F\u009C\x7F\u0096\u0096\u0096\u00DC\u00D2\u00F3\u00F9IqO\u00D3\u00B7'\u00FE/\u00A7A\u00D9\u00EDv\u00B5\u00B2\u00B2\u00A2w)t<\u00EB\\:M\u00EAE\u00AE\u00AE\u00AE\u00EA\u0081\u00E8t\u008F\u00E0\u00947\u00CEC\u00EA\u00D6\u00D6\u00D6\x1E\u00C7y\u00B3?\u0091\x13I\u0082\u00A7\u00F1},'\u00B1\u0093\u009CE\u00AE\u00AF\u00AF\u00EB\u00D5\u00E6\u00E6\u00A6\u00B2\u00D9l\u0092\u0090\u00C2\u00C8\u00F9\u00ECp8\u00D4\u00C2\u00C2\u0082\u0093\x13\u00B9\u00B5\u00B5\u00A5fgg\u00D5\u00D4\u00D4\u0094\u00DA\u00D8\u00D8P\u00F3\u00F3\u00F3n\u00E9\u008D;j/z\u00F1;11\u00E1\u00E4d\u008C\u00C6iR8o\u00F6\u00F2>99\u00E9\u0095\u00D3b\u0095\u00C4\u00ACV\u00AB\u009B#1\u009Dpb\u00B3\u00B8\u00B8\u00E8\u00E4\u008E\u00DA\u00CB\u00BB\u00D8I\u00CE\x14G\u008D\u008F\u008F+\u00D5\u00D9\u00D9\u00E9\x17\x1D\x1D\u00BD6<<\x1CZWWW\u009F\u009A\u009Ajnoo?\u00C3\u00CF\u00DE\u00D1\u00D1\u00A1\u0090\x0EdpXX\u00D8@UUUIooo~bb\u00E2\bR\x1F\x17\x17\u00F7\u0091\u00D8\u0087\u0086\u0086\x0E\x1B\f\u0086B\u009E\u008B\u0093\u0092\u0092\x06zzz\u0082\u00B0[\u00C7\u008F\u008A\u008F\u008F\u00B7\u009B\u00CD\u00E63HS~~\u00BEqtt4\b\u00BBu\u00F1\u008Dn\u00B9\u00B5\u00B55:66\u00B6\u00BD\u00A8\u00A8\u00C8044\u00F4\"vS}}}2\u00EFf[[\u009B\"\u00B6\u0099\u00D2\u00D2\u00D2\u00AA\u00FE\u00FE\u00FE\u0097\x18oe^\x1F\u00E1\u00B0S\u00C41m4\x1A\u00D3\u00D3\u00D2\u00D2\u00CEfdd\\\u00A4h1\u00F8Zg\u008CJHH\u00B0577?\u00CF\u00EF\\VVV3\u00C9&\u00C0\u00D9-\x16\u008B\u00CC\u00EB\u0080\x0B$\u00D7\u0081\u009A\u009A\u009A\u0097\u00F9e*\u00A5n\x00\u00F5;\u0083\x1C\x05\x05\x05f??\u00BF\u0083\u00E2\u00E2\u00E2F\u00E4\x03\u00F4\x16\u00F09x\x07L\u0093\u00F0nYY\u0099\u00C9\u00D7\u00D7\u00F77\x02?\x1F\x1C\x1C|\x17\u00FD\u00DB`.<<\u00FC\x16\x01\u00B7\u00F8\u00F8\u00F8\x1Cb\u00DF\x04\u00F7\x13zJ\u00AD\u00DE\x07\u009F\u0080\x01|\u00EEUTT\u0094\u00B9\u00ECF\u00C0\u0087\u00E0cp9 \u00E0Nyy\u00F9y\x7F\x7F\u00FF\u0083\u00C2\u00C2\u00C26\u00FC}\u0083~Y\x10\x14\x14\u00B4\u00CF\u00BCF\u00EC\x0F\u0099\u00F7\"\u008B\u00F2\x1Dz\x1B\u00D8\x00_\u0081n\u009DN\u00B7\u0087}#\u00BE\u00F7\u00F3\u00F2\u00F2:cbb\u00B6\u00D0\x7F\x01z\u00F5z\u00FDC8#~\x1E\u00B2\x18\u0096\u00A8\u00A8(\u00C9\u00E9\u008A\u00E4\x04v\u0081\x11\u00FCI\u00FC\u00DD*77\u00F7u\n\u00D1\x1A\x12\x12r\u0097IkH\u00FAg\u00C86&\u00B8\x06\x1C\x12,\u00ABs\u0093\u00C1g\t\u00FA>\u00D2\u00C0\u00FB\x0F\u00E8W\u00C0(\x13\u00DF())\u00A9'\u0091_e\f\u0093}/\u00C9c\u00BB\x03>\u00E0\u00B9\u0093 oS\u0088\\\x12\u0091\"\u00F5\u00A1\u00BF\x02\u00DE\u00E3\u00F9\r\x12\u00DF%X\x03\u00BE\u00EF\u00B1BFV]\u0092\u0098\x11DDDHL\u00AF\u0089o\u00E6h`GI\u00F2\u0093\u00D8\u00DA\u00C0u\u009EM$y\x1B\u00FBj\u00E2\u00BEC!\u009B\u0092\u0093\u0093\u00A5\u0088\u009F\u00C2\u009B\u0099\u00F7\x17\u00E1DJ!\u00D9\u00B5\u00D7\u00E0\x1Cp#\u00E0&0P\u00AC?d\u0091SRR\u00AE\u00AA\u00EC\u00EC\u00EC\x1D)\u0084T\u008F\u0095\u00BD\u00CF\u00E0K@&\u00BA*\x13\u00C3\u00ED\u00E2\u00E8\u0082\u00EC\bV]\u00DB\x11;`\x16\u00EE\x16\u009C\x19\u00EE\x10\u0087\x17\u00E0~Do\x05\u00EFJ@\u00E0\u00CD\u00C0\u00C0\u00C0\x07\u00B2#\u0090\u00F7\u00A4x@\n$A\r\u00C9\u008E\u00C0\u00A7\x11\u00FB\x03\n\u00D1N!eG\u00ACJ\u00A1\x19\u00BF\x0F\u00D7 \u00F3\u00C2\u00B5R\u0098o\u00D1\u00DB%\x19\u00F0\u00B5\x14\u0099x\u00F7\u0099\u00BF\u0091\u00B1{\u00EC\u0088\x0E\u008A\u00B5\u00ED\u00DA-=\u00D8\u00ED\u00C9.\u00A7\u0090{\u008C\u00B1PdwN@\x16\u00B3\t\u00FC\u00C5\x02v\u00B0\u00A0\u009F\u00F1\u00FC\u00A5b\u00B5\u00AE\u00F3=E\u00E7\u00E4\u00E4\x18\u00A9\\\u0093\u00C9dJ\u00E2\u009BZ\u0090\u00EF\x15\u00E7\x1B|\x7F\x01\u00E8/\u00D3\x0F\u008A\u00E8\x01\u00998\u009D\x13\x0E)\u009C/\u00DF\u00E6[|\u00E39\u0095\u0095\u0095\u00AFDFFZ\x18\x13\n\u00B7&\u00FD\x02\u00B9<88\x18\u00C5\u00AA\u00CAn\u00EA\u00C2.\x12\u00DD\u00AA\u00AB\x17\u00ADvuuE\u00B0\"=---\u00AF644d\u0093\u0094\u00B5\u00BB\u00BB['\u00BD\b\x19\u00C0*_\u00C2\u00A6\u00AC\u00B6\u00B66\u0097B\u008F2\u00DE\x0F\u00CE\u00E1\u00EAEs\u00D8=\u0097\u0099\u0099\u00D9P]]m\x1A\x1B\x1B\u00F3\u00A3\u0098\u009B\u00C4)\u009C\r\u00BB\u00C4\u00F4\u00F4\u00F4\u00E6\u00FA\u00FA\u00FAs\u00F4\u0097\x14\u008A\u00B3@/s\u00C6\u008D\u009D?9Y\u00E9\x1B\x06\u00F2}\u0081OpI\u009A\u00AC\u00BB#K7\u00D7:\u00B0g'\u00D7\u00DE\u00E9\u00D0\u00CE\u00AE+\u00DDY\u00D3i'\u0083\u00BCK\u00C7\u009F\u009B\u009B;vJ\u00C8\x18\u00E1\u00BC\u009D Zg\x179==\u00ADfff\u009C\u00A7\u0093\u00E7i\u00E5\u008D\u00F3\u00B4\u00F7<\t\u008F\u00FA\u00D6r\u00D3N\u00BB\u00ED\u00EDm\u00F7I\"yHN\x1A\u0087\u009D\u00DE}\u00E6\u00CAY|\u00D2\x1DA\u00CEc\u00B9\u008Bx\u00E3\u00E4\x0E w\x10\u00D7=\u00E4\u00D8\u0098\u00C7\u00F9v\u00D9;\u00EF+\u00FF\u0095{Dl\u00FF\u00E2d\x11\u0089\u00C1kN\u00AEB:uO\u00E4\u00A6\u00F74o\u0091'\u00D9\u009F\u00D6\u00EE\u00B4\u00F6\u00CF\u00FE'\u00F1\u00C0\u00DFX]4\u008Flo\u00F3\u00A7\x00\x00\x00\x00IEND\u00AEB`\u0082";
var mySolid = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x00LIDATx\u00DA\u00ED\u00D7\u00C1\r\u00C00\bCQo\u00CC\bp`\u00A1\u008E\u0097S\u00A2\u00AA\u00940\u00C4Gz\x1B l\x14\x11\u00C2G\u00EE\u008E\u00A2\u00CCD\u0091\u0099\u00A1\u00BC\u00F3\u00A0i\u00A3i\u00A1\u00B1\x11s3\u00B8\x15?Rd\u00A4\t\u00FDb\u00F4\f\u009A\u00E7h\u00A0\u00FC$\u00D7\x01Uj1\u008C=\u0089\u0095\u009F\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myStraightHash = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x03<IDATx\u00DA\u00ED\u0097\u00DFO\u0092Q\x18\u00C7\x0F\u00EF\x0B\x04L\x14P\u00EC&\u00EDF~\u0088B\u00C1j\u00D6\u00A46\x07l!n2\u00B7l\u00F3BD\x05\x11\u00D7\x10\x14EQ\u00C4\u00D7\x1F\x19\u00B5\u00D6\u00A6\u00E9M\x17\u00DC\u00B4dk+\u00DD\u00FA\u00B9\u00B6~\u00FE\t]t\u00D9E\x7FH\u00DF\u00C7^\n\u00D1\u00B9.\\W/\u00DB\u00D9\u0081\u00E7\u00FB\u009C\u00EF\u00F3\u009C\u00CF9\u0083\x17\u0096\u00CF\u00E7\u00994~\x0F\u00B6\u00B4\u00B4t*\u0083\u00CCN\u00CB\u00EB\x7F\u008C\u00E3\u00FAe\u00AB\u00AB\u00AB\x07\u00C2\u00CA\u00CA\n\x13\x04\u0081-//\x1F\u008A\u00D1\u00E7\u00F2\\\u00ADU\u00AE#\u00B3\u00E3\u00B4r\u00ACz>I;.Fs\u00A5o\u00B5V\u00EE\u00FD_5\u00EA\u0097\u00E24\u00CA1\u0096H$\x14\x0B\x0B\x0B,\u009DN\u00F3\u0099L\u0086\u009B\u009B\u009B\u00A3\u0098<\u0097\u00CB\u00B1T*%'mzz\u009A\u00E2\u0087\u00B4d2\u00F9G\u00A3ud899yDC\u008C\u00A7X\u00A5\u00B6\u00B8\u00B8(;I\u00C3Z\x19\u00DE\x1F\u00D2(\x17k\u008Eh\u00B4)\u00F4\u00C4\u00A3\u00FF\x13\u00B5l6+\u00A3\u00FD\u00945\u00823;;K\x1AG\u00BD\x12\x07\u0086\u00D7\u00F3\u00B1\u00B11\u00AD\u00CDf\u008Bz\u00BD^\x7Fooo#bwgffX}}\u00FD\u00C3\u00A1\u00A1!\u00BD\u00C5b\x19\u00F0\u00FB\u00FD\u00FD\u0081@\u00E0,\u00B4\r\u00980\u00BD^\u00BF122\u00D2l6\u009B\x07<\x1EO\u00FF\u00DA\u00DA\x1A\u0093\u00CB\u00E5\u008F\u00A6\u00A6\u00A6X]]\u00DD\u009D\u00D1\u00D1\u00D1\u00A6\u00D6\u00D6\u00D6.\u0085B\x11G\u00FE\x19\u00BC\u00B6\u00B0\x19\u00A6\u00D5j\u0085X,f5\u0099L\x1E\u00B5Z\x1D\u00A3:\u00D061s555\u00C2\u00F8\u00F8\u00B8)\x12\u0089\u00D8jkks\u00C8\u0097\u0093F\u00F5\u00E0s\x1B~\u00D7\u00E0\u00EB\u0080\x7F\x16u\u0094\u00A4\u00E1 \x18\u00C7qI\u00BB\u00DD~exx\u00D8e0\x18\u00B2\u00D84yn\u00D3\x01\u00A2\u00DF\u0094\u00D3\u00E9\u00EC\x18\x1C\x1C4744\b\x00!\u0083\u00D7v\u00A1P`\u009D\u009D\u009D\u00E1\u00F6\u00F6\u00F6\u00BEh4\u00DA\u0084\u00BCg\x04\u00E3'\u009A\u00D3\u00B7\u00B5\u00B5\u00AD\u00FB|\u00BEP0\x18lFl\u009F\x1A\u00C0\u00E2\u00F7\u00E1p\u00B8\u00D1j\u00B5\u00A6\u00BB\u00BB\u00BB\u0093===\u00E7\u00A1\u00EDQ\x03(\u00BA\u0087\u00C6\u00C0\u00C9\u0092\x06\u00C4$\u00C1@\u0091\u00CF\u00B4a\u009DN\u00F7\x02\x1B2\x03\u00F0M\u00A5RY@\u00BEF\u00A5R}\u00C2)0l\u00B2\u0084\r_\x06\u00C4[\x1A\u008D\u00E6\x00,\u00B4\x0FtJ\x00U\u008A\u00C7\u00E3\x17\u00D1\\\x076\u00FC\x04\u00F9Jh\x1F\u00A9\x1E|\x1E\u00C0/\b_7\u00FC\u008B\u00A8\u00A3\u00A6ut[y\u009E\u00DFt8\x1C~\x1CN\x17\x0E\u00B0H\x07\x02\u00ED\u00CB\u00FC\u00FC<\u008F~\u00B7\\.\u00D7\u008DP(\u00E44\x1A\u008D%\u00DC\x1C\x0E^_\t\u0086\u00DB\u00ED\u00CE\x01\u00E2\x04.\u0083\x19y?\b\u00C6w\u00C0\u00D0\x01F\x0E0\x06\x00\u00E3\x1Cb%\x11\u00C6>`\x18\x01#\x01\x18\x13\u0080A\x04wE\x18\u00BB\u0080a\x02\u008C\x04`L\u00880\u00DE\u00880\u009E\u00A2\u00E9\x16j\x1E\u0085\x05\u00E4S\u00E3\u00AFE\x18E\u00C0p\x01F\x1F`\u00E4E\x18/1s\u0080Q\x04\f\x07`\\\x02\u008C\u00C7\u00C8W@{%\u00C2X\u0087_\x00\u00BEW\u00E1\u00BF\u0083:*Z'\u00C2\u00B8\x07\x18>\u00C0\u00B8\x0E\x18;\"\u008C\u00B7\u0080A7\u00E3>`x\x01\u00E3\x02`\x14\x01C\x06\u00AFw\"\u008C\f`D\x00\u00A3\x05y\u00DF\u00A4\u009BQu3\u00A4\u00EF\u008C\u00F2w\u0086\u00F4kR\u00F1k\"=gT<gHO\u00A0\x15O\u00A0\u00D2\x7F\u0092\u00BF\u00E3\x17N\x07t\x17\u0085{\u00C7\u009F\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myThickThick = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x00NIDATx\u00DA\u00ED\u00D7\u00B1\r\u00C0@\bCQ\u00D7LKE\x0B\x05{]F\u008B\u00A2C\nC|\u00A4\u00B7\x01\u00C2FU%\\\u00CAL\fu7\u0086\u00DC\x1D\u00E3\u009B\u0083af\x0F.E\x04\x06\u009B\u00B17\u0083[\u00B1\u0090\"+M\u00E8\x17\u00ABg\u00D0<W\x03\u00E5'\u00F9\u00BD\u009A0D\u00A7\u00CE\u00C8\u00CE\u00C4\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myThickThin = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x00UIDATx\u00DA\u00ED\u00D7\u00CB\t\u00C00\f\x04\u00D1u\x19i\u00C9'ubP\x03\u00F6A\u00CD\x04\u00D2c>H\x10\x171\u0082W\u0082`Vk-!i\u00CE\u0089\u00A2\u0088@\u00D1\x18\x03E\u00AD\u00B5\x0BI\u00EF\u00DD(\u00BDwG\u0092\u0099\x1DH\u00DF\u009B\u009C(\u00EE\u008EB_\u00EC\u009DAyn\x05\u00CA&\u00F9=\u00EC\u0082J\u00AC\x1F.\u00DC\u0091\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myThickThinThick = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x00MIDATx\u00DA\u00ED\u00D7Q\r\u00C00\b\u0084\u00E139\x1DH\u0080\x07\u00F4TC\u00A55\u00CB\x18E\u00C4O\u00F29 \u00DC\u00A1\u0088\x10>rw\x14e&\u008A\u00CC\f\u00E5\u009D\u008D\u00A6\u0085\u00A6\x07\u008D\u008D\u0098\u009B\u00C1\u00AD\u00F8\u0091\"#M\u00E8\x17\u00A3g\u00D0<G\x03\u00E5'\u00B9\x0E\u008C\u0083\u00E4\x05\u00B8\u0082:2\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myThinThick = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x00UIDATx\u00DA\u00ED\u00D7Q\t\u00C00\fE\u00D1W\x19\u00B3\u00D4\u00AF8)\u00C4@\u00FB\x113\u0083y\u00DC(\t\u00AC\"n\u00E0H\b\u00DC\u00A7\u00B5\u0096\u00904\u00E7DQD\u00A0\u00C8\u00DDQ\u00F6\u00DD(fv!\u00A9\u00F7\u00EEH\u00FBM^\u0094\u00D6\u00DA\u0083\u00A41\x06\n}qv\x06\u00E5y\x14(\u009B\u00E4\u00F7\x01\u00ADrJ\u00ACSW\u00AA3\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myThinThickThin = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x00VIDATx\u00DA\u00ED\u00D7A\r\u00C0@\bD\u00D1\u00A9\t\u00C4p\u00AD\x1BL,\x17\u00CE\u00B5Z\tm\u00C2&\u008B\u0088O\u00F2\x1C\u0090aPf\nMk-l\u00AA*l\u008A\u0088\x0BMf\u00F6\u00A0\u00C9\u00DDo4\u00FD\u00F3bc#\u00C6f\u0090\x15#3\u00B8\"\u00E3\u009A\u00D0/F\u00CF\u00A0y\u008E\x06\u00CAOr|2\u00CD2\u00DB\x04\u009F\u00DA\u00B2\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myThinThin = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x00QIDATx\u00DA\u00ED\u00D7A\r\u00C0@\bD\u00D1\u0091T\x0F8\u00C2\x00\x1C\u00B0\u0080\u0083\x15\u00DA4KRD|\u0092\u00E7\u00800\u00832S\u00B8\x14\x11\x18\u00AA*\f\u00B9;\u00C67\x07\u00C3\u00CC\x1E\\\u00EAn\f6co\x06\u00B7b!EV\u009A\u00D0/V\u00CF\u00A0y\u00AE\x06\u00CAO\u00F2{\x01\x17\u009E`\"%1c<\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myTriple = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x00RIDATx\u00DA\u00ED\u00D7\u00C1\t\u00C0P\bD\u00C1\u00ED\u00C4:\u00FE)5Y\u0081\x1El#\u0090RCP\u0088E<a:\x10wUf\nM\x11\u0081\u00A1\u00AA\u00C2\u0090\u00BBc|\u00F3`\u009Cs.4\u0099\u00D9\u008D\u00C6f\u00EC\u00CD\u00E0V,\u00A4\u00C8J\x13\u00FA\u00C5\u00EA\x194\u00CF\u00D5@\u00F9I~/\u00B3\u00CD!\x0F\u0093\u0080\nU\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myWavy = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x04kIDATx\u00DA\u00EDVYh\u0094W\x14\u00BE\u00FF\u00FFga\u00A2\t\u00B1\u0089y\u0098,MBaB\u009A\u0090\u0085,\u00C6\u00A4I$\u00B4I\u00C0$\u00A6\x0FI\u00CD&d\u00C3\x17\u00B3o\u0090}\u00B2O&i\x05\u0097\bRA|\x16DT\u00A4\u008AV\x04\u00F7B\u00A1\x0F\x05}P\x14DAD\x14Q\u00FBP\u00BF\u00EFzo\x18\u00C7\fF\u00A7P(\x1D8\u00CC\u00FCw\u00CE\u00F9\u00CE\u00F6\u009D\u00F3_111!\u00FE\u0097w\u00F2\u00D9\u0086\u00E3\u00E3\u00E3\u00AB\u00DF\u009E\u00E2\u00F9\u00DF?\u0089\u00E9\u008F\u00AC7>1::j\u008E\u008D\u008D\x19\u00EBq\u00EC\x1D\u00AC\u00B2\u00B5\u00A6\u00A7\u00A7\r\u0088\u0098\u009C\u009C4qfy\u00E3\u00F9\u00C2\u00F5\u00C6\u0083\u009D\u00B4w:\u009D\x12ojj\u00CA >\u00FD|&\u009EA<\u00E0\u0098\x1AO\u00C5\u00C7\u00B8?\u00C0\x13.\u0097K\u00CC\u00CF\u00CF\x0B\x04 <\u0093\u00F0t\u00E8\u00F9\u00AC@X\x00\u00B1\u00B8\u00B8(fggEww\u00B7\u00E8\u00E9\u00E9\x11\u00C3\u00C3\u00C3\u00C2\u00EDv\u008B\u00B9\u00B99\u0089\x07=\u00D3W\x02^\u00E7&\u00F5\x19\x07\u00ED\x07\x07\x07%^oo\u00AFXXX\u00901\"\x11\u00FA\u00B6\u00D6\u0083\u00C7d\u00A9O;J__\u009F\u00C4\x1B\x18\x18\u00901\x13\u0093qC\u00FF=<\u0091\u0091\u0091\u00D1[TT\u0094144$fffd\u00A2\u00BAj\u00DE222b\x02\u00C4 Pkk\u00EB\u00C6\u00EC\u00EC\u00EC\u00C6\u00E4\u00E4\u00E4#B\u0088\u008B\u0090k\u0091\u0091\u0091grrr\x16\u00CB\u00CA\u00CA\u008A\u0088\x07\u00A6H\u0087\u00E8\u00C6\x07LQ\u00CC2\u00D85\u00FE\u00EE\u00EF\u00EF\x0F,((\u00A8\u00CA\u00CA\u00CA\u00DAo\u00B3\u00D9\u00CE\x03\u00EF*\u00E4\\zz\u00FA\x01\u009Cm\u00EF\u00E8\u00E80Y,\u00EA#\x0E\u009Fx\u00F4\u00C7\u00F8:;;\x05b\u00F9\x06\u00F9\u00ED\x05\u00CEY\u00E2\x05\x06\x06^\x04\u00D6\x11\u00C8\u00CE\u00DA\u00DAZ\x1B\x0BF\x16j<~nC\u00DE\x04\x05\x05]jhhp\u00B0 \u00EC,@%E!\x01\u00A4?\x13[^^\x16\u00CD\u00CD\u00CD\u00C2\u00E1p\u00EC\u0081\u00CDc\u00C8#\u00C8\u00E9\u00D4\u00D4TWii\u00A9\x13\u00CEV\u00F0|\x13\u00F2\n\u00F2;\u009Cna\x02\u00C4\u00F4(\u008C\u00C4c\x12\u00EC\x10\u00BF\x13\x12\x12\u00BE\u0087\u00FE=\u00C83\x166<<|oEE\u00853..\u00EE'<\u00FF\u00AA\u00CE\u00EF \u00B1\x1DLriiI\u00DA\u00A9\u00B1\f`\x03\u0089\u00AF\u008A%\u00CA\u00CB\u00CB\u00B7A\u00FF\x0F\u00C8\x0B\u00C8\x15\u00BB\u00DD\u00BEB\u00BC\u0088\u0088\b7\u009E\u00CF\u00A8\u00D8\x1F\u00C4\u00C6\u00C6\u00B6\u00C1^\u00B2G\u008E\t\x00,t2S9}\u0091\u0098\u0098\u00B8\u00BB\u00B1\u00B11\u0098\u0095b\u0085Y\x18\u00D2\u009F\u009D.))\u00F9\u00DA0\u008C_\u00A0\u00F7\x1A\u00AC\u00E8\u00EB\u00EA\u00EA\u00DA@\x16iJ\u00A2\u00C2\u00EC\u008E\u00A8\u00AC\u00AC\u00FC*44\u00F48\u00F4\u00FENJJ\x1Amoo\u00FFBw\u0090c@\x1D\u00FE\u00AE\u00AF\u00AF\u008FG\u00A0?S/::\u00DA]WW\u00B7YuX\u00EA\u00E9\u00CE\u00C3\u00DE\x0E\u009C}\u00D4\x0B\x0B\x0B;XUUe\u00A7/\u00C6\u00A5G\u00886\u00D5\u00D5\u00D5\u009B\u00F1qQ/88\u00F8XSS\u00D3\u0097j\u00FCW\u00FD\x12\x0F\u00E7\u00A1\u00F1\u00F1\u00F1\x03$ATT\u00D4I\u00B0\u00C4\u00C1b\u00CA\u008E\u00B1s\u00A0\u00A9\u0088\u0089\u0089\u00A1\u00C2S\u00C8}\u00CB\u00B2N\u00E4\u00E7\u00E7/\u0080\u00BAN\x00\x1F\u00C6\u00D9o\u0090\u00BF \u00D7Q\u00F94v\u0087\u008Eh\u00CF\u00CExv\u009C\u00FF\u00B1\u0083\u00E8\u00E4.\u00E8?T\u0098\u00E7\u00D1i\u00D9qt~E\u008D\u00C1K\u00C8\u009F\u00F0\u00F3-\x13\u00D3L\x01\u008E\u00C4#\u0093t|\u00EC:\x1AP\u00AE\u0098\u00FC\x1Cr9$$d?\x19\tf\u00FE\u0088g6\u00E9\t\u00E4nZZ\u00DA\x0FL\\-u\u00B9\u0093T|\x16\u00F1Y@\x16\u00A8\u00B0\u00B00\x0By\u00DERL\u00BE\u00F1\u00DE\u00C2\u00A1\u00D4\u00D4\u00D4l\u00CA\u00CB\u00CBkA\u00E5\u008EB\u00E1\x12\u0083\u0086\u00C1\u00A9\u00CC\u00CCL\u00D7\x16|\u0098$\x19\u00A3FH\u00AC5\u00BB\u009CAnn&\u0080Y\u00B7a\\j0\u00FB\u0087\u0080u\u0081\u00B4\u00C5N8\u008B\u00B3e\x14\u00FA;.K\x06\u00A7(\u00EFs\x17p\x19\u00D3o[[\u009B\u0099\u009B\u009B[\u0096\u0092\u0092\u00B2O\x15\u00E0\x1A\x0B\u008D\u00DDu\b\u00E1U\u00B7\u00B4\u00B4\x04\u00B0x\u00DC\x05k\u00BD\u00D5<w\x0B\u008BO\u00C6\x17\x17\x17oE\u00E3\\\u00AB\u00DB\u0098\u0089Q\u0081@\u00DC\u00B8\u00AC(\u00DF\x12\x14nu\x06Lc\u00B5\u00D5\u00CDunuK\u008F\x10m\u0089\u00C3\u00AD\u00CE\x02\u0090\u00B6\u00FA-\u00A6_\u009D\x1F\u00C3cA\u00D8m\u00E2q|1\u00A6\x12\u008F1\u00B2P\u008C\u009B\u00FF\u0093\u00A9\u00DEo\u00C3\u00B5\u00F0\u00E8W\u00BF\u00C5\u0088\u00B9V\x02R\u0089\u0085\u00D1\u00F7\x07np\x7F\u00EE\x0F\u00FA>B\u00B6\x10\x0F\x01h<\u00D3\x1F<\x1D\x1F\u00BF?\u00E5>\u00E2}e\u00D0\u00F7\u0091\x7F\u00E5\x16\u00E8\u00CFM\u00D5W|\u00FE\u00DE~\u00FD\u00BA\u008E\u00FF\x17\u00E5-\u00A2%\u00C2D\x07GSf\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myDiamonds = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00C\x00\x00\x00\r\b\x06\x00\x00\x00\u00F2\u0098\u00D3o\x00\x00\x00\tpHYs\x00\x00\x0B\x13\x00\x00\x0B\x13\x01\x00\u009A\u009C\x18\x00\x00\x03qIDATx\u00DA\u00EDWYOSQ\x10\u009E\u00DB\u00B2\u0085\u00ADlbi\u00A1M\u0091%\u00C1\x02\r%1,\u0085\u00D8\u0082\x11L\x1B\u00A5QD\u00A1\u0094Z\u0090\u008A\u00CAZh\x0B\u0094\u009D\x00\u0085\u00B0&\r\u00BE\x18\t\x06\u00E2\u00A3\u0089KLL\u00FCi~s\u00BD\x17ox \u00C4\x17_\u00DAdr\u00CE\u00CC\u009D\u00EF\u009B\u00EF\u00CC9\u00BD=\u00A5\u00C5\u00C5EJ\u00D8\x1F\u00A3\u0085\u0085\x05q\u00A2\x1C\u00AF\u008A]'\u00E7\x7Fp]\u008E\u00FD\x0B\u008E\u0096\u0096\u0096\x049\x10\u008DFE\x7FyyY\u00E0\u00B9\u009C$\u00E5\bJ b\u00AAK\u00E4\u0082\u0092K\x1A\x056%\u00FF\u00CA\u00CA\u00CAEL6\u00E6R\u00D6\u0093p\u00AA\u00AB\u00B8\x14\u00BA.x\u00C0!\\\u00D6u\u009D\u00F5\u00C8\u00BAh~~\u009EVWWinnN\u00E0\x00F\n\u0087\u00C3\u00B4\u00B6\u00B6\u00C61N\x12\u0093\u00D9g1\u00C8\x178\u009Fc<\u00B2\u00CF\u00C4r\u008C\u00F3\u0099\u0093\u008B\u00F0\u009CG\x14\x17\u00B9\u00D6\u00D7\u00D7ijj\u008A N\u00E4b\u00F1\u00D2\u009C677E.9_6\u00D6%\u00E7H|\u0082\u00A4U\\\u0098\u00A4O\u00E4b\x0E\u00A5.YK(\x14\u00BAr=\u00ACkzz\u009AH\u00A3\u00D1\u008C\u00F9\u00FD\u00FE\u00CC\u009D\u009D\x1D\x11\u0098\u0097\u0097\u00F78%%\u00C5\u00CF\x0F96::\u00AAF\u00CE\u00A4\u00CB\u00E5j\u00E2\"\u00DB\u00DB\u00DB\u00D4\u00DF\u00DF\u00AF\u00CD\u00CC\u00CC\f\x0E\r\r\x19766(\x16\u008BQ{{\u00FB\u009D\u00DC\u00DC\u00DC\x19|\u0092\u00E4XMM\u008DW\u00AF\u00D7\u00F7\u00B0\x00\u00C6\u00F5\u00F6\u00F6\u00A6\x10Q\u00A8\u00BE\u00BE\u00DE\u00C2\u00C2%\u00DC\u00AD\u009C\u009C\u009C\u00C9\u00AE\u00AE\u00AEB\u00C6mmm1\u00CE\u00AE\u00D3\u00E9& R\u00C5y\u00DC\f\u00F8\u00AFjkk\u009D\u00ECs\x0E\u00EAh\u00B2\u00B3\u00B3g;;;\u00CBY'\u00D7hii\u00A9\u00CE\u00CA\u00CA\u009A\u00F0x<Y\x1C\u00E3fj\u00B5ZWRRR`||\\\u00D4\u0080\u00CD\x10\u00B8^GG\u00C7]\u00E6e\r\u0083\u0083\u00837\u00A0+F\x15\x15\x15=\u00E9\u00E9\u00E9\u00AF}>\u009F\x1E\x05\u00DDeee^\u0088y\u0084\u00A6\u00F8\u00B0\u00D8B\x00\u00C7 \u00E2\u00BE\u00C9dz\t\u00BB\u00E7\u00F5z\riii\u0091\u00C6\u00C6F\u0087\u00C1`\u0088\x04\x02\x01\u0093\u00D3\u00E9l)//\x1F\u00A9\u00AA\u00AA\u00EA\u00C4\u00E2\u00DF\u00A0\u00B9Z\u008B\u00C5\u00D2g\u00B5Z\u009F\u0081\u00B3\x1B\u009C=\x10X\u0094\u009C\u009C<\u00D5\u00DA\u00DA\u00DA\x06\u00C1o\u0081o\x00\u00AEL\u00A5R\u0085m6\u009B\x1Db\"hx1\u00E2\x0F\u00F0\u00DC\u00D7\u00D4\u00D4\u00E4\u00AA\u00AC\u00AC\x1C\u0086\u00AE\"\u008C\u00FE\u0092\u0092\x127ty\u009A\u009B\u009B\x1Fvww\u00EBQ;\x04\\\x1B\u00F0\u0093n\u00B7\u00DB\u008C\x06W\u00A39\u00C1\u0086\u0086\x06Gjj\u00EA\u00CC\u00C0\u00C0\u00C0M\u00A3\u00D1\u00F8\x04\u00E6\u00A9\u00AB\u00ABscC\u00BDX\u008F.??\x7F\u00C4l6;\u00A1\u00F7Eqq\u00F1}\u00F0\x1B\u00B8\u00A9\u00C0Y(\x1E\u008F\x13\n\u00D9 \u00E6\x0Bl\u009D\u00BB\u00B5\u00BB\u00BBK\x19\x19\x19\x13\u00F0\u00BFa\u00B7\u00BB\u008E\u008E\u008E(\x12\u0089\u00C0\u00A5w\u00B0O \u00BA}rrB}}}%\u00F0\u00CF\u00D5j\u00F5\x07\u00FE\x1E\x1E\x1E\x1E\u0092\u00DDn\u00EF@\u00EC'N\u00CE\u00CC\u00F1\u00F11\x05\u0083A\u00C6Ea_!\u00A2\u008Dq8!\u00A9\u00F0?\u00C2\u00DE#\u00DFx~~N\x0E\u0087\u00C3\u00CC\\\u00B0#<\u00A7\u00D3\u00D3S*--}\n\u00FF\x17p\u00C3\u00BC\u00D3\u00FB\u00FB\u00FBTPP\x10C\u00EC;p\u00D6\u00B3\u00B33Bs\n%\\\x1C;\u00ACa~\u00E8kd\u009D\u00BC\u00DB\u00B3\u00B3\u00B3\u00C4\u00BA\u00B0\u008E!\u00F8?\u00B0\u00F1\u00CF\u00F7\u00F6\u00F6\u00C4S\u00C3\x18\u00D8glT\u00E9\u00C1\u00C1\x01%N\u0086\u00F2d$\u00DE\x19\u008AwF\u00E2\u00D7D\u00F1k\u0092\u00B8g(\u00EE\x19\u0089\x1B\u00A8\u00E2\x06\u009A\u00F8O\u00F2\u00D7~\x03B+{|\u00F8\u00F2L\u00D4\x00\x00\x00\x00IEND\u00AEB`\u0082";
var myStrokeTypes = [["Solid",mySolid] , ["Thick Thick",myThickThick] , ["Thick Thin",myThickThin] , ["Thick Thin Thick",myThickThinThick] , ["Thin Thick",myThinThick] , ["Thin Thick Thin",myThinThickThin] , ["Thin Thin",myThinThin] , ["Triple",myTriple] , ["Dashed 3-2",myDashed32] , ["Dashed 4-4",myDashed44] , ["Left Slant Hash",myLeftSlant] , ["Right Slant Hash",myRightSlant] , ["Straight Hash",myStraightHash] , ["Dotted",myDotted] , ["Wavy",myWavy] , ["White Diamonds",myDiamonds] , ["Japanese Dots",myJapDots]];
//=============================================================
Copy link to clipboard
Copied
Uwe, what I meant to say is that there is no access to their definitions. In my sample script, I use the definition to create a preview on the fly. To include the built-ins, you have to create something from scratch and guessing their values, or use a screen grab.
Copy link to clipboard
Copied
Hi Jongware,
I feel like we've opened Pandora's box. Great job!
Congrats.
@+
Marc
Copy link to clipboard
Copied
Appendix: pngcheck 2.3.0
pngcheck is a great little tool to test the integrity of PNGs with -- to ensure my home made PNGs were well-formed, I wrote them out into a file and tested them with this little command line tool. At work (Windows 7), I could download the latest version as a Windows executable, but when at home (Mac OS X 10.6), I could not find a good recent version. Fortunately, I'm not one to sit down and take it like a man; since I have VirtualBox on my computer, all I had to do was copy my PNG to the VB shared folder, go to Windows, go to the command line, (sigh) enter the commands and check. Hey, an error. Re-do from Start.
With a little more trouble, I just (1:50 in the a.m.) compiled the latest version for OS X. I have no idea if this will work on others' computers (especially if you are not running Sno Lep, as I am), but feel free to download it from my site and try:
http://www.jongware.com/binaries/pngcheck-2.3.0.zip
You need Terminal experience to use it. It's a command line tool. Best is to place it into your usr/bin folder, to make it available from any folder you are terminalling in:
sudo mv pngcheck /usr/bin
(It needs 'sudo', and your password, because the usr/bin folder is protected. ... don't go experimenting with using it on other commands!)
Copy link to clipboard
Copied
Update.
The PNGs created with this script display okay in InDesign itself, and in OS X's Preview and Windows' Image Viewer. However, pngcheck sometimes fails, and Photoshop cannot read the image in that case either.
... 2 hours later, I found out why. My mistake! Replace the function adler32 inside the main makepng function with this one:
var adler32 = function (/*string*/buf)
{
var i, a = 1, b = 0;
for (i=0; i<buf.length; i++)
{
a += buf.charCodeAt(i); a %= 65521;
b += a; b %= 65521;
}
return (b<<16)+a;
}
-- the error was in the first mod 65521 line, I did that on a wrong variable.
.. Fortunately, no-one noticed this so far
[Edit] Oh, and it transpires the main packing routine needs to check for image data > 64K (an individual data block may not be larger than the 16 bits needed for each deflate block).
Copy link to clipboard
Copied
As Bender once said, "I've always wondered what it would be like to be more annoying." -- now you can try that too!
Introducing "Annoying Addy", based on Microsoft's iconic Clippy:
Download http://www.jongware.com/binaries/annoyingAddy.zip and have some fun Of course the 'buttons' and 'checkboxes' don't really work, it's just an image (but maybe Marc Autret or Peter Kahrel can make them "real").
On a slightly related note, the makepng function in this script is fixed to be able to create PNGs larger than 64K.
Copy link to clipboard
Copied
I am just speechless ! Great work Jongware
Copy link to clipboard
Copied
Almost forgot about the challenge!
Peter
var f = File ('/d/png/addy.png');
var w = new Window ('dialog');
w.orientation = 'stack';
if ($.os.indexOf ('Windows') < 0)
var addy = w.add ('image', undefined, f);
var rb1 = w.add ('radiobutton');
var rb2 = w.add ('radiobutton');
var chb = w.add ('checkbox');
if ($.os.indexOf ('Windows') > -1)
var addy = w.add ('image', undefined, f);
w.onShow = function () {
rb1.location = [25, 147];
rb2.location = [25, 204];
chb.location = [26, 275];
}
w.show();
Copy link to clipboard
Copied
That's totally wicked!
Let's all go to the Feature Request form and submit this as a definitive "must have"!
Copy link to clipboard
Copied
Yes, let's!
(The script I posted was culled from another one, and I now notice that it's not necessary to ceclare the image as a variable. Just remove the two instances of var addy =.)
Peter