yui-compressor-2.4.7/0000755000175000017500000000000011753547175014437 5ustar drazzibdrazzibyui-compressor-2.4.7/build.xml0000644000175000017500000000501211640627104016240 0ustar drazzibdrazzib yui-compressor-2.4.7/ant.properties0000644000175000017500000000032711640627104017323 0ustar drazzibdrazzibsrc.dir = src lib.dir = lib doc.dir = doc build.dir = build product.name = yuicompressor version.number = 2.4.7 jar.name = ${product.name}-${version.number}.jar dist.package.name = ${product.name}-${version.number} yui-compressor-2.4.7/LICENSE.TXT0000644000175000017500000000456311640627104016114 0ustar drazzibdrazzibYUI Compressor Copyright License Agreement (BSD License) Copyright (c) 2011, Yahoo! Inc. All rights reserved. Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Yahoo! Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Yahoo! Inc. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software also requires access to software from the following sources: The Jarg Library v 1.0 ( http://jargs.sourceforge.net/ ) is available under a BSD License – Copyright (c) 2001-2003 Steve Purcell, Copyright (c) 2002 Vidar Holen, Copyright (c) 2002 Michal Ceresna and Copyright (c) 2005 Ewan Mellor. The Rhino Library ( http://www.mozilla.org/rhino/ ) is dually available under an MPL 1.1/GPL 2.0 license, with portions subject to a BSD license. Additionally, this software contains modified versions of the following component files from the Rhino Library: [org/mozilla/javascript/Decompiler.java] [org/mozilla/javascript/Parser.java] [org/mozilla/javascript/Token.java] [org/mozilla/javascript/TokenStream.java] The modified versions of these files are distributed under the MPL v 1.1 ( http://www.mozilla.org/MPL/MPL-1.1.html ) yui-compressor-2.4.7/tools/0000755000175000017500000000000011640627104015561 5ustar drazzibdrazzibyui-compressor-2.4.7/tools/cssmin-debugger.html0000644000175000017500000000567311640627104021540 0ustar drazzibdrazzib

Use This Page to Debug cssmin.js

Your browser does not support the local file access apis used by this page.

Select a css file to compress. You can then step through the cssmin.js implementation using your browser's script debugger.

Compressed



        

Original



        
    
yui-compressor-2.4.7/tests/0000755000175000017500000000000011640627104015563 5ustar  drazzibdrazzibyui-compressor-2.4.7/tests/zeros.css.min0000644000175000017500000000007411640627104020222 0ustar  drazzibdrazziba{margin:0;_padding-top:0;background-position:0 0;padding:0}yui-compressor-2.4.7/tests/zeros.css0000644000175000017500000000015511640627104017440 0ustar  drazzibdrazziba { 
  margin: 0px 0pt 0em 0%;
  _padding-top: 0ex;
  background-position: 0 0;
  padding: 0in 0cm 0mm 0pc
}
yui-compressor-2.4.7/tests/webkit-transform.css.min0000644000175000017500000000007311640627104022355 0ustar  drazzibdrazzibc{-webkit-transform-origin:0 0}d{-moz-transform-origin:0 0}yui-compressor-2.4.7/tests/webkit-transform.css0000644000175000017500000000010211640627104021564 0ustar  drazzibdrazzibc {-webkit-transform-origin: 0 0;}
d {-MOZ-TRANSFORM-ORIGIN: 0 0 }yui-compressor-2.4.7/tests/suite.sh0000644000175000017500000000217011640627104017250 0ustar  drazzibdrazzib#!/usr/bin/env bash

cd $(dirname $0)
	
# Get the jar to use.
jar="$(ls ../build/*.jar | sort | tail -n1)"
echo "jar: $jar"

runtest () {
	testfile="$1"
	expected=${testfile/\.FAIL/}.min
	expected="$(
		cat $expected
	)"
	filetype="$(
		echo $testfile | egrep -o '(cs|j)s'
	)"
	
	if [ "$2" == "cssminjs" ]; then 
	    actual="$(
		    java -jar ../lib/rhino-1.6R7.jar suite.rhino $testfile
	    )"
         
    else
	    actual="$(
		    java -jar $jar --type $filetype $testfile
	    )"
    fi
	
	if [ "$expected" == "$actual" ]; then
		echo "Passed: $testfile" > /dev/stderr
	else
		(
			echo "Test failed: $testfile"
			echo ""
			echo "Expected:"
			echo "$expected"
			echo ""
			echo "Actual:"
			echo "$actual"
		) > /dev/stderr
		return 1
	fi
}


ls *.FAIL | while read failtest; do
	echo "Failing test: " $failtest > /dev/stderr
	runtest $failtest && echo "Test passed, please remove the '.FAIL' from the filename"
done

ls *.{css,js} | while read testfile; do
	runtest $testfile || exit 1
done

echo 
echo "now testing the JS port of CSSMIN..."
ls *.css | while read testfile; do
	runtest $testfile "cssminjs" || exit 1
done

exit 0
yui-compressor-2.4.7/tests/suite.rhino0000644000175000017500000000014511640627104017755 0ustar  drazzibdrazzibinput = readFile(arguments[0]);
load("../ports/js/cssmin.js");
print(YAHOO.compressor.cssmin(input));yui-compressor-2.4.7/tests/string-in-comment.css.min0000644000175000017500000000007011640627104022426 0ustar  drazzibdrazziba{a:1}/*!"preserve" me*/b{content:"/**/"}/*\*/c{c:3}/**/yui-compressor-2.4.7/tests/string-in-comment.css0000644000175000017500000000017711640627104021654 0ustar  drazzibdrazzib/* te " st */
a{a:1}
/*!"preserve" me*/
b{content: "/**/"}
/* quite " quote ' \' \" */
/* ie mac \*/
c {c : 3}
/* end hiding */yui-compressor-2.4.7/tests/star-underscore-hacks.css.min0000644000175000017500000000005411640627104023265 0ustar  drazzibdrazzib#elementarr{width:1px;*width:3pt;_width:2em}yui-compressor-2.4.7/tests/star-underscore-hacks.css0000644000175000017500000000007311640627104022504 0ustar  drazzibdrazzib#elementarr {
  width: 1px;
  *width: 3pt;
  _width: 2em;
}yui-compressor-2.4.7/tests/special-comments.css.min0000644000175000017500000000023711640627104022324 0ustar  drazzibdrazzib/*!************88****
 Preserving comments
    as they are
 ********************
 Keep the initial !
 *******************/#yo{ma:"ma"}/*!
I said
pre-
serve! */yui-compressor-2.4.7/tests/special-comments.css0000644000175000017500000000025211640627104021537 0ustar  drazzibdrazzib/*!************88****
 Preserving comments
    as they are
 ********************
 Keep the initial !
 *******************/
#yo {
    ma: "ma";
}
/*!
I said
pre-
serve! */yui-compressor-2.4.7/tests/pseudo.css.min0000644000175000017500000000003111640627104020350 0ustar  drazzibdrazzibp :link{ba:zinga;foo:bar}yui-compressor-2.4.7/tests/pseudo.css0000644000175000017500000000005011640627104017567 0ustar  drazzibdrazzibp :link { 
  ba:zinga;;;
  foo: bar;;;
}yui-compressor-2.4.7/tests/pseudo-first.css.min0000644000175000017500000000013011640627104021475 0ustar  drazzibdrazzibp:first-letter {buh:hum}p:first-line {baa:1}p:first-line ,a,p:first-letter ,b{color:red}yui-compressor-2.4.7/tests/pseudo-first.css0000644000175000017500000000046311640627104020724 0ustar  drazzibdrazzib/* 
because of IE6 first-letter and first-line
must be followed by a space
http://reference.sitepoint.com/css/pseudoelement-firstletter
Thanks: P.Sorokin comment at http://www.phpied.com/cssmin-js/ 
*/
p:first-letter{
  buh: hum;
}
p:first-line{
  baa: 1;
}

p:first-line,a,p:first-letter,b{
  color: red;
}yui-compressor-2.4.7/tests/preserve-strings.css.min0000644000175000017500000000013711640627104022402 0ustar  drazzibdrazzib.sele{content:"\"keep  \"    me";something:'\\\' .     . ';else:'empty{}';content:"/* test */"}yui-compressor-2.4.7/tests/preserve-strings.css0000644000175000017500000000030011640627104021610 0ustar  drazzibdrazzib/* preserving strings */
.sele {
  content: "\"keep  \"    me";
  something: '\\\' .     . ';
  else: 'empty{}';
  content: "/* test */"; /* <---- this is not a comment, should be be kept */
}yui-compressor-2.4.7/tests/preserve-new-line.css.min0000644000175000017500000000010511640627104022422 0ustar  drazzibdrazzib#sel-o{content:"on\"ce upon \
a time";content:'once upon \
a ti\'me'}yui-compressor-2.4.7/tests/preserve-new-line.css0000644000175000017500000000012011640627104021635 0ustar  drazzibdrazzib#sel-o {
  content: "on\"ce upon \
a time";
  content: 'once upon \
a ti\'me';
}yui-compressor-2.4.7/tests/preserve-case.css.min0000644000175000017500000000025311640627104021623 0ustar  drazzibdrazzib#AddAddressForm{padding:0}#AddAddressForm .messageBoxNeutral{padding:0}#FeedbackMailForm{padding:0}#FeedbackMailForm .classe{margin:0}.classes,#FeedBackMailForm{margin:0}
yui-compressor-2.4.7/tests/preserve-case.css0000644000175000017500000000033311640627104021040 0ustar  drazzibdrazzib#AddAddressForm {
    padding: 0;
}
#AddAddressForm .messageBoxNeutral {
    padding: 0;
}
#FeedbackMailForm{
    padding: 0;
}
#FeedbackMailForm .classe{
    margin: 0;
}
.classes, #FeedBackMailForm {
    margin: 0;
}
yui-compressor-2.4.7/tests/opacity-filter.css.min0000644000175000017500000000023411640627104022011 0ustar  drazzibdrazzibpre{border:solid red;opacity:.8;-ms-filter:"alpha(opacity=80)";filter:alpha(opacity=80);zoom:1}code{-ms-filter:"alpha(opacity=80)";filter:alpha(opacity=80)}yui-compressor-2.4.7/tests/opacity-filter.css0000644000175000017500000000126611640627104021235 0ustar  drazzibdrazzib/*  example from https://developer.mozilla.org/en/CSS/opacity */
pre {                               /* make the box translucent (80% opaque) */
   border: solid red;
   opacity: 0.8;                    /* Firefox, Safari(WebKit), Opera */
   -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; /* IE 8 */
   filter: PROGID:DXImageTransform.Microsoft.Alpha(Opacity=80);       /* IE 4-7 */
   zoom: 1;       /* set "zoom", "width" or "height" to trigger "hasLayout" in IE 7 and lower */ 
}

/** and again */
code {
   -ms-filter: "PROGID:DXImageTransform.Microsoft.Alpha(Opacity=80)"; /* IE 8 */
   filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);       /* IE 4-7 */
}yui-compressor-2.4.7/tests/media-test.css.min0000644000175000017500000000010311640627104021105 0ustar  drazzibdrazzib@media screen and (-webkit-min-device-pixel-ratio:0){some-css:here}yui-compressor-2.4.7/tests/media-test.css0000644000175000017500000000011211640627104020323 0ustar  drazzibdrazzib@media screen and (-webkit-min-device-pixel-ratio:0) {
  some-css : here
}yui-compressor-2.4.7/tests/media-multi.css.min0000644000175000017500000000017011640627104021264 0ustar  drazzibdrazzib@media only all and (max-width:50em),only all and (max-device-width:800px),only all and (max-width:780px){some-css:here}yui-compressor-2.4.7/tests/media-multi.css0000644000175000017500000000020211640627104020476 0ustar  drazzibdrazzib@media only all and (max-width:50em), only all and (max-device-width:800px), only all and (max-width:780px) {
  some-css : here
}
yui-compressor-2.4.7/tests/media-empty-class.css.min0000644000175000017500000000016111640627104022373 0ustar  drazzibdrazzib/*! preserved */@import "another.css";@media print{.noprint{display:none}}@media screen{.printonly{display:none}}yui-compressor-2.4.7/tests/media-empty-class.css0000644000175000017500000000040211640627104021607 0ustar  drazzibdrazzib/*! preserved */
emptiness {}

@import "another.css";
/* I'm empty - delete me */
empty { ;}

@media print {
	.noprint { display: none; }
}

@media screen {
	/* this rule should be removed, not simply minified.*/
	.breakme {}
	.printonly { display: none; }
}yui-compressor-2.4.7/tests/ie5mac.css.min0000644000175000017500000000003711640627104020222 0ustar  drazzibdrazzib/*\*/.selector{color:khaki}/**/yui-compressor-2.4.7/tests/ie5mac.css0000644000175000017500000000014311640627104017436 0ustar  drazzibdrazzib/* Ignore the next rule in IE mac \*/
.selector {
   color: khaki;
}
/* Stop ignoring in IE mac */
yui-compressor-2.4.7/tests/font-face.css.min0000644000175000017500000000015511640627104020722 0ustar  drazzibdrazzib@font-face{font-family:'gzipper';src:url(yanone.eot);src:local('gzipper'),url(yanone.ttf) format('truetype')}yui-compressor-2.4.7/tests/font-face.css0000644000175000017500000000021111640627104020131 0ustar  drazzibdrazzib@font-face {
  font-family: 'gzipper';
  src: url(yanone.eot);
  src: local('gzipper'), 
          url(yanone.ttf) format('truetype');
}
yui-compressor-2.4.7/tests/float.js.min0000644000175000017500000000006511640627104020011 0ustar  drazzibdrazzibobj.css({"float":"left"});obj.css({cssFloat:"left"});yui-compressor-2.4.7/tests/float.js0000644000175000017500000000006711640627104017231 0ustar  drazzibdrazzibobj.css({"float": "left"});
obj.css({cssFloat:"left"});yui-compressor-2.4.7/tests/dollar-header.css.min0000644000175000017500000000011711640627104021561 0ustar  drazzibdrazzib/*!
$Header: /temp/dirname/filename.css 3 2/02/08 3:37p JSmith $
*/foo{bar:baz}yui-compressor-2.4.7/tests/dollar-header.css0000644000175000017500000000012711640627104021000 0ustar  drazzibdrazzib/*!
$Header: /temp/dirname/filename.css 3 2/02/08 3:37p JSmith $
*/

foo {
	bar: baz
}
yui-compressor-2.4.7/tests/decimals.css.min0000644000175000017500000000005311640627104020636 0ustar  drazzibdrazzib::selection{margin:.6px .333pt 1.2em 8.8cm}yui-compressor-2.4.7/tests/decimals.css0000644000175000017500000000006611640627104020060 0ustar  drazzibdrazzib::selection { 
  margin: 0.6px 0.333pt 1.2em 8.8cm;
}
yui-compressor-2.4.7/tests/dataurl-validity.html0000644000175000017500000000216511640627104021734 0ustar  drazzibdrazzib

    
   
   
   
   
   
   


   
non-base64 ("")
non-base64 ()
non-base64 ('')
base64 ("")
base64 ()
base64 ('')
yui-compressor-2.4.7/tests/dataurl-singlequote-font.css.min0000644000175000017500000000054411640627104024017 0ustar drazzibdrazzib.y-ff-1{font-family:"Foo Bar",Helvetica,Arial;text-rendering:optimizeLegibility}.ua-op .y-ff-1{font-family:Helvetica,Arial}@font-face{font-family:"Foo Bar";src:url('data:font/truetype;base64,gRbIUFAIrsQNGditEWbAUKwAA') format("truetype"),url("http://yuilibrary.com/fonts/foo-bar.svg#webfontse22fewwr") format("svg");font-weight:normal;font-style:normal} yui-compressor-2.4.7/tests/dataurl-singlequote-font.css0000644000175000017500000000076711640627104023244 0ustar drazzibdrazzib/*csslint fontfamily: true*/ /** * Foo */ .y-ff-1 { font-family:"Foo Bar",Helvetica,Arial; text-rendering: optimizeLegibility; } .ua-op .y-ff-1 { /* Some Comment */ font-family:Helvetica,Arial; } /* Foo Bar */ @font-face { font-family: "Foo Bar"; src: url('data:font/truetype;base64,gRbIUFAIrsQNGditEWbAUKwAA') format("truetype"), url("http://yuilibrary.com/fonts/foo-bar.svg#webfontse22fewwr") format("svg"); font-weight: normal; font-style: normal; } yui-compressor-2.4.7/tests/dataurl-realdata-yuiapp.css.min0000644000175000017500000000404511640627104023576 0ustar drazzibdrazzibhtml{background:#fff;color:#555;height:100%}#hd,#bd,#ft{padding:0 50px}#bd{padding-bottom:50px;border-bottom:1px solid #006e9c}#ft{background:transparent no-repeat 0 100%;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADcAAAAeCAMAAAC/pnaKAAAAwFBMVEUkXIAoYYQoYYQoYYQyao02bpE6cpQ6cpREe51LgqNUiqtUiqtUiqtZj7BckrNlmrtlmrtlmrtroMB3qsp3qsp3qsp+sdCHudiHudiHudiHudiPwN+YyOaYyOaYyOaf0O2g0O6n1vOn1vOn1vOn1vOw3vu45f245f245f3B7f7K9f7K9f7K9f7X/v7X/v7p//7p//79//79//4AAABhAGMAbwBzAC4AcwB0AHIAaQBuAGcAcwABAAAAwIwmGwEAAABQQKFUAAAAQHRSTlP///////////////////////////////////////////////////////////////////8A////////////////0pfSbwAAAdtJREFUOI2NlNGqgzAMhv/ClDlQQcFdKOx4McFCKcH3f7eTtLWr07mFiUvbzz9Nk2LZGRH5937qZTiGyEx0Cr5xQpEd6xzNueCGc9SzUmAzP8cplO1zgRRutBAlM9EhZwknWj1LKXkwbOVojTqMEpKZOfeUD3OnR24VWeJf1OOBTnTgw8zZr3LyOlbdrWrdGlpG6Alz4Ni3RcT4Ldm8wHpOo9Yo5CPsdngM6D3HmLlESrgHD+YvrtEuUeLeMf7x7j23GJVgbJoHs0/cI3B7TNkfON5btsEUrvSdY694U0P9nXMp2mDsdbLmY14CN8XDjtzgo9CuqpYnGoMscDUmn08qsbOn/3Lte6rgP1eM7qQ1YMP+yPhiTmx2laDQspytgJI1MbIzZ7yHfj2/hYYtZ1xMM4dc3iTukjgJyKsrUBEH4uqFXNUh3aXxtWjbC3DpH8LRVPJ8MXLoA8fsz51ue73Q+1z7RkTEF0dWa1o5a8001C6ZbGuzh0bSTo9iS8X+C/NWbfTW5uZ9Vu4QaL20Xv3uhgyrZUXVtI2NfS3fbzgP75dNek/YbrL+k/EykecuZf6ZOzDJYsf9PCV3xhFHq7043mw+H1ylW+5Ab5jpADuPM2Z1P3POLWnUG/sHnIDsqkOjlqoAAAAASUVORK5CYII=);padding:0 0 40px 0;margin:50px}#hd,#bd{background:#f9f9f9}body{margin:0;padding:0;font:12px "Helvetica Nueue",Arial,sans-serif}#hd{color:#fff;padding-top:50px;margin:0}#hd,h1,h2,p,.color{margin:auto}h1,h2,a{color:#006e9c}h1,h2{margin-top:0}h4 .title{font-weight:bold;letter-spacing:-2px;font-size:47px;text-shadow:0 1px 0 #369;background:#006e9d;color:#fff;padding:0 10px}h4{display:block;float:right;margin:0 0 0 20px}h4 .what{display:block;padding:4px;text-align:center;font-weight:normal}h4 .version{font-size:11px;color:#ccc}h2{font-size:40px;font-family:"HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:300}h4,p{padding:6px 0 6px}#ft p.fine,#ft p.fine a{color:#999}#ft p.intro{font-size:12px}#bd{font-size:14px;color:#666}#ft p{font-size:11px} yui-compressor-2.4.7/tests/dataurl-realdata-yuiapp.css0000644000175000017500000000475011640627104023017 0ustar drazzibdrazzibhtml { background: #fff; color: #555; height: 100%; } #hd, #bd, #ft { padding: 0 50px; } #bd { padding-bottom: 50px; border-bottom: 1px solid #006e9c; } #ft { background: transparent no-repeat 0% 100%; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADcAAAAeCAMAAAC/pnaKAAAAwFBMVEUkXIAoYYQoYYQoYYQyao02bpE6cpQ6cpREe51LgqNUiqtUiqtUiqtZj7BckrNlmrtlmrtlmrtroMB3qsp3qsp3qsp+sdCHudiHudiHudiHudiPwN+YyOaYyOaYyOaf0O2g0O6n1vOn1vOn1vOn1vOw3vu45f245f245f3B7f7K9f7K9f7K9f7X/v7X/v7p//7p//79//79//4AAABhAGMAbwBzAC4AcwB0AHIAaQBuAGcAcwABAAAAwIwmGwEAAABQQKFUAAAAQHRSTlP///////////////////////////////////////////////////////////////////8A////////////////0pfSbwAAAdtJREFUOI2NlNGqgzAMhv/ClDlQQcFdKOx4McFCKcH3f7eTtLWr07mFiUvbzz9Nk2LZGRH5937qZTiGyEx0Cr5xQpEd6xzNueCGc9SzUmAzP8cplO1zgRRutBAlM9EhZwknWj1LKXkwbOVojTqMEpKZOfeUD3OnR24VWeJf1OOBTnTgw8zZr3LyOlbdrWrdGlpG6Alz4Ni3RcT4Ldm8wHpOo9Yo5CPsdngM6D3HmLlESrgHD+YvrtEuUeLeMf7x7j23GJVgbJoHs0/cI3B7TNkfON5btsEUrvSdY694U0P9nXMp2mDsdbLmY14CN8XDjtzgo9CuqpYnGoMscDUmn08qsbOn/3Lte6rgP1eM7qQ1YMP+yPhiTmx2laDQspytgJI1MbIzZ7yHfj2/hYYtZ1xMM4dc3iTukjgJyKsrUBEH4uqFXNUh3aXxtWjbC3DpH8LRVPJ8MXLoA8fsz51ue73Q+1z7RkTEF0dWa1o5a8001C6ZbGuzh0bSTo9iS8X+C/NWbfTW5uZ9Vu4QaL20Xv3uhgyrZUXVtI2NfS3fbzgP75dNek/YbrL+k/EykecuZf6ZOzDJYsf9PCV3xhFHq7043mw+H1ylW+5Ab5jpADuPM2Z1P3POLWnUG/sHnIDsqkOjlqoAAAAASUVORK5CYII=); /* image width: 55px */ padding: 0 0 40px 0; margin: 50px; } #hd, #bd { background: #f9f9f9; } body { margin: 0; padding: 0; font: 12px "Helvetica Nueue", Arial, sans-serif; } #hd { color: #fff; padding-top: 50px; margin: 0; } #hd, h1, h2, p, .color { margin: auto; } h1, h2, a { color: #006e9c; } h1, h2 { margin-top: 0; } h4 .title { font-weight: bold; letter-spacing: -2px; font-size: 47px; text-shadow: 0 1px 0 #369; background: #006e9d; color: #fff; padding: 0 10px; } h4 { display: block; float: right; margin: 0 0 0 20px; } h4 .what { display: block; padding: 4px; text-align: center; font-weight: normal; } h4 .version { font-size: 11px; color: #ccc; } h2 { font-size: 40px; font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", sans-serif; font-weight: 300; } h4, p { padding: 6px 0 6px; } #ft p.fine, #ft p.fine a { color: #999; } #ft p.intro { font-size: 12px; } #bd { font-size: 14px; color: #666; } #ft p { font-size: 11px; } yui-compressor-2.4.7/tests/dataurl-realdata-singlequotes.css.min0000644000175000017500000000501011640627104025002 0ustar drazzibdrazzib.yui3-skin-sam .yui3-scrollview-scrollbar{-webkit-transform:translate3d(0,0,0);-moz-transform:translate(0,0)}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first,.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle,.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last{border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAABCAYAAAD9yd/wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJJREFUeNpiZGBgSGPAAgACDAAIkABoFyloZQAAAABJRU5ErkJggg==')}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first,.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last{border-bottom-right-radius:0;border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last{border-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;-webkit-border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:3px;-webkit-transform:translate3d(0,0,0);-moz-border-radius:0;-moz-border-radius-bottomright:3px;-moz-border-radius-bottomleft:3px;-moz-transform:translate(0,0)}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle{border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;-webkit-transform:translate3d(0,0,0) scaleY(1);-webkit-transform-origin-y:0;-moz-transform:translate(0,0) scaleY(1);-moz-transform-origin:0 0}.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-first,.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last{border-top-right-radius:0;border-bottom-left-radius:3px;-webkit-border-top-right-radius:0;-webkit-border-bottom-left-radius:3px;-moz-border-radius-topright:0;-moz-border-radius-bottomleft:3px}.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last{border-bottom-left-radius:0;border-top-right-radius:3px;-webkit-border-bottom-left-radius:0;-webkit-border-top-right-radius:3px;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:3px}.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-middle{-webkit-transform:translate3d(0,0,0) scaleX(1);-webkit-transform-origin:0 0;-moz-transform:translate(0,0) scaleX(1);-moz-transform-origin:0 0}.yui3-skin-sam .yui3-scrollview-scrollbar-vert-basic .yui3-scrollview-child,.yui3-skin-sam .yui3-scrollview-scrollbar-horiz-basic .yui3-scrollview-child{background-color:#aaa;background-image:none}yui-compressor-2.4.7/tests/dataurl-realdata-singlequotes.css0000644000175000017500000000556211640627104024234 0ustar drazzibdrazzib.yui3-skin-sam .yui3-scrollview-scrollbar { -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate(0, 0); } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first, .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle, .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last { border-radius:3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAABCAYAAAD9yd/wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJJREFUeNpiZGBgSGPAAgACDAAIkABoFyloZQAAAABJRU5ErkJggg=='); } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first, .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last { border-bottom-right-radius:0; border-bottom-left-radius:0; -webkit-border-bottom-right-radius:0; -webkit-border-bottom-left-radius:0; -moz-border-radius-bottomright:0; -moz-border-radius-bottomleft:0; } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last { border-radius:0; border-bottom-right-radius:3px; border-bottom-left-radius:3px; -webkit-border-radius:0; -webkit-border-bottom-right-radius:3px; -webkit-border-bottom-left-radius:3px; -webkit-transform: translate3d(0, 0, 0); -moz-border-radius:0; -moz-border-radius-bottomright:3px; -moz-border-radius-bottomleft:3px; -moz-transform: translate(0, 0); } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle { border-radius:0; -webkit-border-radius: 0; -moz-border-radius: 0; -webkit-transform: translate3d(0,0,0) scaleY(1); -webkit-transform-origin-y: 0; -moz-transform: translate(0,0) scaleY(1); -moz-transform-origin: 0 0; } .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-first, .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last { border-top-right-radius: 0; border-bottom-left-radius: 3px; -webkit-border-top-right-radius: 0; -webkit-border-bottom-left-radius: 3px; -moz-border-radius-topright: 0; -moz-border-radius-bottomleft: 3px; } .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last { border-bottom-left-radius: 0; border-top-right-radius: 3px; -webkit-border-bottom-left-radius: 0; -webkit-border-top-right-radius: 3px; -moz-border-radius-bottomleft: 0; -moz-border-radius-topright: 3px; } .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-middle { -webkit-transform: translate3d(0,0,0) scaleX(1); -webkit-transform-origin: 0 0; -moz-transform: translate(0,0) scaleX(1); -moz-transform-origin: 0 0; } .yui3-skin-sam .yui3-scrollview-scrollbar-vert-basic .yui3-scrollview-child, .yui3-skin-sam .yui3-scrollview-scrollbar-horiz-basic .yui3-scrollview-child { background-color: #aaa; background-image: none; }yui-compressor-2.4.7/tests/dataurl-realdata-noquotes.css.min0000644000175000017500000000500611640627104024142 0ustar drazzibdrazzib.yui3-skin-sam .yui3-scrollview-scrollbar{-webkit-transform:translate3d(0,0,0);-moz-transform:translate(0,0)}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first,.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle,.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last{border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAABCAYAAAD9yd/wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJJREFUeNpiZGBgSGPAAgACDAAIkABoFyloZQAAAABJRU5ErkJggg==)}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first,.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last{border-bottom-right-radius:0;border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last{border-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;-webkit-border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:3px;-webkit-transform:translate3d(0,0,0);-moz-border-radius:0;-moz-border-radius-bottomright:3px;-moz-border-radius-bottomleft:3px;-moz-transform:translate(0,0)}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle{border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;-webkit-transform:translate3d(0,0,0) scaleY(1);-webkit-transform-origin-y:0;-moz-transform:translate(0,0) scaleY(1);-moz-transform-origin:0 0}.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-first,.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last{border-top-right-radius:0;border-bottom-left-radius:3px;-webkit-border-top-right-radius:0;-webkit-border-bottom-left-radius:3px;-moz-border-radius-topright:0;-moz-border-radius-bottomleft:3px}.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last{border-bottom-left-radius:0;border-top-right-radius:3px;-webkit-border-bottom-left-radius:0;-webkit-border-top-right-radius:3px;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:3px}.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-middle{-webkit-transform:translate3d(0,0,0) scaleX(1);-webkit-transform-origin:0 0;-moz-transform:translate(0,0) scaleX(1);-moz-transform-origin:0 0}.yui3-skin-sam .yui3-scrollview-scrollbar-vert-basic .yui3-scrollview-child,.yui3-skin-sam .yui3-scrollview-scrollbar-horiz-basic .yui3-scrollview-child{background-color:#aaa;background-image:none}yui-compressor-2.4.7/tests/dataurl-realdata-noquotes.css0000644000175000017500000000556011640627104023365 0ustar drazzibdrazzib.yui3-skin-sam .yui3-scrollview-scrollbar { -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate(0, 0); } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first, .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle, .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last { border-radius:3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAABCAYAAAD9yd/wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJJREFUeNpiZGBgSGPAAgACDAAIkABoFyloZQAAAABJRU5ErkJggg==); } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first, .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last { border-bottom-right-radius:0; border-bottom-left-radius:0; -webkit-border-bottom-right-radius:0; -webkit-border-bottom-left-radius:0; -moz-border-radius-bottomright:0; -moz-border-radius-bottomleft:0; } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last { border-radius:0; border-bottom-right-radius:3px; border-bottom-left-radius:3px; -webkit-border-radius:0; -webkit-border-bottom-right-radius:3px; -webkit-border-bottom-left-radius:3px; -webkit-transform: translate3d(0, 0, 0); -moz-border-radius:0; -moz-border-radius-bottomright:3px; -moz-border-radius-bottomleft:3px; -moz-transform: translate(0, 0); } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle { border-radius:0; -webkit-border-radius: 0; -moz-border-radius: 0; -webkit-transform: translate3d(0,0,0) scaleY(1); -webkit-transform-origin-y: 0; -moz-transform: translate(0,0) scaleY(1); -moz-transform-origin: 0 0; } .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-first, .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last { border-top-right-radius: 0; border-bottom-left-radius: 3px; -webkit-border-top-right-radius: 0; -webkit-border-bottom-left-radius: 3px; -moz-border-radius-topright: 0; -moz-border-radius-bottomleft: 3px; } .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last { border-bottom-left-radius: 0; border-top-right-radius: 3px; -webkit-border-bottom-left-radius: 0; -webkit-border-top-right-radius: 3px; -moz-border-radius-bottomleft: 0; -moz-border-radius-topright: 3px; } .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-middle { -webkit-transform: translate3d(0,0,0) scaleX(1); -webkit-transform-origin: 0 0; -moz-transform: translate(0,0) scaleX(1); -moz-transform-origin: 0 0; } .yui3-skin-sam .yui3-scrollview-scrollbar-vert-basic .yui3-scrollview-child, .yui3-skin-sam .yui3-scrollview-scrollbar-horiz-basic .yui3-scrollview-child { background-color: #aaa; background-image: none; }yui-compressor-2.4.7/tests/dataurl-realdata-doublequotes.css.min0000644000175000017500000000501111640627104024774 0ustar drazzibdrazzib.yui3-skin-sam .yui3-scrollview-scrollbar{-webkit-transform:translate3d(0,0,0);-moz-transform:translate(0,0)}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first,.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle,.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last{border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAABCAYAAAD9yd/wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJJREFUeNpiZGBgSGPAAgACDAAIkABoFyloZQAAAABJRU5ErkJggg==")}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first,.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last{border-bottom-right-radius:0;border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomright:0;-moz-border-radius-bottomleft:0}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last{border-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;-webkit-border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:3px;-webkit-transform:translate3d(0,0,0);-moz-border-radius:0;-moz-border-radius-bottomright:3px;-moz-border-radius-bottomleft:3px;-moz-transform:translate(0,0)}.yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle{border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;-webkit-transform:translate3d(0,0,0) scaleY(1);-webkit-transform-origin-y:0;-moz-transform:translate(0,0) scaleY(1);-moz-transform-origin:0 0}.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-first,.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last{border-top-right-radius:0;border-bottom-left-radius:3px;-webkit-border-top-right-radius:0;-webkit-border-bottom-left-radius:3px;-moz-border-radius-topright:0;-moz-border-radius-bottomleft:3px}.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last{border-bottom-left-radius:0;border-top-right-radius:3px;-webkit-border-bottom-left-radius:0;-webkit-border-top-right-radius:3px;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:3px}.yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-middle{-webkit-transform:translate3d(0,0,0) scaleX(1);-webkit-transform-origin:0 0;-moz-transform:translate(0,0) scaleX(1);-moz-transform-origin:0 0}.yui3-skin-sam .yui3-scrollview-scrollbar-vert-basic .yui3-scrollview-child,.yui3-skin-sam .yui3-scrollview-scrollbar-horiz-basic .yui3-scrollview-child{background-color:#aaa;background-image:none} yui-compressor-2.4.7/tests/dataurl-realdata-doublequotes.css0000644000175000017500000000556211640627104024225 0ustar drazzibdrazzib.yui3-skin-sam .yui3-scrollview-scrollbar { -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate(0, 0); } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first, .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle, .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last { border-radius:3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAABCAYAAAD9yd/wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJJREFUeNpiZGBgSGPAAgACDAAIkABoFyloZQAAAABJRU5ErkJggg=="); } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-first, .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last { border-bottom-right-radius:0; border-bottom-left-radius:0; -webkit-border-bottom-right-radius:0; -webkit-border-bottom-left-radius:0; -moz-border-radius-bottomright:0; -moz-border-radius-bottomleft:0; } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-last { border-radius:0; border-bottom-right-radius:3px; border-bottom-left-radius:3px; -webkit-border-radius:0; -webkit-border-bottom-right-radius:3px; -webkit-border-bottom-left-radius:3px; -webkit-transform: translate3d(0, 0, 0); -moz-border-radius:0; -moz-border-radius-bottomright:3px; -moz-border-radius-bottomleft:3px; -moz-transform: translate(0, 0); } .yui3-skin-sam .yui3-scrollview-scrollbar .yui3-scrollview-middle { border-radius:0; -webkit-border-radius: 0; -moz-border-radius: 0; -webkit-transform: translate3d(0,0,0) scaleY(1); -webkit-transform-origin-y: 0; -moz-transform: translate(0,0) scaleY(1); -moz-transform-origin: 0 0; } .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-first, .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last { border-top-right-radius: 0; border-bottom-left-radius: 3px; -webkit-border-top-right-radius: 0; -webkit-border-bottom-left-radius: 3px; -moz-border-radius-topright: 0; -moz-border-radius-bottomleft: 3px; } .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-last { border-bottom-left-radius: 0; border-top-right-radius: 3px; -webkit-border-bottom-left-radius: 0; -webkit-border-top-right-radius: 3px; -moz-border-radius-bottomleft: 0; -moz-border-radius-topright: 3px; } .yui3-skin-sam .yui3-scrollview-scrollbar-horiz .yui3-scrollview-middle { -webkit-transform: translate3d(0,0,0) scaleX(1); -webkit-transform-origin: 0 0; -moz-transform: translate(0,0) scaleX(1); -moz-transform-origin: 0 0; } .yui3-skin-sam .yui3-scrollview-scrollbar-vert-basic .yui3-scrollview-child, .yui3-skin-sam .yui3-scrollview-scrollbar-horiz-basic .yui3-scrollview-child { background-color: #aaa; background-image: none; }yui-compressor-2.4.7/tests/dataurl-noquote-multiline-font.css.min0000644000175000017500000000054211640627104025150 0ustar drazzibdrazzib.y-ff-1{font-family:"Foo Bar",Helvetica,Arial;text-rendering:optimizeLegibility}.ua-op .y-ff-1{font-family:Helvetica,Arial}@font-face{font-family:"Foo Bar";src:url(data:font/truetype;base64,gRbIUFAIrsQNGditEWbAUKwAA) format("truetype"),url("http://yuilibrary.com/fonts/foo-bar.svg#webfontse22fewwr") format("svg");font-weight:normal;font-style:normal} yui-compressor-2.4.7/tests/dataurl-noquote-multiline-font.css0000644000175000017500000000100211640627104024356 0ustar drazzibdrazzib/*csslint fontfamily: true*/ /** * Foo */ .y-ff-1 { font-family:"Foo Bar",Helvetica,Arial; text-rendering: optimizeLegibility; } .ua-op .y-ff-1 { /* Some Comment */ font-family:Helvetica,Arial; } /* Foo Bar */ @font-face { font-family: "Foo Bar"; src: url( data:font/truetype;base64,gRbIUFAIrsQNGditEWbAUKwAA) format("truetype"), url("http://yuilibrary.com/fonts/foo-bar.svg#webfontse22fewwr") format("svg"); font-weight: normal; font-style: normal; } yui-compressor-2.4.7/tests/dataurl-nonbase64-singlequotes.css.min0000644000175000017500000000224711640627104025035 0ustar drazzibdrazzibdiv.nonbase64-singlequotes{width:100px;height:100px;background-image:url('data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%0C%00%00%00%0E%08%03%00%00%00%2Cc%0D%DE%00%00%00%A2PLTEQQQ%FA%FA%FA%FC%FC%FC%EE%EE%EE%A9%A9%A9%E9%E9%E9%0A%0A%0A%0D%0D%0D444PPP%CD%CD%CD%CC%CC%CC%F5%F5%F5UUU%D0%D0%D0\'\'\'%F9%F9%F9%A6%A6%A6%40%40%40FFF%A0%A0%A0%89%89%89%8D%8D%8D%20%20%20%14%14%14%DA%DA%DA%B6%B6%B6%02%02%02%87%87%87%81%81%81%AC%AC%AC%0E%0E%0E111%7D%7D%7D%92%92%92333%B9%B9%B9%BC%BC%BChhh)))%E1%E1%E1%03%03%03%CB%CB%CB%EB%EB%EB%FD%FD%FD%A3%A3%A3(((%04%04%04%CA%CA%CAttt%2C%2C%2C%F4%F4%F4%00%00%00%FF%FF%FF%D6%DE%02%C3%00%00%006tRNS%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%00%A1%8FN1%00%00%00iIDAT%08%D7E%C7E%16%02Q%10%C5%D0j%C3%DD%BDqw%5E%F6%BF5%06%D4%3Fd%94kx%BDf%DE6%FFIA%AB%C8qYj%1F%E3Xk%93%E0%C8JZ%10%90%9E%3A1%60%BBY%85%A8%AE%14%C0%5E%1A6%8E%C5w%02%60%99%C9%FA%9A%03%60%8C%EFz%8C%CE%0EnSu%3F%01%AD%B2%06%04%F0%3CT%FF%B8nk%3F%7C%01%C5z%1B%F9%26%2F%3Az%00%00%00%00IEND%AEB%60%82');border:1px solid #00a}span.othercss{font-family:"Times New Roman";font-weight:inherit} yui-compressor-2.4.7/tests/dataurl-nonbase64-singlequotes.css0000644000175000017500000000237511640627104024255 0ustar drazzibdrazzib/* Some Comment */ div.nonbase64-singlequotes { width:100px; height:100px; background-image:url('data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%0C%00%00%00%0E%08%03%00%00%00%2Cc%0D%DE%00%00%00%A2PLTEQQQ%FA%FA%FA%FC%FC%FC%EE%EE%EE%A9%A9%A9%E9%E9%E9%0A%0A%0A%0D%0D%0D444PPP%CD%CD%CD%CC%CC%CC%F5%F5%F5UUU%D0%D0%D0\'\'\'%F9%F9%F9%A6%A6%A6%40%40%40FFF%A0%A0%A0%89%89%89%8D%8D%8D%20%20%20%14%14%14%DA%DA%DA%B6%B6%B6%02%02%02%87%87%87%81%81%81%AC%AC%AC%0E%0E%0E111%7D%7D%7D%92%92%92333%B9%B9%B9%BC%BC%BChhh)))%E1%E1%E1%03%03%03%CB%CB%CB%EB%EB%EB%FD%FD%FD%A3%A3%A3(((%04%04%04%CA%CA%CAttt%2C%2C%2C%F4%F4%F4%00%00%00%FF%FF%FF%D6%DE%02%C3%00%00%006tRNS%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%00%A1%8FN1%00%00%00iIDAT%08%D7E%C7E%16%02Q%10%C5%D0j%C3%DD%BDqw%5E%F6%BF5%06%D4%3Fd%94kx%BDf%DE6%FFIA%AB%C8qYj%1F%E3Xk%93%E0%C8JZ%10%90%9E%3A1%60%BBY%85%A8%AE%14%C0%5E%1A6%8E%C5w%02%60%99%C9%FA%9A%03%60%8C%EFz%8C%CE%0EnSu%3F%01%AD%B2%06%04%F0%3CT%FF%B8nk%3F%7C%01%C5z%1B%F9%26%2F%3Az%00%00%00%00IEND%AEB%60%82'); border:1px solid #0000aa; } /* Some Other Comment */ span.othercss { font-family:"Times New Roman"; font-weight:inherit; } yui-compressor-2.4.7/tests/dataurl-nonbase64-noquotes.css.min0000644000175000017500000000224511640627104024166 0ustar drazzibdrazzibdiv.nonbase64-noquotes{width:100px;height:100px;background-image:url(data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%0C%00%00%00%0E%08%03%00%00%00%2Cc%0D%DE%00%00%00%A2PLTEQQQ%FA%FA%FA%FC%FC%FC%EE%EE%EE%A9%A9%A9%E9%E9%E9%0A%0A%0A%0D%0D%0D444PPP%CD%CD%CD%CC%CC%CC%F5%F5%F5UUU%D0%D0%D0\'\'\'%F9%F9%F9%A6%A6%A6%40%40%40FFF%A0%A0%A0%89%89%89%8D%8D%8D%20%20%20%14%14%14%DA%DA%DA%B6%B6%B6%02%02%02%87%87%87%81%81%81%AC%AC%AC%0E%0E%0E111%7D%7D%7D%92%92%92333%B9%B9%B9%BC%BC%BChhh\)\)\)%E1%E1%E1%03%03%03%CB%CB%CB%EB%EB%EB%FD%FD%FD%A3%A3%A3\(\(\(%04%04%04%CA%CA%CAttt%2C%2C%2C%F4%F4%F4%00%00%00%FF%FF%FF%D6%DE%02%C3%00%00%006tRNS%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%00%A1%8FN1%00%00%00iIDAT%08%D7E%C7E%16%02Q%10%C5%D0j%C3%DD%BDqw%5E%F6%BF5%06%D4%3Fd%94kx%BDf%DE6%FFIA%AB%C8qYj%1F%E3Xk%93%E0%C8JZ%10%90%9E%3A1%60%BBY%85%A8%AE%14%C0%5E%1A6%8E%C5w%02%60%99%C9%FA%9A%03%60%8C%EFz%8C%CE%0EnSu%3F%01%AD%B2%06%04%F0%3CT%FF%B8nk%3F%7C%01%C5z%1B%F9%26%2F%3Az%00%00%00%00IEND%AEB%60%82);border:1px solid red}span.othercss{font-family:"Times New Roman";font-weight:inherit} yui-compressor-2.4.7/tests/dataurl-nonbase64-noquotes.css0000644000175000017500000000231511640627104023402 0ustar drazzibdrazzibdiv.nonbase64-noquotes { width:100px; height:100px; background-image:url( data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%0C%00%00%00%0E%08%03%00%00%00%2Cc%0D%DE%00%00%00%A2PLTEQQQ%FA%FA%FA%FC%FC%FC%EE%EE%EE%A9%A9%A9%E9%E9%E9%0A%0A%0A%0D%0D%0D444PPP%CD%CD%CD%CC%CC%CC%F5%F5%F5UUU%D0%D0%D0\'\'\'%F9%F9%F9%A6%A6%A6%40%40%40FFF%A0%A0%A0%89%89%89%8D%8D%8D%20%20%20%14%14%14%DA%DA%DA%B6%B6%B6%02%02%02%87%87%87%81%81%81%AC%AC%AC%0E%0E%0E111%7D%7D%7D%92%92%92333%B9%B9%B9%BC%BC%BChhh\)\)\)%E1%E1%E1%03%03%03%CB%CB%CB%EB%EB%EB%FD%FD%FD%A3%A3%A3\(\(\(%04%04%04%CA%CA%CAttt%2C%2C%2C%F4%F4%F4%00%00%00%FF%FF%FF%D6%DE%02%C3%00%00%006tRNS%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%00%A1%8FN1%00%00%00iIDAT%08%D7E%C7E%16%02Q%10%C5%D0j%C3%DD%BDqw%5E%F6%BF5%06%D4%3Fd%94kx%BDf%DE6%FFIA%AB%C8qYj%1F%E3Xk%93%E0%C8JZ%10%90%9E%3A1%60%BBY%85%A8%AE%14%C0%5E%1A6%8E%C5w%02%60%99%C9%FA%9A%03%60%8C%EFz%8C%CE%0EnSu%3F%01%AD%B2%06%04%F0%3CT%FF%B8nk%3F%7C%01%C5z%1B%F9%26%2F%3Az%00%00%00%00IEND%AEB%60%82 ); border:1px solid red; } span.othercss { font-family:"Times New Roman"; font-weight:inherit; } yui-compressor-2.4.7/tests/dataurl-nonbase64-doublequotes.css.min0000644000175000017500000000224311640627104025022 0ustar drazzibdrazzibdiv.nonbase64-doublequotes{width:100px;height:100px;background-image:url("data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%0C%00%00%00%0E%08%03%00%00%00%2Cc%0D%DE%00%00%00%A2PLTEQQQ%FA%FA%FA%FC%FC%FC%EE%EE%EE%A9%A9%A9%E9%E9%E9%0A%0A%0A%0D%0D%0D444PPP%CD%CD%CD%CC%CC%CC%F5%F5%F5UUU%D0%D0%D0'''%F9%F9%F9%A6%A6%A6%40%40%40FFF%A0%A0%A0%89%89%89%8D%8D%8D%20%20%20%14%14%14%DA%DA%DA%B6%B6%B6%02%02%02%87%87%87%81%81%81%AC%AC%AC%0E%0E%0E111%7D%7D%7D%92%92%92333%B9%B9%B9%BC%BC%BChhh)))%E1%E1%E1%03%03%03%CB%CB%CB%EB%EB%EB%FD%FD%FD%A3%A3%A3(((%04%04%04%CA%CA%CAttt%2C%2C%2C%F4%F4%F4%00%00%00%FF%FF%FF%D6%DE%02%C3%00%00%006tRNS%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%00%A1%8FN1%00%00%00iIDAT%08%D7E%C7E%16%02Q%10%C5%D0j%C3%DD%BDqw%5E%F6%BF5%06%D4%3Fd%94kx%BDf%DE6%FFIA%AB%C8qYj%1F%E3Xk%93%E0%C8JZ%10%90%9E%3A1%60%BBY%85%A8%AE%14%C0%5E%1A6%8E%C5w%02%60%99%C9%FA%9A%03%60%8C%EFz%8C%CE%0EnSu%3F%01%AD%B2%06%04%F0%3CT%FF%B8nk%3F%7C%01%C5z%1B%F9%26%2F%3Az%00%00%00%00IEND%AEB%60%82");border:1px solid #0a0}span.othercss{font-family:"Times New Roman";font-weight:inherit} yui-compressor-2.4.7/tests/dataurl-nonbase64-doublequotes.css0000644000175000017500000000233211640627104024237 0ustar drazzibdrazzibdiv.nonbase64-doublequotes { width:100px; height:100px; background-image:url( "data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%0C%00%00%00%0E%08%03%00%00%00%2Cc%0D%DE%00%00%00%A2PLTEQQQ%FA%FA%FA%FC%FC%FC%EE%EE%EE%A9%A9%A9%E9%E9%E9%0A%0A%0A%0D%0D%0D444PPP%CD%CD%CD%CC%CC%CC%F5%F5%F5UUU%D0%D0%D0'''%F9%F9%F9%A6%A6%A6%40%40%40FFF%A0%A0%A0%89%89%89%8D%8D%8D%20%20%20%14%14%14%DA%DA%DA%B6%B6%B6%02%02%02%87%87%87%81%81%81%AC%AC%AC%0E%0E%0E111%7D%7D%7D%92%92%92333%B9%B9%B9%BC%BC%BChhh)))%E1%E1%E1%03%03%03%CB%CB%CB%EB%EB%EB%FD%FD%FD%A3%A3%A3(((%04%04%04%CA%CA%CAttt%2C%2C%2C%F4%F4%F4%00%00%00%FF%FF%FF%D6%DE%02%C3%00%00%006tRNS%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%00%A1%8FN1%00%00%00iIDAT%08%D7E%C7E%16%02Q%10%C5%D0j%C3%DD%BDqw%5E%F6%BF5%06%D4%3Fd%94kx%BDf%DE6%FFIA%AB%C8qYj%1F%E3Xk%93%E0%C8JZ%10%90%9E%3A1%60%BBY%85%A8%AE%14%C0%5E%1A6%8E%C5w%02%60%99%C9%FA%9A%03%60%8C%EFz%8C%CE%0EnSu%3F%01%AD%B2%06%04%F0%3CT%FF%B8nk%3F%7C%01%C5z%1B%F9%26%2F%3Az%00%00%00%00IEND%AEB%60%82" ); border:1px solid #00aa00; } span.othercss { font-family:"Times New Roman"; font-weight:inherit; } yui-compressor-2.4.7/tests/dataurl-dbquote-font.css.min0000644000175000017500000000054611640627104023125 0ustar drazzibdrazzib.y-ff-1{font-family:"Foo Bar",Helvetica,Arial;text-rendering:optimizeLegibility}.ua-op .y-ff-1{font-family:Helvetica,Arial}@font-face{font-family:"Foo Bar";src:url("data:font/truetype;base64,gRbIUFAIrsQNGditEWbAUKwAA") format("truetype"),url("http://yuilibrary.com/fonts/foo-bar.svg#webfontse22fewwr") format("svg");font-weight:normal;font-style:normal} yui-compressor-2.4.7/tests/dataurl-dbquote-font.css0000644000175000017500000000075311640627104022343 0ustar drazzibdrazzib/*csslint fontfamily: true*/ /** * Foo */ .y-ff-1 { font-family:"Foo Bar",Helvetica,Arial; text-rendering: optimizeLegibility; } .ua-op .y-ff-1 { /* Some Comment */ font-family:Helvetica,Arial; } /* Foo Bar */ @font-face { font-family: "Foo Bar"; src: url("data:font/truetype;base64,gRbIUFAIrsQNGditEWbAUKwAA") format("truetype"), url("http://yuilibrary.com/fonts/foo-bar.svg#webfontse22fewwr") format("svg"); font-weight: normal; font-style: normal; } yui-compressor-2.4.7/tests/dataurl-base64-twourls.css.min0000644000175000017500000001020311640627104023306 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml,.yui3-skin-night .yui3-dial-center-button-vml,.yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min,.yui3-skin-night v\:oval.yui3-dial-marker-max-min,.yui3-skin-night .yui3-dial-marker-vml,.yui3-skin-night .yui3-dial-handle-vml{background:0;opacity:1}div.base64-singlequotes{width:100px;height:100px;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QAAAAAAAD5Q7t%2FAAAACXBIWXMAAA3WAAAN1gGQb3mcAAAFrUlEQVRYw%2B2Xz28kRxXHP%2B9Vdc8vj2fG9uIkm2yUeFGEhNCKQwBpj1yRUBAnpJU4ceZP4MxfkBxy2GO45bQXuEGQohUKigQ%2BsBBE1sbYXv8Yz%2FRMd9fjUN09PV5nFZA4kZZa79W3quu9er%2FqNfy%2FPwJgZty%2Ffz%2FZ29vrpmmqhlWTgmFg1UpbfWhYhG6Yq2cFi%2FNrj9nJyWnx%2BPHjeafbMTEzPvjVB9%2B6d%2B%2FezweDwV1BfHubivkC3lZya%2F4m7Np8UZYXhweHH7733rvvC0Kyv7%2F%2F7p07d34qIjyvr63RNb4l4CbsRUrNrq6OfvfRRz%2FxDx486A%2F6g7vXhX9ZIf%2Bp4JomaToZj8d7Pk1SFRFXb1aWodq09l%2F9YZu%2FCWMVL9e%2FaVFVQVUREEG8r3VUEZ4cX%2FHL30%2B5shRtAhFq4wggNb6GrXgVa2K2jYtACIHv7Sz54TfHjWWagBOBy0Xgt%2BcjLtwQxVCpNwURQat1DdYaT7pwdwKDFA6ncHgFizJmSb3WLPDa7PMIVlb2daqZxdONUnAetEojEdBGiXXhTmAjhZ0%2B3N6AlzeEROH1TXiWGf%2BcwmkWZYnAfAkdx1pq%2BhUbT9z3IElUJlVhI4WsgCLUyggi4MQYd4VXNmCYRqXOspV7UoHbQ3hpEMeLAk5mkFYRYlWI%2BHZ6CTDwkKSQqrA7gFeHMF3C6VyYLmFZGiKCE6GrMFsaWb7yuVOh66N1FkUUpBJ3TyvFovToBl9XMbNY2bZ70BsKfW94hbyErosmXpQwy4VgkCjMizjvRRik0EtiLNwagBf465lwOqtkETEn60XT1%2BlTazrpKlR%2BKkooy3Xfb3Wj3wGWJRQhnni7B53q5FqZ4%2FUR7PYhGMxyuMwgWVqTxrYWAwZYQX78J5i8ie9txSAkoOqqQAqk3pBgKLDhlY5XVKPCi3w97YRoKSFaceCgF2hqSXRBPQAIOcXRH8hP%2F0y6%2BRpWLrEyg3SbS9tmzggzJQSLQZo4xoOE8UbCsJfQ7zi6iaIizZ5OBVfXDKPireWC%2BvAYWOBqeszl9Jg03afbH6OqGH%2FBSUrqbrFIXiHoiEDC%2FPySi2d9nnZHJE7opY7dcY%2FdcZej84zpPGfY9Uw2ErYGCf2O4mUVEzELWtqUxZKjf3zK2cURzicMRy%2BzvbuH8ylFPqXIPqNczClKY1mUZFcnSDKkv%2FUNuptbWG%2BLw%2FMh%2FzrYpKBHKV3ONOXzYxeV20z49qhs7gaMWIjqQQiBxVXB4irg05yz4u%2FMpieoJuTLjDJfUJYBzBAFUUHkhMvLvzFPuvQ2JvQ3duh0R%2FjuiDQdIn6MJdvkxTafZUPuaN6UaOo6UNtgNl9weboguwqoA5fCjEusNCzE8LJQFRuNrzpQD%2BrmZNM55%2F4A5z1J2iHtDEg6fZK0j0uHlDrh2N4i3Ptuc%2BH5tjp5HliWQmmOUAhlYe0rqUqWSEOhcZ05AvE1UdColSQJaHWlSUYgJy%2FO2fFfo%2F34piphFOZ4OrvNdL5EJZbcmE8OQzFxIJEGEgIeE1%2FhrjJLxZcOrIVpVC7TW00WmLWyAMDEs%2Bi9wVJDtG17Y21vVmNxLKqIOkQqqoq2qHORmgj9UQcza7mgFm4GmiDjO5C72DSoQ6uPVTW%2BzuFUcQ2teKd4pzhd8b6Nu6jg7vZsrb1rClEIxhu7Q37x47fIy3j%2Fi8iqqlUuEWTFN%2FOrMU3fEEuhUM8FIPDqZgcRIVhsAXxtjGDGS5M%2BP%2Fv%2Bm7yopVrRVsPabsW%2BYG1T%2Fy3KahqSg6cHRb5cTmt5ZXhxQ7nS6yZsVWOajDFbw2JSCSGEIsuyC%2F%2Fo0aPp%2Fv7%2Br9NO5%2F5gMOhJLNn%2FpQLrLfw6tkKKorCDg4NPP%2Fnkjx%2FLOz96h2enzyZvf%2BftH9za2fm6qLrnO9tGk2vY86f%2FMliWZRdPnjz5zcOHDz%2B%2B%2Fifimorzv31C9X718G%2FYrCYSNJa5LgAAACJ6VFh0U29mdHdhcmUAAHjaKy8v18vMyy5OTixI1csvSgcANtgGWBBTylwAAAAASUVORK5CYII%3D');background-position:center center;border:1px solid #0a0}div.otherdataurl{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFBQ0WDWwqwjwAAANMSURBVEjHrdZbaFxVFAbgb2aSTG6GTi6mVIwxNxF9qFI0RQnFUqiYamutVutLa2t9EY0oPggFoYgPRR%2FaghYviA%2BiIAYvmBJKoYWiiBCigVTT1FisbUhrEtNkJpc5PuQkjGEmJqkLFmdz2Hv%2Fa%2F3rX3tvlm95oS%2FLokuZtIpbdvAs7KFtL22wjb3V1C41upy2ke1DXC2k%2FBjv1HHXDrbkEamg7lX2P8QTldQ2UtfOB8uiJsHNiB%2Fik0GmO%2BgZIxgnGA59nGCMoJPeQaYP047iBDXZEohkAYof4%2FNyKlZRdR%2F1ASZCnoOMhWkUheMz9F1laJSRZ3gEqVw1ipZQjcoBRrbT3Ez9OJLhZkHG5CD8l8Q47qXhMZp%2FYxhVFaxBLBtQejdtA%2FTtZPMIJnOknI2WSYzicTYN8OtTvICZbECxdr5Pkm6iPL0C3c%2BgkfIJgi%2F4LnP%2FudRKD3K4jf1VJGLEAiuz6VnA4AGam1h7gpNIzSFe66D3NurLKVhJNkHo07N9V9BE3XHOYmyeuirqG1l9mdHgOkDSGd8%2FGWtg9Roa56lrYdchDtRQPLlCkEywKVRScDfrurnwC2diiPTRe47iVtbnLZDxckGCkKYpPM%2FRr3kbyRhsYOtRDiQonFoBSHrBOI18rOeOPvr76YrCeUbf5fTvjOddJ0gQ1uMPku9z6hwjiEZhgOMn%2BaaUeHQJIOkMD7KMA5QQP01HP18hPbfvDTvZPETqb2YiS1BWrozM6jk9SPJJHkZZ5qFagtoaNnbyZg1FE4sUPRdlAQpwkdSjvDZAJ%2FoxNt%2Bw6NlGbQVFl5iKLKKsXCAwyFQZ8S3ciu65ho1lBJ5%2FkZk3OBGjpJWGmVCmsjTkQvA8JHCUU7s5eImevzg%2Fd7BGFhzCARIf8uVN3J5Heh1VM%2BHlko2y%2FHBxF0NJolfo38eDuJJxbf0ro%2FnMurh8hM%2FupH4tdT8zciOFsTC8SAgQoJfRxKzCuvfw0k%2F8MDx7xqUyez%2BS48ESIN7Ky6OUpfAtrxzhx03UR4m0c%2FZF7tnKW2mma4l9yuthTSIZIvxPi6EcpZW0PM0xtOzjo%2Bf4GPfv4r1qNqAUFYs9diJLBC1CIa7FZx8fUlwI22LuNv%2FfLbKMAOftH9TwRXg6%2FiCDAAAAAElFTkSuQmCC")}.yui-skin-sam .yui-h-slider{background:url(bg-h.gif) no-repeat 5px 0;height:28px;width:228px}yui-compressor-2.4.7/tests/dataurl-base64-twourls.css0000644000175000017500000001033311640627104022530 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml, .yui3-skin-night .yui3-dial-center-button-vml, .yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min, .yui3-skin-night v\:oval.yui3-dial-marker-max-min, .yui3-skin-night .yui3-dial-marker-vml, .yui3-skin-night .yui3-dial-handle-vml { background: none; opacity:1; } div.base64-singlequotes { width:100px; height:100px; background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QAAAAAAAD5Q7t%2FAAAACXBIWXMAAA3WAAAN1gGQb3mcAAAFrUlEQVRYw%2B2Xz28kRxXHP%2B9Vdc8vj2fG9uIkm2yUeFGEhNCKQwBpj1yRUBAnpJU4ceZP4MxfkBxy2GO45bQXuEGQohUKigQ%2BsBBE1sbYXv8Yz%2FRMd9fjUN09PV5nFZA4kZZa79W3quu9er%2FqNfy%2FPwJgZty%2Ffz%2FZ29vrpmmqhlWTgmFg1UpbfWhYhG6Yq2cFi%2FNrj9nJyWnx%2BPHjeafbMTEzPvjVB9%2B6d%2B%2FezweDwV1BfHubivkC3lZya%2F4m7Np8UZYXhweHH7733rvvC0Kyv7%2F%2F7p07d34qIjyvr63RNb4l4CbsRUrNrq6OfvfRRz%2FxDx486A%2F6g7vXhX9ZIf%2Bp4JomaToZj8d7Pk1SFRFXb1aWodq09l%2F9YZu%2FCWMVL9e%2FaVFVQVUREEG8r3VUEZ4cX%2FHL30%2B5shRtAhFq4wggNb6GrXgVa2K2jYtACIHv7Sz54TfHjWWagBOBy0Xgt%2BcjLtwQxVCpNwURQat1DdYaT7pwdwKDFA6ncHgFizJmSb3WLPDa7PMIVlb2daqZxdONUnAetEojEdBGiXXhTmAjhZ0%2B3N6AlzeEROH1TXiWGf%2BcwmkWZYnAfAkdx1pq%2BhUbT9z3IElUJlVhI4WsgCLUyggi4MQYd4VXNmCYRqXOspV7UoHbQ3hpEMeLAk5mkFYRYlWI%2BHZ6CTDwkKSQqrA7gFeHMF3C6VyYLmFZGiKCE6GrMFsaWb7yuVOh66N1FkUUpBJ3TyvFovToBl9XMbNY2bZ70BsKfW94hbyErosmXpQwy4VgkCjMizjvRRik0EtiLNwagBf465lwOqtkETEn60XT1%2BlTazrpKlR%2BKkooy3Xfb3Wj3wGWJRQhnni7B53q5FqZ4%2FUR7PYhGMxyuMwgWVqTxrYWAwZYQX78J5i8ie9txSAkoOqqQAqk3pBgKLDhlY5XVKPCi3w97YRoKSFaceCgF2hqSXRBPQAIOcXRH8hP%2F0y6%2BRpWLrEyg3SbS9tmzggzJQSLQZo4xoOE8UbCsJfQ7zi6iaIizZ5OBVfXDKPireWC%2BvAYWOBqeszl9Jg03afbH6OqGH%2FBSUrqbrFIXiHoiEDC%2FPySi2d9nnZHJE7opY7dcY%2FdcZej84zpPGfY9Uw2ErYGCf2O4mUVEzELWtqUxZKjf3zK2cURzicMRy%2BzvbuH8ylFPqXIPqNczClKY1mUZFcnSDKkv%2FUNuptbWG%2BLw%2FMh%2FzrYpKBHKV3ONOXzYxeV20z49qhs7gaMWIjqQQiBxVXB4irg05yz4u%2FMpieoJuTLjDJfUJYBzBAFUUHkhMvLvzFPuvQ2JvQ3duh0R%2FjuiDQdIn6MJdvkxTafZUPuaN6UaOo6UNtgNl9weboguwqoA5fCjEusNCzE8LJQFRuNrzpQD%2BrmZNM55%2F4A5z1J2iHtDEg6fZK0j0uHlDrh2N4i3Ptuc%2BH5tjp5HliWQmmOUAhlYe0rqUqWSEOhcZ05AvE1UdColSQJaHWlSUYgJy%2FO2fFfo%2F34piphFOZ4OrvNdL5EJZbcmE8OQzFxIJEGEgIeE1%2FhrjJLxZcOrIVpVC7TW00WmLWyAMDEs%2Bi9wVJDtG17Y21vVmNxLKqIOkQqqoq2qHORmgj9UQcza7mgFm4GmiDjO5C72DSoQ6uPVTW%2BzuFUcQ2teKd4pzhd8b6Nu6jg7vZsrb1rClEIxhu7Q37x47fIy3j%2Fi8iqqlUuEWTFN%2FOrMU3fEEuhUM8FIPDqZgcRIVhsAXxtjGDGS5M%2BP%2Fv%2Bm7yopVrRVsPabsW%2BYG1T%2Fy3KahqSg6cHRb5cTmt5ZXhxQ7nS6yZsVWOajDFbw2JSCSGEIsuyC%2F%2Fo0aPp%2Fv7%2Br9NO5%2F5gMOhJLNn%2FpQLrLfw6tkKKorCDg4NPP%2Fnkjx%2FLOz96h2enzyZvf%2BftH9za2fm6qLrnO9tGk2vY86f%2FMliWZRdPnjz5zcOHDz%2B%2B%2Fifimorzv31C9X718G%2FYrCYSNJa5LgAAACJ6VFh0U29mdHdhcmUAAHjaKy8v18vMyy5OTixI1csvSgcANtgGWBBTylwAAAAASUVORK5CYII%3D'); background-position:center center; border:1px solid #00aa00; } div.otherdataurl { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFBQ0WDWwqwjwAAANMSURBVEjHrdZbaFxVFAbgb2aSTG6GTi6mVIwxNxF9qFI0RQnFUqiYamutVutLa2t9EY0oPggFoYgPRR%2FaghYviA%2BiIAYvmBJKoYWiiBCigVTT1FisbUhrEtNkJpc5PuQkjGEmJqkLFmdz2Hv%2Fa%2F3rX3tvlm95oS%2FLokuZtIpbdvAs7KFtL22wjb3V1C41upy2ke1DXC2k%2FBjv1HHXDrbkEamg7lX2P8QTldQ2UtfOB8uiJsHNiB%2Fik0GmO%2BgZIxgnGA59nGCMoJPeQaYP047iBDXZEohkAYof4%2FNyKlZRdR%2F1ASZCnoOMhWkUheMz9F1laJSRZ3gEqVw1ipZQjcoBRrbT3Ez9OJLhZkHG5CD8l8Q47qXhMZp%2FYxhVFaxBLBtQejdtA%2FTtZPMIJnOknI2WSYzicTYN8OtTvICZbECxdr5Pkm6iPL0C3c%2BgkfIJgi%2F4LnP%2FudRKD3K4jf1VJGLEAiuz6VnA4AGam1h7gpNIzSFe66D3NurLKVhJNkHo07N9V9BE3XHOYmyeuirqG1l9mdHgOkDSGd8%2FGWtg9Roa56lrYdchDtRQPLlCkEywKVRScDfrurnwC2diiPTRe47iVtbnLZDxckGCkKYpPM%2FRr3kbyRhsYOtRDiQonFoBSHrBOI18rOeOPvr76YrCeUbf5fTvjOddJ0gQ1uMPku9z6hwjiEZhgOMn%2BaaUeHQJIOkMD7KMA5QQP01HP18hPbfvDTvZPETqb2YiS1BWrozM6jk9SPJJHkZZ5qFagtoaNnbyZg1FE4sUPRdlAQpwkdSjvDZAJ%2FoxNt%2Bw6NlGbQVFl5iKLKKsXCAwyFQZ8S3ciu65ho1lBJ5%2FkZk3OBGjpJWGmVCmsjTkQvA8JHCUU7s5eImevzg%2Fd7BGFhzCARIf8uVN3J5Heh1VM%2BHlko2y%2FHBxF0NJolfo38eDuJJxbf0ro%2FnMurh8hM%2FupH4tdT8zciOFsTC8SAgQoJfRxKzCuvfw0k%2F8MDx7xqUyez%2BS48ESIN7Ky6OUpfAtrxzhx03UR4m0c%2FZF7tnKW2mma4l9yuthTSIZIvxPi6EcpZW0PM0xtOzjo%2Bf4GPfv4r1qNqAUFYs9diJLBC1CIa7FZx8fUlwI22LuNv%2FfLbKMAOftH9TwRXg6%2FiCDAAAAAElFTkSuQmCC"); } .yui-skin-sam .yui-h-slider { background: url(bg-h.gif) no-repeat 5px 0; height: 28px; width: 228px; }yui-compressor-2.4.7/tests/dataurl-base64-singlequotes.css.min0000644000175000017500000024524211640627104024326 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml,.yui3-skin-night .yui3-dial-center-button-vml,.yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min,.yui3-skin-night v\:oval.yui3-dial-marker-max-min,.yui3-skin-night .yui3-dial-marker-vml,.yui3-skin-night .yui3-dial-handle-vml{background:0;opacity:1}div.base64-singlequotes{width:100px;height:100px;background-image:url('data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAgEAZABkAAD%2F4RfJRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAeAAAAcgEyAAIAAAAUAAAAkIdpAAQAAAABAAAApAAAANAAD0JAAAAnEAAPQkAAACcQQWRvYmUgUGhvdG9zaG9wIENTMiBNYWNpbnRvc2gAMjAwODowNzoxOSAxNDo1ODowNQAAA6ABAAMAAAAB%2F%2F8AAKACAAQAAAABAAABwqADAAQAAAABAAABRQAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAEeARsABQAAAAEAAAEmASgAAwAAAAEAAgAAAgEABAAAAAEAAAEuAgIABAAAAAEAABaTAAAAAAAAAEgAAAABAAAASAAAAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZ%2F%2B01IlBob3Rvc2hvcCAzLjAAOEJJTQQlAAAAAAAQAAAAAAAAAAAAAAAAAAAAADhCSU0D6gAAAAAYEDw%2FeG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8%2BCjwhRE9DVFlQRSBwbGlzdCBQVUJMSUMgIi0vL0FwcGxlLy9EVEQgUExJU1QgMS4wLy9FTiIgImh0dHA6Ly93d3cuYXBwbGUuY29tL0RURHMvUHJvcGVydHlMaXN0LTEuMC5kdGQiPgo8cGxpc3QgdmVyc2lvbj0iMS4wIj4KPGRpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNSG9yaXpvbnRhbFJlczwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1Ib3Jpem9udGFsUmVzPC9rZXk%2BCgkJCQk8cmVhbD43MjwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgkJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNU2NhbGluZzwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1TY2FsaW5nPC9rZXk%2BCgkJCQk8cmVhbD4xPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCTxkaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q%2BCgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCQkJCTxyZWFsPjcyPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsU2NhbGluZzwva2V5PgoJCQkJPHJlYWw%2BMTwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuc3ViVGlja2V0LnBhcGVyX2luZm9fdGlja2V0PC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BUE1UaW9nYVBhcGVyTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNVGlvZ2FQYXBlck5hbWU8L2tleT4KCQkJCQk8c3RyaW5nPm5hLWxldHRlcjwvc3RyaW5nPgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk%2BCgkJCQkJCTxyZWFsPi0xODwvcmVhbD4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD43NzQ8L3JlYWw%2BCgkJCQkJCTxyZWFsPjU5NDwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNUGFwZXJOYW1lPC9rZXk%2BCgkJCQkJPHN0cmluZz5uYS1sZXR0ZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk%2BCgkJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhZ2VSZWN0PC9rZXk%2BCgkJPGRpY3Q%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD4tMTg8L3JlYWw%2BCgkJCQkJCTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTk0PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLnBwZC5QTVBhcGVyTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BVVMgTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5BUElWZXJzaW9uPC9rZXk%2BCgkJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC50eXBlPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvVGlja2V0PC9zdHJpbmc%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuQVBJVmVyc2lvbjwva2V5PgoJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnR5cGU8L2tleT4KCTxzdHJpbmc%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXRUaWNrZXQ8L3N0cmluZz4KPC9kaWN0Pgo8L3BsaXN0Pgo4QklNA%2BkAAAAAAHgAAwAAAEgASAAAAAAC3gJA%2F%2B7%2F7gMGAlIDZwUoA%2FwAAgAAAEgASAAAAAAC2AIoAAEAAABkAAAAAQADAwMAAAABf%2F8AAQABAAAAAAAAAAAAAAAAaAgAGQGQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4QklNA%2B0AAAAAABAAZAAAAAEAAQBkAAAAAQABOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD%2BAAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNBAoAAAAAAAEAADhCSU0nEAAAAAAACgABAAAAAAAAAAE4QklNA%2FUAAAAAAEgAL2ZmAAEAbGZmAAYAAAAAAAEAL2ZmAAEAoZmaAAYAAAAAAAEAMgAAAAEAWgAAAAYAAAAAAAEANQAAAAEALQAAAAYAAAAAAAE4QklNA%2FgAAAAAAHAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAAAD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FA%2BgAAAAA%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwPoAAAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAOEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJAAAAAADhCSU0EHgAAAAAABAAAAAA4QklNBBoAAAAAA1UAAAAGAAAAAAAAAAAAAAFFAAABwgAAABAAcwB3AGkAcwBzAF8AYQByAG0AeQBfAGsAbgBpAGYAZQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABwgAAAUUAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAG51bGwAAAACAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9uZwAAAUUAAAAAUmdodGxvbmcAAAHCAAAABnNsaWNlc1ZsTHMAAAABT2JqYwAAAAEAAAAAAAVzbGljZQAAABIAAAAHc2xpY2VJRGxvbmcAAAAAAAAAB2dyb3VwSURsb25nAAAAAAAAAAZvcmlnaW5lbnVtAAAADEVTbGljZU9yaWdpbgAAAA1hdXRvR2VuZXJhdGVkAAAAAFR5cGVlbnVtAAAACkVTbGljZVR5cGUAAAAASW1nIAAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAFFAAAAAFJnaHRsb25nAAABwgAAAAN1cmxURVhUAAAAAQAAAAAAAG51bGxURVhUAAAAAQAAAAAAAE1zZ2VURVhUAAAAAQAAAAAABmFsdFRhZ1RFWFQAAAABAAAAAAAOY2VsbFRleHRJc0hUTUxib29sAQAAAAhjZWxsVGV4dFRFWFQAAAABAAAAAAAJaG9yekFsaWduZW51bQAAAA9FU2xpY2VIb3J6QWxpZ24AAAAHZGVmYXVsdAAAAAl2ZXJ0QWxpZ25lbnVtAAAAD0VTbGljZVZlcnRBbGlnbgAAAAdkZWZhdWx0AAAAC2JnQ29sb3JUeXBlZW51bQAAABFFU2xpY2VCR0NvbG9yVHlwZQAAAABOb25lAAAACXRvcE91dHNldGxvbmcAAAAAAAAACmxlZnRPdXRzZXRsb25nAAAAAAAAAAxib3R0b21PdXRzZXRsb25nAAAAAAAAAAtyaWdodE91dHNldGxvbmcAAAAAADhCSU0EKAAAAAAADAAAAAE%2F8AAAAAAAADhCSU0EEQAAAAAAAQEAOEJJTQQUAAAAAAAEAAAAAThCSU0EDAAAAAAWrwAAAAEAAACgAAAAdAAAAeAAANmAAAAWkwAYAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZADhCSU0EIQAAAAAAVQAAAAEBAAAADwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAAAABMAQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAIABDAFMAMgAAAAEAOEJJTQQGAAAAAAAHAAIAAAABAQD%2F4TkjaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu%2B7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI%2FPgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSIzLjEuMS0xMTIiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyI%2BCiAgICAgICAgIDx4YXBNTTpEb2N1bWVudElEPnV1aWQ6RTcxOTVFNTY1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkRvY3VtZW50SUQ%2BCiAgICAgICAgIDx4YXBNTTpJbnN0YW5jZUlEPnV1aWQ6RTcxOTVFNTc1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkluc3RhbmNlSUQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eGFwOkNyZWF0ZURhdGU%2BMjAwOC0wNy0xOVQxNDo1Nzo0MS0wNTowMDwveGFwOkNyZWF0ZURhdGU%2BCiAgICAgICAgIDx4YXA6TW9kaWZ5RGF0ZT4yMDA4LTA3LTE5VDE0OjU4OjA1LTA1OjAwPC94YXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhhcDpNZXRhZGF0YURhdGU%2BMjAwOC0wNy0xOVQxNDo1ODowNS0wNTowMDwveGFwOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhhcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1MyIE1hY2ludG9zaDwveGFwOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9qcGVnPC9kYzpmb3JtYXQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOkhpc3RvcnkvPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpOYXRpdmVEaWdlc3Q%2BMjU2LDI1NywyNTgsMjU5LDI2MiwyNzQsMjc3LDI4NCw1MzAsNTMxLDI4MiwyODMsMjk2LDMwMSwzMTgsMzE5LDUyOSw1MzIsMzA2LDI3MCwyNzEsMjcyLDMwNSwzMTUsMzM0MzI7QzA1QTE5MDRGRjAwQUJEQzA1MUJERkFGMDIwNEVBNTE8L3RpZmY6TmF0aXZlRGlnZXN0PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24%2BNDUwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjMyNTwvZXhpZjpQaXhlbFlEaW1lbnNpb24%2BCiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U%2BLTE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6TmF0aXZlRGlnZXN0PjM2ODY0LDQwOTYwLDQwOTYxLDM3MTIxLDM3MTIyLDQwOTYyLDQwOTYzLDM3NTEwLDQwOTY0LDM2ODY3LDM2ODY4LDMzNDM0LDMzNDM3LDM0ODUwLDM0ODUyLDM0ODU1LDM0ODU2LDM3Mzc3LDM3Mzc4LDM3Mzc5LDM3MzgwLDM3MzgxLDM3MzgyLDM3MzgzLDM3Mzg0LDM3Mzg1LDM3Mzg2LDM3Mzk2LDQxNDgzLDQxNDg0LDQxNDg2LDQxNDg3LDQxNDg4LDQxNDkyLDQxNDkzLDQxNDk1LDQxNzI4LDQxNzI5LDQxNzMwLDQxOTg1LDQxOTg2LDQxOTg3LDQxOTg4LDQxOTg5LDQxOTkwLDQxOTkxLDQxOTkyLDQxOTkzLDQxOTk0LDQxOTk1LDQxOTk2LDQyMDE2LDAsMiw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwyMCwyMiwyMywyNCwyNSwyNiwyNywyOCwzMDtENDYzN0NCOUQ0MUExMEJBN0VGNUVCQ0RCNjMxODMyOTwvZXhpZjpOYXRpdmVEaWdlc3Q%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY%2BCjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8%2B%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEJCAgJCgkLCQkLDgsNCw4RDg4ODhERDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgBRQHCAwEiAAIRAQMRAf%2FdAAQAHf%2FEAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPBUtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4%2FPE1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BCk5SVlpeYmZqbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp0%2BPzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BDlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq%2Bv%2FaAAwDAQACEQMRAD8A7%2FmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmrlHI2utXn6WltnFESb0RFSp41WjD5q3LCBaslzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2E2rj0LuzvF7PxftUf8AXPLDnC3XI0ewdpOkTK4P08T%2FAMK2Ec1TLNgaxmE9pFIDy%2BEAn3GxwTgV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F%2F0e%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXYUeZpfR0a4kpUAx19h6i74b4X65CbjR76FV5FoJKKe5C1GIVLdDuGhuXs2IKOX4gfsvGdx%2FskKtkiyD6bctHHbXgPImOC4qOpXj6E1ff4Mm4Ndxkpc770BvNmzZFLs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Lv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVokKCT0G%2F3ZgaioNQemANZuhaWLyE0LlY1%2BbGn6sWspA8QA%2FZ%2FUcVRWbNmxV2bNmxV2bNmxV2NZQwKnodj9OOzYqwDT4iiPZsa%2FVLm5sj7I%2F76L%2BOTXTpjPZQSt9pkAb5r8JyKXqfUvMOpIQOFxFDfoP8qFvTl%2F4Q5INDkrFPAf8AdUhI%2FwBV%2FiH8cnLeAPcxHMprmzZsgydmzZsVdmzZsVdmzZsVdmzYyWRIo2kkYKiirMdgAMVX5sjTeaGl1CzsbSAOLuX0w7k14KCzyAD%2BUZJBirebNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F9Pv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVo4CXUFa9e0CbJRWkr%2B0RWlMHZEJ5WtPMtzE5%2BGYJKnyK0%2F4kuEC1ZeM2IW0okjFT8S7H%2BuL4FYz52mMWn2tDTlcpX6FbDHR5ecCH%2BZevywl%2FMM8dJtn7LdJ%2BKvgry9ccrOJ69KVw9E9GS5s2bAh2bNmxV2bNmxV2bNmxVi3miFU1LSbxvsStJYzH%2FJnSi%2F8ADYpoEzLcxq1T68FGr%2FvyE8GrgjzdC0mhXEsY%2Fe2pS5i%2F1omDf8RwttJRHdrcDaNbhZVI6endIG%2F4mcnHeJCDzDL82bNkEuzZs2KuzZs2KuzZs2KurkZ843Zhs4bVTQzvVqfyrvg3zHNPb2UMsLtGBPGJSpIqjEqRUb9ch%2BvSSvp0JlcvJCLyMuxJb4JNvi%2F1SuEBVvkaX9L%2BZbm8Sv1fTbf0Y6%2F78lPxH%2FgFzpeRvyPbWcXlyyubWBIXuoxJOUG7uKjk5%2FaOSSoxPNXZs2bArs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FU7%2FmzZsVQ2osyWM7o3FlQkMOxGPtZhPBHKCDyUE08e%2BM1Bedjcr4xPT%2FgThV5cvBJbpGergEfMDcYa2PkqfZs2bArs2bNirs2bNirs2bNirshfnRGtb7T9TX7LcoJD2qDzSv3vk0wl81WDajodzDGKzRj1oR35R%2FFT6RthHNXaVcrKsUtftDi304dZz7yrqPrQCIncdMnsEnqRK%2Fcjf54yVjP5gwtJ5ckcD%2B5mik%2BivH%2FAI3wD5RnEtpwrWgw983RGby1qiqKlYGkA%2F4x%2FvP%2BNchnke5BIUGoPQ%2FPEJHJ6XG3JFbxAOPxOA1iX7sUwIdmzZsVdmzZsVdmzZsVUbqBbq2mtm%2BzMjRn5MKZDLP4rC2UVq9qYj7SWshWn%2BtxOTnIVG4ttWvdNaiiK7FxGDtWG6Ti%2FwDwMuShzRLky%2B1lE9vFMP8AdiK33gYscKtBmDWhtq%2FHbOyMp68SeSH5UOGpyJ5pYde3moWPmW5KzH0pIo2WNt0A3Wv0ts2D73zJ6FgzxqqXpKpHG9eDMx7EYXed45VeC4gPCdYyqua0I5q5VgOv2cAW8sWo2QMqhwwoyHcVyQFhVOLzvrNrdf6fFHLFX4kVeBH%2Br1%2F4bJlp%2Bt2GqWrXFnICyKWeJtnUgV3XOP67qFjaFLHUrprecy%2BlZajxPDmN1jn8Dv8Aa%2By%2BIaXrclrdtZ34NrfR1USofgeo2K06c%2F8AgcBCXr%2FlvXRrdnzk4rcoSJFXYfMbnDzOV%2BTr82eqAOQIpaBq7AV2r%2BOdTriRSEp8z8RoN9I5AWJPV5HYD0yHr%2BGQg3Ntq1lcLazx3CiZviiYOKzQo9Kjb7YzoWqRevpt5AOskEij5lCOmc60%2BWCK0j9ONYo5IYp%2BEahQWBeNjRafEcMVTvTb%2B80fyHZ3FugE9vSORJBUqPVZW%2BEHw3yVaXeC%2FsobulGkX41HQMNmH%2FBZzC%2B1iTTbadZUkjtJjzkQqSKqNm5fsdMPfyr1%2FRdT8vra2E5N5C8kl3bSMTKpkctz%2BL7SP9peOA7fFkIkgkCwOfkz7NlA1y8DF2bNmxV2bEJLy1injtpJVWeavpREjk3Hc8V64virs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Xv%2BbNmxVplDqUbcMKH5HIPokjWsstqx%2BK2lZPf4Wpk5yF6nF9R8xswHGO8QSj%2FAFh8D%2Fqrkoc6VmSMHUOOjAEfTjsAaZMXhMRPxRnYf5J6YPyJV2bNmxV2bNmxVQuzOtu729PVUclBFa07U98DafqsF6i9EkI6ePywwyF6vG2i6oJRUWl6xZCP2JOrr%2FsvtLhG6s0yiK4X6Zfi4QI7Vb9lv5h%2FXDHrgV5c8B0LzLc2Q%2BGF29WDw4SfF%2Fwp%2BHOg6ZMHi4j2YfTkZ%2FMGwpFaazGDytm9GYj%2FAH25%2BEn%2FAFX%2FAOJ4N8uXwliicnps305LmFZDewrc2dxbt0lieNvkylc45%2BX10UCQzHjLATE4P%2BQeNc6L55e5i0J57WVonikRmZDSq7jf2yB2Op%2FVYor2%2FwBNjktpAGjv7ZvU%2BInoy8Vao%2Fa44xCQ9as25RVBqKnfBGRby9rBEsljcIY0aQ%2Bg5FCCQD6bj9lslGAikN5s2bArs2bGyOI0aRuiAsfoFcVS%2B%2F1q2sJltyrSytuyp%2ByDsC3zwxBqAfHfI%2Fodmt2z6pcjnJK5dAexPT%2FgRkhxV2c782mSy82WUgNIdUhNs4PTmlXQ%2FwDBDOiZAvzLb6nHpOrlFkjs7lWdG9yvxVG%2FwiuGJ3Up3YTJFr7op%2BC8t1ljHjxodv8AYtkiyHbxx6XfKx%2FcXBilJ3%2BAsVUV8FRlyYA4Z80DkkPmq3EtlHJSpR%2BJPgHBH66ZBtIufqt9Np8pALHnEpO5p1oM6Xq0P1jTriPoePIfNdxnLtZtrGZluBcG3vF%2BFJYuJfx40IIxHJKzzb5et9ZtZYp1LwygcgPtKy%2FZkT%2FKWuRKKCOC6tNH1CblcWiILDUWHH6wg6wyDejx9Fw4sfOMjEBY5biH1HgLy8VYulOfJV%2By38q4ndH9LlL219K4iilHrWzLxlhI6SgE1%2F2SnFKo0Czxy28zMqcSzspIYBPj2I%2F1cd%2FytnVZdNQ2D1I%2BESMoPw%2FzMftdMG20TSQyyblmjenzoc4TY6ld6ddyKwMUsbFZoHqNwd1KnGXRXs9n5%2Fv7lg98GlWhMjwk1A%2Fm4k%2FF7jDSwSPULTTJI3PGBphGNwG4OHVW%2BgnONX%2BsWFpDFPaSSJcTESG3TcRlf2uRK%2Fazq%2BkR3aeT7e%2BjnX6yoW8ibht%2B9i9Tg%2B%2FQ98QVZHqstutowuSPSdSpV91IPVWzif1i98t%2BZ7m40FjbSWUrNCqEmkex4EH7acT9lv2c6lonmbTvMUTWdwgiumWktrLQhge6H9of6uRLzd5ZurDVP8Q2KetYFUW7jXeSKi%2Bm0hH7UZH7X7OCY4g2YM0sMrjvexB5SHcXsnkPz3Y%2BcdPqKQ6lAB9bta%2F8lI69Y2%2F4XJeDXPJlvPe6JqMeq6NMYLuE842To6ntToyuv2k%2Faz0J5E8%2B2HnGyI2t9VgA%2Bt2ZP0epH%2FNEf%2BEyESeUuff3tmbFAx8bB9H8Uf4sZ8%2F6P82TMMLNb1iDRrQ3EpBkkPC3j7s5%2FwCNV%2B0%2BGVc4n5m8yfpnzJcsr%2F6HYsLe232PBv3j0%2Fy3%2BH%2FY5JxkLourX175%2Ftb28maSZrloqsdlQ1Tgo%2FZUDO755%2B8uxlvPcMI6i6LAe2zZ6BwlS7NmzYFdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVf%2FW7%2FmzZsVdkb83W5%2BrW1%2Bg%2BK1kAc%2F5D%2FCf%2BG45JMC6jare2FxaEf3qMo%2BdPh%2F4bCNiqV6VOOcTV%2BGReB37%2FaX9WHoyFaJMz23BqiWE7juCh%2FsyaRsHRXHRgCPpwy52gLs2bNkUuzZs2Kuwu1rS49W06Wzb4XI5Qv8Ayuu6nDHMemKvONE1KWGVrG7rHPCxRgeqsppk7sb0XC8W2lUbjxHiMhnnnTHtLmPXrZfgakd1TsR9iQ%2FP7LYtomq%2FWI0Iakybof4H55LmFZdqNlFqNjcWMwqk6FD8z9k%2FQc515XuZbW4l0%2B5%2BGWFzE6n%2BZTTOlW063EQkXY9GXwPhnO%2FNsS6T5qtbofBHqaniexmi%2B2v%2BsU4v%2FlfFgHcrPTFbanZNb3caywyApLE3Qj3zjutwW%2FljzBc6Pp6fV9JHpsLNSSgR1HIorV3Vvizq2jXQk%2BAndlBA9xnNvzRiWPzJBJWnr2gJP%2FGNyv8AHAdikJ3YGf0o5pZDIboSD1GJJ9aAgh6%2F5aUzoFnN9YtYZ6gmRFY06VI3zlXk%2FVI5bi2hnlBgdBuxFFahhfr0rSNsnHlXU4JI5NJaSt1avIQm%2B8RaquD0I%2BLjkpbgIZJmzZsirsDagC1jcqvUxOB%2FwJwTjXUMrK32WBB%2BWKpfofE6Xb8f5d%2FnhjkMPmvR%2FKlrJBqkxBSVkjC0PIDpTfI15s%2FMNbu3jbR5plsZVp69swRi9N0eSjMnH%2BRcVpm669cWWtXGnatwjgKma2uPsj0x%2FNXw%2FayOfmLr%2BhX3l%2BPTYrkXM%2BpGtm1uPUUceX7yRx8KLtx%2F1s5xoN%2FefpVr6C8muVVfUuLO8kMrEIeTem7faRk5Iy5FdTuZ9B169trGZvqkc5eFD8SmJzzUcTtsrceWHzTT3fRJv0p5UZvtOYYrgCu%2FJV4P%2FwANHnPrj83vM2lX9zpWoBJYInaJ540pOi1%2BGRQDxf4cln5Z3qT2stjWrK0iexEgE60%2F2XLOUfmHYNZeZbhWP94Ayn%2FV%2BD%2FjVclLlbEdQn955q1wTiU3huLadeQCsfSljO9VNev%2FAA0bYHub1Z7V5yWkhHxpcVHJNwGiuP8AKStVk%2FbyGafqLQxyafO5S2lPJWUAmGQ%2F7uiB8f8Ad0X%2B7F%2Fy8Ctd6jpl3Lb3v%2BkQTpxniqTDcQn7LoR%2FwUb%2FALDZCyyekWl9ZyaFLPelZGN2tqDEtZJHenEs67ckpVXwq1bU7G1iKWvqtcCR4bkkhFYx%2FCHXhvvX48C%2BU7H1SbK3k9Wya5hv4HchSBF8FxBL2WeOJ1k%2F4s9P4cu%2F0j%2Fc1FphmFxPLeOhZBxAiL8jt40%2Fa5YegV6PprvLpcE8sfpTNbh3QVoGK12zluoQ2PnZih42fmWIVt5z8Md4q9I5P5J17Z2A8YrWVl%2BERoaDwoNvupnLtb02LzREdR0hBba7bVe4tEPFZwpr6sH%2FABb%2FAJOSkgPNLqGaG7e3v42iuoTwlicUIK9iM755KnGoeT7ZX6m1CH%2FYSNCf%2BFOctnuIfNkSWeqEWuu249OC8ccfW47elcd%2Bf%2BVnQ%2FyyS5t9Dk067jMVzaSXMLK3hRJlp4r9rjkQl5PbalcaRd%2BlI7PbwysI5lNJIirU%2BH%2FmnOueV%2FOUeo%2BnY6hIpuWX9xPtwnU%2Fhz%2FnTOPeY4zY%2BYNTgpVBcSVQ9CrHkP14Gsb9rFgRWSzY1K1%2BKNh%2B0p%2FZcY2Qdlev%2BZ%2FLKxK19pcdYBUzWqdYx1Lwj%2BT%2BaP8AZ%2FZyHW9xe6ZfQ6ppk7QXsBDRTIevsR%2B0p%2FlyY%2BUPNR1KJLK5lD3KrW3m6esg67f79T9pMD%2BZtCjTnqVilIW%2BKeFRshPWVAP2P9%2BJ%2BzkZRB3DPFlljlxRPz5Edx8mcw%2Fm3aXvkzULyUC3122jET2oNA8kh9NZYT%2FJvzb%2BTOZabIhnWkgaOQcwxO577%2F5fjhKIYndoZvgaUD05v5SN1J%2FyG6YI0RZ4tS%2BoyKQS1HTwYHsffALrdOQwM%2BLGOEHfhu6PWvJ6f5FsfrXnqW8K%2FDBEZD4cmAVf1Z2fOSeSLmfT9RrHEWlvDSZaVagNR0%2BztnW8mWsuzZs2BDs2bNirs2bNirs2bNirs2bNirs2bNir%2F9fv%2BbNmxV2Y5so4qw6WL9HeYLiLpFcUnjHQfH9r%2FhuWSbTnBgMXeJiv0H4l%2FA4T%2Ba4fTW01FRvDJ6chA%2FYfpX5MMGaXcBmHxbSrsCdi6%2F2f8RyZ3j7kdU4zZzrTfO2qQa3eaHrkax6haux%2Br9FkgJ%2FdT2790ZP%2BGydWWoWt%2BnK3erAfHGdmX5rkSEovNm2yiQASTQDqcCt5sL5dZ06Ko9YSMNqRAv8Aiu2Iv5i0qJecsrKo%2FwAkk%2FctTho9yo69htbi2e2vApgmHB1cgA1%2BffOYX%2BnXflXUghJezkNbabxH8jH%2BdcPPN82l65b2j213DN9WdmmtefCRkdeJaNSVb1I%2FtYXWM8cVk2javM95pUv9zcPvLB%2FI3LvwwhIT2x12KCBrxjyjRS06jrxG5YD%2BZcrzzpkXmjyhLPpzCSaFVv8ATZozuXjHP4GH%2B%2FE5JkUmju9BujaTsJYHHKC4G6Sxn9r%2FAJqwJH5g1fyjDaw2KrcaE0zSNE27RiQmtuXPSJ6%2FuW%2FYkxI6hUg8ia9qulatHe3s0k8DgxGKZywBk%2By3%2BTkn%2FN63a8ttG1a3rHL%2B9hIB%2BIdGK%2F8ABA5DNbS0tL%2B4ksJOenzETWrjYiOT4gjD9l4WqjL%2FAJOTTU9XtNc8r6dDP8E8rc4iSP71RwkTfcP%2FALsX%2Bflgq09zFvKeoTMwV2NeCsB0BaNqf8a5N9Zu59K83W2pWb%2Bn9cjBo24ZXUNxI%2F1lyCWsL6fNb3LLxid24tSgINA9Puyb67pd%2Fr2kaPc6bxN5b8owWYKAYW%2BGpP8Ak4RyQU8ufOF7JLD9XRLaAj96ZPiYv4A9An%2FDYOfz9oEbtA0kjXSqG%2Brqh5NtU%2BkW4iQL%2Fk5yK%2FiuNagjEcpTU7Rj6YqaSAbtG3%2FFin4om%2Fa%2BxhXcGeWxlDgpPbfvUFaPDKpFXiI%2FYk%2Fk%2FmwFXr0n5hfXBJFpVtxmC84jOa81%2FaKqv7Sfy5GL7zJq2rwXFhqF40AlWiSQfAEPVW%2BH7Sfz%2FwCRkTl1dLW3t7xi8108C3g9EBArCnI8jtVvtNRcR1zzTdJcQvYwRW7y28dwzFfUblIvI05fAo%2F2OGxSt3zSW9LPXITMlCjiuzofsyRt2YfsPkd0iabTtQksp1Zra4U84X6SJ%2Bw4%2FwAoD7Ei5dzqV7LFCt7KZnVAY%2BRqyg9aj%2BX%2BTJdouuaHrltb2PmCNfrkKmO2vKcT%2FkgsP2v5cjtapfo0Jt%2FMllFGHltZvVeK4ptwWNi6yU%2BzIvRlwm1mUarpNtJHEWutOkuIbh0FSbfkGiZ2%2Fb4MxH%2Bpk6uZNM8saddywStNK605tsKnYcF%2FmbOZy3s2nWaLE%2FG4e4%2BsK43HELxowOzK%2FL4lx5fFWb%2FlprP1TWLQMaLMFRh%2FlRtxr%2FwLYn%2BfNjLp%2Bp2WpwghWLxuf2SGoRX%2FAIDI9peo2kMtjfWQMUi3JM9u24j5rT4D%2B1G5qyfyfYzp%2FwCcdimr%2BUra%2FG%2FwpISOoIpXJDcIPN4HDcR3Scl2I6qeoOGNvcQyw%2Fo%2B%2FJWGpNvP1aBz%2B0PGFv8Adkf%2BzXIxSaym2NCOh7MMNYLhLlOS7H9pfA5FU30vUNQ8uaqjIqsaqHiO8UsZ6EeKsrfA%2BS3yUr6p5iudTl2S1RvRTchTKeCgV%2FlTlkOsvUveOn8VkdatauxoyN%2FID%2B0r%2FwAmTfyYHsrnTdPasc1%2FNczXMZArwhT04g3%2FAD05Yjml6Fditlcmu%2FpvX%2FgTnK5bS4sp1mDtFID6kLioPXZgc61NGTBNH4o1PpUjIpNbyX0Ulvcw%2FV9Tst7i2IqHWn99EP2kZf7xF%2F18nMX1pANMR1TTYfMkRuYYlt%2FMEY5EfYW7UftL%2FwAXjDf8u%2FMFzM8mnX6MJLWRFkMh4yiqtGUYU%2FZP82IzW%2FH4DVQG%2FduPtRP1FG%2Flb9lsG6ZJDJfPcvGI9WCoJZwPhmRGHF2X%2Ffi4AP2peafmBE8Hmq8LgATCOVaeBUL%2BtcjauUPip6qe%2BdJ82x293Pb2GtyL9ZmWRoL5QAUZZGQK47p9nOd39hdaZctaXScXXdSN1YHoynupwFCL0zUX0y4SVGf6uWDqybPG46On%2BWv%2FAA652nRtY%2FTdqJbfjLdqnK4gjpSVen1iBf5G%2FwB3Rf7qfOCxycaqwqjfaH8ck%2Fk%2B61K11AC1kZYIT6gmB%2Bxy2oP%2BMi%2FC6f7LEGlZCbBr%2B%2Bu%2FqqpBCjP6cbtxHwn4ljrX%2FgckOj2EMcC6lK6yTRKYmkIoYl6gE9xT7L5HhcTJqM1jJCEjjQSQsK7qT3rgi%2FuJ7PTDKQ31S5f03ZPi3SrfGP5RiKG6bej%2BQPzB0CG%2BuNHvB9VeZx9WvZKBX7cCf2P8jOvghgGU1B3BHfPHaQrfuEt3DHkAJakKhP8AO37A%2BedX8i%2BYPOen6dNp2qK5t4JFjs5HClyoNJfTdieUaL8S%2FwDCZEcRNEc%2BrfOOKWMTgeGUaEoHfi%2FpRP8Aunt2Ab3UorWqAc5QK8egHzOPhuoTYrdesJYgnJptgDTqdu%2FtkT1C9XnLPIwofjLduJ6fhkgLcYsi0vVRfSSRSUWRd1UeGGgyN%2BVrCSkmrXKlXnHC3RtuMXXlT%2BaTJKMTV7JdmzZsCuzZs2KuzZs2KuzZs2Kv%2F9Dv%2BbNmxV2bNmxVB6rafXtOuLXvIh4HwYbr%2BORbRL%2BsMTMaSQsOSnrseLZNDnIdfXXtP8zXtnZGC2tJWEsUz8pH4yAE8Y14rs3JfibJRPMKyf8AMXye3mKyh1LTH%2Bra1px9S0ulFSV6mNwPtRnIb5e8wXlw%2FwCj9VR9N1u12PGoD9vUgfpJG%2F7UedN8uapcXsH1e7C%2BrAi%2FvV6OPs1K%2FsttgLzP5Ysr%2B3NzHFxmjPMlNj%2FrLTdWHtiNtlU9I82sxa11lAssf2bmMfA9PFf2G%2F4XIt501y81SykEEjRQRMGEaMV5L0%2BKn2sq4ke3j9O4asuyLNSnMduX%2BV%2FxLCfVZ%2FS0u8cDkVhYhfGgxodGQDDZPMculusTzpwryMT7mneh%2B0uTVNL1e%2Bsob1tLmmtJlEkbFW5FGFR8NfUzi2iQ%2FXNXtLjUAXWe6hE3L%2BQyKHG%2FbjnqzzP5ok0H0baxgWVyodi5IRU6KBx74ASrzOzsfL1tcH69ppMtdxM0h4%2F883OS2GLS7239K1pGpGwj%2BEr%2FALHphVcecBcyrc6vBFdabL%2B7lV0UPbt12KDnx%2FlYYGvrWKwP1nTp3kirsT0BpWgcdf8AZDJg%2FFjSanSb8xC2ursXtpG5kt7dkVRGaU4g%2FETy%2FwBbIzc60xSeylsgphDJeafNtIY%2BnqREfCygYcWPmV14x3qkqQDzAo4X%2BYr%2B0ME6h%2BidZZImjM90FLQzQj40BFNn2%2B1X7DYkd2yi%2BrHNIh8uXbLp7yLJdToZbZJDX1EU0NOXxCeL9tf%2BJ4PhbTLya58sXqqt3EoKlV9MSoRUMn8ssf7XH%2FXyD%2BcfKFzoWnRatFqUUU%2BnSGSGAsBcFXZaFeHJVZDu2HOn3See9Kt1%2BsCx8x2y%2BpaXabB2TxH8pP21%2FZwAnu3VQuV1CC2iW9cx%2FwCkS28kMtA5dKLHL1%2B00TJyZPhk%2B1nS%2FKN59Z0GSNno6yI6e1V4v%2Fwy5z9pv8YWj6Hrcf6P836EWmiiHSfiv2ox%2B2kwH7P2ftLk28uxrbeXYLhYXV7gMzxkE0IqPiqNq%2Fy4gb%2BSk7PNdX1m%2BHmqaytJ%2FTtTdx%2FBGoSu6swZqcj8YbCnRmM97drKxKXcslu7tXb1%2BSBq%2FwCSzZK9c06xuNUutStkBls5IFkAIAMoHqUUfzNRkbCPW5Xs70rZcVtL0%2BtCoAFVc1oK%2FwArni2RIShdD0rU9Z0g2UNW1DR5JLG%2BirRlQuXhmp1ZP72M%2FwCph75g0K2sra21G8ch5baGJUpt6yARuvL6OWEQk1eJrq9s55YLxBzuGhJEjr3LKvxSqv7WISanq2oQRXGryvd2MtVhuSQ8aNQch8OyNjsqElhK1hbcr%2Fcv3K%2FyV%2FycRSQBmUiifsfQM6FpfljSbrR0mCy3EjDlDIzN9sGnphU%2FZ%2FlbIrqnl%2F6jM3Cb1VRqOoU8078XoOHPISIiQCd5ckgE3tyS4StK6xSy%2FDJ%2B7HqseO%2FYVw0W2thatp10he2b7YH21cfZljP86f8AD%2FYxO4tbO4so4I7ZUvG5Lpl3PssprUws392JD%2Fut%2FwCbAOh6sLuU6VqYMF4hKRu2x5DrFID0YY7rsh4tMn06%2FkspjzjniaS1nQfDIE%2BJWXwdafEv7Od0ugnmL8tmYipWEOB1oGWp%2FwCH5Zy4hoT9WuU5BTzj7FHp%2FeIe3%2BX%2FADrnR%2FysvRfaHeaJIwZ4RJGo8QDzQ%2F8AAy5OPVBfPNxbpMpifYqaBu4IwFYWlx9fEIJU7lmH7S%2F83ZJ9e0x7K9unRg8azMkoHWJySVR%2F9YH4W%2Bzj%2FKtvFdaxBDLQKzAVO243G%2F8ArYPJUXb2NvDZtdyWxe3B4meCQ%2BtG37Jkjb9lafaXHRXl9q2r6etnWJ7Yxx28h%2B1UNyMjt%2FlH4myX6lp1poPm57CIFLG8jikCsKisqqXWncc2%2BzhLZW0Om35hCuLiCeSgIHFY67KT9rl4YaV63IwMVSakg1pt27eGRuzvrTWILdYbnlcIWXSdQc8W5pXlp91%2FLIP91M%2F94mG9tcfW3AQ14xgsPH4c4Zp%2Btz6HqN2rJ61nNIy3loTTkA54yIf91zR%2FailyRNUinpV0iXqyyxw%2BjdW5Md%2FaN1iPdqf74f8A5Jtka1ZZ4LWYxsySKpaCRT8QI%2BIxkj2Hw5KLe6%2FTsUF%2Fp1wsmrRRk2l0QAL6Fft290g%2Fu7uP7Lo395hFquqaL9XZmmWCRwySWTgs8MgG6Oo%2FY5fZbAUhC%2BZ9JsfMl1SKYW%2BqyQRT2DMf3UvJeTwt4M5%2BJchKyrOr6D5gQwTQEpFK%2FwDeQv8Ayn%2BZDk%2B1Gyj1ew0SaC4gS5ntmCtX0ELQtQAM%2FEcv5Fwv1bQxr%2Bnhr4oms2ymP6xuCStSIbof6v8AdzYOaGAQ%2BXdTm1NdLjj5SN8QkG6FOvqBu%2BTjTrS2sbZLCMcVUmkpFGLn7Rf%2FAFv%2BFxTTme102DTuILIwZpKksW%2BzxWtW41%2FZyU2XlW41HhcahytOQJZVHKaXw%2Fd%2F7rY%2FzviAqQ21ldXtytrDG0k524qKmnj8sO736roNmNIltfVv7hFeaMnkUqTwpxNA2S2MaT5etS9w6WdtEvx1b42A7Symh%2F2C5zTzb%2BZun3swOjacGVKwrqMgoajeiJSr%2FOTDVdVZPYa3pOj%2BW7u31uKKzuZGP1dePP1Iz1UovxtJ%2FlYU%2Fl%2F5hOtyS%2BWrlis1Gm0pyfiR4%2Fi9Kv7SumcrvNYnu5DcXH7yToamrfSf6YL8ratLZ%2BZtJvoT6bwXMbEjuCwVh8uJauPFuFe%2Bx%2BYJ4NMawQiOFzyZOlDX4h%2FwQyQeVtAn1BY9R1QN9WU1toG%2Fa3qGYeGE3lnRLPVfM19LdAyWkTtcW8a7xOGaq1kGz7k%2FAM6moAACigA2AxJ7lojn72wANgKAbDLzZsirs2bNirs2bNirs2bNirs2bNir%2F9Hv%2BbNmxV2bNmxV2Qzz3p3P6rqKbFKwyt%2Fkn4lJPseWTPOVfnX5gmstNtdBtnMbajykuXHX0YyPh%2F2b%2FwDEcbrfm24MRzZI447GR59w6pMfNyWl7EdD1KM3Cp6dwoKldj%2B1zHE%2FRko0rz1rUtz9SvLe2lm2Hp8jC7BhWqV5xvUb%2FDnn01jPEin8pHgckemXmsTaHcxANw05o57O7IIKxliJYll%2FaRT%2B84%2FsNkIZhIkSjRDl6zs%2FwIjJCXFHkb5gp3%2Ba2r%2BbdPuEvYLVbLRpiFL27c2EvWkj0%2Fd8v2VpkGsfN2p3Kra3V2XicgEsQeQJ3qSNs7d%2BkdO1rSbKw1LhN%2BlbRXVJKFZyq8ZV3%2F3YGHLOEecvKFx5TvTLDym0idv3EvdG%2FwB9yf5a%2Fst%2B3lpHUOvsua4iNwbWCruHK%2FB0qN9j0zoy%2BarW48r2Oq3l1Le2sSizuGkqk6zgUVXMda8F%2FwCDTOO2M01rIs0XCRQ4kHqCqGnZl74NgkTlMqSOIZpPVNrXjGG8Qvfj2wXzSyqz1eO%2FtNSjQM8sVubhFbbkIpPiI%2BUR5Yca3q17IdPmtZ2js7yztriONNhyAKSciPtMJUfIZaXDWL%2Bra0jcq0ZYAV4yAq6mv8ynJf5Yex1PRjpUsfO%2F0pnuLJWNPUgkNZ4l%2Fm9Nh6vH%2BVpMRa2uvBcXej2Gp2rSC5tJJbOZkqW4v%2B%2FgY%2Bx%2FeJhtBB5sOi313boLa9ihMlo3EB5ClGkULy%2B16XJk4rhlZarBFAbZljtrS5Tg%2FoIF4fyOT1JjbC1L%2BbSbowyMwu4WrzJryX9h1PQpxw%2FFWFXNut9PB6srS6frlqI4JZHJ%2Br30bCsbOf5phx3%2FAN1T%2FwCRgPQbtreVrEFrW8gfnDU0dJUPF09unHD%2FAFeygjjvbi2haTQbpxcXlpHvLp9x9n6xClfjtjXi1P2P3b%2FGseE99ol9qtyjIKamYlktb6Mn0L5QKJ8Zp6d3x%2BH4vt8OD%2FvciTXPZaZ%2Bkdp5%2Bgt19Yad5p0%2Fe0vU2Y8T0NPiaM%2FtJ%2FuvOj6lcGysFaRlYxJWUjfkUXk3z5MM5p%2BV2l3U2pPdalFHK1sOLyqQxSZaFOdDWOT7W%2F7eTTzK8UdlcxREhXBTf%2BdzWg%2B7JxNji70HnTz%2B51GXyrrFxaapD69nfcRqSftqxHL1oj%2FOjPjtQ0GNYCfrCXWi3QMtlelhyjkYbFfdvsyx4M87Wy6zqemTq4X9KwQnmegkK%2Bmf%2BSi5G9M1PVfLUt3od3CJIGDEQS7iKUD4Zov8%2FjyErqrruPNkK58%2FJN7Sx0%2B0sDe3k0k9xA6JBJACGqwPHiKp8S8fts2F0mrDS3nubPThH6ZLa5YcQsnBvs3kSsCnJeXJuK%2FB%2FwAYmwQ%2FrXdjEsQRizhvjKCrUp8If4uW%2FwCyuK3Fs893p1nezfVdeDCOxmHFi8ZH%2B89wSeBjP2YuX%2BVFiYggA70Pmt9QzfyjdxXeiPeaY3rNYt9ZjdKUkgP2gyj7L8ftL%2FPgTz2tuLdJIT6cN1JFcxzJ2U7Sb%2Fs%2Fa5BsKfLEMvlPXby2sJI40uF%2F0izVuUcb05n0z3gkTlw%2F3237vHeddXN5pEMdnbmOys4BFcy0qDcF6GJa%2FwDFacmyX8Pu2R1QOi6Yupabd2F78dj6xjLVFUlpySaHwkUf7F0%2BDIrrvl6dr42N0eOtRIHs7ldkv4B9ijf8tKgfB%2FP%2FAHX28mPluyb0Vs7OdTL6SSReoK8%2FTZqN%2FrqOPL%2FJwTqdhFr9m1lqUhjnhcm2uv8AdltN%2FMKf7pb9tP8AZrjVhWHaHrEWqxjTb9gt9GKQytsXptxNf2sl35d3J0jznJbCojuQlR26cT%2Btc55qthdyXcyyJ9X8wWfx3ESbC6UbrcwfzS8fjfj%2FAHyfvPt88N%2FKuq3F3q1hqBIEyc4pWZuCkoAwck9MA50VPJV%2FMq2k0TznfCJQUmPJom%2BzJG%2FxcW9t%2FwDY4Q6cILa6ZY2eKRwslv6goaDfjy%2FaK4f%2FAJleadM80a8t1pcZ9GCJYmuG2MrD7TAfsqv2V%2Fmwr0WyuNXUw%2FVxci1%2BKLt%2Fw23wrg6qGVanr1vrK2t3csIry1aESBjxJEYYOQff4cjvm3zLbpZXLWTGC5vr%2FwCswRjfjBGoC8yfi%2BIjCPX2vNMu%2FqZDRNGKSAgUqxqgqKruF%2BH4sjsyPPIZZSXJ7knfG1e9%2Flxrdt5ksbqdSFu7eMLcW5O4%2BE0cV6xvnF75uVzcb14yyBW7%2FaO2KeS9RutC8yWd7DMYLfn6d3L%2Bx6D7SLJ7YhdkNd3UkRDRSXErxMDUFGclT9IwndCtpWrz6ZN8MskcDsGdojxkjcfZmip%2B2v8AL%2B3iWoySfXbiHUmFy14frKXqH4nL14zK%2FVuX7cbYEeJWDPQVpU0Pj0x6yqLL0pJUW4tXE1o5O9SaSRbeP28Cob1Z1T6vPKzxjeNSSQK9aV%2BznXLfUrdtDt9T1U%2BjeRxpa3iMvF5V41jcg%2Ftrx%2BLOd6VbaTqJlS7lMl5Iri3hHwRiQj920snhzODppWsii6zcGeSZg3po3NSy%2FD%2Fen4K9V542r0LyheaXcm5uaCCWNhxkl%2FvClOqcvs4rrn5g2enI9tpKi4uqlWck0rSvxP8Atf7HITazpccriNaLGD%2FozGnBVIJkZP261%2BFuWE4juLqSZo2pbJMjyitAQeVPwrjxbUE01reuXGvCKPUZJ2Cs0iqgUgFtunw%2FCKfDhWLXSzayW73jxuGElWgJUbUoSDhkLcXEjJDSJqkoSd%2BH7OGlh5a1HzDONIit%2FWvZEMkJRlQtGlKsCxVX4%2Fy%2FawWtILTLTTmeMmbTrm1jXe0nmMLOwH2nZlrWv%2BVhlBb6Lql09zpemrbx2cJe5WNqiRi3EKrfyj%2BZR8WJ6x%2BVPnXQrK41i9sljsrUB5pBLGzAVCgiNWLNufs4I8h6hp738sNxRBexei5BoBJWscg%2F2Xw4VZjoMllFbx635Y52k9mvPUdKaRjHIF%2B08PInhJQV6%2Fa%2BHOq6d5%2F0G7toZzK%2FBwKzBCVrTo3GpQ%2F62cYW21DQ%2FMUVrFH%2B5vyInPSIqzfE1f2afawkmtp42klt0f6uzuInWoDqrFQRQjkMJV9Q2ms6VfitpeRS%2BwYV%2FwCBNDg2ozzr5Y1vTI7V9L1PnbTDk8E4Qs7M1KKHBDp9GTfQfOdosSxw6txkp8UN0DxBG37WNea09UzZBNY%2FM3SfLcVrLrDIyXZKwm2bmW40DsF3%2BFa%2FF8eTW1uoby2iu7ducMyCSNh3VhUYEK2bNXNirs2bNirs2bNir%2F%2FS7%2FmzZsVdmzZsVdnE%2FwA9rKYXmj6jT9w0ctuT4OpEgB%2F1lOdsyO%2Bd%2FLUfmvy%2FcaXstxtNZyHosybofk32G%2F1sB5ORpMoxZ4TPIGj7pbPl%2BNPrERi%2FaG6H38MkPlXzh%2BjhHo%2BrmunCqwXFKmDmfiSRf27d%2FwBv9pMJBDcWN7JaXcRhuYHKTRPsVdT0P%2FNWB9RiWO6ag%2FdygSL7cuv3HKpkwImPcXoM2KGaHhy3B3BHf3h6B5qslXQooNOVof0a7Xdi6fDxBPKQQ78vT35xNl6Fr1l5s0yXSNZRHujHxlRhtMv%2B%2FE8JB9r%2FAIfILo2pT6XfLd8mmiKehPAzE8oT%2ByvKtOPWP%2BXKvrafSpl1XT2L6ez84LqLrE1a8WH7PH7NDlkMoluPiHRarRz05F%2BqJ5SHf1CT%2BZ%2FLlz5WvvTUmXT5jW2nP%2FEH%2FwCLB%2Fw2FauD8Sn6c67a3Vh5x0p7G%2BRfrAWskY6EHpLFXp%2FxpnLdc0S88t3ptrir27msE3ZlH6nX9pcmR1HJxFS3uA4oftDBlvcz2lxHc2sjQzxMGjlTYgjCVG6Mh%2BWD4ZRIvv3GC1Z7pdxHraNJCViukq13aswVAO9xCW%2F3Uf8Adkf%2B6%2F8AVw1t5NPkKabe3SyqKG2uIquYDX7Jc7ei37a%2FZ%2Fazm9tdT2dxHdWzcJYzyQ9R4UI7qw%2BFhkwhvDqECTaZbExyHhPbqKmCYivBf%2BKZPtR%2F8DgIkSDxVHqK%2FSyBFbjfvR8k1xY6gVtLb6vJbVWZbhvVLo38yAemYZF%2F4XCjW0McX986%2BX72Uem6V56bekVAYLu0D%2F8AJSL%2FAItjw7W0utVgj0%2B7k9DULc%2BnaSMaFkrvaz%2F8yXP%2Bpgq00iztbkaVcP8AWBer6NzEworLWjRsoJ4yRv8AEjr9jGOMDbn5y3UyJ8vcyfyHpl1puhy31zEE1e9cJfKxXjK8JMaTqfGZCrt%2FN9rCX8wda%2BqyabAGAM85aYA9FUcV%2FwCGyZXElvb20VgHb1LeNDEKmpKDhGS%2FfOK%2BcrhtU1G8vLZ%2BYsz6M0Q%2B0nBh6cwH%2B%2B5af7F8slsAAxG5tkesTm68saddo3GbTZ5bb1B1G%2FrRfrxGTW7LzPpcrahALfzDpir9biI4tJESAZowftJ8Svx%2FY%2F1cD6VMb3RNTsShJmhju4gVP2ovtH%2FgG%2BLBVnb6b5g0ux1JGWDXNDj4SEiongQcGjk%2F34hX7LfsYBukt%2BWba4gWHWmj%2BsWdpK0Dwqy%2BoWkonJE%2FvHZOfNcKdasnk80288TN6EEqxOXNWSOJiS7n2p8eB4bySw1ilv8Au4OQk47kKo%2BLv%2FLX7WK6jr4u9Uee1jItndiIiasyv9sV%2Fl3wWAFZBbvYajqsV%2FDSP1yITPUgSKH9SSinYcIRw%2BH7TSJhr%2BYOr2sOkWmnhHSK6YiRolFF5A%2Bn6ngJif8AWyP2ML6dbiRI%2FrqsAI3SRAsMY%2BxHKrlGhfl%2FefB%2B8%2F3XgXXYppJG1m2unkbj6Op2pUSKVAqksSNsif5L%2FFH9vHoUlrytdtDCgdmV7d5I2boU%2BINGT%2FLhpr3nLTKJ9UT19TB4zNHtCe3Jj3b2XIssp1Y8bUfFOQsix7SCSlAXpTmj4av5OnsdM%2BuzB3Zm9OWaNGD2%2FMgRTolP3sXP4Zv92fyYi6oITDVrG28x6NBeBvqWoWS1ivSeIikU8jFI%2BzLA6%2FGn%2B%2B3yFaq1pcXix28ZUGi3U2wadx%2FuziAEWv8Aq%2FH9vDLV7TzXeWrqbaWO4VhHeNHtFdCP7EhX5D4v9%2BfbwpC3liGgvIoVdSqt6pLPGr0pTj%2Bz8Xw4CUkEGil7RwRu9ZzwjPx8UZiKePShyb%2BRfMdhHM2kLEV%2BsDlDLQFncUCxcRX7WEF1DCs63zCs6r6c1Nkencr7rgXSpFsb5zCForepC9PiUEfZr4DADRVD%2BddUkPmPU4lUgVNtNG4qDw2Bof2kP2GyK1LECpY%2BAqTnUFhsta1Ce%2B1G3inuZCrySsgqwqFNRkwu9R8m%2BWIwscEHrharDBGjSH5tT4f9kcIoop4da6Vqt2GW0tbiQHbikbkH57UwHNFLbSvb3CNFLExSSJxxKsuzKwPQjOu3%2Fmq%2B1mFo1C2NmFMjhTQLGu%2FKRtumQfU%2FMWh3uoTXx0r1pJePKSWSnJlVU5lQNufHnhQxmOYxklSPiFCDvUZQKUIpUn7Jr0%2B7D8eYrBP7nRbUf61W%2FhmPmtkBFvptnEezCMkj78CpRZOY5w%2FBmWhBCjseuSyyn0pIpIr2CSr2gtbYTQt6aylufPp8PBWbCZPNurROskYgVkYOv7tSAVNRtg2780%2BYPNd5CdWuRJHEWkWONFjRaih%2BFAPljsqLeRrVh%2BjQt3GBRoXBBKAfFwag%2BLJ15B17yfealE2taTHcXMG63Eq%2FvbYL%2FvyH%2B6eFK%2F3iJyT9vAXkPygPNEuoxx3KQ3VrAHtYWP8AeOxpv%2FxWqijMv2WZMLdS8vBLx4pg9jqVqTFJIvwup6fvP5lP%2FDLillv5i%2BStPtL867pEEcem6hxkivLWjIk%2FevHb05ftZF9Okd5Et5mayvoWEtrdRmnCUfYmhYfzftp%2B3k3%2FAC68zLfx%2FwCFdWt1eElrbUoW%2BwGIrDPGv7CyU%2BLj%2B18eIeavKM3lq7WqfWNOkYizuXFeNesE9P8AiX7WNbqCncfm2fzRoUmg6zEqa7ZPDPPCv93eQRMC00A%2Fa%2FZaWLCHzf8Al7oOra5b6h5KuBHe3rj61Ywr%2B5Xlu0%2FL%2FdDfzx%2F8Qwpup4VWBrORhfW7iS0YkrJbkdRLKv2om%2FY4fbzsvkXU7fWNHju3jhj1ZAI9UEKhSJvEmg%2BF1%2BPEhXgPm%2B98y%2BWriTyxrM0iCMBo5VVW9aDoJIZm%2BLif5ftRthN5X8zxWXm%2FTZ9dHq6HH%2Foz2z1eNLd1Kq4TvwY%2Bo2el%2FPXkjTPPGkNY3n7q7hq9jeqPjikp%2FwANE%2F8AuxM8mazo%2Bq%2BV9UuNI1KL07y2PFlbdWU%2FZljP7UTfstih9Jy6d%2BVV3f2dja3ltHe6ipezS2mrzAFfh%2B2iMf2K%2FE2Xcfk5ojoTZ311bz1JEjFXG%2FitE%2F4lnlh3USLKCY7lSGLQ7UI3DA9mz0L%2BVP5wLqxi8s%2BaZRHqIpHZX0hAE9NljlPaf%2FK%2F3Z%2FrYqqal%2BS%2BoXb2EYvraWG3kcyvLG3IRuwY%2BkgPFW2PfJjZ%2BRruwuFa21iRYFACKFKsKf6r%2Bmf%2BReTUDxy6Yqo20LQQpE8rzso3lkpyb58QBi2bNirs2bNirs2bNir%2FAP%2FT7%2FmzZsVdmzZsVdlEA9cvNirzb8zvIf6bhOu6REP0tbL%2B%2BjUb3EQ%2FZ%2F4yp%2Bx%2FP9jOHagvqWsMw%2B1ETGwPWh33z1znI%2FzL8hqEutf0qP4JRzvrdR9lwR%2FpCDw%2F37%2FweRnGxTtNBreExw5DsD6Sen9F4gpphto2prYSSQ3Ketp11RbyAiu3QSoP50%2F4ZcK5YzG5Q7eGPEUyRpMykRSEhH7MV2IzGAkDY5h3OSEMkDjyCxL8beaZaglxoOpxTW7qLSWkmn3cX2eJ34nx%2FwApclMsen%2BcdIeC4QCZQPXjH2kanwyxe2RjT7%2B2e0bRtVHLT5SWhl%2Fat5Ozr%2FxWx%2B2uJWtxe6HqSw8wtxDvBL%2BxLGegP8yOMyceQEbcuo7nnNVpZ4JmMtwd4y%2FnD9bENU0y80C%2BazuRyTrHIPsunZh%2FTKil4kSIaj%2BGdZ1HTtM846SXUenKv2gN3glp1%2FykP%2FD5yO9s7vRb2SxvU4sh3I6MOzp7NkyOo5OKmSuGUMvQ9MMdF1m40S%2FjvoAHUfDPA32ZIz9pGH%2FDIf2Gwjt5Qh3%2Bw3%2BdcFnrir0GW5Kyx6hav6ltfqDHddW5Dbi1do5V%2Bw6%2FzZLPLbQ6nP8AWrpAby3oJGI2kXqkrfyyqR9rOU6HrKWHq2N8Gl0y6p66Lu0bjZZ4v%2BLF%2FaX%2FAHYmda8p2i2tk8sjrI7miTITxkj%2B1HJQ7huJ%2BLJR3K3snuq3fo2ruoqQC3idvsgD%2FWpnMJ%2FJ%2Fme4Msq2jC9tuUaXcXER3drJ1japH72NW%2BFmX%2Fit%2FwB5nTdIksyzW0c%2FryxVZgzBmCsa4eCZAKHDIWgbPDvK9jquh6xaW%2BtW81rDL6lozTKaFJQVAB%2BKtfhwvs47myvL%2BNQfTs2kD9UK8gQKlv2Xp8StnR%2FzQ1GW08u%2BlZO0d3dTxxQshKsKHm7hh9jiq%2Fazi6MxEiI5YOa3NyxJMjVrux%2BIrlctmQ3TS91E3jCG2jHI09R1qOdOgFf91r%2Fw2CLKFYxyJBIFZJOwHgMC2NryG3wRnq56t%2FZhusZiihu7cMWt5ir2zpyikUAU9T%2BYcuWR5pdPqiacQrWqXCzR1USVBAb%2FAHYp%2FnwutdVhtdTa%2FgWVBOAk8BcNG9BTqyk4c6rc2dxe2F3c2kcKJGI7qx4kUjpyR0B6Vr%2FNhBqc9haSxpHERaXRaWIt%2FuvcoTRa75PlyQn%2FAJZvYI%2FMUS2SNELiVTEygUjnVW9OlftI8hVWVsnSXVxfTGS6laSViCS2wodjsNs5%2Fo8rrL69qwd6pIrqAw%2Fd%2FYPw9OmSua51GVJ762swQXLCD1AiryNQrMfi2%2FyVwxKkIjW7%2BezjR7PTpr%2BUbv6WyUH8zfa6duOEPnjT7SEWmrxxkSXatazowA5KY%2BScgD9qIrxwQ3mPX7EetqFhAtqPtegzySAewA45F%2FMHm1dcRIGjMdvC%2FqRIKcuVCvJ2%2BR%2BzglLY2yhjnLaESfcEquburW8M5HpzKvIr1FaDl79cRbRr6S8%2Br245GCoac%2FCjKp67%2FwAww%2F8AL3li01qBLgPJO8f7t4wP7s%2FsE9fhOHer%2BVtfgg%2BvabcJe1FJrPjwZVUU%2Fdy%2FR9llyIFixuEzjKEjCYojmGM6jaajZ28RjBiEisJzULTi3iSKR0wboHkTXdWt21OLT5ru2A5RlN1k8SrsVWT%2FAGD5ena1aXA%2Bo6pD%2B9J2WcenL%2FlBJR8D%2FwCrnSfy880W%2Flyzl0m7uJZtJR%2BVmXSsltyNXhYD7cP7ScfiT%2BXDXcxosR1D8rvP2qWUdlZadHZW7kPcPcXEYeSn2EKR8%2BKJ9rh%2FNkRu%2FwArtc026ey1FooJo9yKs4IP7StQclz0brf5jeXtKhR7eYX0sieoiQHYL29Rv2Cf5T8WQ7W%2FMj%2BZrOKd0t1Ct%2B6eDk7xMaj05CaNxb%2FVwEgCy249PlyECMefJ4235fXQ63Uf%2FAt%2FXC7VvKsmkfV7iab1dPlISW7jTeFz%2BxJHWoPg37edQ5kyNDIvpyx%2FbQ%2B%2FQg91OB7hFCurIssUq8JoHFUdD%2Byw%2FU2IIIsMMmKeOZhkiYyHMF5g%2BhCNipcyFf3nwD7cH%2B%2FoT%2B1x%2FwB2J%2BziNyW01%2BNseVtMoMc4G7VH82TCbyxfWMxtUMlnDIPrOli55JIh%2FwCK2ZeMqthYYOMVxBNb%2Fu2HK%2Fsl6JU7Xlp%2B1xDfbT%2FdeFgmPknW7q0eC%2FsZ%2BOoWTck5ftRnrG9PtIfstnatY0iw%2FMfQ4%2FMWh8bfXbdSjxnbmyD47S4%2F5ky55gWcaZqDPp1yZo42Ppz8SvIePHOn%2BTfO2qaXML%2FSHiPqcRf2M9fTYf78Xj8XIfs4qoWsGsQ64Tpp%2Bo31zGbK9WYfFE8Z9TceI4FP9lnpNbWDVdGit9RRbiO4gT1g3QkqCW9jX4lzksE1z5382DU7WzEKoqq5UVAoOIeV9uR%2BL%2Fgc7RDGsMMcS%2FZjUIPkopj0UvHtQ%2FKnV9H1F9X8vXCajyYt9TuQoYLSijkx9OTj%2FlcMS8q%2BaLny95guoNYs2s%2FrfEXsLLxKyJXjLH4pxOdpwl1zy1p%2BvCOSctDcw19K5ioHAOxU1HxJ%2Fk4otNoZYriJJoWDxSKGRh0II2IyF%2FmN%2BXll550z4OMGs2oJsLynfr6Mv80L%2FwDCfayU6RYNplhDYNMZxACqyEBSVqSoIH8uDj0xV8NappV7pd7Np%2BoQNbX9qxSaJuoYfrr9pWwuSNg4NSHBqKbEHxrnrL80Py2g86WX1%2BwCw69aJS3kOyzoN%2Fq8x%2F5NP%2Bw2eXm0q8guZoblGglicpNA4pIroaMjfy0OKvpf8lvMusa5ol1ZazOLqXS3jiiuTvIyOvJRIf2ylKc86eM8y%2Fk35usfK2r3FtfyMtjqoRZZ3qRFNGT6bP4IQ7I%2F%2BxztF1%2BaHke01SDR31aN7mZ%2FTLRVeKNu3qTD4F5dMVZlmylIZQwNQdwRuMvFXZs2bFXZs2bFX%2F%2FU7%2FmzZsVdmzZsVdmzZsVdjXVXVlYclIIIPQg47GSOsaNI5oqgsx9h1xV4R%2BZvkA6VK2r6VH%2FuPlarIv8Aulz%2Bz%2Fxjb%2Fdf%2FA5EoJLK%2FwBFh0yOJU1AyrH6oABboqJItebtyJkjZP8AKVs73qnm%2FwAsyW89les7xzwtSMxMRKG%2BHghpx55w%2FwAy%2BWpbIHWNNjeGKFkDjlVw5%2BIPGwp8S%2FtcfsZGUauQHvdvpNWJxjhyyMZA%2BiXQ%2BUmMXNtcWVzJaXSGOeJisiHsRtll1uLf6rcMeKb20vVoW%2F6pP%2B0v7GHsLr5ptvq7mOPU4ElmEhHH1eCII4kp%2Bz6aO7%2FtephBNBPbytDcRtFNGaPG4oR7EZVKJHrhz%2B92JjDPA4cw3HMdR%2FSiiNG1m7028EiEC4j%2BGWMn4JU7qf8AjVslmvaBp3nLSFvbCiTKCY2P2opP24pKfs%2F9d5BTFFIys5ZGX9pKch9B65JvKmrSaVdevxea1m%2BCcEFQyj9tR%2FvxMtxZBIV8x3Oi1eknp5Ud4n6Zd%2F7XmskVxp11JY3sZikjbiyHsf8Amk%2Fs4caPay6peQadE6rJMwVXboF6k%2B%2FEDOn%2BdPIkfmSyGp6QA12qc4JFpSVPtcG9%2FwDjfI35a8qzaFNa3urKrXLmscfI1gP7NSv2n%2FmywxouIN1DWPKDW95DY6K0t5IfgnaUKgD05cl49I6H7TZ0bynBAmmjSVvhcz2qEM60%2BHnVRw9om%2BH%2FAFsItfhndg1q%2FpNdxmIuDQVU%2FECf8oYReSLk6R5nWBw1bmT6sSD8FGBb4h%2FNyXDyPvbsWITE9%2FVGJkB30jPKV1PpOsrBduRLFcPb3JY9VditW%2F2XxZ0%2B91O2spIoJWL3E54wW0Y5SOf9UdF%2Fmdvhzm%2Fm2w%2BoeapJlBVdRjWdCDsZE2cfeuHdvfQW0BngZptVvEH1u%2FlG6gj%2B5hH7Kr0xHc0pD%2BYg8wa1NDFZWjSWtsrCRoiGJcn46b1YdF2yFWemzxsW1CN4Ej%2FZlUofubOs2WpxpNGl2oMP2eSbEe5yTXGkadqFpJaT26T2860YEVBB6EHx8MeCzdpunlEtpHYQ38GqRrFNaPA8EgJcFa%2FGqhadao2XBGlmbe2uCzevbGeRo2PcNJx%2F2S%2FDht51s3sLpYLoH6ncIq21wRU1UceLt9Hxf8Hhj5f8pXerWc%2Bq2VrHqE1oqQWdvNLwUoijmJB%2FO9W4%2Fs8cjVH3LezEvM2mXWqyabNozB7SS1WJ5SwBrHWnLv8A3ZUbfy4onlazmtrKC%2BJlNoHFFNFbmQaHvtTJ9rPlzU7GOO6vrRbeNioQQMrRxmn938IXj4YE0fQLnXBdQ2062l1CP3SSry9Xav7og0%2F4LDsikps7C3s1WK2iWJB%2Bygpg5lNOX0YAVr7TL0xXsxcxsVlhktwpFPtLVWwbf%2Ban0e8tp7LTYrmyILlpyT6hoRw2%2Fu%2FTbdlw3taoK4v7a1dY2dW5GjQ1qVHj%2FwA24Vah5a03VlNxZEQTtvyX7LH%2FAClyfjyfo3nrTrbV9PRNI1i6gM8qRENC8gb05OUI%2BNR6nR1%2F4HIRqOj655Vu%2FQ1SBogT%2B7mU1ikA7pJ0%2FwBi3xZGwdizhOeOXFCRBSPSZNX8maml1MhNsfgldPijdD1H%2BS37S8s6ZLrEEZt2uEe1W6VWtLsg%2BlKGHIGOReS%2F6wOR9dWtRp11dSQ%2FWHt4Wk%2Br93IGyU%2Fysk%2Fk%2FW5INATT9Z0eAWczGT6gr%2BoIlfcgBxsf2vT%2FAGMYxMSeE2D07m7PqBmjEzjWSO3EOUo%2BY72M%2BYfLcd3FJeQRxyo7EzQU792GQ60bU9Hkf9HTAwts1jdVeNl%2FyX%2B2n%2FEc7ZL5XstVSS58p6kYZqVbTrysif6tWPrRr%2FspVzmuvaDq2jzsup2JtA5NCfjtmNf91Tjb%2FYyccJ8tmgJPqV4JJLJpI3sYLqJ2uY%2FtBgP91q6jpIy8Vw0sNNn8tG11m8KWNnqTrAums5YhTvyct%2B0R8fw%2FYb%2FWwLdRpfaVEkkPO50r1HhjJALRSg9HpX92%2FwCzgSW4TV9Hga5uppdVspFt7a0FOMNshHJm3VuZY8fV%2B0zfBlZHq3BNigOnm52LIfDHCYwMCJmVXI8IqMYnzI4f85l%2BsRQc7eSKVRPHKts4ruUkPAcv9R%2FiwbZaY1p5gtrHUoipjnjWZOo4lhRv8pGwcPL9pcROZo2S6ZkaXgyqoaFVk4hn%2BJ9uPqNxwVrmsWupvYzalF9S1K1lTi6GscsYYMpV%2FFWUNx%2FlwYoSjd8jybO0suLMcUsdmUQROxRrnH75PQtd8vaT5itBZapAJI0YPE6njJGw%2FajcfZzg%2FwCZWh3GhW%2Fr2wH1vSZ0DXlPia1m%2FuZuK7MV%2FuLj%2BbPQ1pdR3ltHcxGqyCtOtD3H0HIF%2BZFnb3k8EMqhxPBJHOh6MnIUDfSdssDq3zfqWmR6lFJqenRCO6iHK%2Fsk3FD0ng%2FmjfC3SNVudJuUvrKQJdQOrxc1DoafaSRGqrK%2FRlyU32i3XlnU4RHOYrF2Isr1hy9Jm%2F495%2F8AimT%2FACsKte0Zp%2FW1Kxg9KaL%2FAI6Nipr6bH%2Fd0X88En2lfFX0%2FwDlz5x0fzbpAlsIYrO%2BgAF%2FYxBVCOR%2FeIBTlE%2F7Lf7HJpniLyz5m1TyrqVtq2ly8ZYzuvVWX9qOQftI37WeufJnnHTfOekJqViwSZaLd2pNXhk7qf8AJP7D%2FtYFZJmzZsVdmzZsVaOct%2FNj8sx5ntJNb0NfT1uBayxrt9ajUfY%2F4zqP7tv2vsZ1PKOKvhz0CsbwMzqSSHPRgw2%2BL3%2FmwrlheB%2BD9exHQjxGeqfPH5Oad5lupdW0icabqU3xTqV5QTN%2FOyr8SOf2nX%2FgM59H%2BQfmu5nWC9ns4rbl8U6OzMB%2FkpwGKr%2Fyk%2FOBtOMPlnzTMWsyRHY6g5qYq9I5j3i%2Flf8A3XnoxWV1VkIZWAKsNwQehGc68sfkv5Q8vBZriE6rdrQ%2BpdAemCO6wj4f%2BD550VVCqFUUVRQAbAAYq3mzZsVdmzZsVf%2FV7%2FmzZsVdmzZsVdmzZsVdiNzNDbwSTXLBIUUmRj0A98WwNfPaJbSm%2BKi2pSUv9mh2pirAPON5pMWiStoiPJfM1bVI4yy1G8jDkCnwrhDrD6jFb%2BWbC7Wt36Ecl%2BCP%2BKiZHbtyJajf5WDvP9xZRaNCfKtxKb4zj04IOR403JKkfAOfH%2FWws84ajNd3EEklFuSOUtK%2FDRVXiKduQOFIeeatpk0F5PeaUj%2BlATLIYwSYhXd%2Fh%2ByleuLP9U12ykmiWO2vrWOW4n3PxgcAFXmaty3cf77%2Bx9jO1%2Flvo0EejT388SvJqDMjFxXlEvw8TX9ls5h%2BY%2FkSTyne%2FpHTVY6LdsVUj%2FdDt1hf%2Fitv91t%2FsMgRW4dxo9X4vDiySqcfon%2FO%2FoyYJsQGHfJL5FsrXUdZk0m6uTbR3UTvHQAgzRjkONSODla5GgcX0%2FUJNL1S0v41DPFINm8G%2BE%2Frym%2BHMD0k52txeLppjqPUPfF6l5X8xWlm995evZlguLSdkjR9gTWjrXovP4XTEPM6wwzKSKCT4tuoIO%2B3vke80xXU2tW13ZQ%2Bo15bq8npJ8UlELVp%2B3sMBWOsXOtWy2iEyXNuCyIw5Myf8VsaseFP7tvizL4tq%2BTzNUfvT%2BOU6npky9ZrciVAO5Xw%2Ba8sis01rp%2FmC01O5YrSWJ4kXcyFiB9nsK%2Ft5fljzLXzMlg0bRQujQESbVlDcl5IenL4kyeebPIp8y6j5e1DSEjX0XWO4QsqKYk%2FfRgV%2Fb5gx8cHMe5lGUom4mjuPnzSW%2F1OfVL6R7sJW2keKFUGygGhIJ3PKmNVy%2FTAk1pdWc9zBdrwuElcTIezA%2FEMj%2FmjXbvQtaW3tEBgCJM6PuCHFQExtizSKI1DHJv5VuxKrWMp%2BwC8JPh%2B0v0ZCNLvrfUrGG9tjWOVQfkf2lP%2BqcPdHme3vIZV24sKn2Ox%2FDJBSyzzBplrqWnSQSxLI0P76EsoIDqO3%2BsMgmlaxceUdRXU7ZS9jJRb62XoUP7QH80f2k%2F4HOgXdyVYgHp1%2BWQW8g4TzQyoQpJIVh1VuhGJCh7FG9hrempKhW4sryMMp6hlYV%2B%2FOWa%2FbXfk%2FU0ZJOEL1ayu2%2By1P91udv3if8OuCPJ%2FmhPL1xaaJetx0y4rFFMx2imJJSvhHLXj%2Fr4N%2FO9G%2FwAJ28o%2FYvY69%2BqOMgdlYzqPmWy8xr615aouoxAA3dk4dJB0%2FfRGjofBl54U%2BnCySRNSa1l%2B2vQq3861%2By65GPKcztqxjY7NEw4jYbU32zoNppF1qfrw2JX6yierHExoJivWIf5fH7DYYnZaY3pN9N5N1n9JJEbuIwyRoisY1kDbpVu3F%2FidM7xpl3Y%2BadFt7m5tle3vIUkaCYBx8Qowof5WB%2BPONG0jvLY28qlRUgqwoyOOu37LpiXl3XbjyZqk7XglmtZIfTEKNQGh5REFvsxr8XLjgIrdWQedvy7GiQPrfl4SNaxVe5s1q7Rp3ki%2FaaNf20%2B1kT07WGCqwcMjdJFNQc9C2N9BqNvHc29WiljSVGI2KyCopkFv%2FwAotHu9cOq2d1JYW0x53dhAo4O53JQt8MYf9ocMFyB23ZwGOQIkeCQGxqwfIsatNQSQrIrmOUbrIhoQfEEb5LLHzPP6X1TV4RqFo4ozFVL0%2FwApD8EmFms%2FlxeWBNxoEpuIhubSQj1B%2FqPsHwo0%2B4ltUmW7Ro5ojRo3BVhT2OWCi1t%2BbPJ1pFCfMXlJgtl%2Fx92VCyRHuwjb4kX%2Bdf2ciOlG2huhcX2n8JI2BE8FHHzMTb%2F8TVc6FpWutaySPblJEmHGeCQVVwP1ZGtcsIbe5N3p0Ui2MlWaM7mB%2FwBpQ4%2B1F%2FLkTGulhnDIYnYprf6tYaxaxxCDlxIaG7iko8Z7kGtWr%2B3ywxsdGl1WwitzGbkgkRzugDGnRm34R0%2FZbIJBZwxv9YhAVx8Qp0JPiBnafJl1eXekLNdyrKOXGNgADQD4g3Gg%2BE7Y8WyTLfiHNJbbQvNHle%2Fe50eQX%2BnXAD3Vg53EoWnKImhQmn7Pwv8AyYRX9xql1dmXWOS3XHiqMnp0QEkKq%2BA5fazrQwHqOmWmqQGC7j5D9lxsynxVsFsLeO39hb39tJbXMYlhlHGSNuhB%2FUffOZXy3%2Fl7UV05n5MgrpN1LTjLCT8VncEj%2FYf5Odt1nQbzR3JcerasfgnA2%2BT%2FAMrYB%2F5V3Y%2BdtAvhefubrn%2FuNux1jkQUYkD7Ubnir%2F6uEq8D1rTFk9XUdNgaHix%2Bu2XVoHPcD%2FfbfstnQfyAeb%2FFktC%2FptaSF1VgFNGTiXFfiA%2BLj%2FlZC9WuNd8p6kNM1e04anYsY2mY7TW%2FZG2pKjfsS4K003mkCHzl5WmDLazercWoB9WCvX1FB%2FeQt9lv8nIofYNRl5FPI3njTfO2li7taRXkQUXlp3Rj0Zf5on%2FYbJXirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FW7%2FmzZsVdmzZsVdmzZsVdgHVY9PmtHi1JlW3cgEuQBUbr1wdgPUdNttTtzb3IJWoZSOoYdxirzHztP%2Bi20aTyvdm6uDcJSCMJIPTVhRWKj7Bbbi2B9b8keZrnV3FvberbsQsVwHUKFJ6tU8hSvhk%2B%2FwAPGy1GwvLOkqK5ju0cIP3YQ%2BnItAPiif8A4nkkphKQaQOk6eml6ba6fGQVt4whPif2j%2FwWO1LTbPVrGfTr%2BITWtyhSWMjqD%2FEfs4MzEVwIsg2Ni%2BVPOHlm58p65NpU1XhP72znP%2B7IWPwn%2FXX7En%2BVgW28s63f2kWr29m76Ys6xyXQpxUggNUfa4iv2uOen9c8t6J5it0t9as0uo4zyjLVDKf8l1oy5EL7TriGW30Lytp7Q6Dbs0d7xI4Oz%2FFWPlycmNvib%2BfKziufETs7WXahOn8Ph9dVIn6a7%2FewDzPd3ukNplzYtxtEhW2adVBKzRktTkalOdf%2BBw60bydZ%2BaNR%2FwARaPq0VjOIw509bcLIkw%2B16yh%2FjRm%2F3an28de6dLYTXGk6xDztpx8aHoyn7Lqfb9nI3YX%2BreQ9ThS3pcWhcvazMBWSE%2FbgaQ%2FF8P8AJlrrDvunvmryB9buFvzAtnrkQD84z%2B6mKHkGRtu%2F82HWnO%2BoadLpU5aC4ZeUL9Gil%2B0jKR0aOYZOLO80jzho0d3Zv6kMn2WFPUhlGxVh%2By6H7WQWaO80rV1hvwBMjcfUAoskTbLIP%2BNsIr5oSu10tfOt7Ikt4th5ijQC6hkSsdz6fwfWIiCCr7UmTj%2Fl5JG%2FKTSdTjg%2FxDILh4UCUgHD7P8Axafj45GPMdkYtRkvbWf6jewEXNhcr9ppT9pEVatJWnxJx%2BznRPIfmz%2FFujfW5Y%2FSvLZ%2Fq94gBCmQCvNQfiVX%2B1xb7OA2NleaX%2Fkr%2FA19Jb2rO%2BlXbc7UvuFbuvL%2Bb%2FiWC7M7HOuarpdrq9jLY3i8o5Bse6t2df8AKXOP6jbaj5dvpLK5USBd0fcB07Ov8cMT3qkP5l6trkWp2kNi8sVr6CShoyVDyH7RJHXj8OQpfNfmCN1%2BsXcsnBeCrOfUAUdFHP4uP052ny%2Fq2g6veR6T5hgX94Almsp%2Fdsw%2F3W%2F%2BU37GSHUfyp8n6hUpavZse8DkD%2FgH5p%2BGCXNeTwM%2BbzeWxtr%2B3SVHFGMZKMP8oBqr%2FwANh9qv5gpr3kVfLV9zk1O3uIjFOwrzt4w1GZhUeqn2P8rJD5i%2FJJrK2lvNKufrSx%2FEYCnCXiOtCpKPx%2F1M503lq7tpDxDNUUUGlPwyJtWQflfpMWseaFtLgssZtZnDJ1VhxCn3651e38qanp%2Bs2ZX95brKG%2BtR7UVfio6%2Fs16YS%2Fk3pGmWxvNR%2BspJqfEW7WnR4kryLFW3PqN%2FL%2FLnW8I2UsW8x%2BVo71n1LT0CXp3mjGwlp3%2F4yD%2Fhsgl9oyXUaxX1u8LoCY2dStV%2FaG%2Fgc7JTEbiztrr0zcRrIYmDxlhWjDJCXQoeVeW9Rv8Ay1PKL25kuNO9ELEo%2BIjgaoKk%2FAqJyzqtrdQXkCXNs3qQyqGjcdCCK7ZFPMPl1Yg95aLWA7zQjfjXqw%2FycB6JrNzY3BW7uAbARKgUqSQVIC8KfCq8K8vhxq9wlntK4DvtJ07UgBfW6TU6FhvTwqN8FRyRyoHiYOjCoZTUEHH5FDC9Y%2FL6wuSZ9Ic2M3X0tzEfo6p%2FscL9B%2FLy8XVJNS8y3Yuo41aKz0%2BEkQrGwoWlO3N2zomVTDZV4l5n8s3Plq94oS%2BnTk%2FVZj27%2Bk5%2FnX%2FhsMNI893Wj2ht2thNVSEp8PGSlBK%2F%2BSf286nqOnWmqWcllexiSGQbg9QezKf2WGco13yhdaVMUT95A39zL0DDwPg%2BIZc3pPlzU5dStGa4IaeNgGZaAFWHJWoMOc5v5E1B7Wf6tcAoD%2B5PLb3jP0fYzo4xIYrZIo5UaOVQ6MKMrCoIPtidrZ29lAttaoI4UrxQdBU1OL5sCsO8%2FwD5e6V5708RXNINQgB%2Bp3oFStf2JAKc4m%2F4XOIWX5R%2FmVoOpummwIySAxNMssZhZG2q3Mqen80eeoKZqYq8l8h%2Fk%2FceW9Qt9Z1DU3W4gPJLS0JCEGvwTytT1U3%2Bx6arnWs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F1%2B%2F5s2bFXZs2bFXZs2bFXZs2bFXUzZs2KuzZs2KoXUjILG49E0k4EKetK43TYkhsoQp5EqGZvEnvgp1DKVbdW2I9jhDdaDqT%2FuLLWJbOzP8AulEVnAPVVkb4hiqB8wWUXmS%2BXTYWQi3ikZphuUlqOKmn7P8ANnOtRsiPW0TWUKqD9ofajYfZkQ%2B3%2FDLnYtH0Wy0W3aC0BJc8pJHPJ2J8ThV5u8tJrdoZrdQL6EH0z0Lj%2BQ%2F8a4bTbxXQPMGq%2Fl9r7mSs9jcUN3Cv2Zo%2B1xD4Sp%2FzZnaNYhtfNmgRaho7JcMwE1pKCASP246%2Fsn%2BZf58gsugWWtaPFp1xRL21qFkFCyP3U96YR%2BUfMt7%2BX%2BqvpmqEtpUsnGeOtQjE0FxD%2FwAzUxOy%2B5kHmGCOa1s7%2BVeEsFYpHI3SvwyBvDi647RtH1by3qEXmPT5VlgnWmo2C1Amj6rIrH4RMnVcCz3FvJ5x1pIqX2h30cVy3ouv2nQEeka9XZW5ZJNPult7dbZpTLasP9HlYUalP7uVf2JlH2v%2BEw891ZzY3tvqNtHdWz84pBUHoQe6sP2WX9rC7zJoEOu2Xp7LdRVa3lPY90b%2FACHwi0IahBqtdOo9hKf9LjY0Vf8ALU%2F78ybZFD591jS3R3gnRo5Ymp4MjA9snHkr8weRi0LzJII7pQEtdQc0SYdFWQ%2Fsy%2F5X7eH%2FAJw8uLqMDX9qg%2BtRL%2B8Uf7sQf8bLnJbuyjcNFKnND1U%2Fw8Dh5pfQo3Gc487eVFhMmq2KfuHNbmNR%2Fdsf92KP5G%2Fa%2FlyPeXPM%2Fmfy2Y4pmk1PRqfBBKpNwiDr6E3%2B7OH8j51%2B1ubXU7JLiKklvcJWjDqrDdWH%2FEsV5PntoFiuUuQOFxFvHKpKsPpWnLJZ5b8w65p1xEguXuIp3q8d07P1%2FZVm%2Bx%2Fkccbr%2Bhm2125sbPggX95AZq8FRhy3p%2FL8Srk181aDHqempqtvRLu2hDngPheMDmV%2F2P2ozjsrKLW5ju4Eni%2By4rQ9Qe4OL5D%2FACp5hgu7iOwkkUXFxD6yx9DWM8HNMmGJFFDRFRQioPUHIhrmgrAXubdK2z19WOleFepH%2BRkwymCkUIqD1BxBpWIaNq09o31WURrZoiem32ePEheCIB8VV%2BLJcGB3BBHtka1LQXVne0XnC9eUQ%2B0tevHxXA2lxazHfW620rx2atW4gkSqFOPCgdvjDClVwkA7hWYZswzZFXYnNBFPG0UyCSNvtKwqDimbFWE6voE1hIbu0Be3BrQVLIP8rxXJRo92b3T4Z2%2B1Ti3zG1cGkAih3B7ZSRpGvCNQqjsooN8NquzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxViPmbyo91cfpvQiINVT%2B%2Bh6RXSD9iXwl%2F33N%2FwWQzW9AXXo%2FXaFg7L%2B%2BhK0mjdBuafzACjrnYcDTWNrPKk8kYMsZDI42NR40w3tRW3z1p2l6ho%2BotLAfXVE5OgDVljA%2BLj%2FxZGv7OS2BbeaRbscpI5YuLQq3ETIfiQcv2ZVP90%2F8AsMk3mi1FjqBnt0CpcIHIUU%2BNT8RFP5tuWRDTFEulwPaP9YjVSfVjBIFGPM%2F7BvHCOSXqXlu6trnTI1t7Y2Zj%2BGW1YhmQ%2BJcfb5fzYcZBPKl1I7GRXHKGi3AY%2FajPRvdsnQNd8BFFDjnL%2FPWhJaXguIKRw33KngklPi%2F2Pxcs6jkY892Ul3onqwoZJLWRZeAHIlT8D7fJsAVBaLpUeueS9PtriYPcWykQXkfZ4yVDD%2FJP2WwX5X1NJ2NrQIGXkoXpzQ8JP65GPJfmOTR5G0zXLmGCzlYmzhZPSeE05ceP7UTjfliOhagkWs3CW0gkUXbPZjoZVkY8kQHr8OSHUJZD540vmYtVRBIAvoTo260JrGzU7cvhzaJ5jgm0t9O1u7giu%2FRdY%2BJ48oyCg%2Fd9QyfZ%2FwArJhPBFcwvbzqHikBV0PQg9sgt%2FwCSLpJy9pxniPRiQsgH8rfzYB5ql%2Fkq1hXU4ZigNwjsizftemU3Uf5Jzp%2BRXyloF%2Fpj3FzqYiR3YraxREsyx%2FzTOaL6j%2Fyp8CZKsSUOzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Hv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVg35iPrMEFld6XbR3CRM%2Fro1fUIIHwx%2Fs4U%2FlrqOkz3c1lYQmENFJI8DCgRzIDIg5b1JavTOiajZLf2cls1KsKofBh9k5ydpJPL%2FmzT9ZcBIWY2t5sFoD8Ls5C1%2FwCDkyQ5KyjWdLGi6ml3brSyvKxuo6I58P8AJPVclOiXZurPi5rLAfTf5fsn7sE3drBqFq9vLR4pV2I7dwy%2B%2BF2j6Xf2F5dS3EqNbyhViVa8iV%2Fbfag6%2FZXBdj3KnWURXLzYFYV5n8n3us6ut7btEITGsbc6hl418B8WFd75Ym8svHqVqPrQiCsJSPiikH2jQfsNnScayhwVYBlOxB3BGG1Sby7rf6YgZ5KCZftIBSmHeFllodlp95LeWqlDMKGIfYB7kDDPE%2BSuzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F%2F0u%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZFfM%2BipLW%2BSJZAf71CtaMPsygf8SyVZRAIIO4PbCDW6pP5YvDd6Wiu1Zbc%2Bi%2B9Tt9mv%2Bxw5xG3tbe1Vlt41jDHkwUUqfE4tgPNXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Pv%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV%2F%2FZ');background-position:center center;border:1px solid #0a0}.yui-skin-sam .yui-h-slider{background:url(bg-h.gif) no-repeat 5px 0;height:28px;width:228px}yui-compressor-2.4.7/tests/dataurl-base64-singlequotes.css0000644000175000017500000024536011640627104023545 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml, .yui3-skin-night .yui3-dial-center-button-vml, .yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min, .yui3-skin-night v\:oval.yui3-dial-marker-max-min, .yui3-skin-night .yui3-dial-marker-vml, .yui3-skin-night .yui3-dial-handle-vml { background: none; opacity:1; } div.base64-singlequotes { width:100px; height:100px; background-image:url('data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAgEAZABkAAD%2F4RfJRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAeAAAAcgEyAAIAAAAUAAAAkIdpAAQAAAABAAAApAAAANAAD0JAAAAnEAAPQkAAACcQQWRvYmUgUGhvdG9zaG9wIENTMiBNYWNpbnRvc2gAMjAwODowNzoxOSAxNDo1ODowNQAAA6ABAAMAAAAB%2F%2F8AAKACAAQAAAABAAABwqADAAQAAAABAAABRQAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAEeARsABQAAAAEAAAEmASgAAwAAAAEAAgAAAgEABAAAAAEAAAEuAgIABAAAAAEAABaTAAAAAAAAAEgAAAABAAAASAAAAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZ%2F%2B01IlBob3Rvc2hvcCAzLjAAOEJJTQQlAAAAAAAQAAAAAAAAAAAAAAAAAAAAADhCSU0D6gAAAAAYEDw%2FeG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8%2BCjwhRE9DVFlQRSBwbGlzdCBQVUJMSUMgIi0vL0FwcGxlLy9EVEQgUExJU1QgMS4wLy9FTiIgImh0dHA6Ly93d3cuYXBwbGUuY29tL0RURHMvUHJvcGVydHlMaXN0LTEuMC5kdGQiPgo8cGxpc3QgdmVyc2lvbj0iMS4wIj4KPGRpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNSG9yaXpvbnRhbFJlczwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1Ib3Jpem9udGFsUmVzPC9rZXk%2BCgkJCQk8cmVhbD43MjwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgkJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNU2NhbGluZzwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1TY2FsaW5nPC9rZXk%2BCgkJCQk8cmVhbD4xPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCTxkaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q%2BCgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCQkJCTxyZWFsPjcyPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsU2NhbGluZzwva2V5PgoJCQkJPHJlYWw%2BMTwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuc3ViVGlja2V0LnBhcGVyX2luZm9fdGlja2V0PC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BUE1UaW9nYVBhcGVyTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNVGlvZ2FQYXBlck5hbWU8L2tleT4KCQkJCQk8c3RyaW5nPm5hLWxldHRlcjwvc3RyaW5nPgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk%2BCgkJCQkJCTxyZWFsPi0xODwvcmVhbD4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD43NzQ8L3JlYWw%2BCgkJCQkJCTxyZWFsPjU5NDwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNUGFwZXJOYW1lPC9rZXk%2BCgkJCQkJPHN0cmluZz5uYS1sZXR0ZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk%2BCgkJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhZ2VSZWN0PC9rZXk%2BCgkJPGRpY3Q%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD4tMTg8L3JlYWw%2BCgkJCQkJCTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTk0PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLnBwZC5QTVBhcGVyTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BVVMgTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5BUElWZXJzaW9uPC9rZXk%2BCgkJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC50eXBlPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvVGlja2V0PC9zdHJpbmc%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuQVBJVmVyc2lvbjwva2V5PgoJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnR5cGU8L2tleT4KCTxzdHJpbmc%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXRUaWNrZXQ8L3N0cmluZz4KPC9kaWN0Pgo8L3BsaXN0Pgo4QklNA%2BkAAAAAAHgAAwAAAEgASAAAAAAC3gJA%2F%2B7%2F7gMGAlIDZwUoA%2FwAAgAAAEgASAAAAAAC2AIoAAEAAABkAAAAAQADAwMAAAABf%2F8AAQABAAAAAAAAAAAAAAAAaAgAGQGQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4QklNA%2B0AAAAAABAAZAAAAAEAAQBkAAAAAQABOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD%2BAAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNBAoAAAAAAAEAADhCSU0nEAAAAAAACgABAAAAAAAAAAE4QklNA%2FUAAAAAAEgAL2ZmAAEAbGZmAAYAAAAAAAEAL2ZmAAEAoZmaAAYAAAAAAAEAMgAAAAEAWgAAAAYAAAAAAAEANQAAAAEALQAAAAYAAAAAAAE4QklNA%2FgAAAAAAHAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAAAD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FA%2BgAAAAA%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwPoAAAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAOEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJAAAAAADhCSU0EHgAAAAAABAAAAAA4QklNBBoAAAAAA1UAAAAGAAAAAAAAAAAAAAFFAAABwgAAABAAcwB3AGkAcwBzAF8AYQByAG0AeQBfAGsAbgBpAGYAZQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABwgAAAUUAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAG51bGwAAAACAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9uZwAAAUUAAAAAUmdodGxvbmcAAAHCAAAABnNsaWNlc1ZsTHMAAAABT2JqYwAAAAEAAAAAAAVzbGljZQAAABIAAAAHc2xpY2VJRGxvbmcAAAAAAAAAB2dyb3VwSURsb25nAAAAAAAAAAZvcmlnaW5lbnVtAAAADEVTbGljZU9yaWdpbgAAAA1hdXRvR2VuZXJhdGVkAAAAAFR5cGVlbnVtAAAACkVTbGljZVR5cGUAAAAASW1nIAAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAFFAAAAAFJnaHRsb25nAAABwgAAAAN1cmxURVhUAAAAAQAAAAAAAG51bGxURVhUAAAAAQAAAAAAAE1zZ2VURVhUAAAAAQAAAAAABmFsdFRhZ1RFWFQAAAABAAAAAAAOY2VsbFRleHRJc0hUTUxib29sAQAAAAhjZWxsVGV4dFRFWFQAAAABAAAAAAAJaG9yekFsaWduZW51bQAAAA9FU2xpY2VIb3J6QWxpZ24AAAAHZGVmYXVsdAAAAAl2ZXJ0QWxpZ25lbnVtAAAAD0VTbGljZVZlcnRBbGlnbgAAAAdkZWZhdWx0AAAAC2JnQ29sb3JUeXBlZW51bQAAABFFU2xpY2VCR0NvbG9yVHlwZQAAAABOb25lAAAACXRvcE91dHNldGxvbmcAAAAAAAAACmxlZnRPdXRzZXRsb25nAAAAAAAAAAxib3R0b21PdXRzZXRsb25nAAAAAAAAAAtyaWdodE91dHNldGxvbmcAAAAAADhCSU0EKAAAAAAADAAAAAE%2F8AAAAAAAADhCSU0EEQAAAAAAAQEAOEJJTQQUAAAAAAAEAAAAAThCSU0EDAAAAAAWrwAAAAEAAACgAAAAdAAAAeAAANmAAAAWkwAYAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZADhCSU0EIQAAAAAAVQAAAAEBAAAADwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAAAABMAQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAIABDAFMAMgAAAAEAOEJJTQQGAAAAAAAHAAIAAAABAQD%2F4TkjaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu%2B7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI%2FPgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSIzLjEuMS0xMTIiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyI%2BCiAgICAgICAgIDx4YXBNTTpEb2N1bWVudElEPnV1aWQ6RTcxOTVFNTY1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkRvY3VtZW50SUQ%2BCiAgICAgICAgIDx4YXBNTTpJbnN0YW5jZUlEPnV1aWQ6RTcxOTVFNTc1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkluc3RhbmNlSUQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eGFwOkNyZWF0ZURhdGU%2BMjAwOC0wNy0xOVQxNDo1Nzo0MS0wNTowMDwveGFwOkNyZWF0ZURhdGU%2BCiAgICAgICAgIDx4YXA6TW9kaWZ5RGF0ZT4yMDA4LTA3LTE5VDE0OjU4OjA1LTA1OjAwPC94YXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhhcDpNZXRhZGF0YURhdGU%2BMjAwOC0wNy0xOVQxNDo1ODowNS0wNTowMDwveGFwOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhhcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1MyIE1hY2ludG9zaDwveGFwOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9qcGVnPC9kYzpmb3JtYXQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOkhpc3RvcnkvPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpOYXRpdmVEaWdlc3Q%2BMjU2LDI1NywyNTgsMjU5LDI2MiwyNzQsMjc3LDI4NCw1MzAsNTMxLDI4MiwyODMsMjk2LDMwMSwzMTgsMzE5LDUyOSw1MzIsMzA2LDI3MCwyNzEsMjcyLDMwNSwzMTUsMzM0MzI7QzA1QTE5MDRGRjAwQUJEQzA1MUJERkFGMDIwNEVBNTE8L3RpZmY6TmF0aXZlRGlnZXN0PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24%2BNDUwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjMyNTwvZXhpZjpQaXhlbFlEaW1lbnNpb24%2BCiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U%2BLTE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6TmF0aXZlRGlnZXN0PjM2ODY0LDQwOTYwLDQwOTYxLDM3MTIxLDM3MTIyLDQwOTYyLDQwOTYzLDM3NTEwLDQwOTY0LDM2ODY3LDM2ODY4LDMzNDM0LDMzNDM3LDM0ODUwLDM0ODUyLDM0ODU1LDM0ODU2LDM3Mzc3LDM3Mzc4LDM3Mzc5LDM3MzgwLDM3MzgxLDM3MzgyLDM3MzgzLDM3Mzg0LDM3Mzg1LDM3Mzg2LDM3Mzk2LDQxNDgzLDQxNDg0LDQxNDg2LDQxNDg3LDQxNDg4LDQxNDkyLDQxNDkzLDQxNDk1LDQxNzI4LDQxNzI5LDQxNzMwLDQxOTg1LDQxOTg2LDQxOTg3LDQxOTg4LDQxOTg5LDQxOTkwLDQxOTkxLDQxOTkyLDQxOTkzLDQxOTk0LDQxOTk1LDQxOTk2LDQyMDE2LDAsMiw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwyMCwyMiwyMywyNCwyNSwyNiwyNywyOCwzMDtENDYzN0NCOUQ0MUExMEJBN0VGNUVCQ0RCNjMxODMyOTwvZXhpZjpOYXRpdmVEaWdlc3Q%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY%2BCjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8%2B%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEJCAgJCgkLCQkLDgsNCw4RDg4ODhERDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgBRQHCAwEiAAIRAQMRAf%2FdAAQAHf%2FEAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPBUtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4%2FPE1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BCk5SVlpeYmZqbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp0%2BPzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BDlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq%2Bv%2FaAAwDAQACEQMRAD8A7%2FmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmrlHI2utXn6WltnFESb0RFSp41WjD5q3LCBaslzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2E2rj0LuzvF7PxftUf8AXPLDnC3XI0ewdpOkTK4P08T%2FAMK2Ec1TLNgaxmE9pFIDy%2BEAn3GxwTgV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F%2F0e%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXYUeZpfR0a4kpUAx19h6i74b4X65CbjR76FV5FoJKKe5C1GIVLdDuGhuXs2IKOX4gfsvGdx%2FskKtkiyD6bctHHbXgPImOC4qOpXj6E1ff4Mm4Ndxkpc770BvNmzZFLs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Lv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVokKCT0G%2F3ZgaioNQemANZuhaWLyE0LlY1%2BbGn6sWspA8QA%2FZ%2FUcVRWbNmxV2bNmxV2bNmxV2NZQwKnodj9OOzYqwDT4iiPZsa%2FVLm5sj7I%2F76L%2BOTXTpjPZQSt9pkAb5r8JyKXqfUvMOpIQOFxFDfoP8qFvTl%2F4Q5INDkrFPAf8AdUhI%2FwBV%2FiH8cnLeAPcxHMprmzZsgydmzZsVdmzZsVdmzZsVdmzYyWRIo2kkYKiirMdgAMVX5sjTeaGl1CzsbSAOLuX0w7k14KCzyAD%2BUZJBirebNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F9Pv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVo4CXUFa9e0CbJRWkr%2B0RWlMHZEJ5WtPMtzE5%2BGYJKnyK0%2F4kuEC1ZeM2IW0okjFT8S7H%2BuL4FYz52mMWn2tDTlcpX6FbDHR5ecCH%2BZevywl%2FMM8dJtn7LdJ%2BKvgry9ccrOJ69KVw9E9GS5s2bAh2bNmxV2bNmxV2bNmxVi3miFU1LSbxvsStJYzH%2FJnSi%2F8ADYpoEzLcxq1T68FGr%2FvyE8GrgjzdC0mhXEsY%2Fe2pS5i%2F1omDf8RwttJRHdrcDaNbhZVI6endIG%2F4mcnHeJCDzDL82bNkEuzZs2KuzZs2KuzZs2KurkZ843Zhs4bVTQzvVqfyrvg3zHNPb2UMsLtGBPGJSpIqjEqRUb9ch%2BvSSvp0JlcvJCLyMuxJb4JNvi%2F1SuEBVvkaX9L%2BZbm8Sv1fTbf0Y6%2F78lPxH%2FgFzpeRvyPbWcXlyyubWBIXuoxJOUG7uKjk5%2FaOSSoxPNXZs2bArs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FU7%2FmzZsVQ2osyWM7o3FlQkMOxGPtZhPBHKCDyUE08e%2BM1Bedjcr4xPT%2FgThV5cvBJbpGergEfMDcYa2PkqfZs2bArs2bNirs2bNirs2bNirshfnRGtb7T9TX7LcoJD2qDzSv3vk0wl81WDajodzDGKzRj1oR35R%2FFT6RthHNXaVcrKsUtftDi304dZz7yrqPrQCIncdMnsEnqRK%2Fcjf54yVjP5gwtJ5ckcD%2B5mik%2BivH%2FAI3wD5RnEtpwrWgw983RGby1qiqKlYGkA%2F4x%2FvP%2BNchnke5BIUGoPQ%2FPEJHJ6XG3JFbxAOPxOA1iX7sUwIdmzZsVdmzZsVdmzZsVUbqBbq2mtm%2BzMjRn5MKZDLP4rC2UVq9qYj7SWshWn%2BtxOTnIVG4ttWvdNaiiK7FxGDtWG6Ti%2FwDwMuShzRLky%2B1lE9vFMP8AdiK33gYscKtBmDWhtq%2FHbOyMp68SeSH5UOGpyJ5pYde3moWPmW5KzH0pIo2WNt0A3Wv0ts2D73zJ6FgzxqqXpKpHG9eDMx7EYXed45VeC4gPCdYyqua0I5q5VgOv2cAW8sWo2QMqhwwoyHcVyQFhVOLzvrNrdf6fFHLFX4kVeBH%2Br1%2F4bJlp%2Bt2GqWrXFnICyKWeJtnUgV3XOP67qFjaFLHUrprecy%2BlZajxPDmN1jn8Dv8Aa%2By%2BIaXrclrdtZ34NrfR1USofgeo2K06c%2F8AgcBCXr%2FlvXRrdnzk4rcoSJFXYfMbnDzOV%2BTr82eqAOQIpaBq7AV2r%2BOdTriRSEp8z8RoN9I5AWJPV5HYD0yHr%2BGQg3Ntq1lcLazx3CiZviiYOKzQo9Kjb7YzoWqRevpt5AOskEij5lCOmc60%2BWCK0j9ONYo5IYp%2BEahQWBeNjRafEcMVTvTb%2B80fyHZ3FugE9vSORJBUqPVZW%2BEHw3yVaXeC%2FsobulGkX41HQMNmH%2FBZzC%2B1iTTbadZUkjtJjzkQqSKqNm5fsdMPfyr1%2FRdT8vra2E5N5C8kl3bSMTKpkctz%2BL7SP9peOA7fFkIkgkCwOfkz7NlA1y8DF2bNmxV2bEJLy1injtpJVWeavpREjk3Hc8V64virs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Xv%2BbNmxVplDqUbcMKH5HIPokjWsstqx%2BK2lZPf4Wpk5yF6nF9R8xswHGO8QSj%2FAFh8D%2Fqrkoc6VmSMHUOOjAEfTjsAaZMXhMRPxRnYf5J6YPyJV2bNmxV2bNmxVQuzOtu729PVUclBFa07U98DafqsF6i9EkI6ePywwyF6vG2i6oJRUWl6xZCP2JOrr%2FsvtLhG6s0yiK4X6Zfi4QI7Vb9lv5h%2FXDHrgV5c8B0LzLc2Q%2BGF29WDw4SfF%2Fwp%2BHOg6ZMHi4j2YfTkZ%2FMGwpFaazGDytm9GYj%2FAH25%2BEn%2FAFX%2FAOJ4N8uXwliicnps305LmFZDewrc2dxbt0lieNvkylc45%2BX10UCQzHjLATE4P%2BQeNc6L55e5i0J57WVonikRmZDSq7jf2yB2Op%2FVYor2%2FwBNjktpAGjv7ZvU%2BInoy8Vao%2Fa44xCQ9as25RVBqKnfBGRby9rBEsljcIY0aQ%2Bg5FCCQD6bj9lslGAikN5s2bArs2bGyOI0aRuiAsfoFcVS%2B%2F1q2sJltyrSytuyp%2ByDsC3zwxBqAfHfI%2Fodmt2z6pcjnJK5dAexPT%2FgRkhxV2c782mSy82WUgNIdUhNs4PTmlXQ%2FwDBDOiZAvzLb6nHpOrlFkjs7lWdG9yvxVG%2FwiuGJ3Up3YTJFr7op%2BC8t1ljHjxodv8AYtkiyHbxx6XfKx%2FcXBilJ3%2BAsVUV8FRlyYA4Z80DkkPmq3EtlHJSpR%2BJPgHBH66ZBtIufqt9Np8pALHnEpO5p1oM6Xq0P1jTriPoePIfNdxnLtZtrGZluBcG3vF%2BFJYuJfx40IIxHJKzzb5et9ZtZYp1LwygcgPtKy%2FZkT%2FKWuRKKCOC6tNH1CblcWiILDUWHH6wg6wyDejx9Fw4sfOMjEBY5biH1HgLy8VYulOfJV%2By38q4ndH9LlL219K4iilHrWzLxlhI6SgE1%2F2SnFKo0Czxy28zMqcSzspIYBPj2I%2F1cd%2FytnVZdNQ2D1I%2BESMoPw%2FzMftdMG20TSQyyblmjenzoc4TY6ld6ddyKwMUsbFZoHqNwd1KnGXRXs9n5%2Fv7lg98GlWhMjwk1A%2Fm4k%2FF7jDSwSPULTTJI3PGBphGNwG4OHVW%2BgnONX%2BsWFpDFPaSSJcTESG3TcRlf2uRK%2Fazq%2BkR3aeT7e%2BjnX6yoW8ibht%2B9i9Tg%2B%2FQ98QVZHqstutowuSPSdSpV91IPVWzif1i98t%2BZ7m40FjbSWUrNCqEmkex4EH7acT9lv2c6lonmbTvMUTWdwgiumWktrLQhge6H9of6uRLzd5ZurDVP8Q2KetYFUW7jXeSKi%2Bm0hH7UZH7X7OCY4g2YM0sMrjvexB5SHcXsnkPz3Y%2BcdPqKQ6lAB9bta%2F8lI69Y2%2F4XJeDXPJlvPe6JqMeq6NMYLuE842To6ntToyuv2k%2Faz0J5E8%2B2HnGyI2t9VgA%2Bt2ZP0epH%2FNEf%2BEyESeUuff3tmbFAx8bB9H8Uf4sZ8%2F6P82TMMLNb1iDRrQ3EpBkkPC3j7s5%2FwCNV%2B0%2BGVc4n5m8yfpnzJcsr%2F6HYsLe232PBv3j0%2Fy3%2BH%2FY5JxkLourX175%2Ftb28maSZrloqsdlQ1Tgo%2FZUDO755%2B8uxlvPcMI6i6LAe2zZ6BwlS7NmzYFdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVf%2FW7%2FmzZsVdkb83W5%2BrW1%2Bg%2BK1kAc%2F5D%2FCf%2BG45JMC6jare2FxaEf3qMo%2BdPh%2F4bCNiqV6VOOcTV%2BGReB37%2FaX9WHoyFaJMz23BqiWE7juCh%2FsyaRsHRXHRgCPpwy52gLs2bNkUuzZs2Kuwu1rS49W06Wzb4XI5Qv8Ayuu6nDHMemKvONE1KWGVrG7rHPCxRgeqsppk7sb0XC8W2lUbjxHiMhnnnTHtLmPXrZfgakd1TsR9iQ%2FP7LYtomq%2FWI0Iakybof4H55LmFZdqNlFqNjcWMwqk6FD8z9k%2FQc515XuZbW4l0%2B5%2BGWFzE6n%2BZTTOlW063EQkXY9GXwPhnO%2FNsS6T5qtbofBHqaniexmi%2B2v%2BsU4v%2FlfFgHcrPTFbanZNb3caywyApLE3Qj3zjutwW%2FljzBc6Pp6fV9JHpsLNSSgR1HIorV3Vvizq2jXQk%2BAndlBA9xnNvzRiWPzJBJWnr2gJP%2FGNyv8AHAdikJ3YGf0o5pZDIboSD1GJJ9aAgh6%2F5aUzoFnN9YtYZ6gmRFY06VI3zlXk%2FVI5bi2hnlBgdBuxFFahhfr0rSNsnHlXU4JI5NJaSt1avIQm%2B8RaquD0I%2BLjkpbgIZJmzZsirsDagC1jcqvUxOB%2FwJwTjXUMrK32WBB%2BWKpfofE6Xb8f5d%2FnhjkMPmvR%2FKlrJBqkxBSVkjC0PIDpTfI15s%2FMNbu3jbR5plsZVp69swRi9N0eSjMnH%2BRcVpm669cWWtXGnatwjgKma2uPsj0x%2FNXw%2FayOfmLr%2BhX3l%2BPTYrkXM%2BpGtm1uPUUceX7yRx8KLtx%2F1s5xoN%2FefpVr6C8muVVfUuLO8kMrEIeTem7faRk5Iy5FdTuZ9B169trGZvqkc5eFD8SmJzzUcTtsrceWHzTT3fRJv0p5UZvtOYYrgCu%2FJV4P%2FwANHnPrj83vM2lX9zpWoBJYInaJ540pOi1%2BGRQDxf4cln5Z3qT2stjWrK0iexEgE60%2F2XLOUfmHYNZeZbhWP94Ayn%2FV%2BD%2FjVclLlbEdQn955q1wTiU3huLadeQCsfSljO9VNev%2FAA0bYHub1Z7V5yWkhHxpcVHJNwGiuP8AKStVk%2FbyGafqLQxyafO5S2lPJWUAmGQ%2F7uiB8f8Ad0X%2B7F%2Fy8Ctd6jpl3Lb3v%2BkQTpxniqTDcQn7LoR%2FwUb%2FALDZCyyekWl9ZyaFLPelZGN2tqDEtZJHenEs67ckpVXwq1bU7G1iKWvqtcCR4bkkhFYx%2FCHXhvvX48C%2BU7H1SbK3k9Wya5hv4HchSBF8FxBL2WeOJ1k%2F4s9P4cu%2F0j%2Fc1FphmFxPLeOhZBxAiL8jt40%2Fa5YegV6PprvLpcE8sfpTNbh3QVoGK12zluoQ2PnZih42fmWIVt5z8Md4q9I5P5J17Z2A8YrWVl%2BERoaDwoNvupnLtb02LzREdR0hBba7bVe4tEPFZwpr6sH%2FABb%2FAJOSkgPNLqGaG7e3v42iuoTwlicUIK9iM755KnGoeT7ZX6m1CH%2FYSNCf%2BFOctnuIfNkSWeqEWuu249OC8ccfW47elcd%2Bf%2BVnQ%2FyyS5t9Dk067jMVzaSXMLK3hRJlp4r9rjkQl5PbalcaRd%2BlI7PbwysI5lNJIirU%2BH%2FmnOueV%2FOUeo%2BnY6hIpuWX9xPtwnU%2Fhz%2FnTOPeY4zY%2BYNTgpVBcSVQ9CrHkP14Gsb9rFgRWSzY1K1%2BKNh%2B0p%2FZcY2Qdlev%2BZ%2FLKxK19pcdYBUzWqdYx1Lwj%2BT%2BaP8AZ%2FZyHW9xe6ZfQ6ppk7QXsBDRTIevsR%2B0p%2FlyY%2BUPNR1KJLK5lD3KrW3m6esg67f79T9pMD%2BZtCjTnqVilIW%2BKeFRshPWVAP2P9%2BJ%2BzkZRB3DPFlljlxRPz5Edx8mcw%2Fm3aXvkzULyUC3122jET2oNA8kh9NZYT%2FJvzb%2BTOZabIhnWkgaOQcwxO577%2F5fjhKIYndoZvgaUD05v5SN1J%2FyG6YI0RZ4tS%2BoyKQS1HTwYHsffALrdOQwM%2BLGOEHfhu6PWvJ6f5FsfrXnqW8K%2FDBEZD4cmAVf1Z2fOSeSLmfT9RrHEWlvDSZaVagNR0%2BztnW8mWsuzZs2BDs2bNirs2bNirs2bNirs2bNirs2bNir%2F9fv%2BbNmxV2Y5so4qw6WL9HeYLiLpFcUnjHQfH9r%2FhuWSbTnBgMXeJiv0H4l%2FA4T%2Ba4fTW01FRvDJ6chA%2FYfpX5MMGaXcBmHxbSrsCdi6%2F2f8RyZ3j7kdU4zZzrTfO2qQa3eaHrkax6haux%2Br9FkgJ%2FdT2790ZP%2BGydWWoWt%2BnK3erAfHGdmX5rkSEovNm2yiQASTQDqcCt5sL5dZ06Ko9YSMNqRAv8Aiu2Iv5i0qJecsrKo%2FwAkk%2FctTho9yo69htbi2e2vApgmHB1cgA1%2BffOYX%2BnXflXUghJezkNbabxH8jH%2BdcPPN82l65b2j213DN9WdmmtefCRkdeJaNSVb1I%2FtYXWM8cVk2javM95pUv9zcPvLB%2FI3LvwwhIT2x12KCBrxjyjRS06jrxG5YD%2BZcrzzpkXmjyhLPpzCSaFVv8ATZozuXjHP4GH%2B%2FE5JkUmju9BujaTsJYHHKC4G6Sxn9r%2FAJqwJH5g1fyjDaw2KrcaE0zSNE27RiQmtuXPSJ6%2FuW%2FYkxI6hUg8ia9qulatHe3s0k8DgxGKZywBk%2By3%2BTkn%2FN63a8ttG1a3rHL%2B9hIB%2BIdGK%2F8ABA5DNbS0tL%2B4ksJOenzETWrjYiOT4gjD9l4WqjL%2FAJOTTU9XtNc8r6dDP8E8rc4iSP71RwkTfcP%2FALsX%2Bflgq09zFvKeoTMwV2NeCsB0BaNqf8a5N9Zu59K83W2pWb%2Bn9cjBo24ZXUNxI%2F1lyCWsL6fNb3LLxid24tSgINA9Puyb67pd%2Fr2kaPc6bxN5b8owWYKAYW%2BGpP8Ak4RyQU8ufOF7JLD9XRLaAj96ZPiYv4A9An%2FDYOfz9oEbtA0kjXSqG%2Brqh5NtU%2BkW4iQL%2Fk5yK%2FiuNagjEcpTU7Rj6YqaSAbtG3%2FFin4om%2Fa%2BxhXcGeWxlDgpPbfvUFaPDKpFXiI%2FYk%2Fk%2FmwFXr0n5hfXBJFpVtxmC84jOa81%2FaKqv7Sfy5GL7zJq2rwXFhqF40AlWiSQfAEPVW%2BH7Sfz%2FwCRkTl1dLW3t7xi8108C3g9EBArCnI8jtVvtNRcR1zzTdJcQvYwRW7y28dwzFfUblIvI05fAo%2F2OGxSt3zSW9LPXITMlCjiuzofsyRt2YfsPkd0iabTtQksp1Zra4U84X6SJ%2Bw4%2FwAoD7Ei5dzqV7LFCt7KZnVAY%2BRqyg9aj%2BX%2BTJdouuaHrltb2PmCNfrkKmO2vKcT%2FkgsP2v5cjtapfo0Jt%2FMllFGHltZvVeK4ptwWNi6yU%2BzIvRlwm1mUarpNtJHEWutOkuIbh0FSbfkGiZ2%2Fb4MxH%2Bpk6uZNM8saddywStNK605tsKnYcF%2FmbOZy3s2nWaLE%2FG4e4%2BsK43HELxowOzK%2FL4lx5fFWb%2FlprP1TWLQMaLMFRh%2FlRtxr%2FwLYn%2BfNjLp%2Bp2WpwghWLxuf2SGoRX%2FAIDI9peo2kMtjfWQMUi3JM9u24j5rT4D%2B1G5qyfyfYzp%2FwCcdimr%2BUra%2FG%2FwpISOoIpXJDcIPN4HDcR3Scl2I6qeoOGNvcQyw%2Fo%2B%2FJWGpNvP1aBz%2B0PGFv8Adkf%2BzXIxSaym2NCOh7MMNYLhLlOS7H9pfA5FU30vUNQ8uaqjIqsaqHiO8UsZ6EeKsrfA%2BS3yUr6p5iudTl2S1RvRTchTKeCgV%2FlTlkOsvUveOn8VkdatauxoyN%2FID%2B0r%2FwAmTfyYHsrnTdPasc1%2FNczXMZArwhT04g3%2FAD05Yjml6Fditlcmu%2FpvX%2FgTnK5bS4sp1mDtFID6kLioPXZgc61NGTBNH4o1PpUjIpNbyX0Ulvcw%2FV9Tst7i2IqHWn99EP2kZf7xF%2F18nMX1pANMR1TTYfMkRuYYlt%2FMEY5EfYW7UftL%2FwAXjDf8u%2FMFzM8mnX6MJLWRFkMh4yiqtGUYU%2FZP82IzW%2FH4DVQG%2FduPtRP1FG%2Flb9lsG6ZJDJfPcvGI9WCoJZwPhmRGHF2X%2Ffi4AP2peafmBE8Hmq8LgATCOVaeBUL%2BtcjauUPip6qe%2BdJ82x293Pb2GtyL9ZmWRoL5QAUZZGQK47p9nOd39hdaZctaXScXXdSN1YHoynupwFCL0zUX0y4SVGf6uWDqybPG46On%2BWv%2FAA652nRtY%2FTdqJbfjLdqnK4gjpSVen1iBf5G%2FwB3Rf7qfOCxycaqwqjfaH8ck%2Fk%2B61K11AC1kZYIT6gmB%2Bxy2oP%2BMi%2FC6f7LEGlZCbBr%2B%2Bu%2FqqpBCjP6cbtxHwn4ljrX%2FgckOj2EMcC6lK6yTRKYmkIoYl6gE9xT7L5HhcTJqM1jJCEjjQSQsK7qT3rgi%2FuJ7PTDKQ31S5f03ZPi3SrfGP5RiKG6bej%2BQPzB0CG%2BuNHvB9VeZx9WvZKBX7cCf2P8jOvghgGU1B3BHfPHaQrfuEt3DHkAJakKhP8AO37A%2BedX8i%2BYPOen6dNp2qK5t4JFjs5HClyoNJfTdieUaL8S%2FwDCZEcRNEc%2BrfOOKWMTgeGUaEoHfi%2FpRP8Aunt2Ab3UorWqAc5QK8egHzOPhuoTYrdesJYgnJptgDTqdu%2FtkT1C9XnLPIwofjLduJ6fhkgLcYsi0vVRfSSRSUWRd1UeGGgyN%2BVrCSkmrXKlXnHC3RtuMXXlT%2BaTJKMTV7JdmzZsCuzZs2KuzZs2KuzZs2Kv%2F9Dv%2BbNmxV2bNmxVB6rafXtOuLXvIh4HwYbr%2BORbRL%2BsMTMaSQsOSnrseLZNDnIdfXXtP8zXtnZGC2tJWEsUz8pH4yAE8Y14rs3JfibJRPMKyf8AMXye3mKyh1LTH%2Bra1px9S0ulFSV6mNwPtRnIb5e8wXlw%2FwCj9VR9N1u12PGoD9vUgfpJG%2F7UedN8uapcXsH1e7C%2BrAi%2FvV6OPs1K%2FsttgLzP5Ysr%2B3NzHFxmjPMlNj%2FrLTdWHtiNtlU9I82sxa11lAssf2bmMfA9PFf2G%2F4XIt501y81SykEEjRQRMGEaMV5L0%2BKn2sq4ke3j9O4asuyLNSnMduX%2BV%2FxLCfVZ%2FS0u8cDkVhYhfGgxodGQDDZPMculusTzpwryMT7mneh%2B0uTVNL1e%2Bsob1tLmmtJlEkbFW5FGFR8NfUzi2iQ%2FXNXtLjUAXWe6hE3L%2BQyKHG%2FbjnqzzP5ok0H0baxgWVyodi5IRU6KBx74ASrzOzsfL1tcH69ppMtdxM0h4%2F883OS2GLS7239K1pGpGwj%2BEr%2FALHphVcecBcyrc6vBFdabL%2B7lV0UPbt12KDnx%2FlYYGvrWKwP1nTp3kirsT0BpWgcdf8AZDJg%2FFjSanSb8xC2ursXtpG5kt7dkVRGaU4g%2FETy%2FwBbIzc60xSeylsgphDJeafNtIY%2BnqREfCygYcWPmV14x3qkqQDzAo4X%2BYr%2B0ME6h%2BidZZImjM90FLQzQj40BFNn2%2B1X7DYkd2yi%2BrHNIh8uXbLp7yLJdToZbZJDX1EU0NOXxCeL9tf%2BJ4PhbTLya58sXqqt3EoKlV9MSoRUMn8ssf7XH%2FXyD%2BcfKFzoWnRatFqUUU%2BnSGSGAsBcFXZaFeHJVZDu2HOn3See9Kt1%2BsCx8x2y%2BpaXabB2TxH8pP21%2FZwAnu3VQuV1CC2iW9cx%2FwCkS28kMtA5dKLHL1%2B00TJyZPhk%2B1nS%2FKN59Z0GSNno6yI6e1V4v%2Fwy5z9pv8YWj6Hrcf6P836EWmiiHSfiv2ox%2B2kwH7P2ftLk28uxrbeXYLhYXV7gMzxkE0IqPiqNq%2Fy4gb%2BSk7PNdX1m%2BHmqaytJ%2FTtTdx%2FBGoSu6swZqcj8YbCnRmM97drKxKXcslu7tXb1%2BSBq%2FwCSzZK9c06xuNUutStkBls5IFkAIAMoHqUUfzNRkbCPW5Xs70rZcVtL0%2BtCoAFVc1oK%2FwArni2RIShdD0rU9Z0g2UNW1DR5JLG%2BirRlQuXhmp1ZP72M%2FwCph75g0K2sra21G8ch5baGJUpt6yARuvL6OWEQk1eJrq9s55YLxBzuGhJEjr3LKvxSqv7WISanq2oQRXGryvd2MtVhuSQ8aNQch8OyNjsqElhK1hbcr%2Fcv3K%2FyV%2FycRSQBmUiifsfQM6FpfljSbrR0mCy3EjDlDIzN9sGnphU%2FZ%2FlbIrqnl%2F6jM3Cb1VRqOoU8078XoOHPISIiQCd5ckgE3tyS4StK6xSy%2FDJ%2B7HqseO%2FYVw0W2thatp10he2b7YH21cfZljP86f8AD%2FYxO4tbO4so4I7ZUvG5Lpl3PssprUws392JD%2Fut%2FwCbAOh6sLuU6VqYMF4hKRu2x5DrFID0YY7rsh4tMn06%2FkspjzjniaS1nQfDIE%2BJWXwdafEv7Od0ugnmL8tmYipWEOB1oGWp%2FwCH5Zy4hoT9WuU5BTzj7FHp%2FeIe3%2BX%2FADrnR%2FysvRfaHeaJIwZ4RJGo8QDzQ%2F8AAy5OPVBfPNxbpMpifYqaBu4IwFYWlx9fEIJU7lmH7S%2F83ZJ9e0x7K9unRg8azMkoHWJySVR%2F9YH4W%2Bzj%2FKtvFdaxBDLQKzAVO243G%2F8ArYPJUXb2NvDZtdyWxe3B4meCQ%2BtG37Jkjb9lafaXHRXl9q2r6etnWJ7Yxx28h%2B1UNyMjt%2FlH4myX6lp1poPm57CIFLG8jikCsKisqqXWncc2%2BzhLZW0Om35hCuLiCeSgIHFY67KT9rl4YaV63IwMVSakg1pt27eGRuzvrTWILdYbnlcIWXSdQc8W5pXlp91%2FLIP91M%2F94mG9tcfW3AQ14xgsPH4c4Zp%2Btz6HqN2rJ61nNIy3loTTkA54yIf91zR%2FailyRNUinpV0iXqyyxw%2BjdW5Md%2FaN1iPdqf74f8A5Jtka1ZZ4LWYxsySKpaCRT8QI%2BIxkj2Hw5KLe6%2FTsUF%2Fp1wsmrRRk2l0QAL6Fft290g%2Fu7uP7Lo395hFquqaL9XZmmWCRwySWTgs8MgG6Oo%2FY5fZbAUhC%2BZ9JsfMl1SKYW%2BqyQRT2DMf3UvJeTwt4M5%2BJchKyrOr6D5gQwTQEpFK%2FwDeQv8Ayn%2BZDk%2B1Gyj1ew0SaC4gS5ntmCtX0ELQtQAM%2FEcv5Fwv1bQxr%2Bnhr4oms2ymP6xuCStSIbof6v8AdzYOaGAQ%2BXdTm1NdLjj5SN8QkG6FOvqBu%2BTjTrS2sbZLCMcVUmkpFGLn7Rf%2FAFv%2BFxTTme102DTuILIwZpKksW%2BzxWtW41%2FZyU2XlW41HhcahytOQJZVHKaXw%2Fd%2F7rY%2FzviAqQ21ldXtytrDG0k524qKmnj8sO736roNmNIltfVv7hFeaMnkUqTwpxNA2S2MaT5etS9w6WdtEvx1b42A7Symh%2F2C5zTzb%2BZun3swOjacGVKwrqMgoajeiJSr%2FOTDVdVZPYa3pOj%2BW7u31uKKzuZGP1dePP1Iz1UovxtJ%2FlYU%2Fl%2F5hOtyS%2BWrlis1Gm0pyfiR4%2Fi9Kv7SumcrvNYnu5DcXH7yToamrfSf6YL8ratLZ%2BZtJvoT6bwXMbEjuCwVh8uJauPFuFe%2Bx%2BYJ4NMawQiOFzyZOlDX4h%2FwQyQeVtAn1BY9R1QN9WU1toG%2Fa3qGYeGE3lnRLPVfM19LdAyWkTtcW8a7xOGaq1kGz7k%2FAM6moAACigA2AxJ7lojn72wANgKAbDLzZsirs2bNirs2bNirs2bNirs2bNir%2F9Hv%2BbNmxV2bNmxV2Qzz3p3P6rqKbFKwyt%2Fkn4lJPseWTPOVfnX5gmstNtdBtnMbajykuXHX0YyPh%2F2b%2FwDEcbrfm24MRzZI447GR59w6pMfNyWl7EdD1KM3Cp6dwoKldj%2B1zHE%2FRko0rz1rUtz9SvLe2lm2Hp8jC7BhWqV5xvUb%2FDnn01jPEin8pHgckemXmsTaHcxANw05o57O7IIKxliJYll%2FaRT%2B84%2FsNkIZhIkSjRDl6zs%2FwIjJCXFHkb5gp3%2Ba2r%2BbdPuEvYLVbLRpiFL27c2EvWkj0%2Fd8v2VpkGsfN2p3Kra3V2XicgEsQeQJ3qSNs7d%2BkdO1rSbKw1LhN%2BlbRXVJKFZyq8ZV3%2F3YGHLOEecvKFx5TvTLDym0idv3EvdG%2FwB9yf5a%2Fst%2B3lpHUOvsua4iNwbWCruHK%2FB0qN9j0zoy%2BarW48r2Oq3l1Le2sSizuGkqk6zgUVXMda8F%2FwCDTOO2M01rIs0XCRQ4kHqCqGnZl74NgkTlMqSOIZpPVNrXjGG8Qvfj2wXzSyqz1eO%2FtNSjQM8sVubhFbbkIpPiI%2BUR5Yca3q17IdPmtZ2js7yztriONNhyAKSciPtMJUfIZaXDWL%2Bra0jcq0ZYAV4yAq6mv8ynJf5Yex1PRjpUsfO%2F0pnuLJWNPUgkNZ4l%2Fm9Nh6vH%2BVpMRa2uvBcXej2Gp2rSC5tJJbOZkqW4v%2B%2FgY%2Bx%2FeJhtBB5sOi313boLa9ihMlo3EB5ClGkULy%2B16XJk4rhlZarBFAbZljtrS5Tg%2FoIF4fyOT1JjbC1L%2BbSbowyMwu4WrzJryX9h1PQpxw%2FFWFXNut9PB6srS6frlqI4JZHJ%2Br30bCsbOf5phx3%2FAN1T%2FwCRgPQbtreVrEFrW8gfnDU0dJUPF09unHD%2FAFeygjjvbi2haTQbpxcXlpHvLp9x9n6xClfjtjXi1P2P3b%2FGseE99ol9qtyjIKamYlktb6Mn0L5QKJ8Zp6d3x%2BH4vt8OD%2FvciTXPZaZ%2Bkdp5%2Bgt19Yad5p0%2Fe0vU2Y8T0NPiaM%2FtJ%2FuvOj6lcGysFaRlYxJWUjfkUXk3z5MM5p%2BV2l3U2pPdalFHK1sOLyqQxSZaFOdDWOT7W%2F7eTTzK8UdlcxREhXBTf%2BdzWg%2B7JxNji70HnTz%2B51GXyrrFxaapD69nfcRqSftqxHL1oj%2FOjPjtQ0GNYCfrCXWi3QMtlelhyjkYbFfdvsyx4M87Wy6zqemTq4X9KwQnmegkK%2Bmf%2BSi5G9M1PVfLUt3od3CJIGDEQS7iKUD4Zov8%2FjyErqrruPNkK58%2FJN7Sx0%2B0sDe3k0k9xA6JBJACGqwPHiKp8S8fts2F0mrDS3nubPThH6ZLa5YcQsnBvs3kSsCnJeXJuK%2FB%2FwAYmwQ%2FrXdjEsQRizhvjKCrUp8If4uW%2FwCyuK3Fs893p1nezfVdeDCOxmHFi8ZH%2B89wSeBjP2YuX%2BVFiYggA70Pmt9QzfyjdxXeiPeaY3rNYt9ZjdKUkgP2gyj7L8ftL%2FPgTz2tuLdJIT6cN1JFcxzJ2U7Sb%2Fs%2Fa5BsKfLEMvlPXby2sJI40uF%2F0izVuUcb05n0z3gkTlw%2F3237vHeddXN5pEMdnbmOys4BFcy0qDcF6GJa%2FwDFacmyX8Pu2R1QOi6Yupabd2F78dj6xjLVFUlpySaHwkUf7F0%2BDIrrvl6dr42N0eOtRIHs7ldkv4B9ijf8tKgfB%2FP%2FAHX28mPluyb0Vs7OdTL6SSReoK8%2FTZqN%2FrqOPL%2FJwTqdhFr9m1lqUhjnhcm2uv8AdltN%2FMKf7pb9tP8AZrjVhWHaHrEWqxjTb9gt9GKQytsXptxNf2sl35d3J0jznJbCojuQlR26cT%2Btc55qthdyXcyyJ9X8wWfx3ESbC6UbrcwfzS8fjfj%2FAHyfvPt88N%2FKuq3F3q1hqBIEyc4pWZuCkoAwck9MA50VPJV%2FMq2k0TznfCJQUmPJom%2BzJG%2FxcW9t%2FwDY4Q6cILa6ZY2eKRwslv6goaDfjy%2FaK4f%2FAJleadM80a8t1pcZ9GCJYmuG2MrD7TAfsqv2V%2Fmwr0WyuNXUw%2FVxci1%2BKLt%2Fw23wrg6qGVanr1vrK2t3csIry1aESBjxJEYYOQff4cjvm3zLbpZXLWTGC5vr%2FwCswRjfjBGoC8yfi%2BIjCPX2vNMu%2FqZDRNGKSAgUqxqgqKruF%2BH4sjsyPPIZZSXJ7knfG1e9%2Flxrdt5ksbqdSFu7eMLcW5O4%2BE0cV6xvnF75uVzcb14yyBW7%2FaO2KeS9RutC8yWd7DMYLfn6d3L%2Bx6D7SLJ7YhdkNd3UkRDRSXErxMDUFGclT9IwndCtpWrz6ZN8MskcDsGdojxkjcfZmip%2B2v8AL%2B3iWoySfXbiHUmFy14frKXqH4nL14zK%2FVuX7cbYEeJWDPQVpU0Pj0x6yqLL0pJUW4tXE1o5O9SaSRbeP28Cob1Z1T6vPKzxjeNSSQK9aV%2BznXLfUrdtDt9T1U%2BjeRxpa3iMvF5V41jcg%2Ftrx%2BLOd6VbaTqJlS7lMl5Iri3hHwRiQj920snhzODppWsii6zcGeSZg3po3NSy%2FD%2Fen4K9V542r0LyheaXcm5uaCCWNhxkl%2FvClOqcvs4rrn5g2enI9tpKi4uqlWck0rSvxP8Atf7HITazpccriNaLGD%2FozGnBVIJkZP261%2BFuWE4juLqSZo2pbJMjyitAQeVPwrjxbUE01reuXGvCKPUZJ2Cs0iqgUgFtunw%2FCKfDhWLXSzayW73jxuGElWgJUbUoSDhkLcXEjJDSJqkoSd%2BH7OGlh5a1HzDONIit%2FWvZEMkJRlQtGlKsCxVX4%2Fy%2FawWtILTLTTmeMmbTrm1jXe0nmMLOwH2nZlrWv%2BVhlBb6Lql09zpemrbx2cJe5WNqiRi3EKrfyj%2BZR8WJ6x%2BVPnXQrK41i9sljsrUB5pBLGzAVCgiNWLNufs4I8h6hp738sNxRBexei5BoBJWscg%2F2Xw4VZjoMllFbx635Y52k9mvPUdKaRjHIF%2B08PInhJQV6%2Fa%2BHOq6d5%2F0G7toZzK%2FBwKzBCVrTo3GpQ%2F62cYW21DQ%2FMUVrFH%2B5vyInPSIqzfE1f2afawkmtp42klt0f6uzuInWoDqrFQRQjkMJV9Q2ms6VfitpeRS%2BwYV%2FwCBNDg2ozzr5Y1vTI7V9L1PnbTDk8E4Qs7M1KKHBDp9GTfQfOdosSxw6txkp8UN0DxBG37WNea09UzZBNY%2FM3SfLcVrLrDIyXZKwm2bmW40DsF3%2BFa%2FF8eTW1uoby2iu7ducMyCSNh3VhUYEK2bNXNirs2bNirs2bNir%2F%2FS7%2FmzZsVdmzZsVdnE%2FwA9rKYXmj6jT9w0ctuT4OpEgB%2F1lOdsyO%2Bd%2FLUfmvy%2FcaXstxtNZyHosybofk32G%2F1sB5ORpMoxZ4TPIGj7pbPl%2BNPrERi%2FaG6H38MkPlXzh%2BjhHo%2BrmunCqwXFKmDmfiSRf27d%2FwBv9pMJBDcWN7JaXcRhuYHKTRPsVdT0P%2FNWB9RiWO6ag%2FdygSL7cuv3HKpkwImPcXoM2KGaHhy3B3BHf3h6B5qslXQooNOVof0a7Xdi6fDxBPKQQ78vT35xNl6Fr1l5s0yXSNZRHujHxlRhtMv%2B%2FE8JB9r%2FAIfILo2pT6XfLd8mmiKehPAzE8oT%2ByvKtOPWP%2BXKvrafSpl1XT2L6ez84LqLrE1a8WH7PH7NDlkMoluPiHRarRz05F%2BqJ5SHf1CT%2BZ%2FLlz5WvvTUmXT5jW2nP%2FEH%2FwCLB%2Fw2FauD8Sn6c67a3Vh5x0p7G%2BRfrAWskY6EHpLFXp%2FxpnLdc0S88t3ptrir27msE3ZlH6nX9pcmR1HJxFS3uA4oftDBlvcz2lxHc2sjQzxMGjlTYgjCVG6Mh%2BWD4ZRIvv3GC1Z7pdxHraNJCViukq13aswVAO9xCW%2F3Uf8Adkf%2B6%2F8AVw1t5NPkKabe3SyqKG2uIquYDX7Jc7ei37a%2FZ%2Fazm9tdT2dxHdWzcJYzyQ9R4UI7qw%2BFhkwhvDqECTaZbExyHhPbqKmCYivBf%2BKZPtR%2F8DgIkSDxVHqK%2FSyBFbjfvR8k1xY6gVtLb6vJbVWZbhvVLo38yAemYZF%2F4XCjW0McX986%2BX72Uem6V56bekVAYLu0D%2F8AJSL%2FAItjw7W0utVgj0%2B7k9DULc%2BnaSMaFkrvaz%2F8yXP%2Bpgq00iztbkaVcP8AWBer6NzEworLWjRsoJ4yRv8AEjr9jGOMDbn5y3UyJ8vcyfyHpl1puhy31zEE1e9cJfKxXjK8JMaTqfGZCrt%2FN9rCX8wda%2BqyabAGAM85aYA9FUcV%2FwCGyZXElvb20VgHb1LeNDEKmpKDhGS%2FfOK%2BcrhtU1G8vLZ%2BYsz6M0Q%2B0nBh6cwH%2B%2B5af7F8slsAAxG5tkesTm68saddo3GbTZ5bb1B1G%2FrRfrxGTW7LzPpcrahALfzDpir9biI4tJESAZowftJ8Svx%2FY%2F1cD6VMb3RNTsShJmhju4gVP2ovtH%2FgG%2BLBVnb6b5g0ux1JGWDXNDj4SEiongQcGjk%2F34hX7LfsYBukt%2BWba4gWHWmj%2BsWdpK0Dwqy%2BoWkonJE%2FvHZOfNcKdasnk80288TN6EEqxOXNWSOJiS7n2p8eB4bySw1ilv8Au4OQk47kKo%2BLv%2FLX7WK6jr4u9Uee1jItndiIiasyv9sV%2Fl3wWAFZBbvYajqsV%2FDSP1yITPUgSKH9SSinYcIRw%2BH7TSJhr%2BYOr2sOkWmnhHSK6YiRolFF5A%2Bn6ngJif8AWyP2ML6dbiRI%2FrqsAI3SRAsMY%2BxHKrlGhfl%2FefB%2B8%2F3XgXXYppJG1m2unkbj6Op2pUSKVAqksSNsif5L%2FFH9vHoUlrytdtDCgdmV7d5I2boU%2BINGT%2FLhpr3nLTKJ9UT19TB4zNHtCe3Jj3b2XIssp1Y8bUfFOQsix7SCSlAXpTmj4av5OnsdM%2BuzB3Zm9OWaNGD2%2FMgRTolP3sXP4Zv92fyYi6oITDVrG28x6NBeBvqWoWS1ivSeIikU8jFI%2BzLA6%2FGn%2B%2B3yFaq1pcXix28ZUGi3U2wadx%2FuziAEWv8Aq%2FH9vDLV7TzXeWrqbaWO4VhHeNHtFdCP7EhX5D4v9%2BfbwpC3liGgvIoVdSqt6pLPGr0pTj%2Bz8Xw4CUkEGil7RwRu9ZzwjPx8UZiKePShyb%2BRfMdhHM2kLEV%2BsDlDLQFncUCxcRX7WEF1DCs63zCs6r6c1Nkencr7rgXSpFsb5zCForepC9PiUEfZr4DADRVD%2BddUkPmPU4lUgVNtNG4qDw2Bof2kP2GyK1LECpY%2BAqTnUFhsta1Ce%2B1G3inuZCrySsgqwqFNRkwu9R8m%2BWIwscEHrharDBGjSH5tT4f9kcIoop4da6Vqt2GW0tbiQHbikbkH57UwHNFLbSvb3CNFLExSSJxxKsuzKwPQjOu3%2Fmq%2B1mFo1C2NmFMjhTQLGu%2FKRtumQfU%2FMWh3uoTXx0r1pJePKSWSnJlVU5lQNufHnhQxmOYxklSPiFCDvUZQKUIpUn7Jr0%2B7D8eYrBP7nRbUf61W%2FhmPmtkBFvptnEezCMkj78CpRZOY5w%2FBmWhBCjseuSyyn0pIpIr2CSr2gtbYTQt6aylufPp8PBWbCZPNurROskYgVkYOv7tSAVNRtg2780%2BYPNd5CdWuRJHEWkWONFjRaih%2BFAPljsqLeRrVh%2BjQt3GBRoXBBKAfFwag%2BLJ15B17yfealE2taTHcXMG63Eq%2FvbYL%2FvyH%2B6eFK%2F3iJyT9vAXkPygPNEuoxx3KQ3VrAHtYWP8AeOxpv%2FxWqijMv2WZMLdS8vBLx4pg9jqVqTFJIvwup6fvP5lP%2FDLillv5i%2BStPtL867pEEcem6hxkivLWjIk%2FevHb05ftZF9Okd5Et5mayvoWEtrdRmnCUfYmhYfzftp%2B3k3%2FAC68zLfx%2FwCFdWt1eElrbUoW%2BwGIrDPGv7CyU%2BLj%2B18eIeavKM3lq7WqfWNOkYizuXFeNesE9P8AiX7WNbqCncfm2fzRoUmg6zEqa7ZPDPPCv93eQRMC00A%2Fa%2FZaWLCHzf8Al7oOra5b6h5KuBHe3rj61Ywr%2B5Xlu0%2FL%2FdDfzx%2F8Qwpup4VWBrORhfW7iS0YkrJbkdRLKv2om%2FY4fbzsvkXU7fWNHju3jhj1ZAI9UEKhSJvEmg%2BF1%2BPEhXgPm%2B98y%2BWriTyxrM0iCMBo5VVW9aDoJIZm%2BLif5ftRthN5X8zxWXm%2FTZ9dHq6HH%2Foz2z1eNLd1Kq4TvwY%2Bo2el%2FPXkjTPPGkNY3n7q7hq9jeqPjikp%2FwANE%2F8AuxM8mazo%2Bq%2BV9UuNI1KL07y2PFlbdWU%2FZljP7UTfstih9Jy6d%2BVV3f2dja3ltHe6ipezS2mrzAFfh%2B2iMf2K%2FE2Xcfk5ojoTZ311bz1JEjFXG%2FitE%2F4lnlh3USLKCY7lSGLQ7UI3DA9mz0L%2BVP5wLqxi8s%2BaZRHqIpHZX0hAE9NljlPaf%2FK%2F3Z%2FrYqqal%2BS%2BoXb2EYvraWG3kcyvLG3IRuwY%2BkgPFW2PfJjZ%2BRruwuFa21iRYFACKFKsKf6r%2Bmf%2BReTUDxy6Yqo20LQQpE8rzso3lkpyb58QBi2bNirs2bNirs2bNir%2FAP%2FT7%2FmzZsVdmzZsVdlEA9cvNirzb8zvIf6bhOu6REP0tbL%2B%2BjUb3EQ%2FZ%2F4yp%2Bx%2FP9jOHagvqWsMw%2B1ETGwPWh33z1znI%2FzL8hqEutf0qP4JRzvrdR9lwR%2FpCDw%2F37%2FweRnGxTtNBreExw5DsD6Sen9F4gpphto2prYSSQ3Ketp11RbyAiu3QSoP50%2F4ZcK5YzG5Q7eGPEUyRpMykRSEhH7MV2IzGAkDY5h3OSEMkDjyCxL8beaZaglxoOpxTW7qLSWkmn3cX2eJ34nx%2FwApclMsen%2BcdIeC4QCZQPXjH2kanwyxe2RjT7%2B2e0bRtVHLT5SWhl%2Fat5Ozr%2FxWx%2B2uJWtxe6HqSw8wtxDvBL%2BxLGegP8yOMyceQEbcuo7nnNVpZ4JmMtwd4y%2FnD9bENU0y80C%2BazuRyTrHIPsunZh%2FTKil4kSIaj%2BGdZ1HTtM846SXUenKv2gN3glp1%2FykP%2FD5yO9s7vRb2SxvU4sh3I6MOzp7NkyOo5OKmSuGUMvQ9MMdF1m40S%2FjvoAHUfDPA32ZIz9pGH%2FDIf2Gwjt5Qh3%2Bw3%2BdcFnrir0GW5Kyx6hav6ltfqDHddW5Dbi1do5V%2Bw6%2FzZLPLbQ6nP8AWrpAby3oJGI2kXqkrfyyqR9rOU6HrKWHq2N8Gl0y6p66Lu0bjZZ4v%2BLF%2FaX%2FAHYmda8p2i2tk8sjrI7miTITxkj%2B1HJQ7huJ%2BLJR3K3snuq3fo2ruoqQC3idvsgD%2FWpnMJ%2FJ%2Fme4Msq2jC9tuUaXcXER3drJ1japH72NW%2BFmX%2Fit%2FwB5nTdIksyzW0c%2FryxVZgzBmCsa4eCZAKHDIWgbPDvK9jquh6xaW%2BtW81rDL6lozTKaFJQVAB%2BKtfhwvs47myvL%2BNQfTs2kD9UK8gQKlv2Xp8StnR%2FzQ1GW08u%2BlZO0d3dTxxQshKsKHm7hh9jiq%2Fazi6MxEiI5YOa3NyxJMjVrux%2BIrlctmQ3TS91E3jCG2jHI09R1qOdOgFf91r%2Fw2CLKFYxyJBIFZJOwHgMC2NryG3wRnq56t%2FZhusZiihu7cMWt5ir2zpyikUAU9T%2BYcuWR5pdPqiacQrWqXCzR1USVBAb%2FAHYp%2FnwutdVhtdTa%2FgWVBOAk8BcNG9BTqyk4c6rc2dxe2F3c2kcKJGI7qx4kUjpyR0B6Vr%2FNhBqc9haSxpHERaXRaWIt%2FuvcoTRa75PlyQn%2FAJZvYI%2FMUS2SNELiVTEygUjnVW9OlftI8hVWVsnSXVxfTGS6laSViCS2wodjsNs5%2Fo8rrL69qwd6pIrqAw%2Fd%2FYPw9OmSua51GVJ762swQXLCD1AiryNQrMfi2%2FyVwxKkIjW7%2BezjR7PTpr%2BUbv6WyUH8zfa6duOEPnjT7SEWmrxxkSXatazowA5KY%2BScgD9qIrxwQ3mPX7EetqFhAtqPtegzySAewA45F%2FMHm1dcRIGjMdvC%2FqRIKcuVCvJ2%2BR%2BzglLY2yhjnLaESfcEquburW8M5HpzKvIr1FaDl79cRbRr6S8%2Br245GCoac%2FCjKp67%2FwAww%2F8AL3li01qBLgPJO8f7t4wP7s%2FsE9fhOHer%2BVtfgg%2BvabcJe1FJrPjwZVUU%2Fdy%2FR9llyIFixuEzjKEjCYojmGM6jaajZ28RjBiEisJzULTi3iSKR0wboHkTXdWt21OLT5ru2A5RlN1k8SrsVWT%2FAGD5ena1aXA%2Bo6pD%2B9J2WcenL%2FlBJR8D%2FwCrnSfy880W%2Flyzl0m7uJZtJR%2BVmXSsltyNXhYD7cP7ScfiT%2BXDXcxosR1D8rvP2qWUdlZadHZW7kPcPcXEYeSn2EKR8%2BKJ9rh%2FNkRu%2FwArtc026ey1FooJo9yKs4IP7StQclz0brf5jeXtKhR7eYX0sieoiQHYL29Rv2Cf5T8WQ7W%2FMj%2BZrOKd0t1Ct%2B6eDk7xMaj05CaNxb%2FVwEgCy249PlyECMefJ4235fXQ63Uf%2FAt%2FXC7VvKsmkfV7iab1dPlISW7jTeFz%2BxJHWoPg37edQ5kyNDIvpyx%2FbQ%2B%2FQg91OB7hFCurIssUq8JoHFUdD%2Byw%2FU2IIIsMMmKeOZhkiYyHMF5g%2BhCNipcyFf3nwD7cH%2B%2FoT%2B1x%2FwB2J%2BziNyW01%2BNseVtMoMc4G7VH82TCbyxfWMxtUMlnDIPrOli55JIh%2FwCK2ZeMqthYYOMVxBNb%2Fu2HK%2Fsl6JU7Xlp%2B1xDfbT%2FdeFgmPknW7q0eC%2FsZ%2BOoWTck5ftRnrG9PtIfstnatY0iw%2FMfQ4%2FMWh8bfXbdSjxnbmyD47S4%2F5ky55gWcaZqDPp1yZo42Ppz8SvIePHOn%2BTfO2qaXML%2FSHiPqcRf2M9fTYf78Xj8XIfs4qoWsGsQ64Tpp%2Bo31zGbK9WYfFE8Z9TceI4FP9lnpNbWDVdGit9RRbiO4gT1g3QkqCW9jX4lzksE1z5382DU7WzEKoqq5UVAoOIeV9uR%2BL%2Fgc7RDGsMMcS%2FZjUIPkopj0UvHtQ%2FKnV9H1F9X8vXCajyYt9TuQoYLSijkx9OTj%2FlcMS8q%2BaLny95guoNYs2s%2FrfEXsLLxKyJXjLH4pxOdpwl1zy1p%2BvCOSctDcw19K5ioHAOxU1HxJ%2Fk4otNoZYriJJoWDxSKGRh0II2IyF%2FmN%2BXll550z4OMGs2oJsLynfr6Mv80L%2FwDCfayU6RYNplhDYNMZxACqyEBSVqSoIH8uDj0xV8NappV7pd7Np%2BoQNbX9qxSaJuoYfrr9pWwuSNg4NSHBqKbEHxrnrL80Py2g86WX1%2BwCw69aJS3kOyzoN%2Fq8x%2F5NP%2Bw2eXm0q8guZoblGglicpNA4pIroaMjfy0OKvpf8lvMusa5ol1ZazOLqXS3jiiuTvIyOvJRIf2ylKc86eM8y%2Fk35usfK2r3FtfyMtjqoRZZ3qRFNGT6bP4IQ7I%2F%2BxztF1%2BaHke01SDR31aN7mZ%2FTLRVeKNu3qTD4F5dMVZlmylIZQwNQdwRuMvFXZs2bFXZs2bFX%2F%2FU7%2FmzZsVdmzZsVdmzZsVdjXVXVlYclIIIPQg47GSOsaNI5oqgsx9h1xV4R%2BZvkA6VK2r6VH%2FuPlarIv8Aulz%2Bz%2Fxjb%2Fdf%2FA5EoJLK%2FwBFh0yOJU1AyrH6oABboqJItebtyJkjZP8AKVs73qnm%2FwAsyW89les7xzwtSMxMRKG%2BHghpx55w%2FwAy%2BWpbIHWNNjeGKFkDjlVw5%2BIPGwp8S%2FtcfsZGUauQHvdvpNWJxjhyyMZA%2BiXQ%2BUmMXNtcWVzJaXSGOeJisiHsRtll1uLf6rcMeKb20vVoW%2F6pP%2B0v7GHsLr5ptvq7mOPU4ElmEhHH1eCII4kp%2Bz6aO7%2FtephBNBPbytDcRtFNGaPG4oR7EZVKJHrhz%2B92JjDPA4cw3HMdR%2FSiiNG1m7028EiEC4j%2BGWMn4JU7qf8AjVslmvaBp3nLSFvbCiTKCY2P2opP24pKfs%2F9d5BTFFIys5ZGX9pKch9B65JvKmrSaVdevxea1m%2BCcEFQyj9tR%2FvxMtxZBIV8x3Oi1eknp5Ud4n6Zd%2F7XmskVxp11JY3sZikjbiyHsf8Amk%2Fs4caPay6peQadE6rJMwVXboF6k%2B%2FEDOn%2BdPIkfmSyGp6QA12qc4JFpSVPtcG9%2FwDjfI35a8qzaFNa3urKrXLmscfI1gP7NSv2n%2FmywxouIN1DWPKDW95DY6K0t5IfgnaUKgD05cl49I6H7TZ0bynBAmmjSVvhcz2qEM60%2BHnVRw9om%2BH%2FAFsItfhndg1q%2FpNdxmIuDQVU%2FECf8oYReSLk6R5nWBw1bmT6sSD8FGBb4h%2FNyXDyPvbsWITE9%2FVGJkB30jPKV1PpOsrBduRLFcPb3JY9VditW%2F2XxZ0%2B91O2spIoJWL3E54wW0Y5SOf9UdF%2Fmdvhzm%2Fm2w%2BoeapJlBVdRjWdCDsZE2cfeuHdvfQW0BngZptVvEH1u%2FlG6gj%2B5hH7Kr0xHc0pD%2BYg8wa1NDFZWjSWtsrCRoiGJcn46b1YdF2yFWemzxsW1CN4Ej%2FZlUofubOs2WpxpNGl2oMP2eSbEe5yTXGkadqFpJaT26T2860YEVBB6EHx8MeCzdpunlEtpHYQ38GqRrFNaPA8EgJcFa%2FGqhadao2XBGlmbe2uCzevbGeRo2PcNJx%2F2S%2FDht51s3sLpYLoH6ncIq21wRU1UceLt9Hxf8Hhj5f8pXerWc%2Bq2VrHqE1oqQWdvNLwUoijmJB%2FO9W4%2Fs8cjVH3LezEvM2mXWqyabNozB7SS1WJ5SwBrHWnLv8A3ZUbfy4onlazmtrKC%2BJlNoHFFNFbmQaHvtTJ9rPlzU7GOO6vrRbeNioQQMrRxmn938IXj4YE0fQLnXBdQ2062l1CP3SSry9Xav7og0%2F4LDsikps7C3s1WK2iWJB%2Bygpg5lNOX0YAVr7TL0xXsxcxsVlhktwpFPtLVWwbf%2Ban0e8tp7LTYrmyILlpyT6hoRw2%2Fu%2FTbdlw3taoK4v7a1dY2dW5GjQ1qVHj%2FwA24Vah5a03VlNxZEQTtvyX7LH%2FAClyfjyfo3nrTrbV9PRNI1i6gM8qRENC8gb05OUI%2BNR6nR1%2F4HIRqOj655Vu%2FQ1SBogT%2B7mU1ikA7pJ0%2FwBi3xZGwdizhOeOXFCRBSPSZNX8maml1MhNsfgldPijdD1H%2BS37S8s6ZLrEEZt2uEe1W6VWtLsg%2BlKGHIGOReS%2F6wOR9dWtRp11dSQ%2FWHt4Wk%2Br93IGyU%2Fysk%2Fk%2FW5INATT9Z0eAWczGT6gr%2BoIlfcgBxsf2vT%2FAGMYxMSeE2D07m7PqBmjEzjWSO3EOUo%2BY72M%2BYfLcd3FJeQRxyo7EzQU792GQ60bU9Hkf9HTAwts1jdVeNl%2FyX%2B2n%2FEc7ZL5XstVSS58p6kYZqVbTrysif6tWPrRr%2FspVzmuvaDq2jzsup2JtA5NCfjtmNf91Tjb%2FYyccJ8tmgJPqV4JJLJpI3sYLqJ2uY%2FtBgP91q6jpIy8Vw0sNNn8tG11m8KWNnqTrAums5YhTvyct%2B0R8fw%2FYb%2FWwLdRpfaVEkkPO50r1HhjJALRSg9HpX92%2FwCzgSW4TV9Hga5uppdVspFt7a0FOMNshHJm3VuZY8fV%2B0zfBlZHq3BNigOnm52LIfDHCYwMCJmVXI8IqMYnzI4f85l%2BsRQc7eSKVRPHKts4ruUkPAcv9R%2FiwbZaY1p5gtrHUoipjnjWZOo4lhRv8pGwcPL9pcROZo2S6ZkaXgyqoaFVk4hn%2BJ9uPqNxwVrmsWupvYzalF9S1K1lTi6GscsYYMpV%2FFWUNx%2FlwYoSjd8jybO0suLMcUsdmUQROxRrnH75PQtd8vaT5itBZapAJI0YPE6njJGw%2FajcfZzg%2FwCZWh3GhW%2Fr2wH1vSZ0DXlPia1m%2FuZuK7MV%2FuLj%2BbPQ1pdR3ltHcxGqyCtOtD3H0HIF%2BZFnb3k8EMqhxPBJHOh6MnIUDfSdssDq3zfqWmR6lFJqenRCO6iHK%2Fsk3FD0ng%2FmjfC3SNVudJuUvrKQJdQOrxc1DoafaSRGqrK%2FRlyU32i3XlnU4RHOYrF2Isr1hy9Jm%2F495%2F8AimT%2FACsKte0Zp%2FW1Kxg9KaL%2FAI6Nipr6bH%2Fd0X88En2lfFX0%2FwDlz5x0fzbpAlsIYrO%2BgAF%2FYxBVCOR%2FeIBTlE%2F7Lf7HJpniLyz5m1TyrqVtq2ly8ZYzuvVWX9qOQftI37WeufJnnHTfOekJqViwSZaLd2pNXhk7qf8AJP7D%2FtYFZJmzZsVdmzZsVaOct%2FNj8sx5ntJNb0NfT1uBayxrt9ajUfY%2F4zqP7tv2vsZ1PKOKvhz0CsbwMzqSSHPRgw2%2BL3%2FmwrlheB%2BD9exHQjxGeqfPH5Oad5lupdW0icabqU3xTqV5QTN%2FOyr8SOf2nX%2FgM59H%2BQfmu5nWC9ns4rbl8U6OzMB%2FkpwGKr%2Fyk%2FOBtOMPlnzTMWsyRHY6g5qYq9I5j3i%2Flf8A3XnoxWV1VkIZWAKsNwQehGc68sfkv5Q8vBZriE6rdrQ%2BpdAemCO6wj4f%2BD550VVCqFUUVRQAbAAYq3mzZsVdmzZsVf%2FV7%2FmzZsVdmzZsVdmzZsVdiNzNDbwSTXLBIUUmRj0A98WwNfPaJbSm%2BKi2pSUv9mh2pirAPON5pMWiStoiPJfM1bVI4yy1G8jDkCnwrhDrD6jFb%2BWbC7Wt36Ecl%2BCP%2BKiZHbtyJajf5WDvP9xZRaNCfKtxKb4zj04IOR403JKkfAOfH%2FWws84ajNd3EEklFuSOUtK%2FDRVXiKduQOFIeeatpk0F5PeaUj%2BlATLIYwSYhXd%2Fh%2ByleuLP9U12ykmiWO2vrWOW4n3PxgcAFXmaty3cf77%2Bx9jO1%2Flvo0EejT388SvJqDMjFxXlEvw8TX9ls5h%2BY%2FkSTyne%2FpHTVY6LdsVUj%2FdDt1hf%2Fitv91t%2FsMgRW4dxo9X4vDiySqcfon%2FO%2FoyYJsQGHfJL5FsrXUdZk0m6uTbR3UTvHQAgzRjkONSODla5GgcX0%2FUJNL1S0v41DPFINm8G%2BE%2Frym%2BHMD0k52txeLppjqPUPfF6l5X8xWlm995evZlguLSdkjR9gTWjrXovP4XTEPM6wwzKSKCT4tuoIO%2B3vke80xXU2tW13ZQ%2Bo15bq8npJ8UlELVp%2B3sMBWOsXOtWy2iEyXNuCyIw5Myf8VsaseFP7tvizL4tq%2BTzNUfvT%2BOU6npky9ZrciVAO5Xw%2Ba8sis01rp%2FmC01O5YrSWJ4kXcyFiB9nsK%2Ft5fljzLXzMlg0bRQujQESbVlDcl5IenL4kyeebPIp8y6j5e1DSEjX0XWO4QsqKYk%2FfRgV%2Fb5gx8cHMe5lGUom4mjuPnzSW%2F1OfVL6R7sJW2keKFUGygGhIJ3PKmNVy%2FTAk1pdWc9zBdrwuElcTIezA%2FEMj%2FmjXbvQtaW3tEBgCJM6PuCHFQExtizSKI1DHJv5VuxKrWMp%2BwC8JPh%2B0v0ZCNLvrfUrGG9tjWOVQfkf2lP%2BqcPdHme3vIZV24sKn2Ox%2FDJBSyzzBplrqWnSQSxLI0P76EsoIDqO3%2BsMgmlaxceUdRXU7ZS9jJRb62XoUP7QH80f2k%2F4HOgXdyVYgHp1%2BWQW8g4TzQyoQpJIVh1VuhGJCh7FG9hrempKhW4sryMMp6hlYV%2B%2FOWa%2FbXfk%2FU0ZJOEL1ayu2%2By1P91udv3if8OuCPJ%2FmhPL1xaaJetx0y4rFFMx2imJJSvhHLXj%2Fr4N%2FO9G%2FwAJ28o%2FYvY69%2BqOMgdlYzqPmWy8xr615aouoxAA3dk4dJB0%2FfRGjofBl54U%2BnCySRNSa1l%2B2vQq3861%2By65GPKcztqxjY7NEw4jYbU32zoNppF1qfrw2JX6yierHExoJivWIf5fH7DYYnZaY3pN9N5N1n9JJEbuIwyRoisY1kDbpVu3F%2FidM7xpl3Y%2BadFt7m5tle3vIUkaCYBx8Qowof5WB%2BPONG0jvLY28qlRUgqwoyOOu37LpiXl3XbjyZqk7XglmtZIfTEKNQGh5REFvsxr8XLjgIrdWQedvy7GiQPrfl4SNaxVe5s1q7Rp3ki%2FaaNf20%2B1kT07WGCqwcMjdJFNQc9C2N9BqNvHc29WiljSVGI2KyCopkFv%2FwAotHu9cOq2d1JYW0x53dhAo4O53JQt8MYf9ocMFyB23ZwGOQIkeCQGxqwfIsatNQSQrIrmOUbrIhoQfEEb5LLHzPP6X1TV4RqFo4ozFVL0%2FwApD8EmFms%2FlxeWBNxoEpuIhubSQj1B%2FqPsHwo0%2B4ltUmW7Ro5ojRo3BVhT2OWCi1t%2BbPJ1pFCfMXlJgtl%2Fx92VCyRHuwjb4kX%2Bdf2ciOlG2huhcX2n8JI2BE8FHHzMTb%2F8TVc6FpWutaySPblJEmHGeCQVVwP1ZGtcsIbe5N3p0Ui2MlWaM7mB%2FwBpQ4%2B1F%2FLkTGulhnDIYnYprf6tYaxaxxCDlxIaG7iko8Z7kGtWr%2B3ywxsdGl1WwitzGbkgkRzugDGnRm34R0%2FZbIJBZwxv9YhAVx8Qp0JPiBnafJl1eXekLNdyrKOXGNgADQD4g3Gg%2BE7Y8WyTLfiHNJbbQvNHle%2Fe50eQX%2BnXAD3Vg53EoWnKImhQmn7Pwv8AyYRX9xql1dmXWOS3XHiqMnp0QEkKq%2BA5fazrQwHqOmWmqQGC7j5D9lxsynxVsFsLeO39hb39tJbXMYlhlHGSNuhB%2FUffOZXy3%2Fl7UV05n5MgrpN1LTjLCT8VncEj%2FYf5Odt1nQbzR3JcerasfgnA2%2BT%2FAMrYB%2F5V3Y%2BdtAvhefubrn%2FuNux1jkQUYkD7Ubnir%2F6uEq8D1rTFk9XUdNgaHix%2Bu2XVoHPcD%2FfbfstnQfyAeb%2FFktC%2FptaSF1VgFNGTiXFfiA%2BLj%2FlZC9WuNd8p6kNM1e04anYsY2mY7TW%2FZG2pKjfsS4K003mkCHzl5WmDLazercWoB9WCvX1FB%2FeQt9lv8nIofYNRl5FPI3njTfO2li7taRXkQUXlp3Rj0Zf5on%2FYbJXirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FW7%2FmzZsVdmzZsVdmzZsVdgHVY9PmtHi1JlW3cgEuQBUbr1wdgPUdNttTtzb3IJWoZSOoYdxirzHztP%2Bi20aTyvdm6uDcJSCMJIPTVhRWKj7Bbbi2B9b8keZrnV3FvberbsQsVwHUKFJ6tU8hSvhk%2B%2FwAPGy1GwvLOkqK5ju0cIP3YQ%2BnItAPiif8A4nkkphKQaQOk6eml6ba6fGQVt4whPif2j%2FwWO1LTbPVrGfTr%2BITWtyhSWMjqD%2FEfs4MzEVwIsg2Ni%2BVPOHlm58p65NpU1XhP72znP%2B7IWPwn%2FXX7En%2BVgW28s63f2kWr29m76Ys6xyXQpxUggNUfa4iv2uOen9c8t6J5it0t9as0uo4zyjLVDKf8l1oy5EL7TriGW30Lytp7Q6Dbs0d7xI4Oz%2FFWPlycmNvib%2BfKziufETs7WXahOn8Ph9dVIn6a7%2FewDzPd3ukNplzYtxtEhW2adVBKzRktTkalOdf%2BBw60bydZ%2BaNR%2FwARaPq0VjOIw509bcLIkw%2B16yh%2FjRm%2F3an28de6dLYTXGk6xDztpx8aHoyn7Lqfb9nI3YX%2BreQ9ThS3pcWhcvazMBWSE%2FbgaQ%2FF8P8AJlrrDvunvmryB9buFvzAtnrkQD84z%2B6mKHkGRtu%2F82HWnO%2BoadLpU5aC4ZeUL9Gil%2B0jKR0aOYZOLO80jzho0d3Zv6kMn2WFPUhlGxVh%2By6H7WQWaO80rV1hvwBMjcfUAoskTbLIP%2BNsIr5oSu10tfOt7Ikt4th5ijQC6hkSsdz6fwfWIiCCr7UmTj%2Fl5JG%2FKTSdTjg%2FxDILh4UCUgHD7P8Axafj45GPMdkYtRkvbWf6jewEXNhcr9ppT9pEVatJWnxJx%2BznRPIfmz%2FFujfW5Y%2FSvLZ%2Fq94gBCmQCvNQfiVX%2B1xb7OA2NleaX%2Fkr%2FA19Jb2rO%2BlXbc7UvuFbuvL%2Bb%2FiWC7M7HOuarpdrq9jLY3i8o5Bse6t2df8AKXOP6jbaj5dvpLK5USBd0fcB07Ov8cMT3qkP5l6trkWp2kNi8sVr6CShoyVDyH7RJHXj8OQpfNfmCN1%2BsXcsnBeCrOfUAUdFHP4uP052ny%2Fq2g6veR6T5hgX94Almsp%2Fdsw%2F3W%2F%2BU37GSHUfyp8n6hUpavZse8DkD%2FgH5p%2BGCXNeTwM%2BbzeWxtr%2B3SVHFGMZKMP8oBqr%2FwANh9qv5gpr3kVfLV9zk1O3uIjFOwrzt4w1GZhUeqn2P8rJD5i%2FJJrK2lvNKufrSx%2FEYCnCXiOtCpKPx%2F1M503lq7tpDxDNUUUGlPwyJtWQflfpMWseaFtLgssZtZnDJ1VhxCn3651e38qanp%2Bs2ZX95brKG%2BtR7UVfio6%2Fs16YS%2Fk3pGmWxvNR%2BspJqfEW7WnR4kryLFW3PqN%2FL%2FLnW8I2UsW8x%2BVo71n1LT0CXp3mjGwlp3%2F4yD%2Fhsgl9oyXUaxX1u8LoCY2dStV%2FaG%2Fgc7JTEbiztrr0zcRrIYmDxlhWjDJCXQoeVeW9Rv8Ay1PKL25kuNO9ELEo%2BIjgaoKk%2FAqJyzqtrdQXkCXNs3qQyqGjcdCCK7ZFPMPl1Yg95aLWA7zQjfjXqw%2FycB6JrNzY3BW7uAbARKgUqSQVIC8KfCq8K8vhxq9wlntK4DvtJ07UgBfW6TU6FhvTwqN8FRyRyoHiYOjCoZTUEHH5FDC9Y%2FL6wuSZ9Ic2M3X0tzEfo6p%2FscL9B%2FLy8XVJNS8y3Yuo41aKz0%2BEkQrGwoWlO3N2zomVTDZV4l5n8s3Plq94oS%2BnTk%2FVZj27%2Bk5%2FnX%2FhsMNI893Wj2ht2thNVSEp8PGSlBK%2F%2BSf286nqOnWmqWcllexiSGQbg9QezKf2WGco13yhdaVMUT95A39zL0DDwPg%2BIZc3pPlzU5dStGa4IaeNgGZaAFWHJWoMOc5v5E1B7Wf6tcAoD%2B5PLb3jP0fYzo4xIYrZIo5UaOVQ6MKMrCoIPtidrZ29lAttaoI4UrxQdBU1OL5sCsO8%2FwD5e6V5708RXNINQgB%2Bp3oFStf2JAKc4m%2F4XOIWX5R%2FmVoOpummwIySAxNMssZhZG2q3Mqen80eeoKZqYq8l8h%2Fk%2FceW9Qt9Z1DU3W4gPJLS0JCEGvwTytT1U3%2Bx6arnWs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F1%2B%2F5s2bFXZs2bFXZs2bFXZs2bFXUzZs2KuzZs2KoXUjILG49E0k4EKetK43TYkhsoQp5EqGZvEnvgp1DKVbdW2I9jhDdaDqT%2FuLLWJbOzP8AulEVnAPVVkb4hiqB8wWUXmS%2BXTYWQi3ikZphuUlqOKmn7P8ANnOtRsiPW0TWUKqD9ofajYfZkQ%2B3%2FDLnYtH0Wy0W3aC0BJc8pJHPJ2J8ThV5u8tJrdoZrdQL6EH0z0Lj%2BQ%2F8a4bTbxXQPMGq%2Fl9r7mSs9jcUN3Cv2Zo%2B1xD4Sp%2FzZnaNYhtfNmgRaho7JcMwE1pKCASP246%2Fsn%2BZf58gsugWWtaPFp1xRL21qFkFCyP3U96YR%2BUfMt7%2BX%2BqvpmqEtpUsnGeOtQjE0FxD%2FwAzUxOy%2B5kHmGCOa1s7%2BVeEsFYpHI3SvwyBvDi647RtH1by3qEXmPT5VlgnWmo2C1Amj6rIrH4RMnVcCz3FvJ5x1pIqX2h30cVy3ouv2nQEeka9XZW5ZJNPult7dbZpTLasP9HlYUalP7uVf2JlH2v%2BEw891ZzY3tvqNtHdWz84pBUHoQe6sP2WX9rC7zJoEOu2Xp7LdRVa3lPY90b%2FACHwi0IahBqtdOo9hKf9LjY0Vf8ALU%2F78ybZFD591jS3R3gnRo5Ymp4MjA9snHkr8weRi0LzJII7pQEtdQc0SYdFWQ%2Fsy%2F5X7eH%2FAJw8uLqMDX9qg%2BtRL%2B8Uf7sQf8bLnJbuyjcNFKnND1U%2Fw8Dh5pfQo3Gc487eVFhMmq2KfuHNbmNR%2Fdsf92KP5G%2Fa%2FlyPeXPM%2Fmfy2Y4pmk1PRqfBBKpNwiDr6E3%2B7OH8j51%2B1ubXU7JLiKklvcJWjDqrDdWH%2FEsV5PntoFiuUuQOFxFvHKpKsPpWnLJZ5b8w65p1xEguXuIp3q8d07P1%2FZVm%2Bx%2Fkccbr%2Bhm2125sbPggX95AZq8FRhy3p%2FL8Srk181aDHqempqtvRLu2hDngPheMDmV%2F2P2ozjsrKLW5ju4Eni%2By4rQ9Qe4OL5D%2FACp5hgu7iOwkkUXFxD6yx9DWM8HNMmGJFFDRFRQioPUHIhrmgrAXubdK2z19WOleFepH%2BRkwymCkUIqD1BxBpWIaNq09o31WURrZoiem32ePEheCIB8VV%2BLJcGB3BBHtka1LQXVne0XnC9eUQ%2B0tevHxXA2lxazHfW620rx2atW4gkSqFOPCgdvjDClVwkA7hWYZswzZFXYnNBFPG0UyCSNvtKwqDimbFWE6voE1hIbu0Be3BrQVLIP8rxXJRo92b3T4Z2%2B1Ti3zG1cGkAih3B7ZSRpGvCNQqjsooN8NquzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxViPmbyo91cfpvQiINVT%2B%2Bh6RXSD9iXwl%2F33N%2FwWQzW9AXXo%2FXaFg7L%2B%2BhK0mjdBuafzACjrnYcDTWNrPKk8kYMsZDI42NR40w3tRW3z1p2l6ho%2BotLAfXVE5OgDVljA%2BLj%2FxZGv7OS2BbeaRbscpI5YuLQq3ETIfiQcv2ZVP90%2F8AsMk3mi1FjqBnt0CpcIHIUU%2BNT8RFP5tuWRDTFEulwPaP9YjVSfVjBIFGPM%2F7BvHCOSXqXlu6trnTI1t7Y2Zj%2BGW1YhmQ%2BJcfb5fzYcZBPKl1I7GRXHKGi3AY%2FajPRvdsnQNd8BFFDjnL%2FPWhJaXguIKRw33KngklPi%2F2Pxcs6jkY892Ul3onqwoZJLWRZeAHIlT8D7fJsAVBaLpUeueS9PtriYPcWykQXkfZ4yVDD%2FJP2WwX5X1NJ2NrQIGXkoXpzQ8JP65GPJfmOTR5G0zXLmGCzlYmzhZPSeE05ceP7UTjfliOhagkWs3CW0gkUXbPZjoZVkY8kQHr8OSHUJZD540vmYtVRBIAvoTo260JrGzU7cvhzaJ5jgm0t9O1u7giu%2FRdY%2BJ48oyCg%2Fd9QyfZ%2FwArJhPBFcwvbzqHikBV0PQg9sgt%2FwCSLpJy9pxniPRiQsgH8rfzYB5ql%2Fkq1hXU4ZigNwjsizftemU3Uf5Jzp%2BRXyloF%2Fpj3FzqYiR3YraxREsyx%2FzTOaL6j%2Fyp8CZKsSUOzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Hv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVg35iPrMEFld6XbR3CRM%2Fro1fUIIHwx%2Fs4U%2FlrqOkz3c1lYQmENFJI8DCgRzIDIg5b1JavTOiajZLf2cls1KsKofBh9k5ydpJPL%2FmzT9ZcBIWY2t5sFoD8Ls5C1%2FwCDkyQ5KyjWdLGi6ml3brSyvKxuo6I58P8AJPVclOiXZurPi5rLAfTf5fsn7sE3drBqFq9vLR4pV2I7dwy%2B%2BF2j6Xf2F5dS3EqNbyhViVa8iV%2Fbfag6%2FZXBdj3KnWURXLzYFYV5n8n3us6ut7btEITGsbc6hl418B8WFd75Ym8svHqVqPrQiCsJSPiikH2jQfsNnScayhwVYBlOxB3BGG1Sby7rf6YgZ5KCZftIBSmHeFllodlp95LeWqlDMKGIfYB7kDDPE%2BSuzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F%2F0u%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZFfM%2BipLW%2BSJZAf71CtaMPsygf8SyVZRAIIO4PbCDW6pP5YvDd6Wiu1Zbc%2Bi%2B9Tt9mv%2Bxw5xG3tbe1Vlt41jDHkwUUqfE4tgPNXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Pv%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV%2F%2FZ'); background-position:center center; border:1px solid #00aa00; } .yui-skin-sam .yui-h-slider { background: url(bg-h.gif) no-repeat 5px 0; height: 28px; width: 228px; }yui-compressor-2.4.7/tests/dataurl-base64-noquotes.css.min0000644000175000017500000024523411640627104023462 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml,.yui3-skin-night .yui3-dial-center-button-vml,.yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min,.yui3-skin-night v\:oval.yui3-dial-marker-max-min,.yui3-skin-night .yui3-dial-marker-vml,.yui3-skin-night .yui3-dial-handle-vml{background:0;opacity:1}div.base64-noquotes{width:100px;height:100px;background-image:url(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAgEAZABkAAD%2F4RfJRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAeAAAAcgEyAAIAAAAUAAAAkIdpAAQAAAABAAAApAAAANAAD0JAAAAnEAAPQkAAACcQQWRvYmUgUGhvdG9zaG9wIENTMiBNYWNpbnRvc2gAMjAwODowNzoxOSAxNDo1ODowNQAAA6ABAAMAAAAB%2F%2F8AAKACAAQAAAABAAABwqADAAQAAAABAAABRQAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAEeARsABQAAAAEAAAEmASgAAwAAAAEAAgAAAgEABAAAAAEAAAEuAgIABAAAAAEAABaTAAAAAAAAAEgAAAABAAAASAAAAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZ%2F%2B01IlBob3Rvc2hvcCAzLjAAOEJJTQQlAAAAAAAQAAAAAAAAAAAAAAAAAAAAADhCSU0D6gAAAAAYEDw%2FeG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8%2BCjwhRE9DVFlQRSBwbGlzdCBQVUJMSUMgIi0vL0FwcGxlLy9EVEQgUExJU1QgMS4wLy9FTiIgImh0dHA6Ly93d3cuYXBwbGUuY29tL0RURHMvUHJvcGVydHlMaXN0LTEuMC5kdGQiPgo8cGxpc3QgdmVyc2lvbj0iMS4wIj4KPGRpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNSG9yaXpvbnRhbFJlczwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1Ib3Jpem9udGFsUmVzPC9rZXk%2BCgkJCQk8cmVhbD43MjwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgkJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNU2NhbGluZzwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1TY2FsaW5nPC9rZXk%2BCgkJCQk8cmVhbD4xPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCTxkaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q%2BCgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCQkJCTxyZWFsPjcyPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsU2NhbGluZzwva2V5PgoJCQkJPHJlYWw%2BMTwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuc3ViVGlja2V0LnBhcGVyX2luZm9fdGlja2V0PC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BUE1UaW9nYVBhcGVyTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNVGlvZ2FQYXBlck5hbWU8L2tleT4KCQkJCQk8c3RyaW5nPm5hLWxldHRlcjwvc3RyaW5nPgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk%2BCgkJCQkJCTxyZWFsPi0xODwvcmVhbD4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD43NzQ8L3JlYWw%2BCgkJCQkJCTxyZWFsPjU5NDwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNUGFwZXJOYW1lPC9rZXk%2BCgkJCQkJPHN0cmluZz5uYS1sZXR0ZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk%2BCgkJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhZ2VSZWN0PC9rZXk%2BCgkJPGRpY3Q%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD4tMTg8L3JlYWw%2BCgkJCQkJCTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTk0PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLnBwZC5QTVBhcGVyTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BVVMgTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5BUElWZXJzaW9uPC9rZXk%2BCgkJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC50eXBlPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvVGlja2V0PC9zdHJpbmc%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuQVBJVmVyc2lvbjwva2V5PgoJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnR5cGU8L2tleT4KCTxzdHJpbmc%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXRUaWNrZXQ8L3N0cmluZz4KPC9kaWN0Pgo8L3BsaXN0Pgo4QklNA%2BkAAAAAAHgAAwAAAEgASAAAAAAC3gJA%2F%2B7%2F7gMGAlIDZwUoA%2FwAAgAAAEgASAAAAAAC2AIoAAEAAABkAAAAAQADAwMAAAABf%2F8AAQABAAAAAAAAAAAAAAAAaAgAGQGQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4QklNA%2B0AAAAAABAAZAAAAAEAAQBkAAAAAQABOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD%2BAAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNBAoAAAAAAAEAADhCSU0nEAAAAAAACgABAAAAAAAAAAE4QklNA%2FUAAAAAAEgAL2ZmAAEAbGZmAAYAAAAAAAEAL2ZmAAEAoZmaAAYAAAAAAAEAMgAAAAEAWgAAAAYAAAAAAAEANQAAAAEALQAAAAYAAAAAAAE4QklNA%2FgAAAAAAHAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAAAD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FA%2BgAAAAA%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwPoAAAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAOEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJAAAAAADhCSU0EHgAAAAAABAAAAAA4QklNBBoAAAAAA1UAAAAGAAAAAAAAAAAAAAFFAAABwgAAABAAcwB3AGkAcwBzAF8AYQByAG0AeQBfAGsAbgBpAGYAZQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABwgAAAUUAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAG51bGwAAAACAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9uZwAAAUUAAAAAUmdodGxvbmcAAAHCAAAABnNsaWNlc1ZsTHMAAAABT2JqYwAAAAEAAAAAAAVzbGljZQAAABIAAAAHc2xpY2VJRGxvbmcAAAAAAAAAB2dyb3VwSURsb25nAAAAAAAAAAZvcmlnaW5lbnVtAAAADEVTbGljZU9yaWdpbgAAAA1hdXRvR2VuZXJhdGVkAAAAAFR5cGVlbnVtAAAACkVTbGljZVR5cGUAAAAASW1nIAAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAFFAAAAAFJnaHRsb25nAAABwgAAAAN1cmxURVhUAAAAAQAAAAAAAG51bGxURVhUAAAAAQAAAAAAAE1zZ2VURVhUAAAAAQAAAAAABmFsdFRhZ1RFWFQAAAABAAAAAAAOY2VsbFRleHRJc0hUTUxib29sAQAAAAhjZWxsVGV4dFRFWFQAAAABAAAAAAAJaG9yekFsaWduZW51bQAAAA9FU2xpY2VIb3J6QWxpZ24AAAAHZGVmYXVsdAAAAAl2ZXJ0QWxpZ25lbnVtAAAAD0VTbGljZVZlcnRBbGlnbgAAAAdkZWZhdWx0AAAAC2JnQ29sb3JUeXBlZW51bQAAABFFU2xpY2VCR0NvbG9yVHlwZQAAAABOb25lAAAACXRvcE91dHNldGxvbmcAAAAAAAAACmxlZnRPdXRzZXRsb25nAAAAAAAAAAxib3R0b21PdXRzZXRsb25nAAAAAAAAAAtyaWdodE91dHNldGxvbmcAAAAAADhCSU0EKAAAAAAADAAAAAE%2F8AAAAAAAADhCSU0EEQAAAAAAAQEAOEJJTQQUAAAAAAAEAAAAAThCSU0EDAAAAAAWrwAAAAEAAACgAAAAdAAAAeAAANmAAAAWkwAYAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZADhCSU0EIQAAAAAAVQAAAAEBAAAADwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAAAABMAQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAIABDAFMAMgAAAAEAOEJJTQQGAAAAAAAHAAIAAAABAQD%2F4TkjaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu%2B7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI%2FPgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSIzLjEuMS0xMTIiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyI%2BCiAgICAgICAgIDx4YXBNTTpEb2N1bWVudElEPnV1aWQ6RTcxOTVFNTY1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkRvY3VtZW50SUQ%2BCiAgICAgICAgIDx4YXBNTTpJbnN0YW5jZUlEPnV1aWQ6RTcxOTVFNTc1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkluc3RhbmNlSUQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eGFwOkNyZWF0ZURhdGU%2BMjAwOC0wNy0xOVQxNDo1Nzo0MS0wNTowMDwveGFwOkNyZWF0ZURhdGU%2BCiAgICAgICAgIDx4YXA6TW9kaWZ5RGF0ZT4yMDA4LTA3LTE5VDE0OjU4OjA1LTA1OjAwPC94YXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhhcDpNZXRhZGF0YURhdGU%2BMjAwOC0wNy0xOVQxNDo1ODowNS0wNTowMDwveGFwOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhhcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1MyIE1hY2ludG9zaDwveGFwOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9qcGVnPC9kYzpmb3JtYXQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOkhpc3RvcnkvPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpOYXRpdmVEaWdlc3Q%2BMjU2LDI1NywyNTgsMjU5LDI2MiwyNzQsMjc3LDI4NCw1MzAsNTMxLDI4MiwyODMsMjk2LDMwMSwzMTgsMzE5LDUyOSw1MzIsMzA2LDI3MCwyNzEsMjcyLDMwNSwzMTUsMzM0MzI7QzA1QTE5MDRGRjAwQUJEQzA1MUJERkFGMDIwNEVBNTE8L3RpZmY6TmF0aXZlRGlnZXN0PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24%2BNDUwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjMyNTwvZXhpZjpQaXhlbFlEaW1lbnNpb24%2BCiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U%2BLTE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6TmF0aXZlRGlnZXN0PjM2ODY0LDQwOTYwLDQwOTYxLDM3MTIxLDM3MTIyLDQwOTYyLDQwOTYzLDM3NTEwLDQwOTY0LDM2ODY3LDM2ODY4LDMzNDM0LDMzNDM3LDM0ODUwLDM0ODUyLDM0ODU1LDM0ODU2LDM3Mzc3LDM3Mzc4LDM3Mzc5LDM3MzgwLDM3MzgxLDM3MzgyLDM3MzgzLDM3Mzg0LDM3Mzg1LDM3Mzg2LDM3Mzk2LDQxNDgzLDQxNDg0LDQxNDg2LDQxNDg3LDQxNDg4LDQxNDkyLDQxNDkzLDQxNDk1LDQxNzI4LDQxNzI5LDQxNzMwLDQxOTg1LDQxOTg2LDQxOTg3LDQxOTg4LDQxOTg5LDQxOTkwLDQxOTkxLDQxOTkyLDQxOTkzLDQxOTk0LDQxOTk1LDQxOTk2LDQyMDE2LDAsMiw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwyMCwyMiwyMywyNCwyNSwyNiwyNywyOCwzMDtENDYzN0NCOUQ0MUExMEJBN0VGNUVCQ0RCNjMxODMyOTwvZXhpZjpOYXRpdmVEaWdlc3Q%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY%2BCjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8%2B%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEJCAgJCgkLCQkLDgsNCw4RDg4ODhERDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgBRQHCAwEiAAIRAQMRAf%2FdAAQAHf%2FEAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPBUtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4%2FPE1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BCk5SVlpeYmZqbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp0%2BPzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BDlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq%2Bv%2FaAAwDAQACEQMRAD8A7%2FmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmrlHI2utXn6WltnFESb0RFSp41WjD5q3LCBaslzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2E2rj0LuzvF7PxftUf8AXPLDnC3XI0ewdpOkTK4P08T%2FAMK2Ec1TLNgaxmE9pFIDy%2BEAn3GxwTgV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F%2F0e%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXYUeZpfR0a4kpUAx19h6i74b4X65CbjR76FV5FoJKKe5C1GIVLdDuGhuXs2IKOX4gfsvGdx%2FskKtkiyD6bctHHbXgPImOC4qOpXj6E1ff4Mm4Ndxkpc770BvNmzZFLs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Lv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVokKCT0G%2F3ZgaioNQemANZuhaWLyE0LlY1%2BbGn6sWspA8QA%2FZ%2FUcVRWbNmxV2bNmxV2bNmxV2NZQwKnodj9OOzYqwDT4iiPZsa%2FVLm5sj7I%2F76L%2BOTXTpjPZQSt9pkAb5r8JyKXqfUvMOpIQOFxFDfoP8qFvTl%2F4Q5INDkrFPAf8AdUhI%2FwBV%2FiH8cnLeAPcxHMprmzZsgydmzZsVdmzZsVdmzZsVdmzYyWRIo2kkYKiirMdgAMVX5sjTeaGl1CzsbSAOLuX0w7k14KCzyAD%2BUZJBirebNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F9Pv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVo4CXUFa9e0CbJRWkr%2B0RWlMHZEJ5WtPMtzE5%2BGYJKnyK0%2F4kuEC1ZeM2IW0okjFT8S7H%2BuL4FYz52mMWn2tDTlcpX6FbDHR5ecCH%2BZevywl%2FMM8dJtn7LdJ%2BKvgry9ccrOJ69KVw9E9GS5s2bAh2bNmxV2bNmxV2bNmxVi3miFU1LSbxvsStJYzH%2FJnSi%2F8ADYpoEzLcxq1T68FGr%2FvyE8GrgjzdC0mhXEsY%2Fe2pS5i%2F1omDf8RwttJRHdrcDaNbhZVI6endIG%2F4mcnHeJCDzDL82bNkEuzZs2KuzZs2KuzZs2KurkZ843Zhs4bVTQzvVqfyrvg3zHNPb2UMsLtGBPGJSpIqjEqRUb9ch%2BvSSvp0JlcvJCLyMuxJb4JNvi%2F1SuEBVvkaX9L%2BZbm8Sv1fTbf0Y6%2F78lPxH%2FgFzpeRvyPbWcXlyyubWBIXuoxJOUG7uKjk5%2FaOSSoxPNXZs2bArs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FU7%2FmzZsVQ2osyWM7o3FlQkMOxGPtZhPBHKCDyUE08e%2BM1Bedjcr4xPT%2FgThV5cvBJbpGergEfMDcYa2PkqfZs2bArs2bNirs2bNirs2bNirshfnRGtb7T9TX7LcoJD2qDzSv3vk0wl81WDajodzDGKzRj1oR35R%2FFT6RthHNXaVcrKsUtftDi304dZz7yrqPrQCIncdMnsEnqRK%2Fcjf54yVjP5gwtJ5ckcD%2B5mik%2BivH%2FAI3wD5RnEtpwrWgw983RGby1qiqKlYGkA%2F4x%2FvP%2BNchnke5BIUGoPQ%2FPEJHJ6XG3JFbxAOPxOA1iX7sUwIdmzZsVdmzZsVdmzZsVUbqBbq2mtm%2BzMjRn5MKZDLP4rC2UVq9qYj7SWshWn%2BtxOTnIVG4ttWvdNaiiK7FxGDtWG6Ti%2FwDwMuShzRLky%2B1lE9vFMP8AdiK33gYscKtBmDWhtq%2FHbOyMp68SeSH5UOGpyJ5pYde3moWPmW5KzH0pIo2WNt0A3Wv0ts2D73zJ6FgzxqqXpKpHG9eDMx7EYXed45VeC4gPCdYyqua0I5q5VgOv2cAW8sWo2QMqhwwoyHcVyQFhVOLzvrNrdf6fFHLFX4kVeBH%2Br1%2F4bJlp%2Bt2GqWrXFnICyKWeJtnUgV3XOP67qFjaFLHUrprecy%2BlZajxPDmN1jn8Dv8Aa%2By%2BIaXrclrdtZ34NrfR1USofgeo2K06c%2F8AgcBCXr%2FlvXRrdnzk4rcoSJFXYfMbnDzOV%2BTr82eqAOQIpaBq7AV2r%2BOdTriRSEp8z8RoN9I5AWJPV5HYD0yHr%2BGQg3Ntq1lcLazx3CiZviiYOKzQo9Kjb7YzoWqRevpt5AOskEij5lCOmc60%2BWCK0j9ONYo5IYp%2BEahQWBeNjRafEcMVTvTb%2B80fyHZ3FugE9vSORJBUqPVZW%2BEHw3yVaXeC%2FsobulGkX41HQMNmH%2FBZzC%2B1iTTbadZUkjtJjzkQqSKqNm5fsdMPfyr1%2FRdT8vra2E5N5C8kl3bSMTKpkctz%2BL7SP9peOA7fFkIkgkCwOfkz7NlA1y8DF2bNmxV2bEJLy1injtpJVWeavpREjk3Hc8V64virs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Xv%2BbNmxVplDqUbcMKH5HIPokjWsstqx%2BK2lZPf4Wpk5yF6nF9R8xswHGO8QSj%2FAFh8D%2Fqrkoc6VmSMHUOOjAEfTjsAaZMXhMRPxRnYf5J6YPyJV2bNmxV2bNmxVQuzOtu729PVUclBFa07U98DafqsF6i9EkI6ePywwyF6vG2i6oJRUWl6xZCP2JOrr%2FsvtLhG6s0yiK4X6Zfi4QI7Vb9lv5h%2FXDHrgV5c8B0LzLc2Q%2BGF29WDw4SfF%2Fwp%2BHOg6ZMHi4j2YfTkZ%2FMGwpFaazGDytm9GYj%2FAH25%2BEn%2FAFX%2FAOJ4N8uXwliicnps305LmFZDewrc2dxbt0lieNvkylc45%2BX10UCQzHjLATE4P%2BQeNc6L55e5i0J57WVonikRmZDSq7jf2yB2Op%2FVYor2%2FwBNjktpAGjv7ZvU%2BInoy8Vao%2Fa44xCQ9as25RVBqKnfBGRby9rBEsljcIY0aQ%2Bg5FCCQD6bj9lslGAikN5s2bArs2bGyOI0aRuiAsfoFcVS%2B%2F1q2sJltyrSytuyp%2ByDsC3zwxBqAfHfI%2Fodmt2z6pcjnJK5dAexPT%2FgRkhxV2c782mSy82WUgNIdUhNs4PTmlXQ%2FwDBDOiZAvzLb6nHpOrlFkjs7lWdG9yvxVG%2FwiuGJ3Up3YTJFr7op%2BC8t1ljHjxodv8AYtkiyHbxx6XfKx%2FcXBilJ3%2BAsVUV8FRlyYA4Z80DkkPmq3EtlHJSpR%2BJPgHBH66ZBtIufqt9Np8pALHnEpO5p1oM6Xq0P1jTriPoePIfNdxnLtZtrGZluBcG3vF%2BFJYuJfx40IIxHJKzzb5et9ZtZYp1LwygcgPtKy%2FZkT%2FKWuRKKCOC6tNH1CblcWiILDUWHH6wg6wyDejx9Fw4sfOMjEBY5biH1HgLy8VYulOfJV%2By38q4ndH9LlL219K4iilHrWzLxlhI6SgE1%2F2SnFKo0Czxy28zMqcSzspIYBPj2I%2F1cd%2FytnVZdNQ2D1I%2BESMoPw%2FzMftdMG20TSQyyblmjenzoc4TY6ld6ddyKwMUsbFZoHqNwd1KnGXRXs9n5%2Fv7lg98GlWhMjwk1A%2Fm4k%2FF7jDSwSPULTTJI3PGBphGNwG4OHVW%2BgnONX%2BsWFpDFPaSSJcTESG3TcRlf2uRK%2Fazq%2BkR3aeT7e%2BjnX6yoW8ibht%2B9i9Tg%2B%2FQ98QVZHqstutowuSPSdSpV91IPVWzif1i98t%2BZ7m40FjbSWUrNCqEmkex4EH7acT9lv2c6lonmbTvMUTWdwgiumWktrLQhge6H9of6uRLzd5ZurDVP8Q2KetYFUW7jXeSKi%2Bm0hH7UZH7X7OCY4g2YM0sMrjvexB5SHcXsnkPz3Y%2BcdPqKQ6lAB9bta%2F8lI69Y2%2F4XJeDXPJlvPe6JqMeq6NMYLuE842To6ntToyuv2k%2Faz0J5E8%2B2HnGyI2t9VgA%2Bt2ZP0epH%2FNEf%2BEyESeUuff3tmbFAx8bB9H8Uf4sZ8%2F6P82TMMLNb1iDRrQ3EpBkkPC3j7s5%2FwCNV%2B0%2BGVc4n5m8yfpnzJcsr%2F6HYsLe232PBv3j0%2Fy3%2BH%2FY5JxkLourX175%2Ftb28maSZrloqsdlQ1Tgo%2FZUDO755%2B8uxlvPcMI6i6LAe2zZ6BwlS7NmzYFdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVf%2FW7%2FmzZsVdkb83W5%2BrW1%2Bg%2BK1kAc%2F5D%2FCf%2BG45JMC6jare2FxaEf3qMo%2BdPh%2F4bCNiqV6VOOcTV%2BGReB37%2FaX9WHoyFaJMz23BqiWE7juCh%2FsyaRsHRXHRgCPpwy52gLs2bNkUuzZs2Kuwu1rS49W06Wzb4XI5Qv8Ayuu6nDHMemKvONE1KWGVrG7rHPCxRgeqsppk7sb0XC8W2lUbjxHiMhnnnTHtLmPXrZfgakd1TsR9iQ%2FP7LYtomq%2FWI0Iakybof4H55LmFZdqNlFqNjcWMwqk6FD8z9k%2FQc515XuZbW4l0%2B5%2BGWFzE6n%2BZTTOlW063EQkXY9GXwPhnO%2FNsS6T5qtbofBHqaniexmi%2B2v%2BsU4v%2FlfFgHcrPTFbanZNb3caywyApLE3Qj3zjutwW%2FljzBc6Pp6fV9JHpsLNSSgR1HIorV3Vvizq2jXQk%2BAndlBA9xnNvzRiWPzJBJWnr2gJP%2FGNyv8AHAdikJ3YGf0o5pZDIboSD1GJJ9aAgh6%2F5aUzoFnN9YtYZ6gmRFY06VI3zlXk%2FVI5bi2hnlBgdBuxFFahhfr0rSNsnHlXU4JI5NJaSt1avIQm%2B8RaquD0I%2BLjkpbgIZJmzZsirsDagC1jcqvUxOB%2FwJwTjXUMrK32WBB%2BWKpfofE6Xb8f5d%2FnhjkMPmvR%2FKlrJBqkxBSVkjC0PIDpTfI15s%2FMNbu3jbR5plsZVp69swRi9N0eSjMnH%2BRcVpm669cWWtXGnatwjgKma2uPsj0x%2FNXw%2FayOfmLr%2BhX3l%2BPTYrkXM%2BpGtm1uPUUceX7yRx8KLtx%2F1s5xoN%2FefpVr6C8muVVfUuLO8kMrEIeTem7faRk5Iy5FdTuZ9B169trGZvqkc5eFD8SmJzzUcTtsrceWHzTT3fRJv0p5UZvtOYYrgCu%2FJV4P%2FwANHnPrj83vM2lX9zpWoBJYInaJ540pOi1%2BGRQDxf4cln5Z3qT2stjWrK0iexEgE60%2F2XLOUfmHYNZeZbhWP94Ayn%2FV%2BD%2FjVclLlbEdQn955q1wTiU3huLadeQCsfSljO9VNev%2FAA0bYHub1Z7V5yWkhHxpcVHJNwGiuP8AKStVk%2FbyGafqLQxyafO5S2lPJWUAmGQ%2F7uiB8f8Ad0X%2B7F%2Fy8Ctd6jpl3Lb3v%2BkQTpxniqTDcQn7LoR%2FwUb%2FALDZCyyekWl9ZyaFLPelZGN2tqDEtZJHenEs67ckpVXwq1bU7G1iKWvqtcCR4bkkhFYx%2FCHXhvvX48C%2BU7H1SbK3k9Wya5hv4HchSBF8FxBL2WeOJ1k%2F4s9P4cu%2F0j%2Fc1FphmFxPLeOhZBxAiL8jt40%2Fa5YegV6PprvLpcE8sfpTNbh3QVoGK12zluoQ2PnZih42fmWIVt5z8Md4q9I5P5J17Z2A8YrWVl%2BERoaDwoNvupnLtb02LzREdR0hBba7bVe4tEPFZwpr6sH%2FABb%2FAJOSkgPNLqGaG7e3v42iuoTwlicUIK9iM755KnGoeT7ZX6m1CH%2FYSNCf%2BFOctnuIfNkSWeqEWuu249OC8ccfW47elcd%2Bf%2BVnQ%2FyyS5t9Dk067jMVzaSXMLK3hRJlp4r9rjkQl5PbalcaRd%2BlI7PbwysI5lNJIirU%2BH%2FmnOueV%2FOUeo%2BnY6hIpuWX9xPtwnU%2Fhz%2FnTOPeY4zY%2BYNTgpVBcSVQ9CrHkP14Gsb9rFgRWSzY1K1%2BKNh%2B0p%2FZcY2Qdlev%2BZ%2FLKxK19pcdYBUzWqdYx1Lwj%2BT%2BaP8AZ%2FZyHW9xe6ZfQ6ppk7QXsBDRTIevsR%2B0p%2FlyY%2BUPNR1KJLK5lD3KrW3m6esg67f79T9pMD%2BZtCjTnqVilIW%2BKeFRshPWVAP2P9%2BJ%2BzkZRB3DPFlljlxRPz5Edx8mcw%2Fm3aXvkzULyUC3122jET2oNA8kh9NZYT%2FJvzb%2BTOZabIhnWkgaOQcwxO577%2F5fjhKIYndoZvgaUD05v5SN1J%2FyG6YI0RZ4tS%2BoyKQS1HTwYHsffALrdOQwM%2BLGOEHfhu6PWvJ6f5FsfrXnqW8K%2FDBEZD4cmAVf1Z2fOSeSLmfT9RrHEWlvDSZaVagNR0%2BztnW8mWsuzZs2BDs2bNirs2bNirs2bNirs2bNirs2bNir%2F9fv%2BbNmxV2Y5so4qw6WL9HeYLiLpFcUnjHQfH9r%2FhuWSbTnBgMXeJiv0H4l%2FA4T%2Ba4fTW01FRvDJ6chA%2FYfpX5MMGaXcBmHxbSrsCdi6%2F2f8RyZ3j7kdU4zZzrTfO2qQa3eaHrkax6haux%2Br9FkgJ%2FdT2790ZP%2BGydWWoWt%2BnK3erAfHGdmX5rkSEovNm2yiQASTQDqcCt5sL5dZ06Ko9YSMNqRAv8Aiu2Iv5i0qJecsrKo%2FwAkk%2FctTho9yo69htbi2e2vApgmHB1cgA1%2BffOYX%2BnXflXUghJezkNbabxH8jH%2BdcPPN82l65b2j213DN9WdmmtefCRkdeJaNSVb1I%2FtYXWM8cVk2javM95pUv9zcPvLB%2FI3LvwwhIT2x12KCBrxjyjRS06jrxG5YD%2BZcrzzpkXmjyhLPpzCSaFVv8ATZozuXjHP4GH%2B%2FE5JkUmju9BujaTsJYHHKC4G6Sxn9r%2FAJqwJH5g1fyjDaw2KrcaE0zSNE27RiQmtuXPSJ6%2FuW%2FYkxI6hUg8ia9qulatHe3s0k8DgxGKZywBk%2By3%2BTkn%2FN63a8ttG1a3rHL%2B9hIB%2BIdGK%2F8ABA5DNbS0tL%2B4ksJOenzETWrjYiOT4gjD9l4WqjL%2FAJOTTU9XtNc8r6dDP8E8rc4iSP71RwkTfcP%2FALsX%2Bflgq09zFvKeoTMwV2NeCsB0BaNqf8a5N9Zu59K83W2pWb%2Bn9cjBo24ZXUNxI%2F1lyCWsL6fNb3LLxid24tSgINA9Puyb67pd%2Fr2kaPc6bxN5b8owWYKAYW%2BGpP8Ak4RyQU8ufOF7JLD9XRLaAj96ZPiYv4A9An%2FDYOfz9oEbtA0kjXSqG%2Brqh5NtU%2BkW4iQL%2Fk5yK%2FiuNagjEcpTU7Rj6YqaSAbtG3%2FFin4om%2Fa%2BxhXcGeWxlDgpPbfvUFaPDKpFXiI%2FYk%2Fk%2FmwFXr0n5hfXBJFpVtxmC84jOa81%2FaKqv7Sfy5GL7zJq2rwXFhqF40AlWiSQfAEPVW%2BH7Sfz%2FwCRkTl1dLW3t7xi8108C3g9EBArCnI8jtVvtNRcR1zzTdJcQvYwRW7y28dwzFfUblIvI05fAo%2F2OGxSt3zSW9LPXITMlCjiuzofsyRt2YfsPkd0iabTtQksp1Zra4U84X6SJ%2Bw4%2FwAoD7Ei5dzqV7LFCt7KZnVAY%2BRqyg9aj%2BX%2BTJdouuaHrltb2PmCNfrkKmO2vKcT%2FkgsP2v5cjtapfo0Jt%2FMllFGHltZvVeK4ptwWNi6yU%2BzIvRlwm1mUarpNtJHEWutOkuIbh0FSbfkGiZ2%2Fb4MxH%2Bpk6uZNM8saddywStNK605tsKnYcF%2FmbOZy3s2nWaLE%2FG4e4%2BsK43HELxowOzK%2FL4lx5fFWb%2FlprP1TWLQMaLMFRh%2FlRtxr%2FwLYn%2BfNjLp%2Bp2WpwghWLxuf2SGoRX%2FAIDI9peo2kMtjfWQMUi3JM9u24j5rT4D%2B1G5qyfyfYzp%2FwCcdimr%2BUra%2FG%2FwpISOoIpXJDcIPN4HDcR3Scl2I6qeoOGNvcQyw%2Fo%2B%2FJWGpNvP1aBz%2B0PGFv8Adkf%2BzXIxSaym2NCOh7MMNYLhLlOS7H9pfA5FU30vUNQ8uaqjIqsaqHiO8UsZ6EeKsrfA%2BS3yUr6p5iudTl2S1RvRTchTKeCgV%2FlTlkOsvUveOn8VkdatauxoyN%2FID%2B0r%2FwAmTfyYHsrnTdPasc1%2FNczXMZArwhT04g3%2FAD05Yjml6Fditlcmu%2FpvX%2FgTnK5bS4sp1mDtFID6kLioPXZgc61NGTBNH4o1PpUjIpNbyX0Ulvcw%2FV9Tst7i2IqHWn99EP2kZf7xF%2F18nMX1pANMR1TTYfMkRuYYlt%2FMEY5EfYW7UftL%2FwAXjDf8u%2FMFzM8mnX6MJLWRFkMh4yiqtGUYU%2FZP82IzW%2FH4DVQG%2FduPtRP1FG%2Flb9lsG6ZJDJfPcvGI9WCoJZwPhmRGHF2X%2Ffi4AP2peafmBE8Hmq8LgATCOVaeBUL%2BtcjauUPip6qe%2BdJ82x293Pb2GtyL9ZmWRoL5QAUZZGQK47p9nOd39hdaZctaXScXXdSN1YHoynupwFCL0zUX0y4SVGf6uWDqybPG46On%2BWv%2FAA652nRtY%2FTdqJbfjLdqnK4gjpSVen1iBf5G%2FwB3Rf7qfOCxycaqwqjfaH8ck%2Fk%2B61K11AC1kZYIT6gmB%2Bxy2oP%2BMi%2FC6f7LEGlZCbBr%2B%2Bu%2FqqpBCjP6cbtxHwn4ljrX%2FgckOj2EMcC6lK6yTRKYmkIoYl6gE9xT7L5HhcTJqM1jJCEjjQSQsK7qT3rgi%2FuJ7PTDKQ31S5f03ZPi3SrfGP5RiKG6bej%2BQPzB0CG%2BuNHvB9VeZx9WvZKBX7cCf2P8jOvghgGU1B3BHfPHaQrfuEt3DHkAJakKhP8AO37A%2BedX8i%2BYPOen6dNp2qK5t4JFjs5HClyoNJfTdieUaL8S%2FwDCZEcRNEc%2BrfOOKWMTgeGUaEoHfi%2FpRP8Aunt2Ab3UorWqAc5QK8egHzOPhuoTYrdesJYgnJptgDTqdu%2FtkT1C9XnLPIwofjLduJ6fhkgLcYsi0vVRfSSRSUWRd1UeGGgyN%2BVrCSkmrXKlXnHC3RtuMXXlT%2BaTJKMTV7JdmzZsCuzZs2KuzZs2KuzZs2Kv%2F9Dv%2BbNmxV2bNmxVB6rafXtOuLXvIh4HwYbr%2BORbRL%2BsMTMaSQsOSnrseLZNDnIdfXXtP8zXtnZGC2tJWEsUz8pH4yAE8Y14rs3JfibJRPMKyf8AMXye3mKyh1LTH%2Bra1px9S0ulFSV6mNwPtRnIb5e8wXlw%2FwCj9VR9N1u12PGoD9vUgfpJG%2F7UedN8uapcXsH1e7C%2BrAi%2FvV6OPs1K%2FsttgLzP5Ysr%2B3NzHFxmjPMlNj%2FrLTdWHtiNtlU9I82sxa11lAssf2bmMfA9PFf2G%2F4XIt501y81SykEEjRQRMGEaMV5L0%2BKn2sq4ke3j9O4asuyLNSnMduX%2BV%2FxLCfVZ%2FS0u8cDkVhYhfGgxodGQDDZPMculusTzpwryMT7mneh%2B0uTVNL1e%2Bsob1tLmmtJlEkbFW5FGFR8NfUzi2iQ%2FXNXtLjUAXWe6hE3L%2BQyKHG%2FbjnqzzP5ok0H0baxgWVyodi5IRU6KBx74ASrzOzsfL1tcH69ppMtdxM0h4%2F883OS2GLS7239K1pGpGwj%2BEr%2FALHphVcecBcyrc6vBFdabL%2B7lV0UPbt12KDnx%2FlYYGvrWKwP1nTp3kirsT0BpWgcdf8AZDJg%2FFjSanSb8xC2ursXtpG5kt7dkVRGaU4g%2FETy%2FwBbIzc60xSeylsgphDJeafNtIY%2BnqREfCygYcWPmV14x3qkqQDzAo4X%2BYr%2B0ME6h%2BidZZImjM90FLQzQj40BFNn2%2B1X7DYkd2yi%2BrHNIh8uXbLp7yLJdToZbZJDX1EU0NOXxCeL9tf%2BJ4PhbTLya58sXqqt3EoKlV9MSoRUMn8ssf7XH%2FXyD%2BcfKFzoWnRatFqUUU%2BnSGSGAsBcFXZaFeHJVZDu2HOn3See9Kt1%2BsCx8x2y%2BpaXabB2TxH8pP21%2FZwAnu3VQuV1CC2iW9cx%2FwCkS28kMtA5dKLHL1%2B00TJyZPhk%2B1nS%2FKN59Z0GSNno6yI6e1V4v%2Fwy5z9pv8YWj6Hrcf6P836EWmiiHSfiv2ox%2B2kwH7P2ftLk28uxrbeXYLhYXV7gMzxkE0IqPiqNq%2Fy4gb%2BSk7PNdX1m%2BHmqaytJ%2FTtTdx%2FBGoSu6swZqcj8YbCnRmM97drKxKXcslu7tXb1%2BSBq%2FwCSzZK9c06xuNUutStkBls5IFkAIAMoHqUUfzNRkbCPW5Xs70rZcVtL0%2BtCoAFVc1oK%2FwArni2RIShdD0rU9Z0g2UNW1DR5JLG%2BirRlQuXhmp1ZP72M%2FwCph75g0K2sra21G8ch5baGJUpt6yARuvL6OWEQk1eJrq9s55YLxBzuGhJEjr3LKvxSqv7WISanq2oQRXGryvd2MtVhuSQ8aNQch8OyNjsqElhK1hbcr%2Fcv3K%2FyV%2FycRSQBmUiifsfQM6FpfljSbrR0mCy3EjDlDIzN9sGnphU%2FZ%2FlbIrqnl%2F6jM3Cb1VRqOoU8078XoOHPISIiQCd5ckgE3tyS4StK6xSy%2FDJ%2B7HqseO%2FYVw0W2thatp10he2b7YH21cfZljP86f8AD%2FYxO4tbO4so4I7ZUvG5Lpl3PssprUws392JD%2Fut%2FwCbAOh6sLuU6VqYMF4hKRu2x5DrFID0YY7rsh4tMn06%2FkspjzjniaS1nQfDIE%2BJWXwdafEv7Od0ugnmL8tmYipWEOB1oGWp%2FwCH5Zy4hoT9WuU5BTzj7FHp%2FeIe3%2BX%2FADrnR%2FysvRfaHeaJIwZ4RJGo8QDzQ%2F8AAy5OPVBfPNxbpMpifYqaBu4IwFYWlx9fEIJU7lmH7S%2F83ZJ9e0x7K9unRg8azMkoHWJySVR%2F9YH4W%2Bzj%2FKtvFdaxBDLQKzAVO243G%2F8ArYPJUXb2NvDZtdyWxe3B4meCQ%2BtG37Jkjb9lafaXHRXl9q2r6etnWJ7Yxx28h%2B1UNyMjt%2FlH4myX6lp1poPm57CIFLG8jikCsKisqqXWncc2%2BzhLZW0Om35hCuLiCeSgIHFY67KT9rl4YaV63IwMVSakg1pt27eGRuzvrTWILdYbnlcIWXSdQc8W5pXlp91%2FLIP91M%2F94mG9tcfW3AQ14xgsPH4c4Zp%2Btz6HqN2rJ61nNIy3loTTkA54yIf91zR%2FailyRNUinpV0iXqyyxw%2BjdW5Md%2FaN1iPdqf74f8A5Jtka1ZZ4LWYxsySKpaCRT8QI%2BIxkj2Hw5KLe6%2FTsUF%2Fp1wsmrRRk2l0QAL6Fft290g%2Fu7uP7Lo395hFquqaL9XZmmWCRwySWTgs8MgG6Oo%2FY5fZbAUhC%2BZ9JsfMl1SKYW%2BqyQRT2DMf3UvJeTwt4M5%2BJchKyrOr6D5gQwTQEpFK%2FwDeQv8Ayn%2BZDk%2B1Gyj1ew0SaC4gS5ntmCtX0ELQtQAM%2FEcv5Fwv1bQxr%2Bnhr4oms2ymP6xuCStSIbof6v8AdzYOaGAQ%2BXdTm1NdLjj5SN8QkG6FOvqBu%2BTjTrS2sbZLCMcVUmkpFGLn7Rf%2FAFv%2BFxTTme102DTuILIwZpKksW%2BzxWtW41%2FZyU2XlW41HhcahytOQJZVHKaXw%2Fd%2F7rY%2FzviAqQ21ldXtytrDG0k524qKmnj8sO736roNmNIltfVv7hFeaMnkUqTwpxNA2S2MaT5etS9w6WdtEvx1b42A7Symh%2F2C5zTzb%2BZun3swOjacGVKwrqMgoajeiJSr%2FOTDVdVZPYa3pOj%2BW7u31uKKzuZGP1dePP1Iz1UovxtJ%2FlYU%2Fl%2F5hOtyS%2BWrlis1Gm0pyfiR4%2Fi9Kv7SumcrvNYnu5DcXH7yToamrfSf6YL8ratLZ%2BZtJvoT6bwXMbEjuCwVh8uJauPFuFe%2Bx%2BYJ4NMawQiOFzyZOlDX4h%2FwQyQeVtAn1BY9R1QN9WU1toG%2Fa3qGYeGE3lnRLPVfM19LdAyWkTtcW8a7xOGaq1kGz7k%2FAM6moAACigA2AxJ7lojn72wANgKAbDLzZsirs2bNirs2bNirs2bNirs2bNir%2F9Hv%2BbNmxV2bNmxV2Qzz3p3P6rqKbFKwyt%2Fkn4lJPseWTPOVfnX5gmstNtdBtnMbajykuXHX0YyPh%2F2b%2FwDEcbrfm24MRzZI447GR59w6pMfNyWl7EdD1KM3Cp6dwoKldj%2B1zHE%2FRko0rz1rUtz9SvLe2lm2Hp8jC7BhWqV5xvUb%2FDnn01jPEin8pHgckemXmsTaHcxANw05o57O7IIKxliJYll%2FaRT%2B84%2FsNkIZhIkSjRDl6zs%2FwIjJCXFHkb5gp3%2Ba2r%2BbdPuEvYLVbLRpiFL27c2EvWkj0%2Fd8v2VpkGsfN2p3Kra3V2XicgEsQeQJ3qSNs7d%2BkdO1rSbKw1LhN%2BlbRXVJKFZyq8ZV3%2F3YGHLOEecvKFx5TvTLDym0idv3EvdG%2FwB9yf5a%2Fst%2B3lpHUOvsua4iNwbWCruHK%2FB0qN9j0zoy%2BarW48r2Oq3l1Le2sSizuGkqk6zgUVXMda8F%2FwCDTOO2M01rIs0XCRQ4kHqCqGnZl74NgkTlMqSOIZpPVNrXjGG8Qvfj2wXzSyqz1eO%2FtNSjQM8sVubhFbbkIpPiI%2BUR5Yca3q17IdPmtZ2js7yztriONNhyAKSciPtMJUfIZaXDWL%2Bra0jcq0ZYAV4yAq6mv8ynJf5Yex1PRjpUsfO%2F0pnuLJWNPUgkNZ4l%2Fm9Nh6vH%2BVpMRa2uvBcXej2Gp2rSC5tJJbOZkqW4v%2B%2FgY%2Bx%2FeJhtBB5sOi313boLa9ihMlo3EB5ClGkULy%2B16XJk4rhlZarBFAbZljtrS5Tg%2FoIF4fyOT1JjbC1L%2BbSbowyMwu4WrzJryX9h1PQpxw%2FFWFXNut9PB6srS6frlqI4JZHJ%2Br30bCsbOf5phx3%2FAN1T%2FwCRgPQbtreVrEFrW8gfnDU0dJUPF09unHD%2FAFeygjjvbi2haTQbpxcXlpHvLp9x9n6xClfjtjXi1P2P3b%2FGseE99ol9qtyjIKamYlktb6Mn0L5QKJ8Zp6d3x%2BH4vt8OD%2FvciTXPZaZ%2Bkdp5%2Bgt19Yad5p0%2Fe0vU2Y8T0NPiaM%2FtJ%2FuvOj6lcGysFaRlYxJWUjfkUXk3z5MM5p%2BV2l3U2pPdalFHK1sOLyqQxSZaFOdDWOT7W%2F7eTTzK8UdlcxREhXBTf%2BdzWg%2B7JxNji70HnTz%2B51GXyrrFxaapD69nfcRqSftqxHL1oj%2FOjPjtQ0GNYCfrCXWi3QMtlelhyjkYbFfdvsyx4M87Wy6zqemTq4X9KwQnmegkK%2Bmf%2BSi5G9M1PVfLUt3od3CJIGDEQS7iKUD4Zov8%2FjyErqrruPNkK58%2FJN7Sx0%2B0sDe3k0k9xA6JBJACGqwPHiKp8S8fts2F0mrDS3nubPThH6ZLa5YcQsnBvs3kSsCnJeXJuK%2FB%2FwAYmwQ%2FrXdjEsQRizhvjKCrUp8If4uW%2FwCyuK3Fs893p1nezfVdeDCOxmHFi8ZH%2B89wSeBjP2YuX%2BVFiYggA70Pmt9QzfyjdxXeiPeaY3rNYt9ZjdKUkgP2gyj7L8ftL%2FPgTz2tuLdJIT6cN1JFcxzJ2U7Sb%2Fs%2Fa5BsKfLEMvlPXby2sJI40uF%2F0izVuUcb05n0z3gkTlw%2F3237vHeddXN5pEMdnbmOys4BFcy0qDcF6GJa%2FwDFacmyX8Pu2R1QOi6Yupabd2F78dj6xjLVFUlpySaHwkUf7F0%2BDIrrvl6dr42N0eOtRIHs7ldkv4B9ijf8tKgfB%2FP%2FAHX28mPluyb0Vs7OdTL6SSReoK8%2FTZqN%2FrqOPL%2FJwTqdhFr9m1lqUhjnhcm2uv8AdltN%2FMKf7pb9tP8AZrjVhWHaHrEWqxjTb9gt9GKQytsXptxNf2sl35d3J0jznJbCojuQlR26cT%2Btc55qthdyXcyyJ9X8wWfx3ESbC6UbrcwfzS8fjfj%2FAHyfvPt88N%2FKuq3F3q1hqBIEyc4pWZuCkoAwck9MA50VPJV%2FMq2k0TznfCJQUmPJom%2BzJG%2FxcW9t%2FwDY4Q6cILa6ZY2eKRwslv6goaDfjy%2FaK4f%2FAJleadM80a8t1pcZ9GCJYmuG2MrD7TAfsqv2V%2Fmwr0WyuNXUw%2FVxci1%2BKLt%2Fw23wrg6qGVanr1vrK2t3csIry1aESBjxJEYYOQff4cjvm3zLbpZXLWTGC5vr%2FwCswRjfjBGoC8yfi%2BIjCPX2vNMu%2FqZDRNGKSAgUqxqgqKruF%2BH4sjsyPPIZZSXJ7knfG1e9%2Flxrdt5ksbqdSFu7eMLcW5O4%2BE0cV6xvnF75uVzcb14yyBW7%2FaO2KeS9RutC8yWd7DMYLfn6d3L%2Bx6D7SLJ7YhdkNd3UkRDRSXErxMDUFGclT9IwndCtpWrz6ZN8MskcDsGdojxkjcfZmip%2B2v8AL%2B3iWoySfXbiHUmFy14frKXqH4nL14zK%2FVuX7cbYEeJWDPQVpU0Pj0x6yqLL0pJUW4tXE1o5O9SaSRbeP28Cob1Z1T6vPKzxjeNSSQK9aV%2BznXLfUrdtDt9T1U%2BjeRxpa3iMvF5V41jcg%2Ftrx%2BLOd6VbaTqJlS7lMl5Iri3hHwRiQj920snhzODppWsii6zcGeSZg3po3NSy%2FD%2Fen4K9V542r0LyheaXcm5uaCCWNhxkl%2FvClOqcvs4rrn5g2enI9tpKi4uqlWck0rSvxP8Atf7HITazpccriNaLGD%2FozGnBVIJkZP261%2BFuWE4juLqSZo2pbJMjyitAQeVPwrjxbUE01reuXGvCKPUZJ2Cs0iqgUgFtunw%2FCKfDhWLXSzayW73jxuGElWgJUbUoSDhkLcXEjJDSJqkoSd%2BH7OGlh5a1HzDONIit%2FWvZEMkJRlQtGlKsCxVX4%2Fy%2FawWtILTLTTmeMmbTrm1jXe0nmMLOwH2nZlrWv%2BVhlBb6Lql09zpemrbx2cJe5WNqiRi3EKrfyj%2BZR8WJ6x%2BVPnXQrK41i9sljsrUB5pBLGzAVCgiNWLNufs4I8h6hp738sNxRBexei5BoBJWscg%2F2Xw4VZjoMllFbx635Y52k9mvPUdKaRjHIF%2B08PInhJQV6%2Fa%2BHOq6d5%2F0G7toZzK%2FBwKzBCVrTo3GpQ%2F62cYW21DQ%2FMUVrFH%2B5vyInPSIqzfE1f2afawkmtp42klt0f6uzuInWoDqrFQRQjkMJV9Q2ms6VfitpeRS%2BwYV%2FwCBNDg2ozzr5Y1vTI7V9L1PnbTDk8E4Qs7M1KKHBDp9GTfQfOdosSxw6txkp8UN0DxBG37WNea09UzZBNY%2FM3SfLcVrLrDIyXZKwm2bmW40DsF3%2BFa%2FF8eTW1uoby2iu7ducMyCSNh3VhUYEK2bNXNirs2bNirs2bNir%2F%2FS7%2FmzZsVdmzZsVdnE%2FwA9rKYXmj6jT9w0ctuT4OpEgB%2F1lOdsyO%2Bd%2FLUfmvy%2FcaXstxtNZyHosybofk32G%2F1sB5ORpMoxZ4TPIGj7pbPl%2BNPrERi%2FaG6H38MkPlXzh%2BjhHo%2BrmunCqwXFKmDmfiSRf27d%2FwBv9pMJBDcWN7JaXcRhuYHKTRPsVdT0P%2FNWB9RiWO6ag%2FdygSL7cuv3HKpkwImPcXoM2KGaHhy3B3BHf3h6B5qslXQooNOVof0a7Xdi6fDxBPKQQ78vT35xNl6Fr1l5s0yXSNZRHujHxlRhtMv%2B%2FE8JB9r%2FAIfILo2pT6XfLd8mmiKehPAzE8oT%2ByvKtOPWP%2BXKvrafSpl1XT2L6ez84LqLrE1a8WH7PH7NDlkMoluPiHRarRz05F%2BqJ5SHf1CT%2BZ%2FLlz5WvvTUmXT5jW2nP%2FEH%2FwCLB%2Fw2FauD8Sn6c67a3Vh5x0p7G%2BRfrAWskY6EHpLFXp%2FxpnLdc0S88t3ptrir27msE3ZlH6nX9pcmR1HJxFS3uA4oftDBlvcz2lxHc2sjQzxMGjlTYgjCVG6Mh%2BWD4ZRIvv3GC1Z7pdxHraNJCViukq13aswVAO9xCW%2F3Uf8Adkf%2B6%2F8AVw1t5NPkKabe3SyqKG2uIquYDX7Jc7ei37a%2FZ%2Fazm9tdT2dxHdWzcJYzyQ9R4UI7qw%2BFhkwhvDqECTaZbExyHhPbqKmCYivBf%2BKZPtR%2F8DgIkSDxVHqK%2FSyBFbjfvR8k1xY6gVtLb6vJbVWZbhvVLo38yAemYZF%2F4XCjW0McX986%2BX72Uem6V56bekVAYLu0D%2F8AJSL%2FAItjw7W0utVgj0%2B7k9DULc%2BnaSMaFkrvaz%2F8yXP%2Bpgq00iztbkaVcP8AWBer6NzEworLWjRsoJ4yRv8AEjr9jGOMDbn5y3UyJ8vcyfyHpl1puhy31zEE1e9cJfKxXjK8JMaTqfGZCrt%2FN9rCX8wda%2BqyabAGAM85aYA9FUcV%2FwCGyZXElvb20VgHb1LeNDEKmpKDhGS%2FfOK%2BcrhtU1G8vLZ%2BYsz6M0Q%2B0nBh6cwH%2B%2B5af7F8slsAAxG5tkesTm68saddo3GbTZ5bb1B1G%2FrRfrxGTW7LzPpcrahALfzDpir9biI4tJESAZowftJ8Svx%2FY%2F1cD6VMb3RNTsShJmhju4gVP2ovtH%2FgG%2BLBVnb6b5g0ux1JGWDXNDj4SEiongQcGjk%2F34hX7LfsYBukt%2BWba4gWHWmj%2BsWdpK0Dwqy%2BoWkonJE%2FvHZOfNcKdasnk80288TN6EEqxOXNWSOJiS7n2p8eB4bySw1ilv8Au4OQk47kKo%2BLv%2FLX7WK6jr4u9Uee1jItndiIiasyv9sV%2Fl3wWAFZBbvYajqsV%2FDSP1yITPUgSKH9SSinYcIRw%2BH7TSJhr%2BYOr2sOkWmnhHSK6YiRolFF5A%2Bn6ngJif8AWyP2ML6dbiRI%2FrqsAI3SRAsMY%2BxHKrlGhfl%2FefB%2B8%2F3XgXXYppJG1m2unkbj6Op2pUSKVAqksSNsif5L%2FFH9vHoUlrytdtDCgdmV7d5I2boU%2BINGT%2FLhpr3nLTKJ9UT19TB4zNHtCe3Jj3b2XIssp1Y8bUfFOQsix7SCSlAXpTmj4av5OnsdM%2BuzB3Zm9OWaNGD2%2FMgRTolP3sXP4Zv92fyYi6oITDVrG28x6NBeBvqWoWS1ivSeIikU8jFI%2BzLA6%2FGn%2B%2B3yFaq1pcXix28ZUGi3U2wadx%2FuziAEWv8Aq%2FH9vDLV7TzXeWrqbaWO4VhHeNHtFdCP7EhX5D4v9%2BfbwpC3liGgvIoVdSqt6pLPGr0pTj%2Bz8Xw4CUkEGil7RwRu9ZzwjPx8UZiKePShyb%2BRfMdhHM2kLEV%2BsDlDLQFncUCxcRX7WEF1DCs63zCs6r6c1Nkencr7rgXSpFsb5zCForepC9PiUEfZr4DADRVD%2BddUkPmPU4lUgVNtNG4qDw2Bof2kP2GyK1LECpY%2BAqTnUFhsta1Ce%2B1G3inuZCrySsgqwqFNRkwu9R8m%2BWIwscEHrharDBGjSH5tT4f9kcIoop4da6Vqt2GW0tbiQHbikbkH57UwHNFLbSvb3CNFLExSSJxxKsuzKwPQjOu3%2Fmq%2B1mFo1C2NmFMjhTQLGu%2FKRtumQfU%2FMWh3uoTXx0r1pJePKSWSnJlVU5lQNufHnhQxmOYxklSPiFCDvUZQKUIpUn7Jr0%2B7D8eYrBP7nRbUf61W%2FhmPmtkBFvptnEezCMkj78CpRZOY5w%2FBmWhBCjseuSyyn0pIpIr2CSr2gtbYTQt6aylufPp8PBWbCZPNurROskYgVkYOv7tSAVNRtg2780%2BYPNd5CdWuRJHEWkWONFjRaih%2BFAPljsqLeRrVh%2BjQt3GBRoXBBKAfFwag%2BLJ15B17yfealE2taTHcXMG63Eq%2FvbYL%2FvyH%2B6eFK%2F3iJyT9vAXkPygPNEuoxx3KQ3VrAHtYWP8AeOxpv%2FxWqijMv2WZMLdS8vBLx4pg9jqVqTFJIvwup6fvP5lP%2FDLillv5i%2BStPtL867pEEcem6hxkivLWjIk%2FevHb05ftZF9Okd5Et5mayvoWEtrdRmnCUfYmhYfzftp%2B3k3%2FAC68zLfx%2FwCFdWt1eElrbUoW%2BwGIrDPGv7CyU%2BLj%2B18eIeavKM3lq7WqfWNOkYizuXFeNesE9P8AiX7WNbqCncfm2fzRoUmg6zEqa7ZPDPPCv93eQRMC00A%2Fa%2FZaWLCHzf8Al7oOra5b6h5KuBHe3rj61Ywr%2B5Xlu0%2FL%2FdDfzx%2F8Qwpup4VWBrORhfW7iS0YkrJbkdRLKv2om%2FY4fbzsvkXU7fWNHju3jhj1ZAI9UEKhSJvEmg%2BF1%2BPEhXgPm%2B98y%2BWriTyxrM0iCMBo5VVW9aDoJIZm%2BLif5ftRthN5X8zxWXm%2FTZ9dHq6HH%2Foz2z1eNLd1Kq4TvwY%2Bo2el%2FPXkjTPPGkNY3n7q7hq9jeqPjikp%2FwANE%2F8AuxM8mazo%2Bq%2BV9UuNI1KL07y2PFlbdWU%2FZljP7UTfstih9Jy6d%2BVV3f2dja3ltHe6ipezS2mrzAFfh%2B2iMf2K%2FE2Xcfk5ojoTZ311bz1JEjFXG%2FitE%2F4lnlh3USLKCY7lSGLQ7UI3DA9mz0L%2BVP5wLqxi8s%2BaZRHqIpHZX0hAE9NljlPaf%2FK%2F3Z%2FrYqqal%2BS%2BoXb2EYvraWG3kcyvLG3IRuwY%2BkgPFW2PfJjZ%2BRruwuFa21iRYFACKFKsKf6r%2Bmf%2BReTUDxy6Yqo20LQQpE8rzso3lkpyb58QBi2bNirs2bNirs2bNir%2FAP%2FT7%2FmzZsVdmzZsVdlEA9cvNirzb8zvIf6bhOu6REP0tbL%2B%2BjUb3EQ%2FZ%2F4yp%2Bx%2FP9jOHagvqWsMw%2B1ETGwPWh33z1znI%2FzL8hqEutf0qP4JRzvrdR9lwR%2FpCDw%2F37%2FweRnGxTtNBreExw5DsD6Sen9F4gpphto2prYSSQ3Ketp11RbyAiu3QSoP50%2F4ZcK5YzG5Q7eGPEUyRpMykRSEhH7MV2IzGAkDY5h3OSEMkDjyCxL8beaZaglxoOpxTW7qLSWkmn3cX2eJ34nx%2FwApclMsen%2BcdIeC4QCZQPXjH2kanwyxe2RjT7%2B2e0bRtVHLT5SWhl%2Fat5Ozr%2FxWx%2B2uJWtxe6HqSw8wtxDvBL%2BxLGegP8yOMyceQEbcuo7nnNVpZ4JmMtwd4y%2FnD9bENU0y80C%2BazuRyTrHIPsunZh%2FTKil4kSIaj%2BGdZ1HTtM846SXUenKv2gN3glp1%2FykP%2FD5yO9s7vRb2SxvU4sh3I6MOzp7NkyOo5OKmSuGUMvQ9MMdF1m40S%2FjvoAHUfDPA32ZIz9pGH%2FDIf2Gwjt5Qh3%2Bw3%2BdcFnrir0GW5Kyx6hav6ltfqDHddW5Dbi1do5V%2Bw6%2FzZLPLbQ6nP8AWrpAby3oJGI2kXqkrfyyqR9rOU6HrKWHq2N8Gl0y6p66Lu0bjZZ4v%2BLF%2FaX%2FAHYmda8p2i2tk8sjrI7miTITxkj%2B1HJQ7huJ%2BLJR3K3snuq3fo2ruoqQC3idvsgD%2FWpnMJ%2FJ%2Fme4Msq2jC9tuUaXcXER3drJ1japH72NW%2BFmX%2Fit%2FwB5nTdIksyzW0c%2FryxVZgzBmCsa4eCZAKHDIWgbPDvK9jquh6xaW%2BtW81rDL6lozTKaFJQVAB%2BKtfhwvs47myvL%2BNQfTs2kD9UK8gQKlv2Xp8StnR%2FzQ1GW08u%2BlZO0d3dTxxQshKsKHm7hh9jiq%2Fazi6MxEiI5YOa3NyxJMjVrux%2BIrlctmQ3TS91E3jCG2jHI09R1qOdOgFf91r%2Fw2CLKFYxyJBIFZJOwHgMC2NryG3wRnq56t%2FZhusZiihu7cMWt5ir2zpyikUAU9T%2BYcuWR5pdPqiacQrWqXCzR1USVBAb%2FAHYp%2FnwutdVhtdTa%2FgWVBOAk8BcNG9BTqyk4c6rc2dxe2F3c2kcKJGI7qx4kUjpyR0B6Vr%2FNhBqc9haSxpHERaXRaWIt%2FuvcoTRa75PlyQn%2FAJZvYI%2FMUS2SNELiVTEygUjnVW9OlftI8hVWVsnSXVxfTGS6laSViCS2wodjsNs5%2Fo8rrL69qwd6pIrqAw%2Fd%2FYPw9OmSua51GVJ762swQXLCD1AiryNQrMfi2%2FyVwxKkIjW7%2BezjR7PTpr%2BUbv6WyUH8zfa6duOEPnjT7SEWmrxxkSXatazowA5KY%2BScgD9qIrxwQ3mPX7EetqFhAtqPtegzySAewA45F%2FMHm1dcRIGjMdvC%2FqRIKcuVCvJ2%2BR%2BzglLY2yhjnLaESfcEquburW8M5HpzKvIr1FaDl79cRbRr6S8%2Br245GCoac%2FCjKp67%2FwAww%2F8AL3li01qBLgPJO8f7t4wP7s%2FsE9fhOHer%2BVtfgg%2BvabcJe1FJrPjwZVUU%2Fdy%2FR9llyIFixuEzjKEjCYojmGM6jaajZ28RjBiEisJzULTi3iSKR0wboHkTXdWt21OLT5ru2A5RlN1k8SrsVWT%2FAGD5ena1aXA%2Bo6pD%2B9J2WcenL%2FlBJR8D%2FwCrnSfy880W%2Flyzl0m7uJZtJR%2BVmXSsltyNXhYD7cP7ScfiT%2BXDXcxosR1D8rvP2qWUdlZadHZW7kPcPcXEYeSn2EKR8%2BKJ9rh%2FNkRu%2FwArtc026ey1FooJo9yKs4IP7StQclz0brf5jeXtKhR7eYX0sieoiQHYL29Rv2Cf5T8WQ7W%2FMj%2BZrOKd0t1Ct%2B6eDk7xMaj05CaNxb%2FVwEgCy249PlyECMefJ4235fXQ63Uf%2FAt%2FXC7VvKsmkfV7iab1dPlISW7jTeFz%2BxJHWoPg37edQ5kyNDIvpyx%2FbQ%2B%2FQg91OB7hFCurIssUq8JoHFUdD%2Byw%2FU2IIIsMMmKeOZhkiYyHMF5g%2BhCNipcyFf3nwD7cH%2B%2FoT%2B1x%2FwB2J%2BziNyW01%2BNseVtMoMc4G7VH82TCbyxfWMxtUMlnDIPrOli55JIh%2FwCK2ZeMqthYYOMVxBNb%2Fu2HK%2Fsl6JU7Xlp%2B1xDfbT%2FdeFgmPknW7q0eC%2FsZ%2BOoWTck5ftRnrG9PtIfstnatY0iw%2FMfQ4%2FMWh8bfXbdSjxnbmyD47S4%2F5ky55gWcaZqDPp1yZo42Ppz8SvIePHOn%2BTfO2qaXML%2FSHiPqcRf2M9fTYf78Xj8XIfs4qoWsGsQ64Tpp%2Bo31zGbK9WYfFE8Z9TceI4FP9lnpNbWDVdGit9RRbiO4gT1g3QkqCW9jX4lzksE1z5382DU7WzEKoqq5UVAoOIeV9uR%2BL%2Fgc7RDGsMMcS%2FZjUIPkopj0UvHtQ%2FKnV9H1F9X8vXCajyYt9TuQoYLSijkx9OTj%2FlcMS8q%2BaLny95guoNYs2s%2FrfEXsLLxKyJXjLH4pxOdpwl1zy1p%2BvCOSctDcw19K5ioHAOxU1HxJ%2Fk4otNoZYriJJoWDxSKGRh0II2IyF%2FmN%2BXll550z4OMGs2oJsLynfr6Mv80L%2FwDCfayU6RYNplhDYNMZxACqyEBSVqSoIH8uDj0xV8NappV7pd7Np%2BoQNbX9qxSaJuoYfrr9pWwuSNg4NSHBqKbEHxrnrL80Py2g86WX1%2BwCw69aJS3kOyzoN%2Fq8x%2F5NP%2Bw2eXm0q8guZoblGglicpNA4pIroaMjfy0OKvpf8lvMusa5ol1ZazOLqXS3jiiuTvIyOvJRIf2ylKc86eM8y%2Fk35usfK2r3FtfyMtjqoRZZ3qRFNGT6bP4IQ7I%2F%2BxztF1%2BaHke01SDR31aN7mZ%2FTLRVeKNu3qTD4F5dMVZlmylIZQwNQdwRuMvFXZs2bFXZs2bFX%2F%2FU7%2FmzZsVdmzZsVdmzZsVdjXVXVlYclIIIPQg47GSOsaNI5oqgsx9h1xV4R%2BZvkA6VK2r6VH%2FuPlarIv8Aulz%2Bz%2Fxjb%2Fdf%2FA5EoJLK%2FwBFh0yOJU1AyrH6oABboqJItebtyJkjZP8AKVs73qnm%2FwAsyW89les7xzwtSMxMRKG%2BHghpx55w%2FwAy%2BWpbIHWNNjeGKFkDjlVw5%2BIPGwp8S%2FtcfsZGUauQHvdvpNWJxjhyyMZA%2BiXQ%2BUmMXNtcWVzJaXSGOeJisiHsRtll1uLf6rcMeKb20vVoW%2F6pP%2B0v7GHsLr5ptvq7mOPU4ElmEhHH1eCII4kp%2Bz6aO7%2FtephBNBPbytDcRtFNGaPG4oR7EZVKJHrhz%2B92JjDPA4cw3HMdR%2FSiiNG1m7028EiEC4j%2BGWMn4JU7qf8AjVslmvaBp3nLSFvbCiTKCY2P2opP24pKfs%2F9d5BTFFIys5ZGX9pKch9B65JvKmrSaVdevxea1m%2BCcEFQyj9tR%2FvxMtxZBIV8x3Oi1eknp5Ud4n6Zd%2F7XmskVxp11JY3sZikjbiyHsf8Amk%2Fs4caPay6peQadE6rJMwVXboF6k%2B%2FEDOn%2BdPIkfmSyGp6QA12qc4JFpSVPtcG9%2FwDjfI35a8qzaFNa3urKrXLmscfI1gP7NSv2n%2FmywxouIN1DWPKDW95DY6K0t5IfgnaUKgD05cl49I6H7TZ0bynBAmmjSVvhcz2qEM60%2BHnVRw9om%2BH%2FAFsItfhndg1q%2FpNdxmIuDQVU%2FECf8oYReSLk6R5nWBw1bmT6sSD8FGBb4h%2FNyXDyPvbsWITE9%2FVGJkB30jPKV1PpOsrBduRLFcPb3JY9VditW%2F2XxZ0%2B91O2spIoJWL3E54wW0Y5SOf9UdF%2Fmdvhzm%2Fm2w%2BoeapJlBVdRjWdCDsZE2cfeuHdvfQW0BngZptVvEH1u%2FlG6gj%2B5hH7Kr0xHc0pD%2BYg8wa1NDFZWjSWtsrCRoiGJcn46b1YdF2yFWemzxsW1CN4Ej%2FZlUofubOs2WpxpNGl2oMP2eSbEe5yTXGkadqFpJaT26T2860YEVBB6EHx8MeCzdpunlEtpHYQ38GqRrFNaPA8EgJcFa%2FGqhadao2XBGlmbe2uCzevbGeRo2PcNJx%2F2S%2FDht51s3sLpYLoH6ncIq21wRU1UceLt9Hxf8Hhj5f8pXerWc%2Bq2VrHqE1oqQWdvNLwUoijmJB%2FO9W4%2Fs8cjVH3LezEvM2mXWqyabNozB7SS1WJ5SwBrHWnLv8A3ZUbfy4onlazmtrKC%2BJlNoHFFNFbmQaHvtTJ9rPlzU7GOO6vrRbeNioQQMrRxmn938IXj4YE0fQLnXBdQ2062l1CP3SSry9Xav7og0%2F4LDsikps7C3s1WK2iWJB%2Bygpg5lNOX0YAVr7TL0xXsxcxsVlhktwpFPtLVWwbf%2Ban0e8tp7LTYrmyILlpyT6hoRw2%2Fu%2FTbdlw3taoK4v7a1dY2dW5GjQ1qVHj%2FwA24Vah5a03VlNxZEQTtvyX7LH%2FAClyfjyfo3nrTrbV9PRNI1i6gM8qRENC8gb05OUI%2BNR6nR1%2F4HIRqOj655Vu%2FQ1SBogT%2B7mU1ikA7pJ0%2FwBi3xZGwdizhOeOXFCRBSPSZNX8maml1MhNsfgldPijdD1H%2BS37S8s6ZLrEEZt2uEe1W6VWtLsg%2BlKGHIGOReS%2F6wOR9dWtRp11dSQ%2FWHt4Wk%2Br93IGyU%2Fysk%2Fk%2FW5INATT9Z0eAWczGT6gr%2BoIlfcgBxsf2vT%2FAGMYxMSeE2D07m7PqBmjEzjWSO3EOUo%2BY72M%2BYfLcd3FJeQRxyo7EzQU792GQ60bU9Hkf9HTAwts1jdVeNl%2FyX%2B2n%2FEc7ZL5XstVSS58p6kYZqVbTrysif6tWPrRr%2FspVzmuvaDq2jzsup2JtA5NCfjtmNf91Tjb%2FYyccJ8tmgJPqV4JJLJpI3sYLqJ2uY%2FtBgP91q6jpIy8Vw0sNNn8tG11m8KWNnqTrAums5YhTvyct%2B0R8fw%2FYb%2FWwLdRpfaVEkkPO50r1HhjJALRSg9HpX92%2FwCzgSW4TV9Hga5uppdVspFt7a0FOMNshHJm3VuZY8fV%2B0zfBlZHq3BNigOnm52LIfDHCYwMCJmVXI8IqMYnzI4f85l%2BsRQc7eSKVRPHKts4ruUkPAcv9R%2FiwbZaY1p5gtrHUoipjnjWZOo4lhRv8pGwcPL9pcROZo2S6ZkaXgyqoaFVk4hn%2BJ9uPqNxwVrmsWupvYzalF9S1K1lTi6GscsYYMpV%2FFWUNx%2FlwYoSjd8jybO0suLMcUsdmUQROxRrnH75PQtd8vaT5itBZapAJI0YPE6njJGw%2FajcfZzg%2FwCZWh3GhW%2Fr2wH1vSZ0DXlPia1m%2FuZuK7MV%2FuLj%2BbPQ1pdR3ltHcxGqyCtOtD3H0HIF%2BZFnb3k8EMqhxPBJHOh6MnIUDfSdssDq3zfqWmR6lFJqenRCO6iHK%2Fsk3FD0ng%2FmjfC3SNVudJuUvrKQJdQOrxc1DoafaSRGqrK%2FRlyU32i3XlnU4RHOYrF2Isr1hy9Jm%2F495%2F8AimT%2FACsKte0Zp%2FW1Kxg9KaL%2FAI6Nipr6bH%2Fd0X88En2lfFX0%2FwDlz5x0fzbpAlsIYrO%2BgAF%2FYxBVCOR%2FeIBTlE%2F7Lf7HJpniLyz5m1TyrqVtq2ly8ZYzuvVWX9qOQftI37WeufJnnHTfOekJqViwSZaLd2pNXhk7qf8AJP7D%2FtYFZJmzZsVdmzZsVaOct%2FNj8sx5ntJNb0NfT1uBayxrt9ajUfY%2F4zqP7tv2vsZ1PKOKvhz0CsbwMzqSSHPRgw2%2BL3%2FmwrlheB%2BD9exHQjxGeqfPH5Oad5lupdW0icabqU3xTqV5QTN%2FOyr8SOf2nX%2FgM59H%2BQfmu5nWC9ns4rbl8U6OzMB%2FkpwGKr%2Fyk%2FOBtOMPlnzTMWsyRHY6g5qYq9I5j3i%2Flf8A3XnoxWV1VkIZWAKsNwQehGc68sfkv5Q8vBZriE6rdrQ%2BpdAemCO6wj4f%2BD550VVCqFUUVRQAbAAYq3mzZsVdmzZsVf%2FV7%2FmzZsVdmzZsVdmzZsVdiNzNDbwSTXLBIUUmRj0A98WwNfPaJbSm%2BKi2pSUv9mh2pirAPON5pMWiStoiPJfM1bVI4yy1G8jDkCnwrhDrD6jFb%2BWbC7Wt36Ecl%2BCP%2BKiZHbtyJajf5WDvP9xZRaNCfKtxKb4zj04IOR403JKkfAOfH%2FWws84ajNd3EEklFuSOUtK%2FDRVXiKduQOFIeeatpk0F5PeaUj%2BlATLIYwSYhXd%2Fh%2ByleuLP9U12ykmiWO2vrWOW4n3PxgcAFXmaty3cf77%2Bx9jO1%2Flvo0EejT388SvJqDMjFxXlEvw8TX9ls5h%2BY%2FkSTyne%2FpHTVY6LdsVUj%2FdDt1hf%2Fitv91t%2FsMgRW4dxo9X4vDiySqcfon%2FO%2FoyYJsQGHfJL5FsrXUdZk0m6uTbR3UTvHQAgzRjkONSODla5GgcX0%2FUJNL1S0v41DPFINm8G%2BE%2Frym%2BHMD0k52txeLppjqPUPfF6l5X8xWlm995evZlguLSdkjR9gTWjrXovP4XTEPM6wwzKSKCT4tuoIO%2B3vke80xXU2tW13ZQ%2Bo15bq8npJ8UlELVp%2B3sMBWOsXOtWy2iEyXNuCyIw5Myf8VsaseFP7tvizL4tq%2BTzNUfvT%2BOU6npky9ZrciVAO5Xw%2Ba8sis01rp%2FmC01O5YrSWJ4kXcyFiB9nsK%2Ft5fljzLXzMlg0bRQujQESbVlDcl5IenL4kyeebPIp8y6j5e1DSEjX0XWO4QsqKYk%2FfRgV%2Fb5gx8cHMe5lGUom4mjuPnzSW%2F1OfVL6R7sJW2keKFUGygGhIJ3PKmNVy%2FTAk1pdWc9zBdrwuElcTIezA%2FEMj%2FmjXbvQtaW3tEBgCJM6PuCHFQExtizSKI1DHJv5VuxKrWMp%2BwC8JPh%2B0v0ZCNLvrfUrGG9tjWOVQfkf2lP%2BqcPdHme3vIZV24sKn2Ox%2FDJBSyzzBplrqWnSQSxLI0P76EsoIDqO3%2BsMgmlaxceUdRXU7ZS9jJRb62XoUP7QH80f2k%2F4HOgXdyVYgHp1%2BWQW8g4TzQyoQpJIVh1VuhGJCh7FG9hrempKhW4sryMMp6hlYV%2B%2FOWa%2FbXfk%2FU0ZJOEL1ayu2%2By1P91udv3if8OuCPJ%2FmhPL1xaaJetx0y4rFFMx2imJJSvhHLXj%2Fr4N%2FO9G%2FwAJ28o%2FYvY69%2BqOMgdlYzqPmWy8xr615aouoxAA3dk4dJB0%2FfRGjofBl54U%2BnCySRNSa1l%2B2vQq3861%2By65GPKcztqxjY7NEw4jYbU32zoNppF1qfrw2JX6yierHExoJivWIf5fH7DYYnZaY3pN9N5N1n9JJEbuIwyRoisY1kDbpVu3F%2FidM7xpl3Y%2BadFt7m5tle3vIUkaCYBx8Qowof5WB%2BPONG0jvLY28qlRUgqwoyOOu37LpiXl3XbjyZqk7XglmtZIfTEKNQGh5REFvsxr8XLjgIrdWQedvy7GiQPrfl4SNaxVe5s1q7Rp3ki%2FaaNf20%2B1kT07WGCqwcMjdJFNQc9C2N9BqNvHc29WiljSVGI2KyCopkFv%2FwAotHu9cOq2d1JYW0x53dhAo4O53JQt8MYf9ocMFyB23ZwGOQIkeCQGxqwfIsatNQSQrIrmOUbrIhoQfEEb5LLHzPP6X1TV4RqFo4ozFVL0%2FwApD8EmFms%2FlxeWBNxoEpuIhubSQj1B%2FqPsHwo0%2B4ltUmW7Ro5ojRo3BVhT2OWCi1t%2BbPJ1pFCfMXlJgtl%2Fx92VCyRHuwjb4kX%2Bdf2ciOlG2huhcX2n8JI2BE8FHHzMTb%2F8TVc6FpWutaySPblJEmHGeCQVVwP1ZGtcsIbe5N3p0Ui2MlWaM7mB%2FwBpQ4%2B1F%2FLkTGulhnDIYnYprf6tYaxaxxCDlxIaG7iko8Z7kGtWr%2B3ywxsdGl1WwitzGbkgkRzugDGnRm34R0%2FZbIJBZwxv9YhAVx8Qp0JPiBnafJl1eXekLNdyrKOXGNgADQD4g3Gg%2BE7Y8WyTLfiHNJbbQvNHle%2Fe50eQX%2BnXAD3Vg53EoWnKImhQmn7Pwv8AyYRX9xql1dmXWOS3XHiqMnp0QEkKq%2BA5fazrQwHqOmWmqQGC7j5D9lxsynxVsFsLeO39hb39tJbXMYlhlHGSNuhB%2FUffOZXy3%2Fl7UV05n5MgrpN1LTjLCT8VncEj%2FYf5Odt1nQbzR3JcerasfgnA2%2BT%2FAMrYB%2F5V3Y%2BdtAvhefubrn%2FuNux1jkQUYkD7Ubnir%2F6uEq8D1rTFk9XUdNgaHix%2Bu2XVoHPcD%2FfbfstnQfyAeb%2FFktC%2FptaSF1VgFNGTiXFfiA%2BLj%2FlZC9WuNd8p6kNM1e04anYsY2mY7TW%2FZG2pKjfsS4K003mkCHzl5WmDLazercWoB9WCvX1FB%2FeQt9lv8nIofYNRl5FPI3njTfO2li7taRXkQUXlp3Rj0Zf5on%2FYbJXirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FW7%2FmzZsVdmzZsVdmzZsVdgHVY9PmtHi1JlW3cgEuQBUbr1wdgPUdNttTtzb3IJWoZSOoYdxirzHztP%2Bi20aTyvdm6uDcJSCMJIPTVhRWKj7Bbbi2B9b8keZrnV3FvberbsQsVwHUKFJ6tU8hSvhk%2B%2FwAPGy1GwvLOkqK5ju0cIP3YQ%2BnItAPiif8A4nkkphKQaQOk6eml6ba6fGQVt4whPif2j%2FwWO1LTbPVrGfTr%2BITWtyhSWMjqD%2FEfs4MzEVwIsg2Ni%2BVPOHlm58p65NpU1XhP72znP%2B7IWPwn%2FXX7En%2BVgW28s63f2kWr29m76Ys6xyXQpxUggNUfa4iv2uOen9c8t6J5it0t9as0uo4zyjLVDKf8l1oy5EL7TriGW30Lytp7Q6Dbs0d7xI4Oz%2FFWPlycmNvib%2BfKziufETs7WXahOn8Ph9dVIn6a7%2FewDzPd3ukNplzYtxtEhW2adVBKzRktTkalOdf%2BBw60bydZ%2BaNR%2FwARaPq0VjOIw509bcLIkw%2B16yh%2FjRm%2F3an28de6dLYTXGk6xDztpx8aHoyn7Lqfb9nI3YX%2BreQ9ThS3pcWhcvazMBWSE%2FbgaQ%2FF8P8AJlrrDvunvmryB9buFvzAtnrkQD84z%2B6mKHkGRtu%2F82HWnO%2BoadLpU5aC4ZeUL9Gil%2B0jKR0aOYZOLO80jzho0d3Zv6kMn2WFPUhlGxVh%2By6H7WQWaO80rV1hvwBMjcfUAoskTbLIP%2BNsIr5oSu10tfOt7Ikt4th5ijQC6hkSsdz6fwfWIiCCr7UmTj%2Fl5JG%2FKTSdTjg%2FxDILh4UCUgHD7P8Axafj45GPMdkYtRkvbWf6jewEXNhcr9ppT9pEVatJWnxJx%2BznRPIfmz%2FFujfW5Y%2FSvLZ%2Fq94gBCmQCvNQfiVX%2B1xb7OA2NleaX%2Fkr%2FA19Jb2rO%2BlXbc7UvuFbuvL%2Bb%2FiWC7M7HOuarpdrq9jLY3i8o5Bse6t2df8AKXOP6jbaj5dvpLK5USBd0fcB07Ov8cMT3qkP5l6trkWp2kNi8sVr6CShoyVDyH7RJHXj8OQpfNfmCN1%2BsXcsnBeCrOfUAUdFHP4uP052ny%2Fq2g6veR6T5hgX94Almsp%2Fdsw%2F3W%2F%2BU37GSHUfyp8n6hUpavZse8DkD%2FgH5p%2BGCXNeTwM%2BbzeWxtr%2B3SVHFGMZKMP8oBqr%2FwANh9qv5gpr3kVfLV9zk1O3uIjFOwrzt4w1GZhUeqn2P8rJD5i%2FJJrK2lvNKufrSx%2FEYCnCXiOtCpKPx%2F1M503lq7tpDxDNUUUGlPwyJtWQflfpMWseaFtLgssZtZnDJ1VhxCn3651e38qanp%2Bs2ZX95brKG%2BtR7UVfio6%2Fs16YS%2Fk3pGmWxvNR%2BspJqfEW7WnR4kryLFW3PqN%2FL%2FLnW8I2UsW8x%2BVo71n1LT0CXp3mjGwlp3%2F4yD%2Fhsgl9oyXUaxX1u8LoCY2dStV%2FaG%2Fgc7JTEbiztrr0zcRrIYmDxlhWjDJCXQoeVeW9Rv8Ay1PKL25kuNO9ELEo%2BIjgaoKk%2FAqJyzqtrdQXkCXNs3qQyqGjcdCCK7ZFPMPl1Yg95aLWA7zQjfjXqw%2FycB6JrNzY3BW7uAbARKgUqSQVIC8KfCq8K8vhxq9wlntK4DvtJ07UgBfW6TU6FhvTwqN8FRyRyoHiYOjCoZTUEHH5FDC9Y%2FL6wuSZ9Ic2M3X0tzEfo6p%2FscL9B%2FLy8XVJNS8y3Yuo41aKz0%2BEkQrGwoWlO3N2zomVTDZV4l5n8s3Plq94oS%2BnTk%2FVZj27%2Bk5%2FnX%2FhsMNI893Wj2ht2thNVSEp8PGSlBK%2F%2BSf286nqOnWmqWcllexiSGQbg9QezKf2WGco13yhdaVMUT95A39zL0DDwPg%2BIZc3pPlzU5dStGa4IaeNgGZaAFWHJWoMOc5v5E1B7Wf6tcAoD%2B5PLb3jP0fYzo4xIYrZIo5UaOVQ6MKMrCoIPtidrZ29lAttaoI4UrxQdBU1OL5sCsO8%2FwD5e6V5708RXNINQgB%2Bp3oFStf2JAKc4m%2F4XOIWX5R%2FmVoOpummwIySAxNMssZhZG2q3Mqen80eeoKZqYq8l8h%2Fk%2FceW9Qt9Z1DU3W4gPJLS0JCEGvwTytT1U3%2Bx6arnWs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F1%2B%2F5s2bFXZs2bFXZs2bFXZs2bFXUzZs2KuzZs2KoXUjILG49E0k4EKetK43TYkhsoQp5EqGZvEnvgp1DKVbdW2I9jhDdaDqT%2FuLLWJbOzP8AulEVnAPVVkb4hiqB8wWUXmS%2BXTYWQi3ikZphuUlqOKmn7P8ANnOtRsiPW0TWUKqD9ofajYfZkQ%2B3%2FDLnYtH0Wy0W3aC0BJc8pJHPJ2J8ThV5u8tJrdoZrdQL6EH0z0Lj%2BQ%2F8a4bTbxXQPMGq%2Fl9r7mSs9jcUN3Cv2Zo%2B1xD4Sp%2FzZnaNYhtfNmgRaho7JcMwE1pKCASP246%2Fsn%2BZf58gsugWWtaPFp1xRL21qFkFCyP3U96YR%2BUfMt7%2BX%2BqvpmqEtpUsnGeOtQjE0FxD%2FwAzUxOy%2B5kHmGCOa1s7%2BVeEsFYpHI3SvwyBvDi647RtH1by3qEXmPT5VlgnWmo2C1Amj6rIrH4RMnVcCz3FvJ5x1pIqX2h30cVy3ouv2nQEeka9XZW5ZJNPult7dbZpTLasP9HlYUalP7uVf2JlH2v%2BEw891ZzY3tvqNtHdWz84pBUHoQe6sP2WX9rC7zJoEOu2Xp7LdRVa3lPY90b%2FACHwi0IahBqtdOo9hKf9LjY0Vf8ALU%2F78ybZFD591jS3R3gnRo5Ymp4MjA9snHkr8weRi0LzJII7pQEtdQc0SYdFWQ%2Fsy%2F5X7eH%2FAJw8uLqMDX9qg%2BtRL%2B8Uf7sQf8bLnJbuyjcNFKnND1U%2Fw8Dh5pfQo3Gc487eVFhMmq2KfuHNbmNR%2Fdsf92KP5G%2Fa%2FlyPeXPM%2Fmfy2Y4pmk1PRqfBBKpNwiDr6E3%2B7OH8j51%2B1ubXU7JLiKklvcJWjDqrDdWH%2FEsV5PntoFiuUuQOFxFvHKpKsPpWnLJZ5b8w65p1xEguXuIp3q8d07P1%2FZVm%2Bx%2Fkccbr%2Bhm2125sbPggX95AZq8FRhy3p%2FL8Srk181aDHqempqtvRLu2hDngPheMDmV%2F2P2ozjsrKLW5ju4Eni%2By4rQ9Qe4OL5D%2FACp5hgu7iOwkkUXFxD6yx9DWM8HNMmGJFFDRFRQioPUHIhrmgrAXubdK2z19WOleFepH%2BRkwymCkUIqD1BxBpWIaNq09o31WURrZoiem32ePEheCIB8VV%2BLJcGB3BBHtka1LQXVne0XnC9eUQ%2B0tevHxXA2lxazHfW620rx2atW4gkSqFOPCgdvjDClVwkA7hWYZswzZFXYnNBFPG0UyCSNvtKwqDimbFWE6voE1hIbu0Be3BrQVLIP8rxXJRo92b3T4Z2%2B1Ti3zG1cGkAih3B7ZSRpGvCNQqjsooN8NquzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxViPmbyo91cfpvQiINVT%2B%2Bh6RXSD9iXwl%2F33N%2FwWQzW9AXXo%2FXaFg7L%2B%2BhK0mjdBuafzACjrnYcDTWNrPKk8kYMsZDI42NR40w3tRW3z1p2l6ho%2BotLAfXVE5OgDVljA%2BLj%2FxZGv7OS2BbeaRbscpI5YuLQq3ETIfiQcv2ZVP90%2F8AsMk3mi1FjqBnt0CpcIHIUU%2BNT8RFP5tuWRDTFEulwPaP9YjVSfVjBIFGPM%2F7BvHCOSXqXlu6trnTI1t7Y2Zj%2BGW1YhmQ%2BJcfb5fzYcZBPKl1I7GRXHKGi3AY%2FajPRvdsnQNd8BFFDjnL%2FPWhJaXguIKRw33KngklPi%2F2Pxcs6jkY892Ul3onqwoZJLWRZeAHIlT8D7fJsAVBaLpUeueS9PtriYPcWykQXkfZ4yVDD%2FJP2WwX5X1NJ2NrQIGXkoXpzQ8JP65GPJfmOTR5G0zXLmGCzlYmzhZPSeE05ceP7UTjfliOhagkWs3CW0gkUXbPZjoZVkY8kQHr8OSHUJZD540vmYtVRBIAvoTo260JrGzU7cvhzaJ5jgm0t9O1u7giu%2FRdY%2BJ48oyCg%2Fd9QyfZ%2FwArJhPBFcwvbzqHikBV0PQg9sgt%2FwCSLpJy9pxniPRiQsgH8rfzYB5ql%2Fkq1hXU4ZigNwjsizftemU3Uf5Jzp%2BRXyloF%2Fpj3FzqYiR3YraxREsyx%2FzTOaL6j%2Fyp8CZKsSUOzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Hv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVg35iPrMEFld6XbR3CRM%2Fro1fUIIHwx%2Fs4U%2FlrqOkz3c1lYQmENFJI8DCgRzIDIg5b1JavTOiajZLf2cls1KsKofBh9k5ydpJPL%2FmzT9ZcBIWY2t5sFoD8Ls5C1%2FwCDkyQ5KyjWdLGi6ml3brSyvKxuo6I58P8AJPVclOiXZurPi5rLAfTf5fsn7sE3drBqFq9vLR4pV2I7dwy%2B%2BF2j6Xf2F5dS3EqNbyhViVa8iV%2Fbfag6%2FZXBdj3KnWURXLzYFYV5n8n3us6ut7btEITGsbc6hl418B8WFd75Ym8svHqVqPrQiCsJSPiikH2jQfsNnScayhwVYBlOxB3BGG1Sby7rf6YgZ5KCZftIBSmHeFllodlp95LeWqlDMKGIfYB7kDDPE%2BSuzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F%2F0u%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZFfM%2BipLW%2BSJZAf71CtaMPsygf8SyVZRAIIO4PbCDW6pP5YvDd6Wiu1Zbc%2Bi%2B9Tt9mv%2Bxw5xG3tbe1Vlt41jDHkwUUqfE4tgPNXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Pv%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV%2F%2FZ);background-position:center center;border:1px solid #0a0}.yui-skin-sam .yui-h-slider{background:url(bg-h.gif) no-repeat 5px 0;height:28px;width:228px}yui-compressor-2.4.7/tests/dataurl-base64-noquotes.css0000644000175000017500000024540711640627104022702 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml, .yui3-skin-night .yui3-dial-center-button-vml, .yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min, .yui3-skin-night v\:oval.yui3-dial-marker-max-min, .yui3-skin-night .yui3-dial-marker-vml, .yui3-skin-night .yui3-dial-handle-vml { background: none; opacity:1; } div.base64-noquotes { width:100px; height:100px; background-image:url( data:image/jpeg;base64, %2F9j%2F4AAQSkZJRgABAgEAZABkAAD%2F4RfJRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAeAAAAcgEyAAIAAAAUAAAAkIdpAAQAAAABAAAApAAAANAAD0JAAAAnEAAPQkAAACcQQWRvYmUgUGhvdG9zaG9wIENTMiBNYWNpbnRvc2gAMjAwODowNzoxOSAxNDo1ODowNQAAA6ABAAMAAAAB%2F%2F8AAKACAAQAAAABAAABwqADAAQAAAABAAABRQAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAEeARsABQAAAAEAAAEmASgAAwAAAAEAAgAAAgEABAAAAAEAAAEuAgIABAAAAAEAABaTAAAAAAAAAEgAAAABAAAASAAAAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZ%2F%2B01IlBob3Rvc2hvcCAzLjAAOEJJTQQlAAAAAAAQAAAAAAAAAAAAAAAAAAAAADhCSU0D6gAAAAAYEDw%2FeG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8%2BCjwhRE9DVFlQRSBwbGlzdCBQVUJMSUMgIi0vL0FwcGxlLy9EVEQgUExJU1QgMS4wLy9FTiIgImh0dHA6Ly93d3cuYXBwbGUuY29tL0RURHMvUHJvcGVydHlMaXN0LTEuMC5kdGQiPgo8cGxpc3QgdmVyc2lvbj0iMS4wIj4KPGRpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNSG9yaXpvbnRhbFJlczwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1Ib3Jpem9udGFsUmVzPC9rZXk%2BCgkJCQk8cmVhbD43MjwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgkJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNU2NhbGluZzwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1TY2FsaW5nPC9rZXk%2BCgkJCQk8cmVhbD4xPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCTxkaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q%2BCgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCQkJCTxyZWFsPjcyPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsU2NhbGluZzwva2V5PgoJCQkJPHJlYWw%2BMTwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuc3ViVGlja2V0LnBhcGVyX2luZm9fdGlja2V0PC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BUE1UaW9nYVBhcGVyTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNVGlvZ2FQYXBlck5hbWU8L2tleT4KCQkJCQk8c3RyaW5nPm5hLWxldHRlcjwvc3RyaW5nPgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk%2BCgkJCQkJCTxyZWFsPi0xODwvcmVhbD4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD43NzQ8L3JlYWw%2BCgkJCQkJCTxyZWFsPjU5NDwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNUGFwZXJOYW1lPC9rZXk%2BCgkJCQkJPHN0cmluZz5uYS1sZXR0ZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk%2BCgkJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhZ2VSZWN0PC9rZXk%2BCgkJPGRpY3Q%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD4tMTg8L3JlYWw%2BCgkJCQkJCTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTk0PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLnBwZC5QTVBhcGVyTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BVVMgTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5BUElWZXJzaW9uPC9rZXk%2BCgkJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC50eXBlPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvVGlja2V0PC9zdHJpbmc%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuQVBJVmVyc2lvbjwva2V5PgoJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnR5cGU8L2tleT4KCTxzdHJpbmc%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXRUaWNrZXQ8L3N0cmluZz4KPC9kaWN0Pgo8L3BsaXN0Pgo4QklNA%2BkAAAAAAHgAAwAAAEgASAAAAAAC3gJA%2F%2B7%2F7gMGAlIDZwUoA%2FwAAgAAAEgASAAAAAAC2AIoAAEAAABkAAAAAQADAwMAAAABf%2F8AAQABAAAAAAAAAAAAAAAAaAgAGQGQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4QklNA%2B0AAAAAABAAZAAAAAEAAQBkAAAAAQABOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD%2BAAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNBAoAAAAAAAEAADhCSU0nEAAAAAAACgABAAAAAAAAAAE4QklNA%2FUAAAAAAEgAL2ZmAAEAbGZmAAYAAAAAAAEAL2ZmAAEAoZmaAAYAAAAAAAEAMgAAAAEAWgAAAAYAAAAAAAEANQAAAAEALQAAAAYAAAAAAAE4QklNA%2FgAAAAAAHAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAAAD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FA%2BgAAAAA%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwPoAAAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAOEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJAAAAAADhCSU0EHgAAAAAABAAAAAA4QklNBBoAAAAAA1UAAAAGAAAAAAAAAAAAAAFFAAABwgAAABAAcwB3AGkAcwBzAF8AYQByAG0AeQBfAGsAbgBpAGYAZQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABwgAAAUUAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAG51bGwAAAACAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9uZwAAAUUAAAAAUmdodGxvbmcAAAHCAAAABnNsaWNlc1ZsTHMAAAABT2JqYwAAAAEAAAAAAAVzbGljZQAAABIAAAAHc2xpY2VJRGxvbmcAAAAAAAAAB2dyb3VwSURsb25nAAAAAAAAAAZvcmlnaW5lbnVtAAAADEVTbGljZU9yaWdpbgAAAA1hdXRvR2VuZXJhdGVkAAAAAFR5cGVlbnVtAAAACkVTbGljZVR5cGUAAAAASW1nIAAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAFFAAAAAFJnaHRsb25nAAABwgAAAAN1cmxURVhUAAAAAQAAAAAAAG51bGxURVhUAAAAAQAAAAAAAE1zZ2VURVhUAAAAAQAAAAAABmFsdFRhZ1RFWFQAAAABAAAAAAAOY2VsbFRleHRJc0hUTUxib29sAQAAAAhjZWxsVGV4dFRFWFQAAAABAAAAAAAJaG9yekFsaWduZW51bQAAAA9FU2xpY2VIb3J6QWxpZ24AAAAHZGVmYXVsdAAAAAl2ZXJ0QWxpZ25lbnVtAAAAD0VTbGljZVZlcnRBbGlnbgAAAAdkZWZhdWx0AAAAC2JnQ29sb3JUeXBlZW51bQAAABFFU2xpY2VCR0NvbG9yVHlwZQAAAABOb25lAAAACXRvcE91dHNldGxvbmcAAAAAAAAACmxlZnRPdXRzZXRsb25nAAAAAAAAAAxib3R0b21PdXRzZXRsb25nAAAAAAAAAAtyaWdodE91dHNldGxvbmcAAAAAADhCSU0EKAAAAAAADAAAAAE%2F8AAAAAAAADhCSU0EEQAAAAAAAQEAOEJJTQQUAAAAAAAEAAAAAThCSU0EDAAAAAAWrwAAAAEAAACgAAAAdAAAAeAAANmAAAAWkwAYAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZADhCSU0EIQAAAAAAVQAAAAEBAAAADwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAAAABMAQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAIABDAFMAMgAAAAEAOEJJTQQGAAAAAAAHAAIAAAABAQD%2F4TkjaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu%2B7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI%2FPgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSIzLjEuMS0xMTIiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyI%2BCiAgICAgICAgIDx4YXBNTTpEb2N1bWVudElEPnV1aWQ6RTcxOTVFNTY1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkRvY3VtZW50SUQ%2BCiAgICAgICAgIDx4YXBNTTpJbnN0YW5jZUlEPnV1aWQ6RTcxOTVFNTc1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkluc3RhbmNlSUQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eGFwOkNyZWF0ZURhdGU%2BMjAwOC0wNy0xOVQxNDo1Nzo0MS0wNTowMDwveGFwOkNyZWF0ZURhdGU%2BCiAgICAgICAgIDx4YXA6TW9kaWZ5RGF0ZT4yMDA4LTA3LTE5VDE0OjU4OjA1LTA1OjAwPC94YXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhhcDpNZXRhZGF0YURhdGU%2BMjAwOC0wNy0xOVQxNDo1ODowNS0wNTowMDwveGFwOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhhcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1MyIE1hY2ludG9zaDwveGFwOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9qcGVnPC9kYzpmb3JtYXQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOkhpc3RvcnkvPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpOYXRpdmVEaWdlc3Q%2BMjU2LDI1NywyNTgsMjU5LDI2MiwyNzQsMjc3LDI4NCw1MzAsNTMxLDI4MiwyODMsMjk2LDMwMSwzMTgsMzE5LDUyOSw1MzIsMzA2LDI3MCwyNzEsMjcyLDMwNSwzMTUsMzM0MzI7QzA1QTE5MDRGRjAwQUJEQzA1MUJERkFGMDIwNEVBNTE8L3RpZmY6TmF0aXZlRGlnZXN0PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24%2BNDUwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjMyNTwvZXhpZjpQaXhlbFlEaW1lbnNpb24%2BCiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U%2BLTE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6TmF0aXZlRGlnZXN0PjM2ODY0LDQwOTYwLDQwOTYxLDM3MTIxLDM3MTIyLDQwOTYyLDQwOTYzLDM3NTEwLDQwOTY0LDM2ODY3LDM2ODY4LDMzNDM0LDMzNDM3LDM0ODUwLDM0ODUyLDM0ODU1LDM0ODU2LDM3Mzc3LDM3Mzc4LDM3Mzc5LDM3MzgwLDM3MzgxLDM3MzgyLDM3MzgzLDM3Mzg0LDM3Mzg1LDM3Mzg2LDM3Mzk2LDQxNDgzLDQxNDg0LDQxNDg2LDQxNDg3LDQxNDg4LDQxNDkyLDQxNDkzLDQxNDk1LDQxNzI4LDQxNzI5LDQxNzMwLDQxOTg1LDQxOTg2LDQxOTg3LDQxOTg4LDQxOTg5LDQxOTkwLDQxOTkxLDQxOTkyLDQxOTkzLDQxOTk0LDQxOTk1LDQxOTk2LDQyMDE2LDAsMiw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwyMCwyMiwyMywyNCwyNSwyNiwyNywyOCwzMDtENDYzN0NCOUQ0MUExMEJBN0VGNUVCQ0RCNjMxODMyOTwvZXhpZjpOYXRpdmVEaWdlc3Q%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY%2BCjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8%2B%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEJCAgJCgkLCQkLDgsNCw4RDg4ODhERDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgBRQHCAwEiAAIRAQMRAf%2FdAAQAHf%2FEAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPBUtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4%2FPE1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BCk5SVlpeYmZqbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp0%2BPzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BDlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq%2Bv%2FaAAwDAQACEQMRAD8A7%2FmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmrlHI2utXn6WltnFESb0RFSp41WjD5q3LCBaslzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2E2rj0LuzvF7PxftUf8AXPLDnC3XI0ewdpOkTK4P08T%2FAMK2Ec1TLNgaxmE9pFIDy%2BEAn3GxwTgV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F%2F0e%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXYUeZpfR0a4kpUAx19h6i74b4X65CbjR76FV5FoJKKe5C1GIVLdDuGhuXs2IKOX4gfsvGdx%2FskKtkiyD6bctHHbXgPImOC4qOpXj6E1ff4Mm4Ndxkpc770BvNmzZFLs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Lv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVokKCT0G%2F3ZgaioNQemANZuhaWLyE0LlY1%2BbGn6sWspA8QA%2FZ%2FUcVRWbNmxV2bNmxV2bNmxV2NZQwKnodj9OOzYqwDT4iiPZsa%2FVLm5sj7I%2F76L%2BOTXTpjPZQSt9pkAb5r8JyKXqfUvMOpIQOFxFDfoP8qFvTl%2F4Q5INDkrFPAf8AdUhI%2FwBV%2FiH8cnLeAPcxHMprmzZsgydmzZsVdmzZsVdmzZsVdmzYyWRIo2kkYKiirMdgAMVX5sjTeaGl1CzsbSAOLuX0w7k14KCzyAD%2BUZJBirebNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F9Pv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVo4CXUFa9e0CbJRWkr%2B0RWlMHZEJ5WtPMtzE5%2BGYJKnyK0%2F4kuEC1ZeM2IW0okjFT8S7H%2BuL4FYz52mMWn2tDTlcpX6FbDHR5ecCH%2BZevywl%2FMM8dJtn7LdJ%2BKvgry9ccrOJ69KVw9E9GS5s2bAh2bNmxV2bNmxV2bNmxVi3miFU1LSbxvsStJYzH%2FJnSi%2F8ADYpoEzLcxq1T68FGr%2FvyE8GrgjzdC0mhXEsY%2Fe2pS5i%2F1omDf8RwttJRHdrcDaNbhZVI6endIG%2F4mcnHeJCDzDL82bNkEuzZs2KuzZs2KuzZs2KurkZ843Zhs4bVTQzvVqfyrvg3zHNPb2UMsLtGBPGJSpIqjEqRUb9ch%2BvSSvp0JlcvJCLyMuxJb4JNvi%2F1SuEBVvkaX9L%2BZbm8Sv1fTbf0Y6%2F78lPxH%2FgFzpeRvyPbWcXlyyubWBIXuoxJOUG7uKjk5%2FaOSSoxPNXZs2bArs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FU7%2FmzZsVQ2osyWM7o3FlQkMOxGPtZhPBHKCDyUE08e%2BM1Bedjcr4xPT%2FgThV5cvBJbpGergEfMDcYa2PkqfZs2bArs2bNirs2bNirs2bNirshfnRGtb7T9TX7LcoJD2qDzSv3vk0wl81WDajodzDGKzRj1oR35R%2FFT6RthHNXaVcrKsUtftDi304dZz7yrqPrQCIncdMnsEnqRK%2Fcjf54yVjP5gwtJ5ckcD%2B5mik%2BivH%2FAI3wD5RnEtpwrWgw983RGby1qiqKlYGkA%2F4x%2FvP%2BNchnke5BIUGoPQ%2FPEJHJ6XG3JFbxAOPxOA1iX7sUwIdmzZsVdmzZsVdmzZsVUbqBbq2mtm%2BzMjRn5MKZDLP4rC2UVq9qYj7SWshWn%2BtxOTnIVG4ttWvdNaiiK7FxGDtWG6Ti%2FwDwMuShzRLky%2B1lE9vFMP8AdiK33gYscKtBmDWhtq%2FHbOyMp68SeSH5UOGpyJ5pYde3moWPmW5KzH0pIo2WNt0A3Wv0ts2D73zJ6FgzxqqXpKpHG9eDMx7EYXed45VeC4gPCdYyqua0I5q5VgOv2cAW8sWo2QMqhwwoyHcVyQFhVOLzvrNrdf6fFHLFX4kVeBH%2Br1%2F4bJlp%2Bt2GqWrXFnICyKWeJtnUgV3XOP67qFjaFLHUrprecy%2BlZajxPDmN1jn8Dv8Aa%2By%2BIaXrclrdtZ34NrfR1USofgeo2K06c%2F8AgcBCXr%2FlvXRrdnzk4rcoSJFXYfMbnDzOV%2BTr82eqAOQIpaBq7AV2r%2BOdTriRSEp8z8RoN9I5AWJPV5HYD0yHr%2BGQg3Ntq1lcLazx3CiZviiYOKzQo9Kjb7YzoWqRevpt5AOskEij5lCOmc60%2BWCK0j9ONYo5IYp%2BEahQWBeNjRafEcMVTvTb%2B80fyHZ3FugE9vSORJBUqPVZW%2BEHw3yVaXeC%2FsobulGkX41HQMNmH%2FBZzC%2B1iTTbadZUkjtJjzkQqSKqNm5fsdMPfyr1%2FRdT8vra2E5N5C8kl3bSMTKpkctz%2BL7SP9peOA7fFkIkgkCwOfkz7NlA1y8DF2bNmxV2bEJLy1injtpJVWeavpREjk3Hc8V64virs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Xv%2BbNmxVplDqUbcMKH5HIPokjWsstqx%2BK2lZPf4Wpk5yF6nF9R8xswHGO8QSj%2FAFh8D%2Fqrkoc6VmSMHUOOjAEfTjsAaZMXhMRPxRnYf5J6YPyJV2bNmxV2bNmxVQuzOtu729PVUclBFa07U98DafqsF6i9EkI6ePywwyF6vG2i6oJRUWl6xZCP2JOrr%2FsvtLhG6s0yiK4X6Zfi4QI7Vb9lv5h%2FXDHrgV5c8B0LzLc2Q%2BGF29WDw4SfF%2Fwp%2BHOg6ZMHi4j2YfTkZ%2FMGwpFaazGDytm9GYj%2FAH25%2BEn%2FAFX%2FAOJ4N8uXwliicnps305LmFZDewrc2dxbt0lieNvkylc45%2BX10UCQzHjLATE4P%2BQeNc6L55e5i0J57WVonikRmZDSq7jf2yB2Op%2FVYor2%2FwBNjktpAGjv7ZvU%2BInoy8Vao%2Fa44xCQ9as25RVBqKnfBGRby9rBEsljcIY0aQ%2Bg5FCCQD6bj9lslGAikN5s2bArs2bGyOI0aRuiAsfoFcVS%2B%2F1q2sJltyrSytuyp%2ByDsC3zwxBqAfHfI%2Fodmt2z6pcjnJK5dAexPT%2FgRkhxV2c782mSy82WUgNIdUhNs4PTmlXQ%2FwDBDOiZAvzLb6nHpOrlFkjs7lWdG9yvxVG%2FwiuGJ3Up3YTJFr7op%2BC8t1ljHjxodv8AYtkiyHbxx6XfKx%2FcXBilJ3%2BAsVUV8FRlyYA4Z80DkkPmq3EtlHJSpR%2BJPgHBH66ZBtIufqt9Np8pALHnEpO5p1oM6Xq0P1jTriPoePIfNdxnLtZtrGZluBcG3vF%2BFJYuJfx40IIxHJKzzb5et9ZtZYp1LwygcgPtKy%2FZkT%2FKWuRKKCOC6tNH1CblcWiILDUWHH6wg6wyDejx9Fw4sfOMjEBY5biH1HgLy8VYulOfJV%2By38q4ndH9LlL219K4iilHrWzLxlhI6SgE1%2F2SnFKo0Czxy28zMqcSzspIYBPj2I%2F1cd%2FytnVZdNQ2D1I%2BESMoPw%2FzMftdMG20TSQyyblmjenzoc4TY6ld6ddyKwMUsbFZoHqNwd1KnGXRXs9n5%2Fv7lg98GlWhMjwk1A%2Fm4k%2FF7jDSwSPULTTJI3PGBphGNwG4OHVW%2BgnONX%2BsWFpDFPaSSJcTESG3TcRlf2uRK%2Fazq%2BkR3aeT7e%2BjnX6yoW8ibht%2B9i9Tg%2B%2FQ98QVZHqstutowuSPSdSpV91IPVWzif1i98t%2BZ7m40FjbSWUrNCqEmkex4EH7acT9lv2c6lonmbTvMUTWdwgiumWktrLQhge6H9of6uRLzd5ZurDVP8Q2KetYFUW7jXeSKi%2Bm0hH7UZH7X7OCY4g2YM0sMrjvexB5SHcXsnkPz3Y%2BcdPqKQ6lAB9bta%2F8lI69Y2%2F4XJeDXPJlvPe6JqMeq6NMYLuE842To6ntToyuv2k%2Faz0J5E8%2B2HnGyI2t9VgA%2Bt2ZP0epH%2FNEf%2BEyESeUuff3tmbFAx8bB9H8Uf4sZ8%2F6P82TMMLNb1iDRrQ3EpBkkPC3j7s5%2FwCNV%2B0%2BGVc4n5m8yfpnzJcsr%2F6HYsLe232PBv3j0%2Fy3%2BH%2FY5JxkLourX175%2Ftb28maSZrloqsdlQ1Tgo%2FZUDO755%2B8uxlvPcMI6i6LAe2zZ6BwlS7NmzYFdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVf%2FW7%2FmzZsVdkb83W5%2BrW1%2Bg%2BK1kAc%2F5D%2FCf%2BG45JMC6jare2FxaEf3qMo%2BdPh%2F4bCNiqV6VOOcTV%2BGReB37%2FaX9WHoyFaJMz23BqiWE7juCh%2FsyaRsHRXHRgCPpwy52gLs2bNkUuzZs2Kuwu1rS49W06Wzb4XI5Qv8Ayuu6nDHMemKvONE1KWGVrG7rHPCxRgeqsppk7sb0XC8W2lUbjxHiMhnnnTHtLmPXrZfgakd1TsR9iQ%2FP7LYtomq%2FWI0Iakybof4H55LmFZdqNlFqNjcWMwqk6FD8z9k%2FQc515XuZbW4l0%2B5%2BGWFzE6n%2BZTTOlW063EQkXY9GXwPhnO%2FNsS6T5qtbofBHqaniexmi%2B2v%2BsU4v%2FlfFgHcrPTFbanZNb3caywyApLE3Qj3zjutwW%2FljzBc6Pp6fV9JHpsLNSSgR1HIorV3Vvizq2jXQk%2BAndlBA9xnNvzRiWPzJBJWnr2gJP%2FGNyv8AHAdikJ3YGf0o5pZDIboSD1GJJ9aAgh6%2F5aUzoFnN9YtYZ6gmRFY06VI3zlXk%2FVI5bi2hnlBgdBuxFFahhfr0rSNsnHlXU4JI5NJaSt1avIQm%2B8RaquD0I%2BLjkpbgIZJmzZsirsDagC1jcqvUxOB%2FwJwTjXUMrK32WBB%2BWKpfofE6Xb8f5d%2FnhjkMPmvR%2FKlrJBqkxBSVkjC0PIDpTfI15s%2FMNbu3jbR5plsZVp69swRi9N0eSjMnH%2BRcVpm669cWWtXGnatwjgKma2uPsj0x%2FNXw%2FayOfmLr%2BhX3l%2BPTYrkXM%2BpGtm1uPUUceX7yRx8KLtx%2F1s5xoN%2FefpVr6C8muVVfUuLO8kMrEIeTem7faRk5Iy5FdTuZ9B169trGZvqkc5eFD8SmJzzUcTtsrceWHzTT3fRJv0p5UZvtOYYrgCu%2FJV4P%2FwANHnPrj83vM2lX9zpWoBJYInaJ540pOi1%2BGRQDxf4cln5Z3qT2stjWrK0iexEgE60%2F2XLOUfmHYNZeZbhWP94Ayn%2FV%2BD%2FjVclLlbEdQn955q1wTiU3huLadeQCsfSljO9VNev%2FAA0bYHub1Z7V5yWkhHxpcVHJNwGiuP8AKStVk%2FbyGafqLQxyafO5S2lPJWUAmGQ%2F7uiB8f8Ad0X%2B7F%2Fy8Ctd6jpl3Lb3v%2BkQTpxniqTDcQn7LoR%2FwUb%2FALDZCyyekWl9ZyaFLPelZGN2tqDEtZJHenEs67ckpVXwq1bU7G1iKWvqtcCR4bkkhFYx%2FCHXhvvX48C%2BU7H1SbK3k9Wya5hv4HchSBF8FxBL2WeOJ1k%2F4s9P4cu%2F0j%2Fc1FphmFxPLeOhZBxAiL8jt40%2Fa5YegV6PprvLpcE8sfpTNbh3QVoGK12zluoQ2PnZih42fmWIVt5z8Md4q9I5P5J17Z2A8YrWVl%2BERoaDwoNvupnLtb02LzREdR0hBba7bVe4tEPFZwpr6sH%2FABb%2FAJOSkgPNLqGaG7e3v42iuoTwlicUIK9iM755KnGoeT7ZX6m1CH%2FYSNCf%2BFOctnuIfNkSWeqEWuu249OC8ccfW47elcd%2Bf%2BVnQ%2FyyS5t9Dk067jMVzaSXMLK3hRJlp4r9rjkQl5PbalcaRd%2BlI7PbwysI5lNJIirU%2BH%2FmnOueV%2FOUeo%2BnY6hIpuWX9xPtwnU%2Fhz%2FnTOPeY4zY%2BYNTgpVBcSVQ9CrHkP14Gsb9rFgRWSzY1K1%2BKNh%2B0p%2FZcY2Qdlev%2BZ%2FLKxK19pcdYBUzWqdYx1Lwj%2BT%2BaP8AZ%2FZyHW9xe6ZfQ6ppk7QXsBDRTIevsR%2B0p%2FlyY%2BUPNR1KJLK5lD3KrW3m6esg67f79T9pMD%2BZtCjTnqVilIW%2BKeFRshPWVAP2P9%2BJ%2BzkZRB3DPFlljlxRPz5Edx8mcw%2Fm3aXvkzULyUC3122jET2oNA8kh9NZYT%2FJvzb%2BTOZabIhnWkgaOQcwxO577%2F5fjhKIYndoZvgaUD05v5SN1J%2FyG6YI0RZ4tS%2BoyKQS1HTwYHsffALrdOQwM%2BLGOEHfhu6PWvJ6f5FsfrXnqW8K%2FDBEZD4cmAVf1Z2fOSeSLmfT9RrHEWlvDSZaVagNR0%2BztnW8mWsuzZs2BDs2bNirs2bNirs2bNirs2bNirs2bNir%2F9fv%2BbNmxV2Y5so4qw6WL9HeYLiLpFcUnjHQfH9r%2FhuWSbTnBgMXeJiv0H4l%2FA4T%2Ba4fTW01FRvDJ6chA%2FYfpX5MMGaXcBmHxbSrsCdi6%2F2f8RyZ3j7kdU4zZzrTfO2qQa3eaHrkax6haux%2Br9FkgJ%2FdT2790ZP%2BGydWWoWt%2BnK3erAfHGdmX5rkSEovNm2yiQASTQDqcCt5sL5dZ06Ko9YSMNqRAv8Aiu2Iv5i0qJecsrKo%2FwAkk%2FctTho9yo69htbi2e2vApgmHB1cgA1%2BffOYX%2BnXflXUghJezkNbabxH8jH%2BdcPPN82l65b2j213DN9WdmmtefCRkdeJaNSVb1I%2FtYXWM8cVk2javM95pUv9zcPvLB%2FI3LvwwhIT2x12KCBrxjyjRS06jrxG5YD%2BZcrzzpkXmjyhLPpzCSaFVv8ATZozuXjHP4GH%2B%2FE5JkUmju9BujaTsJYHHKC4G6Sxn9r%2FAJqwJH5g1fyjDaw2KrcaE0zSNE27RiQmtuXPSJ6%2FuW%2FYkxI6hUg8ia9qulatHe3s0k8DgxGKZywBk%2By3%2BTkn%2FN63a8ttG1a3rHL%2B9hIB%2BIdGK%2F8ABA5DNbS0tL%2B4ksJOenzETWrjYiOT4gjD9l4WqjL%2FAJOTTU9XtNc8r6dDP8E8rc4iSP71RwkTfcP%2FALsX%2Bflgq09zFvKeoTMwV2NeCsB0BaNqf8a5N9Zu59K83W2pWb%2Bn9cjBo24ZXUNxI%2F1lyCWsL6fNb3LLxid24tSgINA9Puyb67pd%2Fr2kaPc6bxN5b8owWYKAYW%2BGpP8Ak4RyQU8ufOF7JLD9XRLaAj96ZPiYv4A9An%2FDYOfz9oEbtA0kjXSqG%2Brqh5NtU%2BkW4iQL%2Fk5yK%2FiuNagjEcpTU7Rj6YqaSAbtG3%2FFin4om%2Fa%2BxhXcGeWxlDgpPbfvUFaPDKpFXiI%2FYk%2Fk%2FmwFXr0n5hfXBJFpVtxmC84jOa81%2FaKqv7Sfy5GL7zJq2rwXFhqF40AlWiSQfAEPVW%2BH7Sfz%2FwCRkTl1dLW3t7xi8108C3g9EBArCnI8jtVvtNRcR1zzTdJcQvYwRW7y28dwzFfUblIvI05fAo%2F2OGxSt3zSW9LPXITMlCjiuzofsyRt2YfsPkd0iabTtQksp1Zra4U84X6SJ%2Bw4%2FwAoD7Ei5dzqV7LFCt7KZnVAY%2BRqyg9aj%2BX%2BTJdouuaHrltb2PmCNfrkKmO2vKcT%2FkgsP2v5cjtapfo0Jt%2FMllFGHltZvVeK4ptwWNi6yU%2BzIvRlwm1mUarpNtJHEWutOkuIbh0FSbfkGiZ2%2Fb4MxH%2Bpk6uZNM8saddywStNK605tsKnYcF%2FmbOZy3s2nWaLE%2FG4e4%2BsK43HELxowOzK%2FL4lx5fFWb%2FlprP1TWLQMaLMFRh%2FlRtxr%2FwLYn%2BfNjLp%2Bp2WpwghWLxuf2SGoRX%2FAIDI9peo2kMtjfWQMUi3JM9u24j5rT4D%2B1G5qyfyfYzp%2FwCcdimr%2BUra%2FG%2FwpISOoIpXJDcIPN4HDcR3Scl2I6qeoOGNvcQyw%2Fo%2B%2FJWGpNvP1aBz%2B0PGFv8Adkf%2BzXIxSaym2NCOh7MMNYLhLlOS7H9pfA5FU30vUNQ8uaqjIqsaqHiO8UsZ6EeKsrfA%2BS3yUr6p5iudTl2S1RvRTchTKeCgV%2FlTlkOsvUveOn8VkdatauxoyN%2FID%2B0r%2FwAmTfyYHsrnTdPasc1%2FNczXMZArwhT04g3%2FAD05Yjml6Fditlcmu%2FpvX%2FgTnK5bS4sp1mDtFID6kLioPXZgc61NGTBNH4o1PpUjIpNbyX0Ulvcw%2FV9Tst7i2IqHWn99EP2kZf7xF%2F18nMX1pANMR1TTYfMkRuYYlt%2FMEY5EfYW7UftL%2FwAXjDf8u%2FMFzM8mnX6MJLWRFkMh4yiqtGUYU%2FZP82IzW%2FH4DVQG%2FduPtRP1FG%2Flb9lsG6ZJDJfPcvGI9WCoJZwPhmRGHF2X%2Ffi4AP2peafmBE8Hmq8LgATCOVaeBUL%2BtcjauUPip6qe%2BdJ82x293Pb2GtyL9ZmWRoL5QAUZZGQK47p9nOd39hdaZctaXScXXdSN1YHoynupwFCL0zUX0y4SVGf6uWDqybPG46On%2BWv%2FAA652nRtY%2FTdqJbfjLdqnK4gjpSVen1iBf5G%2FwB3Rf7qfOCxycaqwqjfaH8ck%2Fk%2B61K11AC1kZYIT6gmB%2Bxy2oP%2BMi%2FC6f7LEGlZCbBr%2B%2Bu%2FqqpBCjP6cbtxHwn4ljrX%2FgckOj2EMcC6lK6yTRKYmkIoYl6gE9xT7L5HhcTJqM1jJCEjjQSQsK7qT3rgi%2FuJ7PTDKQ31S5f03ZPi3SrfGP5RiKG6bej%2BQPzB0CG%2BuNHvB9VeZx9WvZKBX7cCf2P8jOvghgGU1B3BHfPHaQrfuEt3DHkAJakKhP8AO37A%2BedX8i%2BYPOen6dNp2qK5t4JFjs5HClyoNJfTdieUaL8S%2FwDCZEcRNEc%2BrfOOKWMTgeGUaEoHfi%2FpRP8Aunt2Ab3UorWqAc5QK8egHzOPhuoTYrdesJYgnJptgDTqdu%2FtkT1C9XnLPIwofjLduJ6fhkgLcYsi0vVRfSSRSUWRd1UeGGgyN%2BVrCSkmrXKlXnHC3RtuMXXlT%2BaTJKMTV7JdmzZsCuzZs2KuzZs2KuzZs2Kv%2F9Dv%2BbNmxV2bNmxVB6rafXtOuLXvIh4HwYbr%2BORbRL%2BsMTMaSQsOSnrseLZNDnIdfXXtP8zXtnZGC2tJWEsUz8pH4yAE8Y14rs3JfibJRPMKyf8AMXye3mKyh1LTH%2Bra1px9S0ulFSV6mNwPtRnIb5e8wXlw%2FwCj9VR9N1u12PGoD9vUgfpJG%2F7UedN8uapcXsH1e7C%2BrAi%2FvV6OPs1K%2FsttgLzP5Ysr%2B3NzHFxmjPMlNj%2FrLTdWHtiNtlU9I82sxa11lAssf2bmMfA9PFf2G%2F4XIt501y81SykEEjRQRMGEaMV5L0%2BKn2sq4ke3j9O4asuyLNSnMduX%2BV%2FxLCfVZ%2FS0u8cDkVhYhfGgxodGQDDZPMculusTzpwryMT7mneh%2B0uTVNL1e%2Bsob1tLmmtJlEkbFW5FGFR8NfUzi2iQ%2FXNXtLjUAXWe6hE3L%2BQyKHG%2FbjnqzzP5ok0H0baxgWVyodi5IRU6KBx74ASrzOzsfL1tcH69ppMtdxM0h4%2F883OS2GLS7239K1pGpGwj%2BEr%2FALHphVcecBcyrc6vBFdabL%2B7lV0UPbt12KDnx%2FlYYGvrWKwP1nTp3kirsT0BpWgcdf8AZDJg%2FFjSanSb8xC2ursXtpG5kt7dkVRGaU4g%2FETy%2FwBbIzc60xSeylsgphDJeafNtIY%2BnqREfCygYcWPmV14x3qkqQDzAo4X%2BYr%2B0ME6h%2BidZZImjM90FLQzQj40BFNn2%2B1X7DYkd2yi%2BrHNIh8uXbLp7yLJdToZbZJDX1EU0NOXxCeL9tf%2BJ4PhbTLya58sXqqt3EoKlV9MSoRUMn8ssf7XH%2FXyD%2BcfKFzoWnRatFqUUU%2BnSGSGAsBcFXZaFeHJVZDu2HOn3See9Kt1%2BsCx8x2y%2BpaXabB2TxH8pP21%2FZwAnu3VQuV1CC2iW9cx%2FwCkS28kMtA5dKLHL1%2B00TJyZPhk%2B1nS%2FKN59Z0GSNno6yI6e1V4v%2Fwy5z9pv8YWj6Hrcf6P836EWmiiHSfiv2ox%2B2kwH7P2ftLk28uxrbeXYLhYXV7gMzxkE0IqPiqNq%2Fy4gb%2BSk7PNdX1m%2BHmqaytJ%2FTtTdx%2FBGoSu6swZqcj8YbCnRmM97drKxKXcslu7tXb1%2BSBq%2FwCSzZK9c06xuNUutStkBls5IFkAIAMoHqUUfzNRkbCPW5Xs70rZcVtL0%2BtCoAFVc1oK%2FwArni2RIShdD0rU9Z0g2UNW1DR5JLG%2BirRlQuXhmp1ZP72M%2FwCph75g0K2sra21G8ch5baGJUpt6yARuvL6OWEQk1eJrq9s55YLxBzuGhJEjr3LKvxSqv7WISanq2oQRXGryvd2MtVhuSQ8aNQch8OyNjsqElhK1hbcr%2Fcv3K%2FyV%2FycRSQBmUiifsfQM6FpfljSbrR0mCy3EjDlDIzN9sGnphU%2FZ%2FlbIrqnl%2F6jM3Cb1VRqOoU8078XoOHPISIiQCd5ckgE3tyS4StK6xSy%2FDJ%2B7HqseO%2FYVw0W2thatp10he2b7YH21cfZljP86f8AD%2FYxO4tbO4so4I7ZUvG5Lpl3PssprUws392JD%2Fut%2FwCbAOh6sLuU6VqYMF4hKRu2x5DrFID0YY7rsh4tMn06%2FkspjzjniaS1nQfDIE%2BJWXwdafEv7Od0ugnmL8tmYipWEOB1oGWp%2FwCH5Zy4hoT9WuU5BTzj7FHp%2FeIe3%2BX%2FADrnR%2FysvRfaHeaJIwZ4RJGo8QDzQ%2F8AAy5OPVBfPNxbpMpifYqaBu4IwFYWlx9fEIJU7lmH7S%2F83ZJ9e0x7K9unRg8azMkoHWJySVR%2F9YH4W%2Bzj%2FKtvFdaxBDLQKzAVO243G%2F8ArYPJUXb2NvDZtdyWxe3B4meCQ%2BtG37Jkjb9lafaXHRXl9q2r6etnWJ7Yxx28h%2B1UNyMjt%2FlH4myX6lp1poPm57CIFLG8jikCsKisqqXWncc2%2BzhLZW0Om35hCuLiCeSgIHFY67KT9rl4YaV63IwMVSakg1pt27eGRuzvrTWILdYbnlcIWXSdQc8W5pXlp91%2FLIP91M%2F94mG9tcfW3AQ14xgsPH4c4Zp%2Btz6HqN2rJ61nNIy3loTTkA54yIf91zR%2FailyRNUinpV0iXqyyxw%2BjdW5Md%2FaN1iPdqf74f8A5Jtka1ZZ4LWYxsySKpaCRT8QI%2BIxkj2Hw5KLe6%2FTsUF%2Fp1wsmrRRk2l0QAL6Fft290g%2Fu7uP7Lo395hFquqaL9XZmmWCRwySWTgs8MgG6Oo%2FY5fZbAUhC%2BZ9JsfMl1SKYW%2BqyQRT2DMf3UvJeTwt4M5%2BJchKyrOr6D5gQwTQEpFK%2FwDeQv8Ayn%2BZDk%2B1Gyj1ew0SaC4gS5ntmCtX0ELQtQAM%2FEcv5Fwv1bQxr%2Bnhr4oms2ymP6xuCStSIbof6v8AdzYOaGAQ%2BXdTm1NdLjj5SN8QkG6FOvqBu%2BTjTrS2sbZLCMcVUmkpFGLn7Rf%2FAFv%2BFxTTme102DTuILIwZpKksW%2BzxWtW41%2FZyU2XlW41HhcahytOQJZVHKaXw%2Fd%2F7rY%2FzviAqQ21ldXtytrDG0k524qKmnj8sO736roNmNIltfVv7hFeaMnkUqTwpxNA2S2MaT5etS9w6WdtEvx1b42A7Symh%2F2C5zTzb%2BZun3swOjacGVKwrqMgoajeiJSr%2FOTDVdVZPYa3pOj%2BW7u31uKKzuZGP1dePP1Iz1UovxtJ%2FlYU%2Fl%2F5hOtyS%2BWrlis1Gm0pyfiR4%2Fi9Kv7SumcrvNYnu5DcXH7yToamrfSf6YL8ratLZ%2BZtJvoT6bwXMbEjuCwVh8uJauPFuFe%2Bx%2BYJ4NMawQiOFzyZOlDX4h%2FwQyQeVtAn1BY9R1QN9WU1toG%2Fa3qGYeGE3lnRLPVfM19LdAyWkTtcW8a7xOGaq1kGz7k%2FAM6moAACigA2AxJ7lojn72wANgKAbDLzZsirs2bNirs2bNirs2bNirs2bNir%2F9Hv%2BbNmxV2bNmxV2Qzz3p3P6rqKbFKwyt%2Fkn4lJPseWTPOVfnX5gmstNtdBtnMbajykuXHX0YyPh%2F2b%2FwDEcbrfm24MRzZI447GR59w6pMfNyWl7EdD1KM3Cp6dwoKldj%2B1zHE%2FRko0rz1rUtz9SvLe2lm2Hp8jC7BhWqV5xvUb%2FDnn01jPEin8pHgckemXmsTaHcxANw05o57O7IIKxliJYll%2FaRT%2B84%2FsNkIZhIkSjRDl6zs%2FwIjJCXFHkb5gp3%2Ba2r%2BbdPuEvYLVbLRpiFL27c2EvWkj0%2Fd8v2VpkGsfN2p3Kra3V2XicgEsQeQJ3qSNs7d%2BkdO1rSbKw1LhN%2BlbRXVJKFZyq8ZV3%2F3YGHLOEecvKFx5TvTLDym0idv3EvdG%2FwB9yf5a%2Fst%2B3lpHUOvsua4iNwbWCruHK%2FB0qN9j0zoy%2BarW48r2Oq3l1Le2sSizuGkqk6zgUVXMda8F%2FwCDTOO2M01rIs0XCRQ4kHqCqGnZl74NgkTlMqSOIZpPVNrXjGG8Qvfj2wXzSyqz1eO%2FtNSjQM8sVubhFbbkIpPiI%2BUR5Yca3q17IdPmtZ2js7yztriONNhyAKSciPtMJUfIZaXDWL%2Bra0jcq0ZYAV4yAq6mv8ynJf5Yex1PRjpUsfO%2F0pnuLJWNPUgkNZ4l%2Fm9Nh6vH%2BVpMRa2uvBcXej2Gp2rSC5tJJbOZkqW4v%2B%2FgY%2Bx%2FeJhtBB5sOi313boLa9ihMlo3EB5ClGkULy%2B16XJk4rhlZarBFAbZljtrS5Tg%2FoIF4fyOT1JjbC1L%2BbSbowyMwu4WrzJryX9h1PQpxw%2FFWFXNut9PB6srS6frlqI4JZHJ%2Br30bCsbOf5phx3%2FAN1T%2FwCRgPQbtreVrEFrW8gfnDU0dJUPF09unHD%2FAFeygjjvbi2haTQbpxcXlpHvLp9x9n6xClfjtjXi1P2P3b%2FGseE99ol9qtyjIKamYlktb6Mn0L5QKJ8Zp6d3x%2BH4vt8OD%2FvciTXPZaZ%2Bkdp5%2Bgt19Yad5p0%2Fe0vU2Y8T0NPiaM%2FtJ%2FuvOj6lcGysFaRlYxJWUjfkUXk3z5MM5p%2BV2l3U2pPdalFHK1sOLyqQxSZaFOdDWOT7W%2F7eTTzK8UdlcxREhXBTf%2BdzWg%2B7JxNji70HnTz%2B51GXyrrFxaapD69nfcRqSftqxHL1oj%2FOjPjtQ0GNYCfrCXWi3QMtlelhyjkYbFfdvsyx4M87Wy6zqemTq4X9KwQnmegkK%2Bmf%2BSi5G9M1PVfLUt3od3CJIGDEQS7iKUD4Zov8%2FjyErqrruPNkK58%2FJN7Sx0%2B0sDe3k0k9xA6JBJACGqwPHiKp8S8fts2F0mrDS3nubPThH6ZLa5YcQsnBvs3kSsCnJeXJuK%2FB%2FwAYmwQ%2FrXdjEsQRizhvjKCrUp8If4uW%2FwCyuK3Fs893p1nezfVdeDCOxmHFi8ZH%2B89wSeBjP2YuX%2BVFiYggA70Pmt9QzfyjdxXeiPeaY3rNYt9ZjdKUkgP2gyj7L8ftL%2FPgTz2tuLdJIT6cN1JFcxzJ2U7Sb%2Fs%2Fa5BsKfLEMvlPXby2sJI40uF%2F0izVuUcb05n0z3gkTlw%2F3237vHeddXN5pEMdnbmOys4BFcy0qDcF6GJa%2FwDFacmyX8Pu2R1QOi6Yupabd2F78dj6xjLVFUlpySaHwkUf7F0%2BDIrrvl6dr42N0eOtRIHs7ldkv4B9ijf8tKgfB%2FP%2FAHX28mPluyb0Vs7OdTL6SSReoK8%2FTZqN%2FrqOPL%2FJwTqdhFr9m1lqUhjnhcm2uv8AdltN%2FMKf7pb9tP8AZrjVhWHaHrEWqxjTb9gt9GKQytsXptxNf2sl35d3J0jznJbCojuQlR26cT%2Btc55qthdyXcyyJ9X8wWfx3ESbC6UbrcwfzS8fjfj%2FAHyfvPt88N%2FKuq3F3q1hqBIEyc4pWZuCkoAwck9MA50VPJV%2FMq2k0TznfCJQUmPJom%2BzJG%2FxcW9t%2FwDY4Q6cILa6ZY2eKRwslv6goaDfjy%2FaK4f%2FAJleadM80a8t1pcZ9GCJYmuG2MrD7TAfsqv2V%2Fmwr0WyuNXUw%2FVxci1%2BKLt%2Fw23wrg6qGVanr1vrK2t3csIry1aESBjxJEYYOQff4cjvm3zLbpZXLWTGC5vr%2FwCswRjfjBGoC8yfi%2BIjCPX2vNMu%2FqZDRNGKSAgUqxqgqKruF%2BH4sjsyPPIZZSXJ7knfG1e9%2Flxrdt5ksbqdSFu7eMLcW5O4%2BE0cV6xvnF75uVzcb14yyBW7%2FaO2KeS9RutC8yWd7DMYLfn6d3L%2Bx6D7SLJ7YhdkNd3UkRDRSXErxMDUFGclT9IwndCtpWrz6ZN8MskcDsGdojxkjcfZmip%2B2v8AL%2B3iWoySfXbiHUmFy14frKXqH4nL14zK%2FVuX7cbYEeJWDPQVpU0Pj0x6yqLL0pJUW4tXE1o5O9SaSRbeP28Cob1Z1T6vPKzxjeNSSQK9aV%2BznXLfUrdtDt9T1U%2BjeRxpa3iMvF5V41jcg%2Ftrx%2BLOd6VbaTqJlS7lMl5Iri3hHwRiQj920snhzODppWsii6zcGeSZg3po3NSy%2FD%2Fen4K9V542r0LyheaXcm5uaCCWNhxkl%2FvClOqcvs4rrn5g2enI9tpKi4uqlWck0rSvxP8Atf7HITazpccriNaLGD%2FozGnBVIJkZP261%2BFuWE4juLqSZo2pbJMjyitAQeVPwrjxbUE01reuXGvCKPUZJ2Cs0iqgUgFtunw%2FCKfDhWLXSzayW73jxuGElWgJUbUoSDhkLcXEjJDSJqkoSd%2BH7OGlh5a1HzDONIit%2FWvZEMkJRlQtGlKsCxVX4%2Fy%2FawWtILTLTTmeMmbTrm1jXe0nmMLOwH2nZlrWv%2BVhlBb6Lql09zpemrbx2cJe5WNqiRi3EKrfyj%2BZR8WJ6x%2BVPnXQrK41i9sljsrUB5pBLGzAVCgiNWLNufs4I8h6hp738sNxRBexei5BoBJWscg%2F2Xw4VZjoMllFbx635Y52k9mvPUdKaRjHIF%2B08PInhJQV6%2Fa%2BHOq6d5%2F0G7toZzK%2FBwKzBCVrTo3GpQ%2F62cYW21DQ%2FMUVrFH%2B5vyInPSIqzfE1f2afawkmtp42klt0f6uzuInWoDqrFQRQjkMJV9Q2ms6VfitpeRS%2BwYV%2FwCBNDg2ozzr5Y1vTI7V9L1PnbTDk8E4Qs7M1KKHBDp9GTfQfOdosSxw6txkp8UN0DxBG37WNea09UzZBNY%2FM3SfLcVrLrDIyXZKwm2bmW40DsF3%2BFa%2FF8eTW1uoby2iu7ducMyCSNh3VhUYEK2bNXNirs2bNirs2bNir%2F%2FS7%2FmzZsVdmzZsVdnE%2FwA9rKYXmj6jT9w0ctuT4OpEgB%2F1lOdsyO%2Bd%2FLUfmvy%2FcaXstxtNZyHosybofk32G%2F1sB5ORpMoxZ4TPIGj7pbPl%2BNPrERi%2FaG6H38MkPlXzh%2BjhHo%2BrmunCqwXFKmDmfiSRf27d%2FwBv9pMJBDcWN7JaXcRhuYHKTRPsVdT0P%2FNWB9RiWO6ag%2FdygSL7cuv3HKpkwImPcXoM2KGaHhy3B3BHf3h6B5qslXQooNOVof0a7Xdi6fDxBPKQQ78vT35xNl6Fr1l5s0yXSNZRHujHxlRhtMv%2B%2FE8JB9r%2FAIfILo2pT6XfLd8mmiKehPAzE8oT%2ByvKtOPWP%2BXKvrafSpl1XT2L6ez84LqLrE1a8WH7PH7NDlkMoluPiHRarRz05F%2BqJ5SHf1CT%2BZ%2FLlz5WvvTUmXT5jW2nP%2FEH%2FwCLB%2Fw2FauD8Sn6c67a3Vh5x0p7G%2BRfrAWskY6EHpLFXp%2FxpnLdc0S88t3ptrir27msE3ZlH6nX9pcmR1HJxFS3uA4oftDBlvcz2lxHc2sjQzxMGjlTYgjCVG6Mh%2BWD4ZRIvv3GC1Z7pdxHraNJCViukq13aswVAO9xCW%2F3Uf8Adkf%2B6%2F8AVw1t5NPkKabe3SyqKG2uIquYDX7Jc7ei37a%2FZ%2Fazm9tdT2dxHdWzcJYzyQ9R4UI7qw%2BFhkwhvDqECTaZbExyHhPbqKmCYivBf%2BKZPtR%2F8DgIkSDxVHqK%2FSyBFbjfvR8k1xY6gVtLb6vJbVWZbhvVLo38yAemYZF%2F4XCjW0McX986%2BX72Uem6V56bekVAYLu0D%2F8AJSL%2FAItjw7W0utVgj0%2B7k9DULc%2BnaSMaFkrvaz%2F8yXP%2Bpgq00iztbkaVcP8AWBer6NzEworLWjRsoJ4yRv8AEjr9jGOMDbn5y3UyJ8vcyfyHpl1puhy31zEE1e9cJfKxXjK8JMaTqfGZCrt%2FN9rCX8wda%2BqyabAGAM85aYA9FUcV%2FwCGyZXElvb20VgHb1LeNDEKmpKDhGS%2FfOK%2BcrhtU1G8vLZ%2BYsz6M0Q%2B0nBh6cwH%2B%2B5af7F8slsAAxG5tkesTm68saddo3GbTZ5bb1B1G%2FrRfrxGTW7LzPpcrahALfzDpir9biI4tJESAZowftJ8Svx%2FY%2F1cD6VMb3RNTsShJmhju4gVP2ovtH%2FgG%2BLBVnb6b5g0ux1JGWDXNDj4SEiongQcGjk%2F34hX7LfsYBukt%2BWba4gWHWmj%2BsWdpK0Dwqy%2BoWkonJE%2FvHZOfNcKdasnk80288TN6EEqxOXNWSOJiS7n2p8eB4bySw1ilv8Au4OQk47kKo%2BLv%2FLX7WK6jr4u9Uee1jItndiIiasyv9sV%2Fl3wWAFZBbvYajqsV%2FDSP1yITPUgSKH9SSinYcIRw%2BH7TSJhr%2BYOr2sOkWmnhHSK6YiRolFF5A%2Bn6ngJif8AWyP2ML6dbiRI%2FrqsAI3SRAsMY%2BxHKrlGhfl%2FefB%2B8%2F3XgXXYppJG1m2unkbj6Op2pUSKVAqksSNsif5L%2FFH9vHoUlrytdtDCgdmV7d5I2boU%2BINGT%2FLhpr3nLTKJ9UT19TB4zNHtCe3Jj3b2XIssp1Y8bUfFOQsix7SCSlAXpTmj4av5OnsdM%2BuzB3Zm9OWaNGD2%2FMgRTolP3sXP4Zv92fyYi6oITDVrG28x6NBeBvqWoWS1ivSeIikU8jFI%2BzLA6%2FGn%2B%2B3yFaq1pcXix28ZUGi3U2wadx%2FuziAEWv8Aq%2FH9vDLV7TzXeWrqbaWO4VhHeNHtFdCP7EhX5D4v9%2BfbwpC3liGgvIoVdSqt6pLPGr0pTj%2Bz8Xw4CUkEGil7RwRu9ZzwjPx8UZiKePShyb%2BRfMdhHM2kLEV%2BsDlDLQFncUCxcRX7WEF1DCs63zCs6r6c1Nkencr7rgXSpFsb5zCForepC9PiUEfZr4DADRVD%2BddUkPmPU4lUgVNtNG4qDw2Bof2kP2GyK1LECpY%2BAqTnUFhsta1Ce%2B1G3inuZCrySsgqwqFNRkwu9R8m%2BWIwscEHrharDBGjSH5tT4f9kcIoop4da6Vqt2GW0tbiQHbikbkH57UwHNFLbSvb3CNFLExSSJxxKsuzKwPQjOu3%2Fmq%2B1mFo1C2NmFMjhTQLGu%2FKRtumQfU%2FMWh3uoTXx0r1pJePKSWSnJlVU5lQNufHnhQxmOYxklSPiFCDvUZQKUIpUn7Jr0%2B7D8eYrBP7nRbUf61W%2FhmPmtkBFvptnEezCMkj78CpRZOY5w%2FBmWhBCjseuSyyn0pIpIr2CSr2gtbYTQt6aylufPp8PBWbCZPNurROskYgVkYOv7tSAVNRtg2780%2BYPNd5CdWuRJHEWkWONFjRaih%2BFAPljsqLeRrVh%2BjQt3GBRoXBBKAfFwag%2BLJ15B17yfealE2taTHcXMG63Eq%2FvbYL%2FvyH%2B6eFK%2F3iJyT9vAXkPygPNEuoxx3KQ3VrAHtYWP8AeOxpv%2FxWqijMv2WZMLdS8vBLx4pg9jqVqTFJIvwup6fvP5lP%2FDLillv5i%2BStPtL867pEEcem6hxkivLWjIk%2FevHb05ftZF9Okd5Et5mayvoWEtrdRmnCUfYmhYfzftp%2B3k3%2FAC68zLfx%2FwCFdWt1eElrbUoW%2BwGIrDPGv7CyU%2BLj%2B18eIeavKM3lq7WqfWNOkYizuXFeNesE9P8AiX7WNbqCncfm2fzRoUmg6zEqa7ZPDPPCv93eQRMC00A%2Fa%2FZaWLCHzf8Al7oOra5b6h5KuBHe3rj61Ywr%2B5Xlu0%2FL%2FdDfzx%2F8Qwpup4VWBrORhfW7iS0YkrJbkdRLKv2om%2FY4fbzsvkXU7fWNHju3jhj1ZAI9UEKhSJvEmg%2BF1%2BPEhXgPm%2B98y%2BWriTyxrM0iCMBo5VVW9aDoJIZm%2BLif5ftRthN5X8zxWXm%2FTZ9dHq6HH%2Foz2z1eNLd1Kq4TvwY%2Bo2el%2FPXkjTPPGkNY3n7q7hq9jeqPjikp%2FwANE%2F8AuxM8mazo%2Bq%2BV9UuNI1KL07y2PFlbdWU%2FZljP7UTfstih9Jy6d%2BVV3f2dja3ltHe6ipezS2mrzAFfh%2B2iMf2K%2FE2Xcfk5ojoTZ311bz1JEjFXG%2FitE%2F4lnlh3USLKCY7lSGLQ7UI3DA9mz0L%2BVP5wLqxi8s%2BaZRHqIpHZX0hAE9NljlPaf%2FK%2F3Z%2FrYqqal%2BS%2BoXb2EYvraWG3kcyvLG3IRuwY%2BkgPFW2PfJjZ%2BRruwuFa21iRYFACKFKsKf6r%2Bmf%2BReTUDxy6Yqo20LQQpE8rzso3lkpyb58QBi2bNirs2bNirs2bNir%2FAP%2FT7%2FmzZsVdmzZsVdlEA9cvNirzb8zvIf6bhOu6REP0tbL%2B%2BjUb3EQ%2FZ%2F4yp%2Bx%2FP9jOHagvqWsMw%2B1ETGwPWh33z1znI%2FzL8hqEutf0qP4JRzvrdR9lwR%2FpCDw%2F37%2FweRnGxTtNBreExw5DsD6Sen9F4gpphto2prYSSQ3Ketp11RbyAiu3QSoP50%2F4ZcK5YzG5Q7eGPEUyRpMykRSEhH7MV2IzGAkDY5h3OSEMkDjyCxL8beaZaglxoOpxTW7qLSWkmn3cX2eJ34nx%2FwApclMsen%2BcdIeC4QCZQPXjH2kanwyxe2RjT7%2B2e0bRtVHLT5SWhl%2Fat5Ozr%2FxWx%2B2uJWtxe6HqSw8wtxDvBL%2BxLGegP8yOMyceQEbcuo7nnNVpZ4JmMtwd4y%2FnD9bENU0y80C%2BazuRyTrHIPsunZh%2FTKil4kSIaj%2BGdZ1HTtM846SXUenKv2gN3glp1%2FykP%2FD5yO9s7vRb2SxvU4sh3I6MOzp7NkyOo5OKmSuGUMvQ9MMdF1m40S%2FjvoAHUfDPA32ZIz9pGH%2FDIf2Gwjt5Qh3%2Bw3%2BdcFnrir0GW5Kyx6hav6ltfqDHddW5Dbi1do5V%2Bw6%2FzZLPLbQ6nP8AWrpAby3oJGI2kXqkrfyyqR9rOU6HrKWHq2N8Gl0y6p66Lu0bjZZ4v%2BLF%2FaX%2FAHYmda8p2i2tk8sjrI7miTITxkj%2B1HJQ7huJ%2BLJR3K3snuq3fo2ruoqQC3idvsgD%2FWpnMJ%2FJ%2Fme4Msq2jC9tuUaXcXER3drJ1japH72NW%2BFmX%2Fit%2FwB5nTdIksyzW0c%2FryxVZgzBmCsa4eCZAKHDIWgbPDvK9jquh6xaW%2BtW81rDL6lozTKaFJQVAB%2BKtfhwvs47myvL%2BNQfTs2kD9UK8gQKlv2Xp8StnR%2FzQ1GW08u%2BlZO0d3dTxxQshKsKHm7hh9jiq%2Fazi6MxEiI5YOa3NyxJMjVrux%2BIrlctmQ3TS91E3jCG2jHI09R1qOdOgFf91r%2Fw2CLKFYxyJBIFZJOwHgMC2NryG3wRnq56t%2FZhusZiihu7cMWt5ir2zpyikUAU9T%2BYcuWR5pdPqiacQrWqXCzR1USVBAb%2FAHYp%2FnwutdVhtdTa%2FgWVBOAk8BcNG9BTqyk4c6rc2dxe2F3c2kcKJGI7qx4kUjpyR0B6Vr%2FNhBqc9haSxpHERaXRaWIt%2FuvcoTRa75PlyQn%2FAJZvYI%2FMUS2SNELiVTEygUjnVW9OlftI8hVWVsnSXVxfTGS6laSViCS2wodjsNs5%2Fo8rrL69qwd6pIrqAw%2Fd%2FYPw9OmSua51GVJ762swQXLCD1AiryNQrMfi2%2FyVwxKkIjW7%2BezjR7PTpr%2BUbv6WyUH8zfa6duOEPnjT7SEWmrxxkSXatazowA5KY%2BScgD9qIrxwQ3mPX7EetqFhAtqPtegzySAewA45F%2FMHm1dcRIGjMdvC%2FqRIKcuVCvJ2%2BR%2BzglLY2yhjnLaESfcEquburW8M5HpzKvIr1FaDl79cRbRr6S8%2Br245GCoac%2FCjKp67%2FwAww%2F8AL3li01qBLgPJO8f7t4wP7s%2FsE9fhOHer%2BVtfgg%2BvabcJe1FJrPjwZVUU%2Fdy%2FR9llyIFixuEzjKEjCYojmGM6jaajZ28RjBiEisJzULTi3iSKR0wboHkTXdWt21OLT5ru2A5RlN1k8SrsVWT%2FAGD5ena1aXA%2Bo6pD%2B9J2WcenL%2FlBJR8D%2FwCrnSfy880W%2Flyzl0m7uJZtJR%2BVmXSsltyNXhYD7cP7ScfiT%2BXDXcxosR1D8rvP2qWUdlZadHZW7kPcPcXEYeSn2EKR8%2BKJ9rh%2FNkRu%2FwArtc026ey1FooJo9yKs4IP7StQclz0brf5jeXtKhR7eYX0sieoiQHYL29Rv2Cf5T8WQ7W%2FMj%2BZrOKd0t1Ct%2B6eDk7xMaj05CaNxb%2FVwEgCy249PlyECMefJ4235fXQ63Uf%2FAt%2FXC7VvKsmkfV7iab1dPlISW7jTeFz%2BxJHWoPg37edQ5kyNDIvpyx%2FbQ%2B%2FQg91OB7hFCurIssUq8JoHFUdD%2Byw%2FU2IIIsMMmKeOZhkiYyHMF5g%2BhCNipcyFf3nwD7cH%2B%2FoT%2B1x%2FwB2J%2BziNyW01%2BNseVtMoMc4G7VH82TCbyxfWMxtUMlnDIPrOli55JIh%2FwCK2ZeMqthYYOMVxBNb%2Fu2HK%2Fsl6JU7Xlp%2B1xDfbT%2FdeFgmPknW7q0eC%2FsZ%2BOoWTck5ftRnrG9PtIfstnatY0iw%2FMfQ4%2FMWh8bfXbdSjxnbmyD47S4%2F5ky55gWcaZqDPp1yZo42Ppz8SvIePHOn%2BTfO2qaXML%2FSHiPqcRf2M9fTYf78Xj8XIfs4qoWsGsQ64Tpp%2Bo31zGbK9WYfFE8Z9TceI4FP9lnpNbWDVdGit9RRbiO4gT1g3QkqCW9jX4lzksE1z5382DU7WzEKoqq5UVAoOIeV9uR%2BL%2Fgc7RDGsMMcS%2FZjUIPkopj0UvHtQ%2FKnV9H1F9X8vXCajyYt9TuQoYLSijkx9OTj%2FlcMS8q%2BaLny95guoNYs2s%2FrfEXsLLxKyJXjLH4pxOdpwl1zy1p%2BvCOSctDcw19K5ioHAOxU1HxJ%2Fk4otNoZYriJJoWDxSKGRh0II2IyF%2FmN%2BXll550z4OMGs2oJsLynfr6Mv80L%2FwDCfayU6RYNplhDYNMZxACqyEBSVqSoIH8uDj0xV8NappV7pd7Np%2BoQNbX9qxSaJuoYfrr9pWwuSNg4NSHBqKbEHxrnrL80Py2g86WX1%2BwCw69aJS3kOyzoN%2Fq8x%2F5NP%2Bw2eXm0q8guZoblGglicpNA4pIroaMjfy0OKvpf8lvMusa5ol1ZazOLqXS3jiiuTvIyOvJRIf2ylKc86eM8y%2Fk35usfK2r3FtfyMtjqoRZZ3qRFNGT6bP4IQ7I%2F%2BxztF1%2BaHke01SDR31aN7mZ%2FTLRVeKNu3qTD4F5dMVZlmylIZQwNQdwRuMvFXZs2bFXZs2bFX%2F%2FU7%2FmzZsVdmzZsVdmzZsVdjXVXVlYclIIIPQg47GSOsaNI5oqgsx9h1xV4R%2BZvkA6VK2r6VH%2FuPlarIv8Aulz%2Bz%2Fxjb%2Fdf%2FA5EoJLK%2FwBFh0yOJU1AyrH6oABboqJItebtyJkjZP8AKVs73qnm%2FwAsyW89les7xzwtSMxMRKG%2BHghpx55w%2FwAy%2BWpbIHWNNjeGKFkDjlVw5%2BIPGwp8S%2FtcfsZGUauQHvdvpNWJxjhyyMZA%2BiXQ%2BUmMXNtcWVzJaXSGOeJisiHsRtll1uLf6rcMeKb20vVoW%2F6pP%2B0v7GHsLr5ptvq7mOPU4ElmEhHH1eCII4kp%2Bz6aO7%2FtephBNBPbytDcRtFNGaPG4oR7EZVKJHrhz%2B92JjDPA4cw3HMdR%2FSiiNG1m7028EiEC4j%2BGWMn4JU7qf8AjVslmvaBp3nLSFvbCiTKCY2P2opP24pKfs%2F9d5BTFFIys5ZGX9pKch9B65JvKmrSaVdevxea1m%2BCcEFQyj9tR%2FvxMtxZBIV8x3Oi1eknp5Ud4n6Zd%2F7XmskVxp11JY3sZikjbiyHsf8Amk%2Fs4caPay6peQadE6rJMwVXboF6k%2B%2FEDOn%2BdPIkfmSyGp6QA12qc4JFpSVPtcG9%2FwDjfI35a8qzaFNa3urKrXLmscfI1gP7NSv2n%2FmywxouIN1DWPKDW95DY6K0t5IfgnaUKgD05cl49I6H7TZ0bynBAmmjSVvhcz2qEM60%2BHnVRw9om%2BH%2FAFsItfhndg1q%2FpNdxmIuDQVU%2FECf8oYReSLk6R5nWBw1bmT6sSD8FGBb4h%2FNyXDyPvbsWITE9%2FVGJkB30jPKV1PpOsrBduRLFcPb3JY9VditW%2F2XxZ0%2B91O2spIoJWL3E54wW0Y5SOf9UdF%2Fmdvhzm%2Fm2w%2BoeapJlBVdRjWdCDsZE2cfeuHdvfQW0BngZptVvEH1u%2FlG6gj%2B5hH7Kr0xHc0pD%2BYg8wa1NDFZWjSWtsrCRoiGJcn46b1YdF2yFWemzxsW1CN4Ej%2FZlUofubOs2WpxpNGl2oMP2eSbEe5yTXGkadqFpJaT26T2860YEVBB6EHx8MeCzdpunlEtpHYQ38GqRrFNaPA8EgJcFa%2FGqhadao2XBGlmbe2uCzevbGeRo2PcNJx%2F2S%2FDht51s3sLpYLoH6ncIq21wRU1UceLt9Hxf8Hhj5f8pXerWc%2Bq2VrHqE1oqQWdvNLwUoijmJB%2FO9W4%2Fs8cjVH3LezEvM2mXWqyabNozB7SS1WJ5SwBrHWnLv8A3ZUbfy4onlazmtrKC%2BJlNoHFFNFbmQaHvtTJ9rPlzU7GOO6vrRbeNioQQMrRxmn938IXj4YE0fQLnXBdQ2062l1CP3SSry9Xav7og0%2F4LDsikps7C3s1WK2iWJB%2Bygpg5lNOX0YAVr7TL0xXsxcxsVlhktwpFPtLVWwbf%2Ban0e8tp7LTYrmyILlpyT6hoRw2%2Fu%2FTbdlw3taoK4v7a1dY2dW5GjQ1qVHj%2FwA24Vah5a03VlNxZEQTtvyX7LH%2FAClyfjyfo3nrTrbV9PRNI1i6gM8qRENC8gb05OUI%2BNR6nR1%2F4HIRqOj655Vu%2FQ1SBogT%2B7mU1ikA7pJ0%2FwBi3xZGwdizhOeOXFCRBSPSZNX8maml1MhNsfgldPijdD1H%2BS37S8s6ZLrEEZt2uEe1W6VWtLsg%2BlKGHIGOReS%2F6wOR9dWtRp11dSQ%2FWHt4Wk%2Br93IGyU%2Fysk%2Fk%2FW5INATT9Z0eAWczGT6gr%2BoIlfcgBxsf2vT%2FAGMYxMSeE2D07m7PqBmjEzjWSO3EOUo%2BY72M%2BYfLcd3FJeQRxyo7EzQU792GQ60bU9Hkf9HTAwts1jdVeNl%2FyX%2B2n%2FEc7ZL5XstVSS58p6kYZqVbTrysif6tWPrRr%2FspVzmuvaDq2jzsup2JtA5NCfjtmNf91Tjb%2FYyccJ8tmgJPqV4JJLJpI3sYLqJ2uY%2FtBgP91q6jpIy8Vw0sNNn8tG11m8KWNnqTrAums5YhTvyct%2B0R8fw%2FYb%2FWwLdRpfaVEkkPO50r1HhjJALRSg9HpX92%2FwCzgSW4TV9Hga5uppdVspFt7a0FOMNshHJm3VuZY8fV%2B0zfBlZHq3BNigOnm52LIfDHCYwMCJmVXI8IqMYnzI4f85l%2BsRQc7eSKVRPHKts4ruUkPAcv9R%2FiwbZaY1p5gtrHUoipjnjWZOo4lhRv8pGwcPL9pcROZo2S6ZkaXgyqoaFVk4hn%2BJ9uPqNxwVrmsWupvYzalF9S1K1lTi6GscsYYMpV%2FFWUNx%2FlwYoSjd8jybO0suLMcUsdmUQROxRrnH75PQtd8vaT5itBZapAJI0YPE6njJGw%2FajcfZzg%2FwCZWh3GhW%2Fr2wH1vSZ0DXlPia1m%2FuZuK7MV%2FuLj%2BbPQ1pdR3ltHcxGqyCtOtD3H0HIF%2BZFnb3k8EMqhxPBJHOh6MnIUDfSdssDq3zfqWmR6lFJqenRCO6iHK%2Fsk3FD0ng%2FmjfC3SNVudJuUvrKQJdQOrxc1DoafaSRGqrK%2FRlyU32i3XlnU4RHOYrF2Isr1hy9Jm%2F495%2F8AimT%2FACsKte0Zp%2FW1Kxg9KaL%2FAI6Nipr6bH%2Fd0X88En2lfFX0%2FwDlz5x0fzbpAlsIYrO%2BgAF%2FYxBVCOR%2FeIBTlE%2F7Lf7HJpniLyz5m1TyrqVtq2ly8ZYzuvVWX9qOQftI37WeufJnnHTfOekJqViwSZaLd2pNXhk7qf8AJP7D%2FtYFZJmzZsVdmzZsVaOct%2FNj8sx5ntJNb0NfT1uBayxrt9ajUfY%2F4zqP7tv2vsZ1PKOKvhz0CsbwMzqSSHPRgw2%2BL3%2FmwrlheB%2BD9exHQjxGeqfPH5Oad5lupdW0icabqU3xTqV5QTN%2FOyr8SOf2nX%2FgM59H%2BQfmu5nWC9ns4rbl8U6OzMB%2FkpwGKr%2Fyk%2FOBtOMPlnzTMWsyRHY6g5qYq9I5j3i%2Flf8A3XnoxWV1VkIZWAKsNwQehGc68sfkv5Q8vBZriE6rdrQ%2BpdAemCO6wj4f%2BD550VVCqFUUVRQAbAAYq3mzZsVdmzZsVf%2FV7%2FmzZsVdmzZsVdmzZsVdiNzNDbwSTXLBIUUmRj0A98WwNfPaJbSm%2BKi2pSUv9mh2pirAPON5pMWiStoiPJfM1bVI4yy1G8jDkCnwrhDrD6jFb%2BWbC7Wt36Ecl%2BCP%2BKiZHbtyJajf5WDvP9xZRaNCfKtxKb4zj04IOR403JKkfAOfH%2FWws84ajNd3EEklFuSOUtK%2FDRVXiKduQOFIeeatpk0F5PeaUj%2BlATLIYwSYhXd%2Fh%2ByleuLP9U12ykmiWO2vrWOW4n3PxgcAFXmaty3cf77%2Bx9jO1%2Flvo0EejT388SvJqDMjFxXlEvw8TX9ls5h%2BY%2FkSTyne%2FpHTVY6LdsVUj%2FdDt1hf%2Fitv91t%2FsMgRW4dxo9X4vDiySqcfon%2FO%2FoyYJsQGHfJL5FsrXUdZk0m6uTbR3UTvHQAgzRjkONSODla5GgcX0%2FUJNL1S0v41DPFINm8G%2BE%2Frym%2BHMD0k52txeLppjqPUPfF6l5X8xWlm995evZlguLSdkjR9gTWjrXovP4XTEPM6wwzKSKCT4tuoIO%2B3vke80xXU2tW13ZQ%2Bo15bq8npJ8UlELVp%2B3sMBWOsXOtWy2iEyXNuCyIw5Myf8VsaseFP7tvizL4tq%2BTzNUfvT%2BOU6npky9ZrciVAO5Xw%2Ba8sis01rp%2FmC01O5YrSWJ4kXcyFiB9nsK%2Ft5fljzLXzMlg0bRQujQESbVlDcl5IenL4kyeebPIp8y6j5e1DSEjX0XWO4QsqKYk%2FfRgV%2Fb5gx8cHMe5lGUom4mjuPnzSW%2F1OfVL6R7sJW2keKFUGygGhIJ3PKmNVy%2FTAk1pdWc9zBdrwuElcTIezA%2FEMj%2FmjXbvQtaW3tEBgCJM6PuCHFQExtizSKI1DHJv5VuxKrWMp%2BwC8JPh%2B0v0ZCNLvrfUrGG9tjWOVQfkf2lP%2BqcPdHme3vIZV24sKn2Ox%2FDJBSyzzBplrqWnSQSxLI0P76EsoIDqO3%2BsMgmlaxceUdRXU7ZS9jJRb62XoUP7QH80f2k%2F4HOgXdyVYgHp1%2BWQW8g4TzQyoQpJIVh1VuhGJCh7FG9hrempKhW4sryMMp6hlYV%2B%2FOWa%2FbXfk%2FU0ZJOEL1ayu2%2By1P91udv3if8OuCPJ%2FmhPL1xaaJetx0y4rFFMx2imJJSvhHLXj%2Fr4N%2FO9G%2FwAJ28o%2FYvY69%2BqOMgdlYzqPmWy8xr615aouoxAA3dk4dJB0%2FfRGjofBl54U%2BnCySRNSa1l%2B2vQq3861%2By65GPKcztqxjY7NEw4jYbU32zoNppF1qfrw2JX6yierHExoJivWIf5fH7DYYnZaY3pN9N5N1n9JJEbuIwyRoisY1kDbpVu3F%2FidM7xpl3Y%2BadFt7m5tle3vIUkaCYBx8Qowof5WB%2BPONG0jvLY28qlRUgqwoyOOu37LpiXl3XbjyZqk7XglmtZIfTEKNQGh5REFvsxr8XLjgIrdWQedvy7GiQPrfl4SNaxVe5s1q7Rp3ki%2FaaNf20%2B1kT07WGCqwcMjdJFNQc9C2N9BqNvHc29WiljSVGI2KyCopkFv%2FwAotHu9cOq2d1JYW0x53dhAo4O53JQt8MYf9ocMFyB23ZwGOQIkeCQGxqwfIsatNQSQrIrmOUbrIhoQfEEb5LLHzPP6X1TV4RqFo4ozFVL0%2FwApD8EmFms%2FlxeWBNxoEpuIhubSQj1B%2FqPsHwo0%2B4ltUmW7Ro5ojRo3BVhT2OWCi1t%2BbPJ1pFCfMXlJgtl%2Fx92VCyRHuwjb4kX%2Bdf2ciOlG2huhcX2n8JI2BE8FHHzMTb%2F8TVc6FpWutaySPblJEmHGeCQVVwP1ZGtcsIbe5N3p0Ui2MlWaM7mB%2FwBpQ4%2B1F%2FLkTGulhnDIYnYprf6tYaxaxxCDlxIaG7iko8Z7kGtWr%2B3ywxsdGl1WwitzGbkgkRzugDGnRm34R0%2FZbIJBZwxv9YhAVx8Qp0JPiBnafJl1eXekLNdyrKOXGNgADQD4g3Gg%2BE7Y8WyTLfiHNJbbQvNHle%2Fe50eQX%2BnXAD3Vg53EoWnKImhQmn7Pwv8AyYRX9xql1dmXWOS3XHiqMnp0QEkKq%2BA5fazrQwHqOmWmqQGC7j5D9lxsynxVsFsLeO39hb39tJbXMYlhlHGSNuhB%2FUffOZXy3%2Fl7UV05n5MgrpN1LTjLCT8VncEj%2FYf5Odt1nQbzR3JcerasfgnA2%2BT%2FAMrYB%2F5V3Y%2BdtAvhefubrn%2FuNux1jkQUYkD7Ubnir%2F6uEq8D1rTFk9XUdNgaHix%2Bu2XVoHPcD%2FfbfstnQfyAeb%2FFktC%2FptaSF1VgFNGTiXFfiA%2BLj%2FlZC9WuNd8p6kNM1e04anYsY2mY7TW%2FZG2pKjfsS4K003mkCHzl5WmDLazercWoB9WCvX1FB%2FeQt9lv8nIofYNRl5FPI3njTfO2li7taRXkQUXlp3Rj0Zf5on%2FYbJXirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FW7%2FmzZsVdmzZsVdmzZsVdgHVY9PmtHi1JlW3cgEuQBUbr1wdgPUdNttTtzb3IJWoZSOoYdxirzHztP%2Bi20aTyvdm6uDcJSCMJIPTVhRWKj7Bbbi2B9b8keZrnV3FvberbsQsVwHUKFJ6tU8hSvhk%2B%2FwAPGy1GwvLOkqK5ju0cIP3YQ%2BnItAPiif8A4nkkphKQaQOk6eml6ba6fGQVt4whPif2j%2FwWO1LTbPVrGfTr%2BITWtyhSWMjqD%2FEfs4MzEVwIsg2Ni%2BVPOHlm58p65NpU1XhP72znP%2B7IWPwn%2FXX7En%2BVgW28s63f2kWr29m76Ys6xyXQpxUggNUfa4iv2uOen9c8t6J5it0t9as0uo4zyjLVDKf8l1oy5EL7TriGW30Lytp7Q6Dbs0d7xI4Oz%2FFWPlycmNvib%2BfKziufETs7WXahOn8Ph9dVIn6a7%2FewDzPd3ukNplzYtxtEhW2adVBKzRktTkalOdf%2BBw60bydZ%2BaNR%2FwARaPq0VjOIw509bcLIkw%2B16yh%2FjRm%2F3an28de6dLYTXGk6xDztpx8aHoyn7Lqfb9nI3YX%2BreQ9ThS3pcWhcvazMBWSE%2FbgaQ%2FF8P8AJlrrDvunvmryB9buFvzAtnrkQD84z%2B6mKHkGRtu%2F82HWnO%2BoadLpU5aC4ZeUL9Gil%2B0jKR0aOYZOLO80jzho0d3Zv6kMn2WFPUhlGxVh%2By6H7WQWaO80rV1hvwBMjcfUAoskTbLIP%2BNsIr5oSu10tfOt7Ikt4th5ijQC6hkSsdz6fwfWIiCCr7UmTj%2Fl5JG%2FKTSdTjg%2FxDILh4UCUgHD7P8Axafj45GPMdkYtRkvbWf6jewEXNhcr9ppT9pEVatJWnxJx%2BznRPIfmz%2FFujfW5Y%2FSvLZ%2Fq94gBCmQCvNQfiVX%2B1xb7OA2NleaX%2Fkr%2FA19Jb2rO%2BlXbc7UvuFbuvL%2Bb%2FiWC7M7HOuarpdrq9jLY3i8o5Bse6t2df8AKXOP6jbaj5dvpLK5USBd0fcB07Ov8cMT3qkP5l6trkWp2kNi8sVr6CShoyVDyH7RJHXj8OQpfNfmCN1%2BsXcsnBeCrOfUAUdFHP4uP052ny%2Fq2g6veR6T5hgX94Almsp%2Fdsw%2F3W%2F%2BU37GSHUfyp8n6hUpavZse8DkD%2FgH5p%2BGCXNeTwM%2BbzeWxtr%2B3SVHFGMZKMP8oBqr%2FwANh9qv5gpr3kVfLV9zk1O3uIjFOwrzt4w1GZhUeqn2P8rJD5i%2FJJrK2lvNKufrSx%2FEYCnCXiOtCpKPx%2F1M503lq7tpDxDNUUUGlPwyJtWQflfpMWseaFtLgssZtZnDJ1VhxCn3651e38qanp%2Bs2ZX95brKG%2BtR7UVfio6%2Fs16YS%2Fk3pGmWxvNR%2BspJqfEW7WnR4kryLFW3PqN%2FL%2FLnW8I2UsW8x%2BVo71n1LT0CXp3mjGwlp3%2F4yD%2Fhsgl9oyXUaxX1u8LoCY2dStV%2FaG%2Fgc7JTEbiztrr0zcRrIYmDxlhWjDJCXQoeVeW9Rv8Ay1PKL25kuNO9ELEo%2BIjgaoKk%2FAqJyzqtrdQXkCXNs3qQyqGjcdCCK7ZFPMPl1Yg95aLWA7zQjfjXqw%2FycB6JrNzY3BW7uAbARKgUqSQVIC8KfCq8K8vhxq9wlntK4DvtJ07UgBfW6TU6FhvTwqN8FRyRyoHiYOjCoZTUEHH5FDC9Y%2FL6wuSZ9Ic2M3X0tzEfo6p%2FscL9B%2FLy8XVJNS8y3Yuo41aKz0%2BEkQrGwoWlO3N2zomVTDZV4l5n8s3Plq94oS%2BnTk%2FVZj27%2Bk5%2FnX%2FhsMNI893Wj2ht2thNVSEp8PGSlBK%2F%2BSf286nqOnWmqWcllexiSGQbg9QezKf2WGco13yhdaVMUT95A39zL0DDwPg%2BIZc3pPlzU5dStGa4IaeNgGZaAFWHJWoMOc5v5E1B7Wf6tcAoD%2B5PLb3jP0fYzo4xIYrZIo5UaOVQ6MKMrCoIPtidrZ29lAttaoI4UrxQdBU1OL5sCsO8%2FwD5e6V5708RXNINQgB%2Bp3oFStf2JAKc4m%2F4XOIWX5R%2FmVoOpummwIySAxNMssZhZG2q3Mqen80eeoKZqYq8l8h%2Fk%2FceW9Qt9Z1DU3W4gPJLS0JCEGvwTytT1U3%2Bx6arnWs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F1%2B%2F5s2bFXZs2bFXZs2bFXZs2bFXUzZs2KuzZs2KoXUjILG49E0k4EKetK43TYkhsoQp5EqGZvEnvgp1DKVbdW2I9jhDdaDqT%2FuLLWJbOzP8AulEVnAPVVkb4hiqB8wWUXmS%2BXTYWQi3ikZphuUlqOKmn7P8ANnOtRsiPW0TWUKqD9ofajYfZkQ%2B3%2FDLnYtH0Wy0W3aC0BJc8pJHPJ2J8ThV5u8tJrdoZrdQL6EH0z0Lj%2BQ%2F8a4bTbxXQPMGq%2Fl9r7mSs9jcUN3Cv2Zo%2B1xD4Sp%2FzZnaNYhtfNmgRaho7JcMwE1pKCASP246%2Fsn%2BZf58gsugWWtaPFp1xRL21qFkFCyP3U96YR%2BUfMt7%2BX%2BqvpmqEtpUsnGeOtQjE0FxD%2FwAzUxOy%2B5kHmGCOa1s7%2BVeEsFYpHI3SvwyBvDi647RtH1by3qEXmPT5VlgnWmo2C1Amj6rIrH4RMnVcCz3FvJ5x1pIqX2h30cVy3ouv2nQEeka9XZW5ZJNPult7dbZpTLasP9HlYUalP7uVf2JlH2v%2BEw891ZzY3tvqNtHdWz84pBUHoQe6sP2WX9rC7zJoEOu2Xp7LdRVa3lPY90b%2FACHwi0IahBqtdOo9hKf9LjY0Vf8ALU%2F78ybZFD591jS3R3gnRo5Ymp4MjA9snHkr8weRi0LzJII7pQEtdQc0SYdFWQ%2Fsy%2F5X7eH%2FAJw8uLqMDX9qg%2BtRL%2B8Uf7sQf8bLnJbuyjcNFKnND1U%2Fw8Dh5pfQo3Gc487eVFhMmq2KfuHNbmNR%2Fdsf92KP5G%2Fa%2FlyPeXPM%2Fmfy2Y4pmk1PRqfBBKpNwiDr6E3%2B7OH8j51%2B1ubXU7JLiKklvcJWjDqrDdWH%2FEsV5PntoFiuUuQOFxFvHKpKsPpWnLJZ5b8w65p1xEguXuIp3q8d07P1%2FZVm%2Bx%2Fkccbr%2Bhm2125sbPggX95AZq8FRhy3p%2FL8Srk181aDHqempqtvRLu2hDngPheMDmV%2F2P2ozjsrKLW5ju4Eni%2By4rQ9Qe4OL5D%2FACp5hgu7iOwkkUXFxD6yx9DWM8HNMmGJFFDRFRQioPUHIhrmgrAXubdK2z19WOleFepH%2BRkwymCkUIqD1BxBpWIaNq09o31WURrZoiem32ePEheCIB8VV%2BLJcGB3BBHtka1LQXVne0XnC9eUQ%2B0tevHxXA2lxazHfW620rx2atW4gkSqFOPCgdvjDClVwkA7hWYZswzZFXYnNBFPG0UyCSNvtKwqDimbFWE6voE1hIbu0Be3BrQVLIP8rxXJRo92b3T4Z2%2B1Ti3zG1cGkAih3B7ZSRpGvCNQqjsooN8NquzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxViPmbyo91cfpvQiINVT%2B%2Bh6RXSD9iXwl%2F33N%2FwWQzW9AXXo%2FXaFg7L%2B%2BhK0mjdBuafzACjrnYcDTWNrPKk8kYMsZDI42NR40w3tRW3z1p2l6ho%2BotLAfXVE5OgDVljA%2BLj%2FxZGv7OS2BbeaRbscpI5YuLQq3ETIfiQcv2ZVP90%2F8AsMk3mi1FjqBnt0CpcIHIUU%2BNT8RFP5tuWRDTFEulwPaP9YjVSfVjBIFGPM%2F7BvHCOSXqXlu6trnTI1t7Y2Zj%2BGW1YhmQ%2BJcfb5fzYcZBPKl1I7GRXHKGi3AY%2FajPRvdsnQNd8BFFDjnL%2FPWhJaXguIKRw33KngklPi%2F2Pxcs6jkY892Ul3onqwoZJLWRZeAHIlT8D7fJsAVBaLpUeueS9PtriYPcWykQXkfZ4yVDD%2FJP2WwX5X1NJ2NrQIGXkoXpzQ8JP65GPJfmOTR5G0zXLmGCzlYmzhZPSeE05ceP7UTjfliOhagkWs3CW0gkUXbPZjoZVkY8kQHr8OSHUJZD540vmYtVRBIAvoTo260JrGzU7cvhzaJ5jgm0t9O1u7giu%2FRdY%2BJ48oyCg%2Fd9QyfZ%2FwArJhPBFcwvbzqHikBV0PQg9sgt%2FwCSLpJy9pxniPRiQsgH8rfzYB5ql%2Fkq1hXU4ZigNwjsizftemU3Uf5Jzp%2BRXyloF%2Fpj3FzqYiR3YraxREsyx%2FzTOaL6j%2Fyp8CZKsSUOzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Hv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVg35iPrMEFld6XbR3CRM%2Fro1fUIIHwx%2Fs4U%2FlrqOkz3c1lYQmENFJI8DCgRzIDIg5b1JavTOiajZLf2cls1KsKofBh9k5ydpJPL%2FmzT9ZcBIWY2t5sFoD8Ls5C1%2FwCDkyQ5KyjWdLGi6ml3brSyvKxuo6I58P8AJPVclOiXZurPi5rLAfTf5fsn7sE3drBqFq9vLR4pV2I7dwy%2B%2BF2j6Xf2F5dS3EqNbyhViVa8iV%2Fbfag6%2FZXBdj3KnWURXLzYFYV5n8n3us6ut7btEITGsbc6hl418B8WFd75Ym8svHqVqPrQiCsJSPiikH2jQfsNnScayhwVYBlOxB3BGG1Sby7rf6YgZ5KCZftIBSmHeFllodlp95LeWqlDMKGIfYB7kDDPE%2BSuzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F%2F0u%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZFfM%2BipLW%2BSJZAf71CtaMPsygf8SyVZRAIIO4PbCDW6pP5YvDd6Wiu1Zbc%2Bi%2B9Tt9mv%2Bxw5xG3tbe1Vlt41jDHkwUUqfE4tgPNXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Pv%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV%2F%2FZ ); background-position:center center; border:1px solid #00aa00; } .yui-skin-sam .yui-h-slider { background: url(bg-h.gif) no-repeat 5px 0; height: 28px; width: 228px; }yui-compressor-2.4.7/tests/dataurl-base64-linebreakindata.css.min0000644000175000017500000000353411640627104024715 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml,.yui3-skin-night .yui3-dial-center-button-vml,.yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min,.yui3-skin-night v\:oval.yui3-dial-marker-max-min,.yui3-skin-night .yui3-dial-marker-vml,.yui3-skin-night .yui3-dial-handle-vml{background:0;opacity:1}div.base64-doublequotes{width:100px;height:100px;background-image:url("data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFBQ0WDWwqwjwAAANMSURBVEjHrdZbaFxVFAbgb2aSTG6GTi6mVIwxNxF9qFI0RQnFUqiYamutVutLa2t9EY0oPggFoYgPRR%2FaghYviA%2BiIAYvmBJKoYWiiBCigVTT1FisbUhrEtNkJpc5PuQkjGEmJqkLFmdz2Hv%2Fa%2F3rX3tvlm95oS%2FLokuZtIpbdvAs7KFtL22wjb3V1C41upy2ke1DXC2k%2FBjv1HHXDrbkEamg7lX2P8QTldQ2UtfOB8uiJsHNiB%2Fik0GmO%2BgZIxgnGA59nGCMoJPeQaYP047iBDXZEohkAYof4%2FNyKlZRdR%2F1ASZCnoOMhWkUheMz9F1laJSRZ3gEqVw1ipZQjcoBRrbT3Ez9OJLhZkHG5CD8l8Q47qXhMZp%2FYxhVFaxBLBtQejdtA%2FTtZPMIJnOknI2WSYzicTYN8OtTvICZbECxdr5Pkm6iPL0C3c%2BgkfIJgi%2F4LnP%2FudRKD3K4jf1VJGLEAiuz6VnA4AGam1h7gpNIzSFe66D3NurLKVhJNkHo07N9V9BE3XHOYmyeuirqG1l9mdHgOkDSGd8%2FGWtg9Roa56lrYdchDtRQPLlCkEywKVRScDfrurnwC2diiPTRe47iVtbnLZDxckGCkKYpPM%2FRr3kbyRhsYOtRDiQonFoBSHrBOI18rOeOPvr76YrCeUbf5fTvjOddJ0gQ1uMPku9z6hwjiEZhgOMn%2BaaUeHQJIOkMD7KMA5QQP01HP18hPbfvDTvZPETqb2YiS1BWrozM6jk9SPJJHkZZ5qFagtoaNnbyZg1FE4sUPRdlAQpwkdSjvDZAJ%2FoxNt%2Bw6NlGbQVFl5iKLKKsXCAwyFQZ8S3ciu65ho1lBJ5%2FkZk3OBGjpJWGmVCmsjTkQvA8JHCUU7s5eImevzg%2Fd7BGFhzCARIf8uVN3J5Heh1VM%2BHlko2y%2FHBxF0NJolfo38eDuJJxbf0ro%2FnMurh8hM%2FupH4tdT8zciOFsTC8SAgQoJfRxKzCuvfw0k%2F8MDx7xqUyez%2BS48ESIN7Ky6OUpfAtrxzhx03UR4m0c%2FZF7tnKW2mma4l9yuthTSIZIvxPi6EcpZW0PM0xtOzjo%2Bf4GPfv4r1qNqAUFYs9diJLBC1CIa7FZx8fUlwI22LuNv%2FfLbKMAOftH9TwRXg6%2FiCDAAAAAElFTkSuQmCC");background-position:center center;border:1px solid #0a0}.yui-skin-sam .yui-h-slider{background:url(bg-h.gif) no-repeat 5px 0;height:28px;width:228px}yui-compressor-2.4.7/tests/dataurl-base64-linebreakindata.css0000644000175000017500000000476611640627104024143 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml, .yui3-skin-night .yui3-dial-center-button-vml, .yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min, .yui3-skin-night v\:oval.yui3-dial-marker-max-min, .yui3-skin-night .yui3-dial-marker-vml, .yui3-skin-night .yui3-dial-handle-vml { background: none; opacity:1; } div.base64-doublequotes { width:100px; height:100px; background-image:url( "data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFBQ0WDWwq wjwAAANMSURBVEjHrdZbaFxVFAbgb2aSTG6GTi6mVIwxNxF9qFI0RQnFUqiYamutVutLa2t9EY0oPggFoYgPRR%2FaghYviA%2BiIAYvmBJKoYWi iBCigVTT1FisbUhrEtNkJpc5PuQkjGEmJqkLFmdz2Hv%2Fa%2F3rX3tvlm95oS%2FLokuZtIpbdvAs7KFtL22wjb3V1C41upy2ke1DXC2k%2FBjv 1HHXDrbkEamg7lX2P8QTldQ2UtfOB8uiJsHNiB%2Fik0GmO%2BgZIxgnGA59nGCMoJPeQaYP047iBDXZEohkAYof4%2FNyKlZRdR%2F1ASZCnoOM hWkUheMz9F1laJSRZ3gEqVw1ipZQjcoBRrbT3Ez9OJLhZkHG5CD8l8Q47qXhMZp%2FYxhVFaxBLBtQejdtA%2FTtZPMIJnOknI2WSYzicTYN8OtT vICZbECxdr5Pkm6iPL0C3c%2BgkfIJgi%2F4LnP%2FudRKD3K4jf1VJGLEAiuz6VnA4AGam1h7gpNIzSFe66D3NurLKVhJNkHo07N9V9BE3XHOYm yeuirqG1l9mdHgOkDSGd8%2FGWtg9Roa56lrYdchDtRQPLlCkEywKVRScDfrurnwC2diiPTRe47iVtbnLZDxckGCkKYpPM%2FRr3kbyRhsYOtRDi QonFoBSHrBOI18rOeOPvr76YrCeUbf5fTvjOddJ0gQ1uMPku9z6hwjiEZhgOMn%2BaaUeHQJIOkMD7KMA5QQP01HP18hPbfvDTvZPETqb2YiS1BW rozM6jk9SPJJHkZZ5qFagtoaNnbyZg1FE4sUPRdlAQpwkdSjvDZAJ%2FoxNt%2Bw6NlGbQVFl5iKLKKsXCAwyFQZ8S3ciu65ho1lBJ5%2FkZk3OB GjpJWGmVCmsjTkQvA8JHCUU7s5eImevzg%2Fd7BGFhzCARIf8uVN3J5Heh1VM%2BHlko2y%2FHBxF0NJolfo38eDuJJxbf0ro%2FnMurh8hM%2Fu pH4tdT8zciOFsTC8SAgQoJfRxKzCuvfw0k%2F8MDx7xqUyez%2BS48ESIN7Ky6OUpfAtrxzhx03UR4m0c%2FZF7tnKW2mma4l9yuthTSIZIvxPi6 EcpZW0PM0xtOzjo%2Bf4GPfv4r1qNqAUFYs9diJLBC1CIa7FZx8fUlwI22LuNv%2FfLbKMAOftH9TwRXg6%2FiCDAAAAAElFTkSuQmCC" ); background-position:center center; border:1px solid #00aa00; } .yui-skin-sam .yui-h-slider { background: url(bg-h.gif) no-repeat 5px 0; height: 28px; width: 228px; } yui-compressor-2.4.7/tests/dataurl-base64-eof.css.min0000644000175000017500000000737011640627104022353 0ustar drazzibdrazzibdiv.base64-singlequotes{width:100px;height:100px;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QAAAAAAAD5Q7t%2FAAAACXBIWXMAAA3WAAAN1gGQb3mcAAAFrUlEQVRYw%2B2Xz28kRxXHP%2B9Vdc8vj2fG9uIkm2yUeFGEhNCKQwBpj1yRUBAnpJU4ceZP4MxfkBxy2GO45bQXuEGQohUKigQ%2BsBBE1sbYXv8Yz%2FRMd9fjUN09PV5nFZA4kZZa79W3quu9er%2FqNfy%2FPwJgZty%2Ffz%2FZ29vrpmmqhlWTgmFg1UpbfWhYhG6Yq2cFi%2FNrj9nJyWnx%2BPHjeafbMTEzPvjVB9%2B6d%2B%2FezweDwV1BfHubivkC3lZya%2F4m7Np8UZYXhweHH7733rvvC0Kyv7%2F%2F7p07d34qIjyvr63RNb4l4CbsRUrNrq6OfvfRRz%2FxDx486A%2F6g7vXhX9ZIf%2Bp4JomaToZj8d7Pk1SFRFXb1aWodq09l%2F9YZu%2FCWMVL9e%2FaVFVQVUREEG8r3VUEZ4cX%2FHL30%2B5shRtAhFq4wggNb6GrXgVa2K2jYtACIHv7Sz54TfHjWWagBOBy0Xgt%2BcjLtwQxVCpNwURQat1DdYaT7pwdwKDFA6ncHgFizJmSb3WLPDa7PMIVlb2daqZxdONUnAetEojEdBGiXXhTmAjhZ0%2B3N6AlzeEROH1TXiWGf%2BcwmkWZYnAfAkdx1pq%2BhUbT9z3IElUJlVhI4WsgCLUyggi4MQYd4VXNmCYRqXOspV7UoHbQ3hpEMeLAk5mkFYRYlWI%2BHZ6CTDwkKSQqrA7gFeHMF3C6VyYLmFZGiKCE6GrMFsaWb7yuVOh66N1FkUUpBJ3TyvFovToBl9XMbNY2bZ70BsKfW94hbyErosmXpQwy4VgkCjMizjvRRik0EtiLNwagBf465lwOqtkETEn60XT1%2BlTazrpKlR%2BKkooy3Xfb3Wj3wGWJRQhnni7B53q5FqZ4%2FUR7PYhGMxyuMwgWVqTxrYWAwZYQX78J5i8ie9txSAkoOqqQAqk3pBgKLDhlY5XVKPCi3w97YRoKSFaceCgF2hqSXRBPQAIOcXRH8hP%2F0y6%2BRpWLrEyg3SbS9tmzggzJQSLQZo4xoOE8UbCsJfQ7zi6iaIizZ5OBVfXDKPireWC%2BvAYWOBqeszl9Jg03afbH6OqGH%2FBSUrqbrFIXiHoiEDC%2FPySi2d9nnZHJE7opY7dcY%2FdcZej84zpPGfY9Uw2ErYGCf2O4mUVEzELWtqUxZKjf3zK2cURzicMRy%2BzvbuH8ylFPqXIPqNczClKY1mUZFcnSDKkv%2FUNuptbWG%2BLw%2FMh%2FzrYpKBHKV3ONOXzYxeV20z49qhs7gaMWIjqQQiBxVXB4irg05yz4u%2FMpieoJuTLjDJfUJYBzBAFUUHkhMvLvzFPuvQ2JvQ3duh0R%2FjuiDQdIn6MJdvkxTafZUPuaN6UaOo6UNtgNl9weboguwqoA5fCjEusNCzE8LJQFRuNrzpQD%2BrmZNM55%2F4A5z1J2iHtDEg6fZK0j0uHlDrh2N4i3Ptuc%2BH5tjp5HliWQmmOUAhlYe0rqUqWSEOhcZ05AvE1UdColSQJaHWlSUYgJy%2FO2fFfo%2F34piphFOZ4OrvNdL5EJZbcmE8OQzFxIJEGEgIeE1%2FhrjJLxZcOrIVpVC7TW00WmLWyAMDEs%2Bi9wVJDtG17Y21vVmNxLKqIOkQqqoq2qHORmgj9UQcza7mgFm4GmiDjO5C72DSoQ6uPVTW%2BzuFUcQ2teKd4pzhd8b6Nu6jg7vZsrb1rClEIxhu7Q37x47fIy3j%2Fi8iqqlUuEWTFN%2FOrMU3fEEuhUM8FIPDqZgcRIVhsAXxtjGDGS5M%2BP%2Fv%2Bm7yopVrRVsPabsW%2BYG1T%2Fy3KahqSg6cHRb5cTmt5ZXhxQ7nS6yZsVWOajDFbw2JSCSGEIsuyC%2F%2Fo0aPp%2Fv7%2Br9NO5%2F5gMOhJLNn%2FpQLrLfw6tkKKorCDg4NPP%2Fnkjx%2FLOz96h2enzyZvf%2BftH9za2fm6qLrnO9tGk2vY86f%2FMliWZRdPnjz5zcOHDz%2B%2B%2Fifimorzv31C9X718G%2FYrCYSNJa5LgAAACJ6VFh0U29mdHdhcmUAAHjaKy8v18vMyy5OTixI1csvSgcANtgGWBBTylwAAAAASUVORK5CYII%3D');background-position:center center;border:1px solid #0a0}div.otherdataurl{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFBQ0WDWwqwjwAAANMSURBVEjHrdZbaFxVFAbgb2aSTG6GTi6mVIwxNxF9qFI0RQnFUqiYamutVutLa2t9EY0oPggFoYgPRR%2FaghYviA%2BiIAYvmBJKoYWiiBCigVTT1FisbUhrEtNkJpc5PuQkjGEmJqkLFmdz2Hv%2Fa%2F3rX3tvlm95oS%2FLokuZtIpbdvAs7KFtL22wjb3V1C41upy2ke1DXC2k%2FBjv1HHXDrbkEamg7lX2P8QTldQ2UtfOB8uiJsHNiB%2Fik0GmO%2BgZIxgnGA59nGCMoJPeQaYP047iBDXZEohkAYof4%2FNyKlZRdR%2F1ASZCnoOMhWkUheMz9F1laJSRZ3gEqVw1ipZQjcoBRrbT3Ez9OJLhZkHG5CD8l8Q47qXhMZp%2FYxhVFaxBLBtQejdtA%2FTtZPMIJnOknI2WSYzicTYN8OtTvICZbECxdr5Pkm6iPL0C3c%2BgkfIJgi%2F4LnP%2FudRKD3K4jf1VJGLEAiuz6VnA4AGam1h7gpNIzSFe66D3NurLKVhJNkHo07N9V9BE3XHOYmyeuirqG1l9mdHgOkDSGd8%2FGWtg9Roa56lrYdchDtRQPLlCkEywKVRScDfrurnwC2diiPTRe47iVtbnLZDxckGCkKYpPM%2FRr3kbyRhsYOtRDiQonFoBSHrBOI18rOeOPvr76YrCeUbf5fTvjOddJ0gQ1uMPku9z6hwjiEZhgOMn%2BaaUeHQJIOkMD7KMA5QQP01HP18hPbfvDTvZPETqb2YiS1BWrozM6jk9SPJJHkZZ5qFagtoaNnbyZg1FE4sUPRdlAQpwkdSjvDZAJ%2FoxNt%2Bw6NlGbQVFl5iKLKKsXCAwyFQZ8S3ciu65ho1lBJ5%2FkZk3OBGjpJWGmVCmsjTkQvA8JHCUU7s5eImevzg%2Fd7BGFhzCARIf8uVN3J5Heh1VM%2BHlko2y%2FHBxF0NJolfo38eDuJJxbf0ro%2FnMurh8hM%2FupH4tdT8zciOFsTC8SAgQoJfRxKzCuvfw0k%2F8MDx7xqUyez%2BS48ESIN7Ky6OUpfAtrxzhx03UR4m0c%2FZF7tnKW2mma4l9yuthTSIZIvxPi6EcpZW0PM0xtOzjo%2Bf4GPfv4r1qNqAUFYs9diJLBC1CIa7FZx8fUlwI22LuNv%2FfLbKMAOftH9TwRXg6%2FiCDAAAAAElFTkSuQmCC")}yui-compressor-2.4.7/tests/dataurl-base64-eof.css0000644000175000017500000000744011640627104021567 0ustar drazzibdrazzibdiv.base64-singlequotes { width:100px; height:100px; background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QAAAAAAAD5Q7t%2FAAAACXBIWXMAAA3WAAAN1gGQb3mcAAAFrUlEQVRYw%2B2Xz28kRxXHP%2B9Vdc8vj2fG9uIkm2yUeFGEhNCKQwBpj1yRUBAnpJU4ceZP4MxfkBxy2GO45bQXuEGQohUKigQ%2BsBBE1sbYXv8Yz%2FRMd9fjUN09PV5nFZA4kZZa79W3quu9er%2FqNfy%2FPwJgZty%2Ffz%2FZ29vrpmmqhlWTgmFg1UpbfWhYhG6Yq2cFi%2FNrj9nJyWnx%2BPHjeafbMTEzPvjVB9%2B6d%2B%2FezweDwV1BfHubivkC3lZya%2F4m7Np8UZYXhweHH7733rvvC0Kyv7%2F%2F7p07d34qIjyvr63RNb4l4CbsRUrNrq6OfvfRRz%2FxDx486A%2F6g7vXhX9ZIf%2Bp4JomaToZj8d7Pk1SFRFXb1aWodq09l%2F9YZu%2FCWMVL9e%2FaVFVQVUREEG8r3VUEZ4cX%2FHL30%2B5shRtAhFq4wggNb6GrXgVa2K2jYtACIHv7Sz54TfHjWWagBOBy0Xgt%2BcjLtwQxVCpNwURQat1DdYaT7pwdwKDFA6ncHgFizJmSb3WLPDa7PMIVlb2daqZxdONUnAetEojEdBGiXXhTmAjhZ0%2B3N6AlzeEROH1TXiWGf%2BcwmkWZYnAfAkdx1pq%2BhUbT9z3IElUJlVhI4WsgCLUyggi4MQYd4VXNmCYRqXOspV7UoHbQ3hpEMeLAk5mkFYRYlWI%2BHZ6CTDwkKSQqrA7gFeHMF3C6VyYLmFZGiKCE6GrMFsaWb7yuVOh66N1FkUUpBJ3TyvFovToBl9XMbNY2bZ70BsKfW94hbyErosmXpQwy4VgkCjMizjvRRik0EtiLNwagBf465lwOqtkETEn60XT1%2BlTazrpKlR%2BKkooy3Xfb3Wj3wGWJRQhnni7B53q5FqZ4%2FUR7PYhGMxyuMwgWVqTxrYWAwZYQX78J5i8ie9txSAkoOqqQAqk3pBgKLDhlY5XVKPCi3w97YRoKSFaceCgF2hqSXRBPQAIOcXRH8hP%2F0y6%2BRpWLrEyg3SbS9tmzggzJQSLQZo4xoOE8UbCsJfQ7zi6iaIizZ5OBVfXDKPireWC%2BvAYWOBqeszl9Jg03afbH6OqGH%2FBSUrqbrFIXiHoiEDC%2FPySi2d9nnZHJE7opY7dcY%2FdcZej84zpPGfY9Uw2ErYGCf2O4mUVEzELWtqUxZKjf3zK2cURzicMRy%2BzvbuH8ylFPqXIPqNczClKY1mUZFcnSDKkv%2FUNuptbWG%2BLw%2FMh%2FzrYpKBHKV3ONOXzYxeV20z49qhs7gaMWIjqQQiBxVXB4irg05yz4u%2FMpieoJuTLjDJfUJYBzBAFUUHkhMvLvzFPuvQ2JvQ3duh0R%2FjuiDQdIn6MJdvkxTafZUPuaN6UaOo6UNtgNl9weboguwqoA5fCjEusNCzE8LJQFRuNrzpQD%2BrmZNM55%2F4A5z1J2iHtDEg6fZK0j0uHlDrh2N4i3Ptuc%2BH5tjp5HliWQmmOUAhlYe0rqUqWSEOhcZ05AvE1UdColSQJaHWlSUYgJy%2FO2fFfo%2F34piphFOZ4OrvNdL5EJZbcmE8OQzFxIJEGEgIeE1%2FhrjJLxZcOrIVpVC7TW00WmLWyAMDEs%2Bi9wVJDtG17Y21vVmNxLKqIOkQqqoq2qHORmgj9UQcza7mgFm4GmiDjO5C72DSoQ6uPVTW%2BzuFUcQ2teKd4pzhd8b6Nu6jg7vZsrb1rClEIxhu7Q37x47fIy3j%2Fi8iqqlUuEWTFN%2FOrMU3fEEuhUM8FIPDqZgcRIVhsAXxtjGDGS5M%2BP%2Fv%2Bm7yopVrRVsPabsW%2BYG1T%2Fy3KahqSg6cHRb5cTmt5ZXhxQ7nS6yZsVWOajDFbw2JSCSGEIsuyC%2F%2Fo0aPp%2Fv7%2Br9NO5%2F5gMOhJLNn%2FpQLrLfw6tkKKorCDg4NPP%2Fnkjx%2FLOz96h2enzyZvf%2BftH9za2fm6qLrnO9tGk2vY86f%2FMliWZRdPnjz5zcOHDz%2B%2B%2Fifimorzv31C9X718G%2FYrCYSNJa5LgAAACJ6VFh0U29mdHdhcmUAAHjaKy8v18vMyy5OTixI1csvSgcANtgGWBBTylwAAAAASUVORK5CYII%3D'); background-position:center center; border:1px solid #00aa00; } div.otherdataurl { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFBQ0WDWwqwjwAAANMSURBVEjHrdZbaFxVFAbgb2aSTG6GTi6mVIwxNxF9qFI0RQnFUqiYamutVutLa2t9EY0oPggFoYgPRR%2FaghYviA%2BiIAYvmBJKoYWiiBCigVTT1FisbUhrEtNkJpc5PuQkjGEmJqkLFmdz2Hv%2Fa%2F3rX3tvlm95oS%2FLokuZtIpbdvAs7KFtL22wjb3V1C41upy2ke1DXC2k%2FBjv1HHXDrbkEamg7lX2P8QTldQ2UtfOB8uiJsHNiB%2Fik0GmO%2BgZIxgnGA59nGCMoJPeQaYP047iBDXZEohkAYof4%2FNyKlZRdR%2F1ASZCnoOMhWkUheMz9F1laJSRZ3gEqVw1ipZQjcoBRrbT3Ez9OJLhZkHG5CD8l8Q47qXhMZp%2FYxhVFaxBLBtQejdtA%2FTtZPMIJnOknI2WSYzicTYN8OtTvICZbECxdr5Pkm6iPL0C3c%2BgkfIJgi%2F4LnP%2FudRKD3K4jf1VJGLEAiuz6VnA4AGam1h7gpNIzSFe66D3NurLKVhJNkHo07N9V9BE3XHOYmyeuirqG1l9mdHgOkDSGd8%2FGWtg9Roa56lrYdchDtRQPLlCkEywKVRScDfrurnwC2diiPTRe47iVtbnLZDxckGCkKYpPM%2FRr3kbyRhsYOtRDiQonFoBSHrBOI18rOeOPvr76YrCeUbf5fTvjOddJ0gQ1uMPku9z6hwjiEZhgOMn%2BaaUeHQJIOkMD7KMA5QQP01HP18hPbfvDTvZPETqb2YiS1BWrozM6jk9SPJJHkZZ5qFagtoaNnbyZg1FE4sUPRdlAQpwkdSjvDZAJ%2FoxNt%2Bw6NlGbQVFl5iKLKKsXCAwyFQZ8S3ciu65ho1lBJ5%2FkZk3OBGjpJWGmVCmsjTkQvA8JHCUU7s5eImevzg%2Fd7BGFhzCARIf8uVN3J5Heh1VM%2BHlko2y%2FHBxF0NJolfo38eDuJJxbf0ro%2FnMurh8hM%2FupH4tdT8zciOFsTC8SAgQoJfRxKzCuvfw0k%2F8MDx7xqUyez%2BS48ESIN7Ky6OUpfAtrxzhx03UR4m0c%2FZF7tnKW2mma4l9yuthTSIZIvxPi6EcpZW0PM0xtOzjo%2Bf4GPfv4r1qNqAUFYs9diJLBC1CIa7FZx8fUlwI22LuNv%2FfLbKMAOftH9TwRXg6%2FiCDAAAAAElFTkSuQmCC"); }yui-compressor-2.4.7/tests/dataurl-base64-doublequotes.css.min0000644000175000017500000024524211640627104024317 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml,.yui3-skin-night .yui3-dial-center-button-vml,.yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min,.yui3-skin-night v\:oval.yui3-dial-marker-max-min,.yui3-skin-night .yui3-dial-marker-vml,.yui3-skin-night .yui3-dial-handle-vml{background:0;opacity:1}div.base64-doublequotes{width:100px;height:100px;background-image:url("data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAgEAZABkAAD%2F4RfJRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAeAAAAcgEyAAIAAAAUAAAAkIdpAAQAAAABAAAApAAAANAAD0JAAAAnEAAPQkAAACcQQWRvYmUgUGhvdG9zaG9wIENTMiBNYWNpbnRvc2gAMjAwODowNzoxOSAxNDo1ODowNQAAA6ABAAMAAAAB%2F%2F8AAKACAAQAAAABAAABwqADAAQAAAABAAABRQAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAEeARsABQAAAAEAAAEmASgAAwAAAAEAAgAAAgEABAAAAAEAAAEuAgIABAAAAAEAABaTAAAAAAAAAEgAAAABAAAASAAAAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZ%2F%2B01IlBob3Rvc2hvcCAzLjAAOEJJTQQlAAAAAAAQAAAAAAAAAAAAAAAAAAAAADhCSU0D6gAAAAAYEDw%2FeG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8%2BCjwhRE9DVFlQRSBwbGlzdCBQVUJMSUMgIi0vL0FwcGxlLy9EVEQgUExJU1QgMS4wLy9FTiIgImh0dHA6Ly93d3cuYXBwbGUuY29tL0RURHMvUHJvcGVydHlMaXN0LTEuMC5kdGQiPgo8cGxpc3QgdmVyc2lvbj0iMS4wIj4KPGRpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNSG9yaXpvbnRhbFJlczwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1Ib3Jpem9udGFsUmVzPC9rZXk%2BCgkJCQk8cmVhbD43MjwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgkJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNU2NhbGluZzwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1TY2FsaW5nPC9rZXk%2BCgkJCQk8cmVhbD4xPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCTxkaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q%2BCgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCQkJCTxyZWFsPjcyPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsU2NhbGluZzwva2V5PgoJCQkJPHJlYWw%2BMTwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuc3ViVGlja2V0LnBhcGVyX2luZm9fdGlja2V0PC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BUE1UaW9nYVBhcGVyTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNVGlvZ2FQYXBlck5hbWU8L2tleT4KCQkJCQk8c3RyaW5nPm5hLWxldHRlcjwvc3RyaW5nPgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk%2BCgkJCQkJCTxyZWFsPi0xODwvcmVhbD4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD43NzQ8L3JlYWw%2BCgkJCQkJCTxyZWFsPjU5NDwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNUGFwZXJOYW1lPC9rZXk%2BCgkJCQkJPHN0cmluZz5uYS1sZXR0ZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk%2BCgkJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhZ2VSZWN0PC9rZXk%2BCgkJPGRpY3Q%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD4tMTg8L3JlYWw%2BCgkJCQkJCTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTk0PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLnBwZC5QTVBhcGVyTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BVVMgTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5BUElWZXJzaW9uPC9rZXk%2BCgkJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC50eXBlPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvVGlja2V0PC9zdHJpbmc%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuQVBJVmVyc2lvbjwva2V5PgoJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnR5cGU8L2tleT4KCTxzdHJpbmc%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXRUaWNrZXQ8L3N0cmluZz4KPC9kaWN0Pgo8L3BsaXN0Pgo4QklNA%2BkAAAAAAHgAAwAAAEgASAAAAAAC3gJA%2F%2B7%2F7gMGAlIDZwUoA%2FwAAgAAAEgASAAAAAAC2AIoAAEAAABkAAAAAQADAwMAAAABf%2F8AAQABAAAAAAAAAAAAAAAAaAgAGQGQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4QklNA%2B0AAAAAABAAZAAAAAEAAQBkAAAAAQABOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD%2BAAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNBAoAAAAAAAEAADhCSU0nEAAAAAAACgABAAAAAAAAAAE4QklNA%2FUAAAAAAEgAL2ZmAAEAbGZmAAYAAAAAAAEAL2ZmAAEAoZmaAAYAAAAAAAEAMgAAAAEAWgAAAAYAAAAAAAEANQAAAAEALQAAAAYAAAAAAAE4QklNA%2FgAAAAAAHAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAAAD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FA%2BgAAAAA%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwPoAAAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAOEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJAAAAAADhCSU0EHgAAAAAABAAAAAA4QklNBBoAAAAAA1UAAAAGAAAAAAAAAAAAAAFFAAABwgAAABAAcwB3AGkAcwBzAF8AYQByAG0AeQBfAGsAbgBpAGYAZQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABwgAAAUUAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAG51bGwAAAACAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9uZwAAAUUAAAAAUmdodGxvbmcAAAHCAAAABnNsaWNlc1ZsTHMAAAABT2JqYwAAAAEAAAAAAAVzbGljZQAAABIAAAAHc2xpY2VJRGxvbmcAAAAAAAAAB2dyb3VwSURsb25nAAAAAAAAAAZvcmlnaW5lbnVtAAAADEVTbGljZU9yaWdpbgAAAA1hdXRvR2VuZXJhdGVkAAAAAFR5cGVlbnVtAAAACkVTbGljZVR5cGUAAAAASW1nIAAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAFFAAAAAFJnaHRsb25nAAABwgAAAAN1cmxURVhUAAAAAQAAAAAAAG51bGxURVhUAAAAAQAAAAAAAE1zZ2VURVhUAAAAAQAAAAAABmFsdFRhZ1RFWFQAAAABAAAAAAAOY2VsbFRleHRJc0hUTUxib29sAQAAAAhjZWxsVGV4dFRFWFQAAAABAAAAAAAJaG9yekFsaWduZW51bQAAAA9FU2xpY2VIb3J6QWxpZ24AAAAHZGVmYXVsdAAAAAl2ZXJ0QWxpZ25lbnVtAAAAD0VTbGljZVZlcnRBbGlnbgAAAAdkZWZhdWx0AAAAC2JnQ29sb3JUeXBlZW51bQAAABFFU2xpY2VCR0NvbG9yVHlwZQAAAABOb25lAAAACXRvcE91dHNldGxvbmcAAAAAAAAACmxlZnRPdXRzZXRsb25nAAAAAAAAAAxib3R0b21PdXRzZXRsb25nAAAAAAAAAAtyaWdodE91dHNldGxvbmcAAAAAADhCSU0EKAAAAAAADAAAAAE%2F8AAAAAAAADhCSU0EEQAAAAAAAQEAOEJJTQQUAAAAAAAEAAAAAThCSU0EDAAAAAAWrwAAAAEAAACgAAAAdAAAAeAAANmAAAAWkwAYAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZADhCSU0EIQAAAAAAVQAAAAEBAAAADwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAAAABMAQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAIABDAFMAMgAAAAEAOEJJTQQGAAAAAAAHAAIAAAABAQD%2F4TkjaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu%2B7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI%2FPgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSIzLjEuMS0xMTIiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyI%2BCiAgICAgICAgIDx4YXBNTTpEb2N1bWVudElEPnV1aWQ6RTcxOTVFNTY1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkRvY3VtZW50SUQ%2BCiAgICAgICAgIDx4YXBNTTpJbnN0YW5jZUlEPnV1aWQ6RTcxOTVFNTc1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkluc3RhbmNlSUQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eGFwOkNyZWF0ZURhdGU%2BMjAwOC0wNy0xOVQxNDo1Nzo0MS0wNTowMDwveGFwOkNyZWF0ZURhdGU%2BCiAgICAgICAgIDx4YXA6TW9kaWZ5RGF0ZT4yMDA4LTA3LTE5VDE0OjU4OjA1LTA1OjAwPC94YXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhhcDpNZXRhZGF0YURhdGU%2BMjAwOC0wNy0xOVQxNDo1ODowNS0wNTowMDwveGFwOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhhcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1MyIE1hY2ludG9zaDwveGFwOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9qcGVnPC9kYzpmb3JtYXQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOkhpc3RvcnkvPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpOYXRpdmVEaWdlc3Q%2BMjU2LDI1NywyNTgsMjU5LDI2MiwyNzQsMjc3LDI4NCw1MzAsNTMxLDI4MiwyODMsMjk2LDMwMSwzMTgsMzE5LDUyOSw1MzIsMzA2LDI3MCwyNzEsMjcyLDMwNSwzMTUsMzM0MzI7QzA1QTE5MDRGRjAwQUJEQzA1MUJERkFGMDIwNEVBNTE8L3RpZmY6TmF0aXZlRGlnZXN0PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24%2BNDUwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjMyNTwvZXhpZjpQaXhlbFlEaW1lbnNpb24%2BCiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U%2BLTE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6TmF0aXZlRGlnZXN0PjM2ODY0LDQwOTYwLDQwOTYxLDM3MTIxLDM3MTIyLDQwOTYyLDQwOTYzLDM3NTEwLDQwOTY0LDM2ODY3LDM2ODY4LDMzNDM0LDMzNDM3LDM0ODUwLDM0ODUyLDM0ODU1LDM0ODU2LDM3Mzc3LDM3Mzc4LDM3Mzc5LDM3MzgwLDM3MzgxLDM3MzgyLDM3MzgzLDM3Mzg0LDM3Mzg1LDM3Mzg2LDM3Mzk2LDQxNDgzLDQxNDg0LDQxNDg2LDQxNDg3LDQxNDg4LDQxNDkyLDQxNDkzLDQxNDk1LDQxNzI4LDQxNzI5LDQxNzMwLDQxOTg1LDQxOTg2LDQxOTg3LDQxOTg4LDQxOTg5LDQxOTkwLDQxOTkxLDQxOTkyLDQxOTkzLDQxOTk0LDQxOTk1LDQxOTk2LDQyMDE2LDAsMiw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwyMCwyMiwyMywyNCwyNSwyNiwyNywyOCwzMDtENDYzN0NCOUQ0MUExMEJBN0VGNUVCQ0RCNjMxODMyOTwvZXhpZjpOYXRpdmVEaWdlc3Q%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY%2BCjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8%2B%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEJCAgJCgkLCQkLDgsNCw4RDg4ODhERDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgBRQHCAwEiAAIRAQMRAf%2FdAAQAHf%2FEAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPBUtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4%2FPE1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BCk5SVlpeYmZqbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp0%2BPzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BDlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq%2Bv%2FaAAwDAQACEQMRAD8A7%2FmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmrlHI2utXn6WltnFESb0RFSp41WjD5q3LCBaslzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2E2rj0LuzvF7PxftUf8AXPLDnC3XI0ewdpOkTK4P08T%2FAMK2Ec1TLNgaxmE9pFIDy%2BEAn3GxwTgV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F%2F0e%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXYUeZpfR0a4kpUAx19h6i74b4X65CbjR76FV5FoJKKe5C1GIVLdDuGhuXs2IKOX4gfsvGdx%2FskKtkiyD6bctHHbXgPImOC4qOpXj6E1ff4Mm4Ndxkpc770BvNmzZFLs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Lv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVokKCT0G%2F3ZgaioNQemANZuhaWLyE0LlY1%2BbGn6sWspA8QA%2FZ%2FUcVRWbNmxV2bNmxV2bNmxV2NZQwKnodj9OOzYqwDT4iiPZsa%2FVLm5sj7I%2F76L%2BOTXTpjPZQSt9pkAb5r8JyKXqfUvMOpIQOFxFDfoP8qFvTl%2F4Q5INDkrFPAf8AdUhI%2FwBV%2FiH8cnLeAPcxHMprmzZsgydmzZsVdmzZsVdmzZsVdmzYyWRIo2kkYKiirMdgAMVX5sjTeaGl1CzsbSAOLuX0w7k14KCzyAD%2BUZJBirebNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F9Pv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVo4CXUFa9e0CbJRWkr%2B0RWlMHZEJ5WtPMtzE5%2BGYJKnyK0%2F4kuEC1ZeM2IW0okjFT8S7H%2BuL4FYz52mMWn2tDTlcpX6FbDHR5ecCH%2BZevywl%2FMM8dJtn7LdJ%2BKvgry9ccrOJ69KVw9E9GS5s2bAh2bNmxV2bNmxV2bNmxVi3miFU1LSbxvsStJYzH%2FJnSi%2F8ADYpoEzLcxq1T68FGr%2FvyE8GrgjzdC0mhXEsY%2Fe2pS5i%2F1omDf8RwttJRHdrcDaNbhZVI6endIG%2F4mcnHeJCDzDL82bNkEuzZs2KuzZs2KuzZs2KurkZ843Zhs4bVTQzvVqfyrvg3zHNPb2UMsLtGBPGJSpIqjEqRUb9ch%2BvSSvp0JlcvJCLyMuxJb4JNvi%2F1SuEBVvkaX9L%2BZbm8Sv1fTbf0Y6%2F78lPxH%2FgFzpeRvyPbWcXlyyubWBIXuoxJOUG7uKjk5%2FaOSSoxPNXZs2bArs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FU7%2FmzZsVQ2osyWM7o3FlQkMOxGPtZhPBHKCDyUE08e%2BM1Bedjcr4xPT%2FgThV5cvBJbpGergEfMDcYa2PkqfZs2bArs2bNirs2bNirs2bNirshfnRGtb7T9TX7LcoJD2qDzSv3vk0wl81WDajodzDGKzRj1oR35R%2FFT6RthHNXaVcrKsUtftDi304dZz7yrqPrQCIncdMnsEnqRK%2Fcjf54yVjP5gwtJ5ckcD%2B5mik%2BivH%2FAI3wD5RnEtpwrWgw983RGby1qiqKlYGkA%2F4x%2FvP%2BNchnke5BIUGoPQ%2FPEJHJ6XG3JFbxAOPxOA1iX7sUwIdmzZsVdmzZsVdmzZsVUbqBbq2mtm%2BzMjRn5MKZDLP4rC2UVq9qYj7SWshWn%2BtxOTnIVG4ttWvdNaiiK7FxGDtWG6Ti%2FwDwMuShzRLky%2B1lE9vFMP8AdiK33gYscKtBmDWhtq%2FHbOyMp68SeSH5UOGpyJ5pYde3moWPmW5KzH0pIo2WNt0A3Wv0ts2D73zJ6FgzxqqXpKpHG9eDMx7EYXed45VeC4gPCdYyqua0I5q5VgOv2cAW8sWo2QMqhwwoyHcVyQFhVOLzvrNrdf6fFHLFX4kVeBH%2Br1%2F4bJlp%2Bt2GqWrXFnICyKWeJtnUgV3XOP67qFjaFLHUrprecy%2BlZajxPDmN1jn8Dv8Aa%2By%2BIaXrclrdtZ34NrfR1USofgeo2K06c%2F8AgcBCXr%2FlvXRrdnzk4rcoSJFXYfMbnDzOV%2BTr82eqAOQIpaBq7AV2r%2BOdTriRSEp8z8RoN9I5AWJPV5HYD0yHr%2BGQg3Ntq1lcLazx3CiZviiYOKzQo9Kjb7YzoWqRevpt5AOskEij5lCOmc60%2BWCK0j9ONYo5IYp%2BEahQWBeNjRafEcMVTvTb%2B80fyHZ3FugE9vSORJBUqPVZW%2BEHw3yVaXeC%2FsobulGkX41HQMNmH%2FBZzC%2B1iTTbadZUkjtJjzkQqSKqNm5fsdMPfyr1%2FRdT8vra2E5N5C8kl3bSMTKpkctz%2BL7SP9peOA7fFkIkgkCwOfkz7NlA1y8DF2bNmxV2bEJLy1injtpJVWeavpREjk3Hc8V64virs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Xv%2BbNmxVplDqUbcMKH5HIPokjWsstqx%2BK2lZPf4Wpk5yF6nF9R8xswHGO8QSj%2FAFh8D%2Fqrkoc6VmSMHUOOjAEfTjsAaZMXhMRPxRnYf5J6YPyJV2bNmxV2bNmxVQuzOtu729PVUclBFa07U98DafqsF6i9EkI6ePywwyF6vG2i6oJRUWl6xZCP2JOrr%2FsvtLhG6s0yiK4X6Zfi4QI7Vb9lv5h%2FXDHrgV5c8B0LzLc2Q%2BGF29WDw4SfF%2Fwp%2BHOg6ZMHi4j2YfTkZ%2FMGwpFaazGDytm9GYj%2FAH25%2BEn%2FAFX%2FAOJ4N8uXwliicnps305LmFZDewrc2dxbt0lieNvkylc45%2BX10UCQzHjLATE4P%2BQeNc6L55e5i0J57WVonikRmZDSq7jf2yB2Op%2FVYor2%2FwBNjktpAGjv7ZvU%2BInoy8Vao%2Fa44xCQ9as25RVBqKnfBGRby9rBEsljcIY0aQ%2Bg5FCCQD6bj9lslGAikN5s2bArs2bGyOI0aRuiAsfoFcVS%2B%2F1q2sJltyrSytuyp%2ByDsC3zwxBqAfHfI%2Fodmt2z6pcjnJK5dAexPT%2FgRkhxV2c782mSy82WUgNIdUhNs4PTmlXQ%2FwDBDOiZAvzLb6nHpOrlFkjs7lWdG9yvxVG%2FwiuGJ3Up3YTJFr7op%2BC8t1ljHjxodv8AYtkiyHbxx6XfKx%2FcXBilJ3%2BAsVUV8FRlyYA4Z80DkkPmq3EtlHJSpR%2BJPgHBH66ZBtIufqt9Np8pALHnEpO5p1oM6Xq0P1jTriPoePIfNdxnLtZtrGZluBcG3vF%2BFJYuJfx40IIxHJKzzb5et9ZtZYp1LwygcgPtKy%2FZkT%2FKWuRKKCOC6tNH1CblcWiILDUWHH6wg6wyDejx9Fw4sfOMjEBY5biH1HgLy8VYulOfJV%2By38q4ndH9LlL219K4iilHrWzLxlhI6SgE1%2F2SnFKo0Czxy28zMqcSzspIYBPj2I%2F1cd%2FytnVZdNQ2D1I%2BESMoPw%2FzMftdMG20TSQyyblmjenzoc4TY6ld6ddyKwMUsbFZoHqNwd1KnGXRXs9n5%2Fv7lg98GlWhMjwk1A%2Fm4k%2FF7jDSwSPULTTJI3PGBphGNwG4OHVW%2BgnONX%2BsWFpDFPaSSJcTESG3TcRlf2uRK%2Fazq%2BkR3aeT7e%2BjnX6yoW8ibht%2B9i9Tg%2B%2FQ98QVZHqstutowuSPSdSpV91IPVWzif1i98t%2BZ7m40FjbSWUrNCqEmkex4EH7acT9lv2c6lonmbTvMUTWdwgiumWktrLQhge6H9of6uRLzd5ZurDVP8Q2KetYFUW7jXeSKi%2Bm0hH7UZH7X7OCY4g2YM0sMrjvexB5SHcXsnkPz3Y%2BcdPqKQ6lAB9bta%2F8lI69Y2%2F4XJeDXPJlvPe6JqMeq6NMYLuE842To6ntToyuv2k%2Faz0J5E8%2B2HnGyI2t9VgA%2Bt2ZP0epH%2FNEf%2BEyESeUuff3tmbFAx8bB9H8Uf4sZ8%2F6P82TMMLNb1iDRrQ3EpBkkPC3j7s5%2FwCNV%2B0%2BGVc4n5m8yfpnzJcsr%2F6HYsLe232PBv3j0%2Fy3%2BH%2FY5JxkLourX175%2Ftb28maSZrloqsdlQ1Tgo%2FZUDO755%2B8uxlvPcMI6i6LAe2zZ6BwlS7NmzYFdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVf%2FW7%2FmzZsVdkb83W5%2BrW1%2Bg%2BK1kAc%2F5D%2FCf%2BG45JMC6jare2FxaEf3qMo%2BdPh%2F4bCNiqV6VOOcTV%2BGReB37%2FaX9WHoyFaJMz23BqiWE7juCh%2FsyaRsHRXHRgCPpwy52gLs2bNkUuzZs2Kuwu1rS49W06Wzb4XI5Qv8Ayuu6nDHMemKvONE1KWGVrG7rHPCxRgeqsppk7sb0XC8W2lUbjxHiMhnnnTHtLmPXrZfgakd1TsR9iQ%2FP7LYtomq%2FWI0Iakybof4H55LmFZdqNlFqNjcWMwqk6FD8z9k%2FQc515XuZbW4l0%2B5%2BGWFzE6n%2BZTTOlW063EQkXY9GXwPhnO%2FNsS6T5qtbofBHqaniexmi%2B2v%2BsU4v%2FlfFgHcrPTFbanZNb3caywyApLE3Qj3zjutwW%2FljzBc6Pp6fV9JHpsLNSSgR1HIorV3Vvizq2jXQk%2BAndlBA9xnNvzRiWPzJBJWnr2gJP%2FGNyv8AHAdikJ3YGf0o5pZDIboSD1GJJ9aAgh6%2F5aUzoFnN9YtYZ6gmRFY06VI3zlXk%2FVI5bi2hnlBgdBuxFFahhfr0rSNsnHlXU4JI5NJaSt1avIQm%2B8RaquD0I%2BLjkpbgIZJmzZsirsDagC1jcqvUxOB%2FwJwTjXUMrK32WBB%2BWKpfofE6Xb8f5d%2FnhjkMPmvR%2FKlrJBqkxBSVkjC0PIDpTfI15s%2FMNbu3jbR5plsZVp69swRi9N0eSjMnH%2BRcVpm669cWWtXGnatwjgKma2uPsj0x%2FNXw%2FayOfmLr%2BhX3l%2BPTYrkXM%2BpGtm1uPUUceX7yRx8KLtx%2F1s5xoN%2FefpVr6C8muVVfUuLO8kMrEIeTem7faRk5Iy5FdTuZ9B169trGZvqkc5eFD8SmJzzUcTtsrceWHzTT3fRJv0p5UZvtOYYrgCu%2FJV4P%2FwANHnPrj83vM2lX9zpWoBJYInaJ540pOi1%2BGRQDxf4cln5Z3qT2stjWrK0iexEgE60%2F2XLOUfmHYNZeZbhWP94Ayn%2FV%2BD%2FjVclLlbEdQn955q1wTiU3huLadeQCsfSljO9VNev%2FAA0bYHub1Z7V5yWkhHxpcVHJNwGiuP8AKStVk%2FbyGafqLQxyafO5S2lPJWUAmGQ%2F7uiB8f8Ad0X%2B7F%2Fy8Ctd6jpl3Lb3v%2BkQTpxniqTDcQn7LoR%2FwUb%2FALDZCyyekWl9ZyaFLPelZGN2tqDEtZJHenEs67ckpVXwq1bU7G1iKWvqtcCR4bkkhFYx%2FCHXhvvX48C%2BU7H1SbK3k9Wya5hv4HchSBF8FxBL2WeOJ1k%2F4s9P4cu%2F0j%2Fc1FphmFxPLeOhZBxAiL8jt40%2Fa5YegV6PprvLpcE8sfpTNbh3QVoGK12zluoQ2PnZih42fmWIVt5z8Md4q9I5P5J17Z2A8YrWVl%2BERoaDwoNvupnLtb02LzREdR0hBba7bVe4tEPFZwpr6sH%2FABb%2FAJOSkgPNLqGaG7e3v42iuoTwlicUIK9iM755KnGoeT7ZX6m1CH%2FYSNCf%2BFOctnuIfNkSWeqEWuu249OC8ccfW47elcd%2Bf%2BVnQ%2FyyS5t9Dk067jMVzaSXMLK3hRJlp4r9rjkQl5PbalcaRd%2BlI7PbwysI5lNJIirU%2BH%2FmnOueV%2FOUeo%2BnY6hIpuWX9xPtwnU%2Fhz%2FnTOPeY4zY%2BYNTgpVBcSVQ9CrHkP14Gsb9rFgRWSzY1K1%2BKNh%2B0p%2FZcY2Qdlev%2BZ%2FLKxK19pcdYBUzWqdYx1Lwj%2BT%2BaP8AZ%2FZyHW9xe6ZfQ6ppk7QXsBDRTIevsR%2B0p%2FlyY%2BUPNR1KJLK5lD3KrW3m6esg67f79T9pMD%2BZtCjTnqVilIW%2BKeFRshPWVAP2P9%2BJ%2BzkZRB3DPFlljlxRPz5Edx8mcw%2Fm3aXvkzULyUC3122jET2oNA8kh9NZYT%2FJvzb%2BTOZabIhnWkgaOQcwxO577%2F5fjhKIYndoZvgaUD05v5SN1J%2FyG6YI0RZ4tS%2BoyKQS1HTwYHsffALrdOQwM%2BLGOEHfhu6PWvJ6f5FsfrXnqW8K%2FDBEZD4cmAVf1Z2fOSeSLmfT9RrHEWlvDSZaVagNR0%2BztnW8mWsuzZs2BDs2bNirs2bNirs2bNirs2bNirs2bNir%2F9fv%2BbNmxV2Y5so4qw6WL9HeYLiLpFcUnjHQfH9r%2FhuWSbTnBgMXeJiv0H4l%2FA4T%2Ba4fTW01FRvDJ6chA%2FYfpX5MMGaXcBmHxbSrsCdi6%2F2f8RyZ3j7kdU4zZzrTfO2qQa3eaHrkax6haux%2Br9FkgJ%2FdT2790ZP%2BGydWWoWt%2BnK3erAfHGdmX5rkSEovNm2yiQASTQDqcCt5sL5dZ06Ko9YSMNqRAv8Aiu2Iv5i0qJecsrKo%2FwAkk%2FctTho9yo69htbi2e2vApgmHB1cgA1%2BffOYX%2BnXflXUghJezkNbabxH8jH%2BdcPPN82l65b2j213DN9WdmmtefCRkdeJaNSVb1I%2FtYXWM8cVk2javM95pUv9zcPvLB%2FI3LvwwhIT2x12KCBrxjyjRS06jrxG5YD%2BZcrzzpkXmjyhLPpzCSaFVv8ATZozuXjHP4GH%2B%2FE5JkUmju9BujaTsJYHHKC4G6Sxn9r%2FAJqwJH5g1fyjDaw2KrcaE0zSNE27RiQmtuXPSJ6%2FuW%2FYkxI6hUg8ia9qulatHe3s0k8DgxGKZywBk%2By3%2BTkn%2FN63a8ttG1a3rHL%2B9hIB%2BIdGK%2F8ABA5DNbS0tL%2B4ksJOenzETWrjYiOT4gjD9l4WqjL%2FAJOTTU9XtNc8r6dDP8E8rc4iSP71RwkTfcP%2FALsX%2Bflgq09zFvKeoTMwV2NeCsB0BaNqf8a5N9Zu59K83W2pWb%2Bn9cjBo24ZXUNxI%2F1lyCWsL6fNb3LLxid24tSgINA9Puyb67pd%2Fr2kaPc6bxN5b8owWYKAYW%2BGpP8Ak4RyQU8ufOF7JLD9XRLaAj96ZPiYv4A9An%2FDYOfz9oEbtA0kjXSqG%2Brqh5NtU%2BkW4iQL%2Fk5yK%2FiuNagjEcpTU7Rj6YqaSAbtG3%2FFin4om%2Fa%2BxhXcGeWxlDgpPbfvUFaPDKpFXiI%2FYk%2Fk%2FmwFXr0n5hfXBJFpVtxmC84jOa81%2FaKqv7Sfy5GL7zJq2rwXFhqF40AlWiSQfAEPVW%2BH7Sfz%2FwCRkTl1dLW3t7xi8108C3g9EBArCnI8jtVvtNRcR1zzTdJcQvYwRW7y28dwzFfUblIvI05fAo%2F2OGxSt3zSW9LPXITMlCjiuzofsyRt2YfsPkd0iabTtQksp1Zra4U84X6SJ%2Bw4%2FwAoD7Ei5dzqV7LFCt7KZnVAY%2BRqyg9aj%2BX%2BTJdouuaHrltb2PmCNfrkKmO2vKcT%2FkgsP2v5cjtapfo0Jt%2FMllFGHltZvVeK4ptwWNi6yU%2BzIvRlwm1mUarpNtJHEWutOkuIbh0FSbfkGiZ2%2Fb4MxH%2Bpk6uZNM8saddywStNK605tsKnYcF%2FmbOZy3s2nWaLE%2FG4e4%2BsK43HELxowOzK%2FL4lx5fFWb%2FlprP1TWLQMaLMFRh%2FlRtxr%2FwLYn%2BfNjLp%2Bp2WpwghWLxuf2SGoRX%2FAIDI9peo2kMtjfWQMUi3JM9u24j5rT4D%2B1G5qyfyfYzp%2FwCcdimr%2BUra%2FG%2FwpISOoIpXJDcIPN4HDcR3Scl2I6qeoOGNvcQyw%2Fo%2B%2FJWGpNvP1aBz%2B0PGFv8Adkf%2BzXIxSaym2NCOh7MMNYLhLlOS7H9pfA5FU30vUNQ8uaqjIqsaqHiO8UsZ6EeKsrfA%2BS3yUr6p5iudTl2S1RvRTchTKeCgV%2FlTlkOsvUveOn8VkdatauxoyN%2FID%2B0r%2FwAmTfyYHsrnTdPasc1%2FNczXMZArwhT04g3%2FAD05Yjml6Fditlcmu%2FpvX%2FgTnK5bS4sp1mDtFID6kLioPXZgc61NGTBNH4o1PpUjIpNbyX0Ulvcw%2FV9Tst7i2IqHWn99EP2kZf7xF%2F18nMX1pANMR1TTYfMkRuYYlt%2FMEY5EfYW7UftL%2FwAXjDf8u%2FMFzM8mnX6MJLWRFkMh4yiqtGUYU%2FZP82IzW%2FH4DVQG%2FduPtRP1FG%2Flb9lsG6ZJDJfPcvGI9WCoJZwPhmRGHF2X%2Ffi4AP2peafmBE8Hmq8LgATCOVaeBUL%2BtcjauUPip6qe%2BdJ82x293Pb2GtyL9ZmWRoL5QAUZZGQK47p9nOd39hdaZctaXScXXdSN1YHoynupwFCL0zUX0y4SVGf6uWDqybPG46On%2BWv%2FAA652nRtY%2FTdqJbfjLdqnK4gjpSVen1iBf5G%2FwB3Rf7qfOCxycaqwqjfaH8ck%2Fk%2B61K11AC1kZYIT6gmB%2Bxy2oP%2BMi%2FC6f7LEGlZCbBr%2B%2Bu%2FqqpBCjP6cbtxHwn4ljrX%2FgckOj2EMcC6lK6yTRKYmkIoYl6gE9xT7L5HhcTJqM1jJCEjjQSQsK7qT3rgi%2FuJ7PTDKQ31S5f03ZPi3SrfGP5RiKG6bej%2BQPzB0CG%2BuNHvB9VeZx9WvZKBX7cCf2P8jOvghgGU1B3BHfPHaQrfuEt3DHkAJakKhP8AO37A%2BedX8i%2BYPOen6dNp2qK5t4JFjs5HClyoNJfTdieUaL8S%2FwDCZEcRNEc%2BrfOOKWMTgeGUaEoHfi%2FpRP8Aunt2Ab3UorWqAc5QK8egHzOPhuoTYrdesJYgnJptgDTqdu%2FtkT1C9XnLPIwofjLduJ6fhkgLcYsi0vVRfSSRSUWRd1UeGGgyN%2BVrCSkmrXKlXnHC3RtuMXXlT%2BaTJKMTV7JdmzZsCuzZs2KuzZs2KuzZs2Kv%2F9Dv%2BbNmxV2bNmxVB6rafXtOuLXvIh4HwYbr%2BORbRL%2BsMTMaSQsOSnrseLZNDnIdfXXtP8zXtnZGC2tJWEsUz8pH4yAE8Y14rs3JfibJRPMKyf8AMXye3mKyh1LTH%2Bra1px9S0ulFSV6mNwPtRnIb5e8wXlw%2FwCj9VR9N1u12PGoD9vUgfpJG%2F7UedN8uapcXsH1e7C%2BrAi%2FvV6OPs1K%2FsttgLzP5Ysr%2B3NzHFxmjPMlNj%2FrLTdWHtiNtlU9I82sxa11lAssf2bmMfA9PFf2G%2F4XIt501y81SykEEjRQRMGEaMV5L0%2BKn2sq4ke3j9O4asuyLNSnMduX%2BV%2FxLCfVZ%2FS0u8cDkVhYhfGgxodGQDDZPMculusTzpwryMT7mneh%2B0uTVNL1e%2Bsob1tLmmtJlEkbFW5FGFR8NfUzi2iQ%2FXNXtLjUAXWe6hE3L%2BQyKHG%2FbjnqzzP5ok0H0baxgWVyodi5IRU6KBx74ASrzOzsfL1tcH69ppMtdxM0h4%2F883OS2GLS7239K1pGpGwj%2BEr%2FALHphVcecBcyrc6vBFdabL%2B7lV0UPbt12KDnx%2FlYYGvrWKwP1nTp3kirsT0BpWgcdf8AZDJg%2FFjSanSb8xC2ursXtpG5kt7dkVRGaU4g%2FETy%2FwBbIzc60xSeylsgphDJeafNtIY%2BnqREfCygYcWPmV14x3qkqQDzAo4X%2BYr%2B0ME6h%2BidZZImjM90FLQzQj40BFNn2%2B1X7DYkd2yi%2BrHNIh8uXbLp7yLJdToZbZJDX1EU0NOXxCeL9tf%2BJ4PhbTLya58sXqqt3EoKlV9MSoRUMn8ssf7XH%2FXyD%2BcfKFzoWnRatFqUUU%2BnSGSGAsBcFXZaFeHJVZDu2HOn3See9Kt1%2BsCx8x2y%2BpaXabB2TxH8pP21%2FZwAnu3VQuV1CC2iW9cx%2FwCkS28kMtA5dKLHL1%2B00TJyZPhk%2B1nS%2FKN59Z0GSNno6yI6e1V4v%2Fwy5z9pv8YWj6Hrcf6P836EWmiiHSfiv2ox%2B2kwH7P2ftLk28uxrbeXYLhYXV7gMzxkE0IqPiqNq%2Fy4gb%2BSk7PNdX1m%2BHmqaytJ%2FTtTdx%2FBGoSu6swZqcj8YbCnRmM97drKxKXcslu7tXb1%2BSBq%2FwCSzZK9c06xuNUutStkBls5IFkAIAMoHqUUfzNRkbCPW5Xs70rZcVtL0%2BtCoAFVc1oK%2FwArni2RIShdD0rU9Z0g2UNW1DR5JLG%2BirRlQuXhmp1ZP72M%2FwCph75g0K2sra21G8ch5baGJUpt6yARuvL6OWEQk1eJrq9s55YLxBzuGhJEjr3LKvxSqv7WISanq2oQRXGryvd2MtVhuSQ8aNQch8OyNjsqElhK1hbcr%2Fcv3K%2FyV%2FycRSQBmUiifsfQM6FpfljSbrR0mCy3EjDlDIzN9sGnphU%2FZ%2FlbIrqnl%2F6jM3Cb1VRqOoU8078XoOHPISIiQCd5ckgE3tyS4StK6xSy%2FDJ%2B7HqseO%2FYVw0W2thatp10he2b7YH21cfZljP86f8AD%2FYxO4tbO4so4I7ZUvG5Lpl3PssprUws392JD%2Fut%2FwCbAOh6sLuU6VqYMF4hKRu2x5DrFID0YY7rsh4tMn06%2FkspjzjniaS1nQfDIE%2BJWXwdafEv7Od0ugnmL8tmYipWEOB1oGWp%2FwCH5Zy4hoT9WuU5BTzj7FHp%2FeIe3%2BX%2FADrnR%2FysvRfaHeaJIwZ4RJGo8QDzQ%2F8AAy5OPVBfPNxbpMpifYqaBu4IwFYWlx9fEIJU7lmH7S%2F83ZJ9e0x7K9unRg8azMkoHWJySVR%2F9YH4W%2Bzj%2FKtvFdaxBDLQKzAVO243G%2F8ArYPJUXb2NvDZtdyWxe3B4meCQ%2BtG37Jkjb9lafaXHRXl9q2r6etnWJ7Yxx28h%2B1UNyMjt%2FlH4myX6lp1poPm57CIFLG8jikCsKisqqXWncc2%2BzhLZW0Om35hCuLiCeSgIHFY67KT9rl4YaV63IwMVSakg1pt27eGRuzvrTWILdYbnlcIWXSdQc8W5pXlp91%2FLIP91M%2F94mG9tcfW3AQ14xgsPH4c4Zp%2Btz6HqN2rJ61nNIy3loTTkA54yIf91zR%2FailyRNUinpV0iXqyyxw%2BjdW5Md%2FaN1iPdqf74f8A5Jtka1ZZ4LWYxsySKpaCRT8QI%2BIxkj2Hw5KLe6%2FTsUF%2Fp1wsmrRRk2l0QAL6Fft290g%2Fu7uP7Lo395hFquqaL9XZmmWCRwySWTgs8MgG6Oo%2FY5fZbAUhC%2BZ9JsfMl1SKYW%2BqyQRT2DMf3UvJeTwt4M5%2BJchKyrOr6D5gQwTQEpFK%2FwDeQv8Ayn%2BZDk%2B1Gyj1ew0SaC4gS5ntmCtX0ELQtQAM%2FEcv5Fwv1bQxr%2Bnhr4oms2ymP6xuCStSIbof6v8AdzYOaGAQ%2BXdTm1NdLjj5SN8QkG6FOvqBu%2BTjTrS2sbZLCMcVUmkpFGLn7Rf%2FAFv%2BFxTTme102DTuILIwZpKksW%2BzxWtW41%2FZyU2XlW41HhcahytOQJZVHKaXw%2Fd%2F7rY%2FzviAqQ21ldXtytrDG0k524qKmnj8sO736roNmNIltfVv7hFeaMnkUqTwpxNA2S2MaT5etS9w6WdtEvx1b42A7Symh%2F2C5zTzb%2BZun3swOjacGVKwrqMgoajeiJSr%2FOTDVdVZPYa3pOj%2BW7u31uKKzuZGP1dePP1Iz1UovxtJ%2FlYU%2Fl%2F5hOtyS%2BWrlis1Gm0pyfiR4%2Fi9Kv7SumcrvNYnu5DcXH7yToamrfSf6YL8ratLZ%2BZtJvoT6bwXMbEjuCwVh8uJauPFuFe%2Bx%2BYJ4NMawQiOFzyZOlDX4h%2FwQyQeVtAn1BY9R1QN9WU1toG%2Fa3qGYeGE3lnRLPVfM19LdAyWkTtcW8a7xOGaq1kGz7k%2FAM6moAACigA2AxJ7lojn72wANgKAbDLzZsirs2bNirs2bNirs2bNirs2bNir%2F9Hv%2BbNmxV2bNmxV2Qzz3p3P6rqKbFKwyt%2Fkn4lJPseWTPOVfnX5gmstNtdBtnMbajykuXHX0YyPh%2F2b%2FwDEcbrfm24MRzZI447GR59w6pMfNyWl7EdD1KM3Cp6dwoKldj%2B1zHE%2FRko0rz1rUtz9SvLe2lm2Hp8jC7BhWqV5xvUb%2FDnn01jPEin8pHgckemXmsTaHcxANw05o57O7IIKxliJYll%2FaRT%2B84%2FsNkIZhIkSjRDl6zs%2FwIjJCXFHkb5gp3%2Ba2r%2BbdPuEvYLVbLRpiFL27c2EvWkj0%2Fd8v2VpkGsfN2p3Kra3V2XicgEsQeQJ3qSNs7d%2BkdO1rSbKw1LhN%2BlbRXVJKFZyq8ZV3%2F3YGHLOEecvKFx5TvTLDym0idv3EvdG%2FwB9yf5a%2Fst%2B3lpHUOvsua4iNwbWCruHK%2FB0qN9j0zoy%2BarW48r2Oq3l1Le2sSizuGkqk6zgUVXMda8F%2FwCDTOO2M01rIs0XCRQ4kHqCqGnZl74NgkTlMqSOIZpPVNrXjGG8Qvfj2wXzSyqz1eO%2FtNSjQM8sVubhFbbkIpPiI%2BUR5Yca3q17IdPmtZ2js7yztriONNhyAKSciPtMJUfIZaXDWL%2Bra0jcq0ZYAV4yAq6mv8ynJf5Yex1PRjpUsfO%2F0pnuLJWNPUgkNZ4l%2Fm9Nh6vH%2BVpMRa2uvBcXej2Gp2rSC5tJJbOZkqW4v%2B%2FgY%2Bx%2FeJhtBB5sOi313boLa9ihMlo3EB5ClGkULy%2B16XJk4rhlZarBFAbZljtrS5Tg%2FoIF4fyOT1JjbC1L%2BbSbowyMwu4WrzJryX9h1PQpxw%2FFWFXNut9PB6srS6frlqI4JZHJ%2Br30bCsbOf5phx3%2FAN1T%2FwCRgPQbtreVrEFrW8gfnDU0dJUPF09unHD%2FAFeygjjvbi2haTQbpxcXlpHvLp9x9n6xClfjtjXi1P2P3b%2FGseE99ol9qtyjIKamYlktb6Mn0L5QKJ8Zp6d3x%2BH4vt8OD%2FvciTXPZaZ%2Bkdp5%2Bgt19Yad5p0%2Fe0vU2Y8T0NPiaM%2FtJ%2FuvOj6lcGysFaRlYxJWUjfkUXk3z5MM5p%2BV2l3U2pPdalFHK1sOLyqQxSZaFOdDWOT7W%2F7eTTzK8UdlcxREhXBTf%2BdzWg%2B7JxNji70HnTz%2B51GXyrrFxaapD69nfcRqSftqxHL1oj%2FOjPjtQ0GNYCfrCXWi3QMtlelhyjkYbFfdvsyx4M87Wy6zqemTq4X9KwQnmegkK%2Bmf%2BSi5G9M1PVfLUt3od3CJIGDEQS7iKUD4Zov8%2FjyErqrruPNkK58%2FJN7Sx0%2B0sDe3k0k9xA6JBJACGqwPHiKp8S8fts2F0mrDS3nubPThH6ZLa5YcQsnBvs3kSsCnJeXJuK%2FB%2FwAYmwQ%2FrXdjEsQRizhvjKCrUp8If4uW%2FwCyuK3Fs893p1nezfVdeDCOxmHFi8ZH%2B89wSeBjP2YuX%2BVFiYggA70Pmt9QzfyjdxXeiPeaY3rNYt9ZjdKUkgP2gyj7L8ftL%2FPgTz2tuLdJIT6cN1JFcxzJ2U7Sb%2Fs%2Fa5BsKfLEMvlPXby2sJI40uF%2F0izVuUcb05n0z3gkTlw%2F3237vHeddXN5pEMdnbmOys4BFcy0qDcF6GJa%2FwDFacmyX8Pu2R1QOi6Yupabd2F78dj6xjLVFUlpySaHwkUf7F0%2BDIrrvl6dr42N0eOtRIHs7ldkv4B9ijf8tKgfB%2FP%2FAHX28mPluyb0Vs7OdTL6SSReoK8%2FTZqN%2FrqOPL%2FJwTqdhFr9m1lqUhjnhcm2uv8AdltN%2FMKf7pb9tP8AZrjVhWHaHrEWqxjTb9gt9GKQytsXptxNf2sl35d3J0jznJbCojuQlR26cT%2Btc55qthdyXcyyJ9X8wWfx3ESbC6UbrcwfzS8fjfj%2FAHyfvPt88N%2FKuq3F3q1hqBIEyc4pWZuCkoAwck9MA50VPJV%2FMq2k0TznfCJQUmPJom%2BzJG%2FxcW9t%2FwDY4Q6cILa6ZY2eKRwslv6goaDfjy%2FaK4f%2FAJleadM80a8t1pcZ9GCJYmuG2MrD7TAfsqv2V%2Fmwr0WyuNXUw%2FVxci1%2BKLt%2Fw23wrg6qGVanr1vrK2t3csIry1aESBjxJEYYOQff4cjvm3zLbpZXLWTGC5vr%2FwCswRjfjBGoC8yfi%2BIjCPX2vNMu%2FqZDRNGKSAgUqxqgqKruF%2BH4sjsyPPIZZSXJ7knfG1e9%2Flxrdt5ksbqdSFu7eMLcW5O4%2BE0cV6xvnF75uVzcb14yyBW7%2FaO2KeS9RutC8yWd7DMYLfn6d3L%2Bx6D7SLJ7YhdkNd3UkRDRSXErxMDUFGclT9IwndCtpWrz6ZN8MskcDsGdojxkjcfZmip%2B2v8AL%2B3iWoySfXbiHUmFy14frKXqH4nL14zK%2FVuX7cbYEeJWDPQVpU0Pj0x6yqLL0pJUW4tXE1o5O9SaSRbeP28Cob1Z1T6vPKzxjeNSSQK9aV%2BznXLfUrdtDt9T1U%2BjeRxpa3iMvF5V41jcg%2Ftrx%2BLOd6VbaTqJlS7lMl5Iri3hHwRiQj920snhzODppWsii6zcGeSZg3po3NSy%2FD%2Fen4K9V542r0LyheaXcm5uaCCWNhxkl%2FvClOqcvs4rrn5g2enI9tpKi4uqlWck0rSvxP8Atf7HITazpccriNaLGD%2FozGnBVIJkZP261%2BFuWE4juLqSZo2pbJMjyitAQeVPwrjxbUE01reuXGvCKPUZJ2Cs0iqgUgFtunw%2FCKfDhWLXSzayW73jxuGElWgJUbUoSDhkLcXEjJDSJqkoSd%2BH7OGlh5a1HzDONIit%2FWvZEMkJRlQtGlKsCxVX4%2Fy%2FawWtILTLTTmeMmbTrm1jXe0nmMLOwH2nZlrWv%2BVhlBb6Lql09zpemrbx2cJe5WNqiRi3EKrfyj%2BZR8WJ6x%2BVPnXQrK41i9sljsrUB5pBLGzAVCgiNWLNufs4I8h6hp738sNxRBexei5BoBJWscg%2F2Xw4VZjoMllFbx635Y52k9mvPUdKaRjHIF%2B08PInhJQV6%2Fa%2BHOq6d5%2F0G7toZzK%2FBwKzBCVrTo3GpQ%2F62cYW21DQ%2FMUVrFH%2B5vyInPSIqzfE1f2afawkmtp42klt0f6uzuInWoDqrFQRQjkMJV9Q2ms6VfitpeRS%2BwYV%2FwCBNDg2ozzr5Y1vTI7V9L1PnbTDk8E4Qs7M1KKHBDp9GTfQfOdosSxw6txkp8UN0DxBG37WNea09UzZBNY%2FM3SfLcVrLrDIyXZKwm2bmW40DsF3%2BFa%2FF8eTW1uoby2iu7ducMyCSNh3VhUYEK2bNXNirs2bNirs2bNir%2F%2FS7%2FmzZsVdmzZsVdnE%2FwA9rKYXmj6jT9w0ctuT4OpEgB%2F1lOdsyO%2Bd%2FLUfmvy%2FcaXstxtNZyHosybofk32G%2F1sB5ORpMoxZ4TPIGj7pbPl%2BNPrERi%2FaG6H38MkPlXzh%2BjhHo%2BrmunCqwXFKmDmfiSRf27d%2FwBv9pMJBDcWN7JaXcRhuYHKTRPsVdT0P%2FNWB9RiWO6ag%2FdygSL7cuv3HKpkwImPcXoM2KGaHhy3B3BHf3h6B5qslXQooNOVof0a7Xdi6fDxBPKQQ78vT35xNl6Fr1l5s0yXSNZRHujHxlRhtMv%2B%2FE8JB9r%2FAIfILo2pT6XfLd8mmiKehPAzE8oT%2ByvKtOPWP%2BXKvrafSpl1XT2L6ez84LqLrE1a8WH7PH7NDlkMoluPiHRarRz05F%2BqJ5SHf1CT%2BZ%2FLlz5WvvTUmXT5jW2nP%2FEH%2FwCLB%2Fw2FauD8Sn6c67a3Vh5x0p7G%2BRfrAWskY6EHpLFXp%2FxpnLdc0S88t3ptrir27msE3ZlH6nX9pcmR1HJxFS3uA4oftDBlvcz2lxHc2sjQzxMGjlTYgjCVG6Mh%2BWD4ZRIvv3GC1Z7pdxHraNJCViukq13aswVAO9xCW%2F3Uf8Adkf%2B6%2F8AVw1t5NPkKabe3SyqKG2uIquYDX7Jc7ei37a%2FZ%2Fazm9tdT2dxHdWzcJYzyQ9R4UI7qw%2BFhkwhvDqECTaZbExyHhPbqKmCYivBf%2BKZPtR%2F8DgIkSDxVHqK%2FSyBFbjfvR8k1xY6gVtLb6vJbVWZbhvVLo38yAemYZF%2F4XCjW0McX986%2BX72Uem6V56bekVAYLu0D%2F8AJSL%2FAItjw7W0utVgj0%2B7k9DULc%2BnaSMaFkrvaz%2F8yXP%2Bpgq00iztbkaVcP8AWBer6NzEworLWjRsoJ4yRv8AEjr9jGOMDbn5y3UyJ8vcyfyHpl1puhy31zEE1e9cJfKxXjK8JMaTqfGZCrt%2FN9rCX8wda%2BqyabAGAM85aYA9FUcV%2FwCGyZXElvb20VgHb1LeNDEKmpKDhGS%2FfOK%2BcrhtU1G8vLZ%2BYsz6M0Q%2B0nBh6cwH%2B%2B5af7F8slsAAxG5tkesTm68saddo3GbTZ5bb1B1G%2FrRfrxGTW7LzPpcrahALfzDpir9biI4tJESAZowftJ8Svx%2FY%2F1cD6VMb3RNTsShJmhju4gVP2ovtH%2FgG%2BLBVnb6b5g0ux1JGWDXNDj4SEiongQcGjk%2F34hX7LfsYBukt%2BWba4gWHWmj%2BsWdpK0Dwqy%2BoWkonJE%2FvHZOfNcKdasnk80288TN6EEqxOXNWSOJiS7n2p8eB4bySw1ilv8Au4OQk47kKo%2BLv%2FLX7WK6jr4u9Uee1jItndiIiasyv9sV%2Fl3wWAFZBbvYajqsV%2FDSP1yITPUgSKH9SSinYcIRw%2BH7TSJhr%2BYOr2sOkWmnhHSK6YiRolFF5A%2Bn6ngJif8AWyP2ML6dbiRI%2FrqsAI3SRAsMY%2BxHKrlGhfl%2FefB%2B8%2F3XgXXYppJG1m2unkbj6Op2pUSKVAqksSNsif5L%2FFH9vHoUlrytdtDCgdmV7d5I2boU%2BINGT%2FLhpr3nLTKJ9UT19TB4zNHtCe3Jj3b2XIssp1Y8bUfFOQsix7SCSlAXpTmj4av5OnsdM%2BuzB3Zm9OWaNGD2%2FMgRTolP3sXP4Zv92fyYi6oITDVrG28x6NBeBvqWoWS1ivSeIikU8jFI%2BzLA6%2FGn%2B%2B3yFaq1pcXix28ZUGi3U2wadx%2FuziAEWv8Aq%2FH9vDLV7TzXeWrqbaWO4VhHeNHtFdCP7EhX5D4v9%2BfbwpC3liGgvIoVdSqt6pLPGr0pTj%2Bz8Xw4CUkEGil7RwRu9ZzwjPx8UZiKePShyb%2BRfMdhHM2kLEV%2BsDlDLQFncUCxcRX7WEF1DCs63zCs6r6c1Nkencr7rgXSpFsb5zCForepC9PiUEfZr4DADRVD%2BddUkPmPU4lUgVNtNG4qDw2Bof2kP2GyK1LECpY%2BAqTnUFhsta1Ce%2B1G3inuZCrySsgqwqFNRkwu9R8m%2BWIwscEHrharDBGjSH5tT4f9kcIoop4da6Vqt2GW0tbiQHbikbkH57UwHNFLbSvb3CNFLExSSJxxKsuzKwPQjOu3%2Fmq%2B1mFo1C2NmFMjhTQLGu%2FKRtumQfU%2FMWh3uoTXx0r1pJePKSWSnJlVU5lQNufHnhQxmOYxklSPiFCDvUZQKUIpUn7Jr0%2B7D8eYrBP7nRbUf61W%2FhmPmtkBFvptnEezCMkj78CpRZOY5w%2FBmWhBCjseuSyyn0pIpIr2CSr2gtbYTQt6aylufPp8PBWbCZPNurROskYgVkYOv7tSAVNRtg2780%2BYPNd5CdWuRJHEWkWONFjRaih%2BFAPljsqLeRrVh%2BjQt3GBRoXBBKAfFwag%2BLJ15B17yfealE2taTHcXMG63Eq%2FvbYL%2FvyH%2B6eFK%2F3iJyT9vAXkPygPNEuoxx3KQ3VrAHtYWP8AeOxpv%2FxWqijMv2WZMLdS8vBLx4pg9jqVqTFJIvwup6fvP5lP%2FDLillv5i%2BStPtL867pEEcem6hxkivLWjIk%2FevHb05ftZF9Okd5Et5mayvoWEtrdRmnCUfYmhYfzftp%2B3k3%2FAC68zLfx%2FwCFdWt1eElrbUoW%2BwGIrDPGv7CyU%2BLj%2B18eIeavKM3lq7WqfWNOkYizuXFeNesE9P8AiX7WNbqCncfm2fzRoUmg6zEqa7ZPDPPCv93eQRMC00A%2Fa%2FZaWLCHzf8Al7oOra5b6h5KuBHe3rj61Ywr%2B5Xlu0%2FL%2FdDfzx%2F8Qwpup4VWBrORhfW7iS0YkrJbkdRLKv2om%2FY4fbzsvkXU7fWNHju3jhj1ZAI9UEKhSJvEmg%2BF1%2BPEhXgPm%2B98y%2BWriTyxrM0iCMBo5VVW9aDoJIZm%2BLif5ftRthN5X8zxWXm%2FTZ9dHq6HH%2Foz2z1eNLd1Kq4TvwY%2Bo2el%2FPXkjTPPGkNY3n7q7hq9jeqPjikp%2FwANE%2F8AuxM8mazo%2Bq%2BV9UuNI1KL07y2PFlbdWU%2FZljP7UTfstih9Jy6d%2BVV3f2dja3ltHe6ipezS2mrzAFfh%2B2iMf2K%2FE2Xcfk5ojoTZ311bz1JEjFXG%2FitE%2F4lnlh3USLKCY7lSGLQ7UI3DA9mz0L%2BVP5wLqxi8s%2BaZRHqIpHZX0hAE9NljlPaf%2FK%2F3Z%2FrYqqal%2BS%2BoXb2EYvraWG3kcyvLG3IRuwY%2BkgPFW2PfJjZ%2BRruwuFa21iRYFACKFKsKf6r%2Bmf%2BReTUDxy6Yqo20LQQpE8rzso3lkpyb58QBi2bNirs2bNirs2bNir%2FAP%2FT7%2FmzZsVdmzZsVdlEA9cvNirzb8zvIf6bhOu6REP0tbL%2B%2BjUb3EQ%2FZ%2F4yp%2Bx%2FP9jOHagvqWsMw%2B1ETGwPWh33z1znI%2FzL8hqEutf0qP4JRzvrdR9lwR%2FpCDw%2F37%2FweRnGxTtNBreExw5DsD6Sen9F4gpphto2prYSSQ3Ketp11RbyAiu3QSoP50%2F4ZcK5YzG5Q7eGPEUyRpMykRSEhH7MV2IzGAkDY5h3OSEMkDjyCxL8beaZaglxoOpxTW7qLSWkmn3cX2eJ34nx%2FwApclMsen%2BcdIeC4QCZQPXjH2kanwyxe2RjT7%2B2e0bRtVHLT5SWhl%2Fat5Ozr%2FxWx%2B2uJWtxe6HqSw8wtxDvBL%2BxLGegP8yOMyceQEbcuo7nnNVpZ4JmMtwd4y%2FnD9bENU0y80C%2BazuRyTrHIPsunZh%2FTKil4kSIaj%2BGdZ1HTtM846SXUenKv2gN3glp1%2FykP%2FD5yO9s7vRb2SxvU4sh3I6MOzp7NkyOo5OKmSuGUMvQ9MMdF1m40S%2FjvoAHUfDPA32ZIz9pGH%2FDIf2Gwjt5Qh3%2Bw3%2BdcFnrir0GW5Kyx6hav6ltfqDHddW5Dbi1do5V%2Bw6%2FzZLPLbQ6nP8AWrpAby3oJGI2kXqkrfyyqR9rOU6HrKWHq2N8Gl0y6p66Lu0bjZZ4v%2BLF%2FaX%2FAHYmda8p2i2tk8sjrI7miTITxkj%2B1HJQ7huJ%2BLJR3K3snuq3fo2ruoqQC3idvsgD%2FWpnMJ%2FJ%2Fme4Msq2jC9tuUaXcXER3drJ1japH72NW%2BFmX%2Fit%2FwB5nTdIksyzW0c%2FryxVZgzBmCsa4eCZAKHDIWgbPDvK9jquh6xaW%2BtW81rDL6lozTKaFJQVAB%2BKtfhwvs47myvL%2BNQfTs2kD9UK8gQKlv2Xp8StnR%2FzQ1GW08u%2BlZO0d3dTxxQshKsKHm7hh9jiq%2Fazi6MxEiI5YOa3NyxJMjVrux%2BIrlctmQ3TS91E3jCG2jHI09R1qOdOgFf91r%2Fw2CLKFYxyJBIFZJOwHgMC2NryG3wRnq56t%2FZhusZiihu7cMWt5ir2zpyikUAU9T%2BYcuWR5pdPqiacQrWqXCzR1USVBAb%2FAHYp%2FnwutdVhtdTa%2FgWVBOAk8BcNG9BTqyk4c6rc2dxe2F3c2kcKJGI7qx4kUjpyR0B6Vr%2FNhBqc9haSxpHERaXRaWIt%2FuvcoTRa75PlyQn%2FAJZvYI%2FMUS2SNELiVTEygUjnVW9OlftI8hVWVsnSXVxfTGS6laSViCS2wodjsNs5%2Fo8rrL69qwd6pIrqAw%2Fd%2FYPw9OmSua51GVJ762swQXLCD1AiryNQrMfi2%2FyVwxKkIjW7%2BezjR7PTpr%2BUbv6WyUH8zfa6duOEPnjT7SEWmrxxkSXatazowA5KY%2BScgD9qIrxwQ3mPX7EetqFhAtqPtegzySAewA45F%2FMHm1dcRIGjMdvC%2FqRIKcuVCvJ2%2BR%2BzglLY2yhjnLaESfcEquburW8M5HpzKvIr1FaDl79cRbRr6S8%2Br245GCoac%2FCjKp67%2FwAww%2F8AL3li01qBLgPJO8f7t4wP7s%2FsE9fhOHer%2BVtfgg%2BvabcJe1FJrPjwZVUU%2Fdy%2FR9llyIFixuEzjKEjCYojmGM6jaajZ28RjBiEisJzULTi3iSKR0wboHkTXdWt21OLT5ru2A5RlN1k8SrsVWT%2FAGD5ena1aXA%2Bo6pD%2B9J2WcenL%2FlBJR8D%2FwCrnSfy880W%2Flyzl0m7uJZtJR%2BVmXSsltyNXhYD7cP7ScfiT%2BXDXcxosR1D8rvP2qWUdlZadHZW7kPcPcXEYeSn2EKR8%2BKJ9rh%2FNkRu%2FwArtc026ey1FooJo9yKs4IP7StQclz0brf5jeXtKhR7eYX0sieoiQHYL29Rv2Cf5T8WQ7W%2FMj%2BZrOKd0t1Ct%2B6eDk7xMaj05CaNxb%2FVwEgCy249PlyECMefJ4235fXQ63Uf%2FAt%2FXC7VvKsmkfV7iab1dPlISW7jTeFz%2BxJHWoPg37edQ5kyNDIvpyx%2FbQ%2B%2FQg91OB7hFCurIssUq8JoHFUdD%2Byw%2FU2IIIsMMmKeOZhkiYyHMF5g%2BhCNipcyFf3nwD7cH%2B%2FoT%2B1x%2FwB2J%2BziNyW01%2BNseVtMoMc4G7VH82TCbyxfWMxtUMlnDIPrOli55JIh%2FwCK2ZeMqthYYOMVxBNb%2Fu2HK%2Fsl6JU7Xlp%2B1xDfbT%2FdeFgmPknW7q0eC%2FsZ%2BOoWTck5ftRnrG9PtIfstnatY0iw%2FMfQ4%2FMWh8bfXbdSjxnbmyD47S4%2F5ky55gWcaZqDPp1yZo42Ppz8SvIePHOn%2BTfO2qaXML%2FSHiPqcRf2M9fTYf78Xj8XIfs4qoWsGsQ64Tpp%2Bo31zGbK9WYfFE8Z9TceI4FP9lnpNbWDVdGit9RRbiO4gT1g3QkqCW9jX4lzksE1z5382DU7WzEKoqq5UVAoOIeV9uR%2BL%2Fgc7RDGsMMcS%2FZjUIPkopj0UvHtQ%2FKnV9H1F9X8vXCajyYt9TuQoYLSijkx9OTj%2FlcMS8q%2BaLny95guoNYs2s%2FrfEXsLLxKyJXjLH4pxOdpwl1zy1p%2BvCOSctDcw19K5ioHAOxU1HxJ%2Fk4otNoZYriJJoWDxSKGRh0II2IyF%2FmN%2BXll550z4OMGs2oJsLynfr6Mv80L%2FwDCfayU6RYNplhDYNMZxACqyEBSVqSoIH8uDj0xV8NappV7pd7Np%2BoQNbX9qxSaJuoYfrr9pWwuSNg4NSHBqKbEHxrnrL80Py2g86WX1%2BwCw69aJS3kOyzoN%2Fq8x%2F5NP%2Bw2eXm0q8guZoblGglicpNA4pIroaMjfy0OKvpf8lvMusa5ol1ZazOLqXS3jiiuTvIyOvJRIf2ylKc86eM8y%2Fk35usfK2r3FtfyMtjqoRZZ3qRFNGT6bP4IQ7I%2F%2BxztF1%2BaHke01SDR31aN7mZ%2FTLRVeKNu3qTD4F5dMVZlmylIZQwNQdwRuMvFXZs2bFXZs2bFX%2F%2FU7%2FmzZsVdmzZsVdmzZsVdjXVXVlYclIIIPQg47GSOsaNI5oqgsx9h1xV4R%2BZvkA6VK2r6VH%2FuPlarIv8Aulz%2Bz%2Fxjb%2Fdf%2FA5EoJLK%2FwBFh0yOJU1AyrH6oABboqJItebtyJkjZP8AKVs73qnm%2FwAsyW89les7xzwtSMxMRKG%2BHghpx55w%2FwAy%2BWpbIHWNNjeGKFkDjlVw5%2BIPGwp8S%2FtcfsZGUauQHvdvpNWJxjhyyMZA%2BiXQ%2BUmMXNtcWVzJaXSGOeJisiHsRtll1uLf6rcMeKb20vVoW%2F6pP%2B0v7GHsLr5ptvq7mOPU4ElmEhHH1eCII4kp%2Bz6aO7%2FtephBNBPbytDcRtFNGaPG4oR7EZVKJHrhz%2B92JjDPA4cw3HMdR%2FSiiNG1m7028EiEC4j%2BGWMn4JU7qf8AjVslmvaBp3nLSFvbCiTKCY2P2opP24pKfs%2F9d5BTFFIys5ZGX9pKch9B65JvKmrSaVdevxea1m%2BCcEFQyj9tR%2FvxMtxZBIV8x3Oi1eknp5Ud4n6Zd%2F7XmskVxp11JY3sZikjbiyHsf8Amk%2Fs4caPay6peQadE6rJMwVXboF6k%2B%2FEDOn%2BdPIkfmSyGp6QA12qc4JFpSVPtcG9%2FwDjfI35a8qzaFNa3urKrXLmscfI1gP7NSv2n%2FmywxouIN1DWPKDW95DY6K0t5IfgnaUKgD05cl49I6H7TZ0bynBAmmjSVvhcz2qEM60%2BHnVRw9om%2BH%2FAFsItfhndg1q%2FpNdxmIuDQVU%2FECf8oYReSLk6R5nWBw1bmT6sSD8FGBb4h%2FNyXDyPvbsWITE9%2FVGJkB30jPKV1PpOsrBduRLFcPb3JY9VditW%2F2XxZ0%2B91O2spIoJWL3E54wW0Y5SOf9UdF%2Fmdvhzm%2Fm2w%2BoeapJlBVdRjWdCDsZE2cfeuHdvfQW0BngZptVvEH1u%2FlG6gj%2B5hH7Kr0xHc0pD%2BYg8wa1NDFZWjSWtsrCRoiGJcn46b1YdF2yFWemzxsW1CN4Ej%2FZlUofubOs2WpxpNGl2oMP2eSbEe5yTXGkadqFpJaT26T2860YEVBB6EHx8MeCzdpunlEtpHYQ38GqRrFNaPA8EgJcFa%2FGqhadao2XBGlmbe2uCzevbGeRo2PcNJx%2F2S%2FDht51s3sLpYLoH6ncIq21wRU1UceLt9Hxf8Hhj5f8pXerWc%2Bq2VrHqE1oqQWdvNLwUoijmJB%2FO9W4%2Fs8cjVH3LezEvM2mXWqyabNozB7SS1WJ5SwBrHWnLv8A3ZUbfy4onlazmtrKC%2BJlNoHFFNFbmQaHvtTJ9rPlzU7GOO6vrRbeNioQQMrRxmn938IXj4YE0fQLnXBdQ2062l1CP3SSry9Xav7og0%2F4LDsikps7C3s1WK2iWJB%2Bygpg5lNOX0YAVr7TL0xXsxcxsVlhktwpFPtLVWwbf%2Ban0e8tp7LTYrmyILlpyT6hoRw2%2Fu%2FTbdlw3taoK4v7a1dY2dW5GjQ1qVHj%2FwA24Vah5a03VlNxZEQTtvyX7LH%2FAClyfjyfo3nrTrbV9PRNI1i6gM8qRENC8gb05OUI%2BNR6nR1%2F4HIRqOj655Vu%2FQ1SBogT%2B7mU1ikA7pJ0%2FwBi3xZGwdizhOeOXFCRBSPSZNX8maml1MhNsfgldPijdD1H%2BS37S8s6ZLrEEZt2uEe1W6VWtLsg%2BlKGHIGOReS%2F6wOR9dWtRp11dSQ%2FWHt4Wk%2Br93IGyU%2Fysk%2Fk%2FW5INATT9Z0eAWczGT6gr%2BoIlfcgBxsf2vT%2FAGMYxMSeE2D07m7PqBmjEzjWSO3EOUo%2BY72M%2BYfLcd3FJeQRxyo7EzQU792GQ60bU9Hkf9HTAwts1jdVeNl%2FyX%2B2n%2FEc7ZL5XstVSS58p6kYZqVbTrysif6tWPrRr%2FspVzmuvaDq2jzsup2JtA5NCfjtmNf91Tjb%2FYyccJ8tmgJPqV4JJLJpI3sYLqJ2uY%2FtBgP91q6jpIy8Vw0sNNn8tG11m8KWNnqTrAums5YhTvyct%2B0R8fw%2FYb%2FWwLdRpfaVEkkPO50r1HhjJALRSg9HpX92%2FwCzgSW4TV9Hga5uppdVspFt7a0FOMNshHJm3VuZY8fV%2B0zfBlZHq3BNigOnm52LIfDHCYwMCJmVXI8IqMYnzI4f85l%2BsRQc7eSKVRPHKts4ruUkPAcv9R%2FiwbZaY1p5gtrHUoipjnjWZOo4lhRv8pGwcPL9pcROZo2S6ZkaXgyqoaFVk4hn%2BJ9uPqNxwVrmsWupvYzalF9S1K1lTi6GscsYYMpV%2FFWUNx%2FlwYoSjd8jybO0suLMcUsdmUQROxRrnH75PQtd8vaT5itBZapAJI0YPE6njJGw%2FajcfZzg%2FwCZWh3GhW%2Fr2wH1vSZ0DXlPia1m%2FuZuK7MV%2FuLj%2BbPQ1pdR3ltHcxGqyCtOtD3H0HIF%2BZFnb3k8EMqhxPBJHOh6MnIUDfSdssDq3zfqWmR6lFJqenRCO6iHK%2Fsk3FD0ng%2FmjfC3SNVudJuUvrKQJdQOrxc1DoafaSRGqrK%2FRlyU32i3XlnU4RHOYrF2Isr1hy9Jm%2F495%2F8AimT%2FACsKte0Zp%2FW1Kxg9KaL%2FAI6Nipr6bH%2Fd0X88En2lfFX0%2FwDlz5x0fzbpAlsIYrO%2BgAF%2FYxBVCOR%2FeIBTlE%2F7Lf7HJpniLyz5m1TyrqVtq2ly8ZYzuvVWX9qOQftI37WeufJnnHTfOekJqViwSZaLd2pNXhk7qf8AJP7D%2FtYFZJmzZsVdmzZsVaOct%2FNj8sx5ntJNb0NfT1uBayxrt9ajUfY%2F4zqP7tv2vsZ1PKOKvhz0CsbwMzqSSHPRgw2%2BL3%2FmwrlheB%2BD9exHQjxGeqfPH5Oad5lupdW0icabqU3xTqV5QTN%2FOyr8SOf2nX%2FgM59H%2BQfmu5nWC9ns4rbl8U6OzMB%2FkpwGKr%2Fyk%2FOBtOMPlnzTMWsyRHY6g5qYq9I5j3i%2Flf8A3XnoxWV1VkIZWAKsNwQehGc68sfkv5Q8vBZriE6rdrQ%2BpdAemCO6wj4f%2BD550VVCqFUUVRQAbAAYq3mzZsVdmzZsVf%2FV7%2FmzZsVdmzZsVdmzZsVdiNzNDbwSTXLBIUUmRj0A98WwNfPaJbSm%2BKi2pSUv9mh2pirAPON5pMWiStoiPJfM1bVI4yy1G8jDkCnwrhDrD6jFb%2BWbC7Wt36Ecl%2BCP%2BKiZHbtyJajf5WDvP9xZRaNCfKtxKb4zj04IOR403JKkfAOfH%2FWws84ajNd3EEklFuSOUtK%2FDRVXiKduQOFIeeatpk0F5PeaUj%2BlATLIYwSYhXd%2Fh%2ByleuLP9U12ykmiWO2vrWOW4n3PxgcAFXmaty3cf77%2Bx9jO1%2Flvo0EejT388SvJqDMjFxXlEvw8TX9ls5h%2BY%2FkSTyne%2FpHTVY6LdsVUj%2FdDt1hf%2Fitv91t%2FsMgRW4dxo9X4vDiySqcfon%2FO%2FoyYJsQGHfJL5FsrXUdZk0m6uTbR3UTvHQAgzRjkONSODla5GgcX0%2FUJNL1S0v41DPFINm8G%2BE%2Frym%2BHMD0k52txeLppjqPUPfF6l5X8xWlm995evZlguLSdkjR9gTWjrXovP4XTEPM6wwzKSKCT4tuoIO%2B3vke80xXU2tW13ZQ%2Bo15bq8npJ8UlELVp%2B3sMBWOsXOtWy2iEyXNuCyIw5Myf8VsaseFP7tvizL4tq%2BTzNUfvT%2BOU6npky9ZrciVAO5Xw%2Ba8sis01rp%2FmC01O5YrSWJ4kXcyFiB9nsK%2Ft5fljzLXzMlg0bRQujQESbVlDcl5IenL4kyeebPIp8y6j5e1DSEjX0XWO4QsqKYk%2FfRgV%2Fb5gx8cHMe5lGUom4mjuPnzSW%2F1OfVL6R7sJW2keKFUGygGhIJ3PKmNVy%2FTAk1pdWc9zBdrwuElcTIezA%2FEMj%2FmjXbvQtaW3tEBgCJM6PuCHFQExtizSKI1DHJv5VuxKrWMp%2BwC8JPh%2B0v0ZCNLvrfUrGG9tjWOVQfkf2lP%2BqcPdHme3vIZV24sKn2Ox%2FDJBSyzzBplrqWnSQSxLI0P76EsoIDqO3%2BsMgmlaxceUdRXU7ZS9jJRb62XoUP7QH80f2k%2F4HOgXdyVYgHp1%2BWQW8g4TzQyoQpJIVh1VuhGJCh7FG9hrempKhW4sryMMp6hlYV%2B%2FOWa%2FbXfk%2FU0ZJOEL1ayu2%2By1P91udv3if8OuCPJ%2FmhPL1xaaJetx0y4rFFMx2imJJSvhHLXj%2Fr4N%2FO9G%2FwAJ28o%2FYvY69%2BqOMgdlYzqPmWy8xr615aouoxAA3dk4dJB0%2FfRGjofBl54U%2BnCySRNSa1l%2B2vQq3861%2By65GPKcztqxjY7NEw4jYbU32zoNppF1qfrw2JX6yierHExoJivWIf5fH7DYYnZaY3pN9N5N1n9JJEbuIwyRoisY1kDbpVu3F%2FidM7xpl3Y%2BadFt7m5tle3vIUkaCYBx8Qowof5WB%2BPONG0jvLY28qlRUgqwoyOOu37LpiXl3XbjyZqk7XglmtZIfTEKNQGh5REFvsxr8XLjgIrdWQedvy7GiQPrfl4SNaxVe5s1q7Rp3ki%2FaaNf20%2B1kT07WGCqwcMjdJFNQc9C2N9BqNvHc29WiljSVGI2KyCopkFv%2FwAotHu9cOq2d1JYW0x53dhAo4O53JQt8MYf9ocMFyB23ZwGOQIkeCQGxqwfIsatNQSQrIrmOUbrIhoQfEEb5LLHzPP6X1TV4RqFo4ozFVL0%2FwApD8EmFms%2FlxeWBNxoEpuIhubSQj1B%2FqPsHwo0%2B4ltUmW7Ro5ojRo3BVhT2OWCi1t%2BbPJ1pFCfMXlJgtl%2Fx92VCyRHuwjb4kX%2Bdf2ciOlG2huhcX2n8JI2BE8FHHzMTb%2F8TVc6FpWutaySPblJEmHGeCQVVwP1ZGtcsIbe5N3p0Ui2MlWaM7mB%2FwBpQ4%2B1F%2FLkTGulhnDIYnYprf6tYaxaxxCDlxIaG7iko8Z7kGtWr%2B3ywxsdGl1WwitzGbkgkRzugDGnRm34R0%2FZbIJBZwxv9YhAVx8Qp0JPiBnafJl1eXekLNdyrKOXGNgADQD4g3Gg%2BE7Y8WyTLfiHNJbbQvNHle%2Fe50eQX%2BnXAD3Vg53EoWnKImhQmn7Pwv8AyYRX9xql1dmXWOS3XHiqMnp0QEkKq%2BA5fazrQwHqOmWmqQGC7j5D9lxsynxVsFsLeO39hb39tJbXMYlhlHGSNuhB%2FUffOZXy3%2Fl7UV05n5MgrpN1LTjLCT8VncEj%2FYf5Odt1nQbzR3JcerasfgnA2%2BT%2FAMrYB%2F5V3Y%2BdtAvhefubrn%2FuNux1jkQUYkD7Ubnir%2F6uEq8D1rTFk9XUdNgaHix%2Bu2XVoHPcD%2FfbfstnQfyAeb%2FFktC%2FptaSF1VgFNGTiXFfiA%2BLj%2FlZC9WuNd8p6kNM1e04anYsY2mY7TW%2FZG2pKjfsS4K003mkCHzl5WmDLazercWoB9WCvX1FB%2FeQt9lv8nIofYNRl5FPI3njTfO2li7taRXkQUXlp3Rj0Zf5on%2FYbJXirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FW7%2FmzZsVdmzZsVdmzZsVdgHVY9PmtHi1JlW3cgEuQBUbr1wdgPUdNttTtzb3IJWoZSOoYdxirzHztP%2Bi20aTyvdm6uDcJSCMJIPTVhRWKj7Bbbi2B9b8keZrnV3FvberbsQsVwHUKFJ6tU8hSvhk%2B%2FwAPGy1GwvLOkqK5ju0cIP3YQ%2BnItAPiif8A4nkkphKQaQOk6eml6ba6fGQVt4whPif2j%2FwWO1LTbPVrGfTr%2BITWtyhSWMjqD%2FEfs4MzEVwIsg2Ni%2BVPOHlm58p65NpU1XhP72znP%2B7IWPwn%2FXX7En%2BVgW28s63f2kWr29m76Ys6xyXQpxUggNUfa4iv2uOen9c8t6J5it0t9as0uo4zyjLVDKf8l1oy5EL7TriGW30Lytp7Q6Dbs0d7xI4Oz%2FFWPlycmNvib%2BfKziufETs7WXahOn8Ph9dVIn6a7%2FewDzPd3ukNplzYtxtEhW2adVBKzRktTkalOdf%2BBw60bydZ%2BaNR%2FwARaPq0VjOIw509bcLIkw%2B16yh%2FjRm%2F3an28de6dLYTXGk6xDztpx8aHoyn7Lqfb9nI3YX%2BreQ9ThS3pcWhcvazMBWSE%2FbgaQ%2FF8P8AJlrrDvunvmryB9buFvzAtnrkQD84z%2B6mKHkGRtu%2F82HWnO%2BoadLpU5aC4ZeUL9Gil%2B0jKR0aOYZOLO80jzho0d3Zv6kMn2WFPUhlGxVh%2By6H7WQWaO80rV1hvwBMjcfUAoskTbLIP%2BNsIr5oSu10tfOt7Ikt4th5ijQC6hkSsdz6fwfWIiCCr7UmTj%2Fl5JG%2FKTSdTjg%2FxDILh4UCUgHD7P8Axafj45GPMdkYtRkvbWf6jewEXNhcr9ppT9pEVatJWnxJx%2BznRPIfmz%2FFujfW5Y%2FSvLZ%2Fq94gBCmQCvNQfiVX%2B1xb7OA2NleaX%2Fkr%2FA19Jb2rO%2BlXbc7UvuFbuvL%2Bb%2FiWC7M7HOuarpdrq9jLY3i8o5Bse6t2df8AKXOP6jbaj5dvpLK5USBd0fcB07Ov8cMT3qkP5l6trkWp2kNi8sVr6CShoyVDyH7RJHXj8OQpfNfmCN1%2BsXcsnBeCrOfUAUdFHP4uP052ny%2Fq2g6veR6T5hgX94Almsp%2Fdsw%2F3W%2F%2BU37GSHUfyp8n6hUpavZse8DkD%2FgH5p%2BGCXNeTwM%2BbzeWxtr%2B3SVHFGMZKMP8oBqr%2FwANh9qv5gpr3kVfLV9zk1O3uIjFOwrzt4w1GZhUeqn2P8rJD5i%2FJJrK2lvNKufrSx%2FEYCnCXiOtCpKPx%2F1M503lq7tpDxDNUUUGlPwyJtWQflfpMWseaFtLgssZtZnDJ1VhxCn3651e38qanp%2Bs2ZX95brKG%2BtR7UVfio6%2Fs16YS%2Fk3pGmWxvNR%2BspJqfEW7WnR4kryLFW3PqN%2FL%2FLnW8I2UsW8x%2BVo71n1LT0CXp3mjGwlp3%2F4yD%2Fhsgl9oyXUaxX1u8LoCY2dStV%2FaG%2Fgc7JTEbiztrr0zcRrIYmDxlhWjDJCXQoeVeW9Rv8Ay1PKL25kuNO9ELEo%2BIjgaoKk%2FAqJyzqtrdQXkCXNs3qQyqGjcdCCK7ZFPMPl1Yg95aLWA7zQjfjXqw%2FycB6JrNzY3BW7uAbARKgUqSQVIC8KfCq8K8vhxq9wlntK4DvtJ07UgBfW6TU6FhvTwqN8FRyRyoHiYOjCoZTUEHH5FDC9Y%2FL6wuSZ9Ic2M3X0tzEfo6p%2FscL9B%2FLy8XVJNS8y3Yuo41aKz0%2BEkQrGwoWlO3N2zomVTDZV4l5n8s3Plq94oS%2BnTk%2FVZj27%2Bk5%2FnX%2FhsMNI893Wj2ht2thNVSEp8PGSlBK%2F%2BSf286nqOnWmqWcllexiSGQbg9QezKf2WGco13yhdaVMUT95A39zL0DDwPg%2BIZc3pPlzU5dStGa4IaeNgGZaAFWHJWoMOc5v5E1B7Wf6tcAoD%2B5PLb3jP0fYzo4xIYrZIo5UaOVQ6MKMrCoIPtidrZ29lAttaoI4UrxQdBU1OL5sCsO8%2FwD5e6V5708RXNINQgB%2Bp3oFStf2JAKc4m%2F4XOIWX5R%2FmVoOpummwIySAxNMssZhZG2q3Mqen80eeoKZqYq8l8h%2Fk%2FceW9Qt9Z1DU3W4gPJLS0JCEGvwTytT1U3%2Bx6arnWs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F1%2B%2F5s2bFXZs2bFXZs2bFXZs2bFXUzZs2KuzZs2KoXUjILG49E0k4EKetK43TYkhsoQp5EqGZvEnvgp1DKVbdW2I9jhDdaDqT%2FuLLWJbOzP8AulEVnAPVVkb4hiqB8wWUXmS%2BXTYWQi3ikZphuUlqOKmn7P8ANnOtRsiPW0TWUKqD9ofajYfZkQ%2B3%2FDLnYtH0Wy0W3aC0BJc8pJHPJ2J8ThV5u8tJrdoZrdQL6EH0z0Lj%2BQ%2F8a4bTbxXQPMGq%2Fl9r7mSs9jcUN3Cv2Zo%2B1xD4Sp%2FzZnaNYhtfNmgRaho7JcMwE1pKCASP246%2Fsn%2BZf58gsugWWtaPFp1xRL21qFkFCyP3U96YR%2BUfMt7%2BX%2BqvpmqEtpUsnGeOtQjE0FxD%2FwAzUxOy%2B5kHmGCOa1s7%2BVeEsFYpHI3SvwyBvDi647RtH1by3qEXmPT5VlgnWmo2C1Amj6rIrH4RMnVcCz3FvJ5x1pIqX2h30cVy3ouv2nQEeka9XZW5ZJNPult7dbZpTLasP9HlYUalP7uVf2JlH2v%2BEw891ZzY3tvqNtHdWz84pBUHoQe6sP2WX9rC7zJoEOu2Xp7LdRVa3lPY90b%2FACHwi0IahBqtdOo9hKf9LjY0Vf8ALU%2F78ybZFD591jS3R3gnRo5Ymp4MjA9snHkr8weRi0LzJII7pQEtdQc0SYdFWQ%2Fsy%2F5X7eH%2FAJw8uLqMDX9qg%2BtRL%2B8Uf7sQf8bLnJbuyjcNFKnND1U%2Fw8Dh5pfQo3Gc487eVFhMmq2KfuHNbmNR%2Fdsf92KP5G%2Fa%2FlyPeXPM%2Fmfy2Y4pmk1PRqfBBKpNwiDr6E3%2B7OH8j51%2B1ubXU7JLiKklvcJWjDqrDdWH%2FEsV5PntoFiuUuQOFxFvHKpKsPpWnLJZ5b8w65p1xEguXuIp3q8d07P1%2FZVm%2Bx%2Fkccbr%2Bhm2125sbPggX95AZq8FRhy3p%2FL8Srk181aDHqempqtvRLu2hDngPheMDmV%2F2P2ozjsrKLW5ju4Eni%2By4rQ9Qe4OL5D%2FACp5hgu7iOwkkUXFxD6yx9DWM8HNMmGJFFDRFRQioPUHIhrmgrAXubdK2z19WOleFepH%2BRkwymCkUIqD1BxBpWIaNq09o31WURrZoiem32ePEheCIB8VV%2BLJcGB3BBHtka1LQXVne0XnC9eUQ%2B0tevHxXA2lxazHfW620rx2atW4gkSqFOPCgdvjDClVwkA7hWYZswzZFXYnNBFPG0UyCSNvtKwqDimbFWE6voE1hIbu0Be3BrQVLIP8rxXJRo92b3T4Z2%2B1Ti3zG1cGkAih3B7ZSRpGvCNQqjsooN8NquzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxViPmbyo91cfpvQiINVT%2B%2Bh6RXSD9iXwl%2F33N%2FwWQzW9AXXo%2FXaFg7L%2B%2BhK0mjdBuafzACjrnYcDTWNrPKk8kYMsZDI42NR40w3tRW3z1p2l6ho%2BotLAfXVE5OgDVljA%2BLj%2FxZGv7OS2BbeaRbscpI5YuLQq3ETIfiQcv2ZVP90%2F8AsMk3mi1FjqBnt0CpcIHIUU%2BNT8RFP5tuWRDTFEulwPaP9YjVSfVjBIFGPM%2F7BvHCOSXqXlu6trnTI1t7Y2Zj%2BGW1YhmQ%2BJcfb5fzYcZBPKl1I7GRXHKGi3AY%2FajPRvdsnQNd8BFFDjnL%2FPWhJaXguIKRw33KngklPi%2F2Pxcs6jkY892Ul3onqwoZJLWRZeAHIlT8D7fJsAVBaLpUeueS9PtriYPcWykQXkfZ4yVDD%2FJP2WwX5X1NJ2NrQIGXkoXpzQ8JP65GPJfmOTR5G0zXLmGCzlYmzhZPSeE05ceP7UTjfliOhagkWs3CW0gkUXbPZjoZVkY8kQHr8OSHUJZD540vmYtVRBIAvoTo260JrGzU7cvhzaJ5jgm0t9O1u7giu%2FRdY%2BJ48oyCg%2Fd9QyfZ%2FwArJhPBFcwvbzqHikBV0PQg9sgt%2FwCSLpJy9pxniPRiQsgH8rfzYB5ql%2Fkq1hXU4ZigNwjsizftemU3Uf5Jzp%2BRXyloF%2Fpj3FzqYiR3YraxREsyx%2FzTOaL6j%2Fyp8CZKsSUOzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Hv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVg35iPrMEFld6XbR3CRM%2Fro1fUIIHwx%2Fs4U%2FlrqOkz3c1lYQmENFJI8DCgRzIDIg5b1JavTOiajZLf2cls1KsKofBh9k5ydpJPL%2FmzT9ZcBIWY2t5sFoD8Ls5C1%2FwCDkyQ5KyjWdLGi6ml3brSyvKxuo6I58P8AJPVclOiXZurPi5rLAfTf5fsn7sE3drBqFq9vLR4pV2I7dwy%2B%2BF2j6Xf2F5dS3EqNbyhViVa8iV%2Fbfag6%2FZXBdj3KnWURXLzYFYV5n8n3us6ut7btEITGsbc6hl418B8WFd75Ym8svHqVqPrQiCsJSPiikH2jQfsNnScayhwVYBlOxB3BGG1Sby7rf6YgZ5KCZftIBSmHeFllodlp95LeWqlDMKGIfYB7kDDPE%2BSuzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F%2F0u%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZFfM%2BipLW%2BSJZAf71CtaMPsygf8SyVZRAIIO4PbCDW6pP5YvDd6Wiu1Zbc%2Bi%2B9Tt9mv%2Bxw5xG3tbe1Vlt41jDHkwUUqfE4tgPNXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Pv%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV%2F%2FZ");background-position:center center;border:1px solid #0a0}.yui-skin-sam .yui-h-slider{background:url(bg-h.gif) no-repeat 5px 0;height:28px;width:228px}yui-compressor-2.4.7/tests/dataurl-base64-doublequotes.css0000644000175000017500000024536511640627104023543 0ustar drazzibdrazzib.yui3-skin-night .yui3-dial-ring-vml, .yui3-skin-night .yui3-dial-center-button-vml, .yui3-skin-night .yui3-dial-marker v\:oval.yui3-dial-marker-max-min, .yui3-skin-night v\:oval.yui3-dial-marker-max-min, .yui3-skin-night .yui3-dial-marker-vml, .yui3-skin-night .yui3-dial-handle-vml { background: none; opacity:1; } div.base64-doublequotes { width:100px; height:100px; background-image:url( "data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAgEAZABkAAD%2F4RfJRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAeAAAAcgEyAAIAAAAUAAAAkIdpAAQAAAABAAAApAAAANAAD0JAAAAnEAAPQkAAACcQQWRvYmUgUGhvdG9zaG9wIENTMiBNYWNpbnRvc2gAMjAwODowNzoxOSAxNDo1ODowNQAAA6ABAAMAAAAB%2F%2F8AAKACAAQAAAABAAABwqADAAQAAAABAAABRQAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAEeARsABQAAAAEAAAEmASgAAwAAAAEAAgAAAgEABAAAAAEAAAEuAgIABAAAAAEAABaTAAAAAAAAAEgAAAABAAAASAAAAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZ%2F%2B01IlBob3Rvc2hvcCAzLjAAOEJJTQQlAAAAAAAQAAAAAAAAAAAAAAAAAAAAADhCSU0D6gAAAAAYEDw%2FeG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8%2BCjwhRE9DVFlQRSBwbGlzdCBQVUJMSUMgIi0vL0FwcGxlLy9EVEQgUExJU1QgMS4wLy9FTiIgImh0dHA6Ly93d3cuYXBwbGUuY29tL0RURHMvUHJvcGVydHlMaXN0LTEuMC5kdGQiPgo8cGxpc3QgdmVyc2lvbj0iMS4wIj4KPGRpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNSG9yaXpvbnRhbFJlczwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1Ib3Jpem9udGFsUmVzPC9rZXk%2BCgkJCQk8cmVhbD43MjwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0aW9uPC9rZXk%2BCgkJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNU2NhbGluZzwva2V5PgoJPGRpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1TY2FsaW5nPC9rZXk%2BCgkJCQk8cmVhbD4xPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCTxkaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q%2BCgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tleT4KCQkJCTxyZWFsPjcyPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk%2BCgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsU2NhbGluZzwva2V5PgoJCQkJPHJlYWw%2BMTwvcmVhbD4KCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuc3ViVGlja2V0LnBhcGVyX2luZm9fdGlja2V0PC9rZXk%2BCgk8ZGljdD4KCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNUFBEUGFwZXJDb2RlTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BUE1UaW9nYVBhcGVyTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PlBNVGlvZ2FQYXBlck5hbWU8L2tleT4KCQkJCQk8c3RyaW5nPm5hLWxldHRlcjwvc3RyaW5nPgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5qb2J0aWNrZXQ8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk%2BCgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk%2BCgkJCQkJCTxyZWFsPi0xODwvcmVhbD4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD43NzQ8L3JlYWw%2BCgkJCQkJCTxyZWFsPjU5NDwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNUGFwZXJOYW1lPC9rZXk%2BCgkJCQkJPHN0cmluZz5uYS1sZXR0ZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk%2BCgkJCQkJPGludGVnZXI%2BMDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q%2BCgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhZ2VSZWN0PC9rZXk%2BCgkJPGRpY3Q%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk%2BCgkJCTxzdHJpbmc%2BY29tLmFwcGxlLmpvYnRpY2tldDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk%2BCgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BMC4wPC9yZWFsPgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw%2BCgkJCQkJCTxyZWFsPjczNDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTc2PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw%2BLTE4PC9yZWFsPgoJCQkJCQk8cmVhbD4tMTg8L3JlYWw%2BCgkJCQkJCTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJlYWw%2BNTk0PC9yZWFsPgoJCQkJCTwvYXJyYXk%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUuam9idGlja2V0PC9zdHJpbmc%2BCgkJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLnBwZC5QTVBhcGVyTmFtZTwva2V5PgoJCQkJCTxzdHJpbmc%2BVVMgTGV0dGVyPC9zdHJpbmc%2BCgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI%2BCgkJCQk8L2RpY3Q%2BCgkJCTwvYXJyYXk%2BCgkJPC9kaWN0PgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC5BUElWZXJzaW9uPC9rZXk%2BCgkJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJCTxrZXk%2BY29tLmFwcGxlLnByaW50LnRpY2tldC50eXBlPC9rZXk%2BCgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvVGlja2V0PC9zdHJpbmc%2BCgk8L2RpY3Q%2BCgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuQVBJVmVyc2lvbjwva2V5PgoJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnR5cGU8L2tleT4KCTxzdHJpbmc%2BY29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXRUaWNrZXQ8L3N0cmluZz4KPC9kaWN0Pgo8L3BsaXN0Pgo4QklNA%2BkAAAAAAHgAAwAAAEgASAAAAAAC3gJA%2F%2B7%2F7gMGAlIDZwUoA%2FwAAgAAAEgASAAAAAAC2AIoAAEAAABkAAAAAQADAwMAAAABf%2F8AAQABAAAAAAAAAAAAAAAAaAgAGQGQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4QklNA%2B0AAAAAABAAZAAAAAEAAQBkAAAAAQABOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD%2BAAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNBAoAAAAAAAEAADhCSU0nEAAAAAAACgABAAAAAAAAAAE4QklNA%2FUAAAAAAEgAL2ZmAAEAbGZmAAYAAAAAAAEAL2ZmAAEAoZmaAAYAAAAAAAEAMgAAAAEAWgAAAAYAAAAAAAEANQAAAAEALQAAAAYAAAAAAAE4QklNA%2FgAAAAAAHAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAAAD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FA%2BgAAAAA%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwPoAAAAAP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8D6AAAOEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJAAAAAADhCSU0EHgAAAAAABAAAAAA4QklNBBoAAAAAA1UAAAAGAAAAAAAAAAAAAAFFAAABwgAAABAAcwB3AGkAcwBzAF8AYQByAG0AeQBfAGsAbgBpAGYAZQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABwgAAAUUAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAG51bGwAAAACAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9uZwAAAUUAAAAAUmdodGxvbmcAAAHCAAAABnNsaWNlc1ZsTHMAAAABT2JqYwAAAAEAAAAAAAVzbGljZQAAABIAAAAHc2xpY2VJRGxvbmcAAAAAAAAAB2dyb3VwSURsb25nAAAAAAAAAAZvcmlnaW5lbnVtAAAADEVTbGljZU9yaWdpbgAAAA1hdXRvR2VuZXJhdGVkAAAAAFR5cGVlbnVtAAAACkVTbGljZVR5cGUAAAAASW1nIAAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAFFAAAAAFJnaHRsb25nAAABwgAAAAN1cmxURVhUAAAAAQAAAAAAAG51bGxURVhUAAAAAQAAAAAAAE1zZ2VURVhUAAAAAQAAAAAABmFsdFRhZ1RFWFQAAAABAAAAAAAOY2VsbFRleHRJc0hUTUxib29sAQAAAAhjZWxsVGV4dFRFWFQAAAABAAAAAAAJaG9yekFsaWduZW51bQAAAA9FU2xpY2VIb3J6QWxpZ24AAAAHZGVmYXVsdAAAAAl2ZXJ0QWxpZ25lbnVtAAAAD0VTbGljZVZlcnRBbGlnbgAAAAdkZWZhdWx0AAAAC2JnQ29sb3JUeXBlZW51bQAAABFFU2xpY2VCR0NvbG9yVHlwZQAAAABOb25lAAAACXRvcE91dHNldGxvbmcAAAAAAAAACmxlZnRPdXRzZXRsb25nAAAAAAAAAAxib3R0b21PdXRzZXRsb25nAAAAAAAAAAtyaWdodE91dHNldGxvbmcAAAAAADhCSU0EKAAAAAAADAAAAAE%2F8AAAAAAAADhCSU0EEQAAAAAAAQEAOEJJTQQUAAAAAAAEAAAAAThCSU0EDAAAAAAWrwAAAAEAAACgAAAAdAAAAeAAANmAAAAWkwAYAAH%2F2P%2FgABBKRklGAAECAABIAEgAAP%2FtAAxBZG9iZV9DTQAC%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgAdACgAwEiAAIRAQMRAf%2FdAAQACv%2FEAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5%2FcRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14%2FNGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x%2F%2FaAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUs4uDSWiXRoOJKFi3Ovx2Wvbse4e5gMwRo5soypdOyN9mTSRHpWvj4Oc4%2FwDVf9WkpupJJJKUkkkkpSSSSSlJJJJKUkkkkp%2F%2F0PVUklCqxttbbG%2FReA4fApKZpJJJKUo2WNrrdY8w1gLnHyAlVOsWvowXZDZ%2FQOZa8D9xrmm3%2FNr3PUswm%2FpmQGamyl4bHiWuhJTYqsFtTLBw9od94U1Q6FkfaOk4tszuqYfwV9JSll1%2FoOt2sOguDXgeTm7f%2FPmN%2FwCCLUWZ1VhrysbKA%2Bjua7zgtuZ%2F1FqIUXTSQcvKZi47sh7XOY0tBDYJhzms3akfR3blVd13prMtuI%2Bwse%2F6L3Ahm7n0%2FU%2Bi2zafzkFOgq9%2Bdj0ZFOM4k3ZDtrGNEnhzt7v3WbWPU8bJpyavVpduZuc2eNWONb2%2F2XtXOY2VU7rA6hnO9RuJS%2Br1hO1lguGJbuYz2extvv3fzLPU%2FwCESU9QkkkkpSSSSSlJJJJKf%2F%2FR9VWf0iwiu3Ff9LGsewT%2B6D7P%2FAyxy0FmunH6xPDMpgd%2FbZFT%2FwDoOx%2F%2B20Qp0lC02CtxqALwDtB4J8FNJBTVovx%2Bo4jvbLLGlltTuRMssrf%2FANJiz%2BhZDqMO%2FEyCX2dOc6t%2Bkuc1gmt%2B3%2FhaPTeoZ5s6R1IZrBGDlkNvI%2BjXcYYyx%2F7tWV9B%2FwDw%2FwDwlyD1LqWH0jq2N1O55rxOogY1rwC4C9uuP6mzdt9Wl1v6T%2Bb%2FAFdFS%2F1Myq%2F2VThusa%2B2tst2k6sPuY73Brm%2Fo3Vv2fy%2F3F0S4TAzq%2Bm%2FWDquKGnbhWOya62DUUlrcmyulktZ6f2ey19Wz8%2F2Ls2Z%2BFYx1jL6yxgBe%2FcIAI3CXfNIqZX3ursqqrZ6j7TqJgNY2PUsPP0dypfWJ%2Fo9NOT2xrarHTxs3tZkf%2By77VR6v9bejdNsbkb3Zbqm2sfVjgOOhrdZFljqsffXs%2FmvV9V%2F%2BDXHdZ%2BuvU8zA6i%2Bj02Y1zawaZLt2LY21tltb7XOb6j6%2FwDR1V%2FzV36v6rPVYFU%2BiCs5PS7cd43O2WUOB77d1X%2FT27lwvVnNyKK8d15q6hij207o9dg3DHdW9m9zLv8AQ%2F4Wu71K%2FTtr9aqzJ%2BuHV8tmR0zNoyLvsXU8Nr7cdtjmtN1J9K%2B2podsbk1%2Fo%2F8A0YsnG6te%2BnLZbdXXY6pttADNwucwmhv2cWbv0tnr%2FpKnfpKbKf8AtsqD1DvrjnfV70cKlldgzgbqjf7QHB3p2sG0sb6lv0%2FfZ6TEcZg630xz2vezK6jVbfhVtf6biQ%2BxltmNY7a2z9Js3Vu%2FwayvrHh1%2BhhdKv3XubjBhY9wDbHtPpOdXkOH6t1Dd%2FRsl%2F6C%2FwDomV7Fg9Wc%2FF%2Bq3RL6biben5WVjh4lljdxbexltf06La9vvp%2FM%2FwAFZ%2FhEuqn0r6lfXM9WYzpvVoo6wxvcbBcGj9Ltr09LLoj9bxf%2BvU%2Fof5mz9avrJd0%2B2jBwHAZTrcd17iA7bVZa2nY0H%2FCXw9v%2FAAdf%2FWl5zidQZ9ZcY3l3oddwg2z1mHZ6zWfQv3t2%2Bnk0%2FwCn%2FwDRf8xf6Df1DqvXGZ%2Be5tzsi7Gd6lm2kPsqNbqqOG1%2F4Cuxnpt%2FS7%2F9I9ALjR1Gh7f96%2BuJJpA1KZj2WNDmODmnhwMhJaySSSSU%2FwD%2F0vVVn9airFGYSGjEcLXuOkV%2Fzd5J%2FdZU%2FwBX%2Fra0EHM9D7Jf9pE4%2Fpv9YHX2bT6mn9RIKcE9U6lgXnJDv2l0jN%2FS497S39C530sOyxn%2BBc%2F%2Bh5P83%2F2kyfS%2FR5NlPrv16uwczExsPHFozLBRWHz6rriWM9Ouv6Hs9T3vseue6B9buoZF5xBU84BDC%2BtoZYW1PczG%2B02Gxm71Gb2XP2fod7P5mtct167q%2FT87Gdfk%2FbscWHI6V1NrQNGu3O2NZ6fp5FN9dTcrH3epR6f9RKwRYXzhKEuGYo%2FxfSMvM6lZlF%2FVfSobU11Q9MGyqLfa%2BrP9PJsr9Kz09n6bGq%2F7dWN1z9VxC3KfZT0%2B%2BPUyGg5NIaPdU7ezZe7KxPR%2FR5Gyr1sX9Db6%2FwDguZx%2Bv352be4WNwft%2B9tb2n21mza%2F07Xn2%2Fp7qmVep6dbP0vqfolqZD7mY91eDmXh9pBAZDGjT9awvb%2Bkp3W%2Fp2Mdkfpav1b%2BXUb0WulTeP23h5Di3JL3UYWTYzlzbKn1sc5rN7baM3FZ9pw8xrvSvr%2FQf0im6uvH6vY7G6hfS2mx1WFYaq7bnk%2Bo2r0rKPTa7bustxX20%2Bz%2Blf4RW%2FqPXeM403s%2FQ9LpdbQ4v97Wl4DcW1nud6PqfrH2e9nszMavNx%2Fs9%2F2hA6i5r77HZLH24Tn1W4%2BUwj2Pva3Jdj5bfzaHb8n7Fk%2F4P9YxP0tX8wulqaWfb1CzZ6GaM30622WDD%2FSV1mp3sfY6tjWOsY1tf8776a%2FTQ7s27qFNVIrqwAfUsbZRXt9S0N9Ky1tX83%2Bgre%2F1sej%2FAE1lzKltdDtbi9ZJsqqbTaBXdS0TbW68PycUxNj8qrIbR%2FpPU%2FSb6%2FTyv6VWf0qvOrzmsYasnGzHmk7gx1Za6K2XR7sd%2B5v6K79JXi3bPU%2FV8i71RRU5%2FWaLMv6kYj7SGX9L6g%2BqK%2Fosrymeux1cf4B17fYsrpuPmNxftz63Pcwl9DWDQ2sIqZkNJ%2FNZe6luR6f%2FAAX%2FAAS1f2pXX0vq%2BJln7LfkVVta3ZAfl4929myn%2FA76rLq86r%2Bbo%2F4qyhVruoZfSek4ldmM12Pe227D9XQBtvptu3%2B7d6Vr66Xf2PU%2FwiSnsuqnDyLMfFtMZORj%2BrXSPeHFseo2l7g31La%2FV%2Bh%2F2oq%2FwfqfpFznVcd9uDZivaxzDZXa1zztZaXB1LW%2Bv%2Fgb%2FZVXi5tv83%2FRsj9AsLqfXv2j0%2FpXqPFedgNurfa10F3uqsx8lv8Ao3Obvrf%2FAMT6n%2BFQquq59%2FURec1zb7CHXMc8htmw7n47v8BtucPUb6v6P9Ld69iNoS9H6Vk0Zzcpj3tqqeW1AAtuc%2F8Am7Meyhv6WvZ%2FNZX%2FAIEugzuk14eLiN69fbi49u6wgBjyWNb6dP6IOa52V6vt247P0dD%2FAFP0ajjdc6kBeekYQd1DIs2tsZVZbdVXt9tYqsG9%2B3%2FTPZ%2Bl%2FwBCsajpXV%2BtX2Zwo%2Fal7Wuvv9S0Mea2%2FT2%2BvZ7m1e1j6GV76PZ%2FpK0NE7avpH1Z69ndU6Ti4mP6mVZktBdbkP3uqbWTRkjKuYGb9t1e6v2776rP9Iuyw8VuJjtoaS8tkueeXOcdz3%2F2nLyb6vdZv6DjDKwmVt3lzbsZz3VsZcHluTgX499hfRYxuzJwn%2FznsyKrLLv8H2vT%2Fr9hODK%2BsM%2FZuSWkvrtFjC1wLmvr%2FWKqW%2Fm%2BzbZ%2BkRR4vVpKn03q%2FTeq47Mnp%2BQy%2Bt7WvG0%2B4Bw3N9Ss%2FpK%2F%2BuNVxBT%2FAP%2FT9VTOa17SxwDmuBDmnUEHsU6SSnxf6x9CzPqt1ECix7GMeben5Q0caneyylzvouto3MruZ%2Fhav0np%2FpFUryaMjFvrzps6dkPbZmUsHvx7zFber4f7rbLP6Wz%2FAEln%2BivYvY%2Bu9L6f1Xpl2H1GG0OG71SQ01uH0b2Pd9B7P%2FUb%2FwBGvH8vpF3T7%2FQpcH5NIea7az6leXSd2%2BzHjdW70qHbMnE%2FwlSZrE2NuzfjKHMY%2BGfpzR2n%2FL9H95wM%2FByOk5hxsgiyuwb6rm613VH6N1X%2FAKMrW10jqbrmHDyHl8MhjY3G6sHd6PO318dv6eiz07fW9P0v%2BOHiPxc6n9j552Ydh3YmVy7FtP5%2Bvvfiu%2Fw%2F%2FB%2Fpf5zehYv1a6pVk5WLnh%2BJZhML6rmiWvsBY6t1Fn0n1NY77Tvp%2FSf8WnijqNWnOEscjGQ4ZB7Oig0fV7Lf01rr8rqR2tez3XPbBx67XsYzayxjbMl9m38%2F9J%2Bl%2FS%2BpzrvUxMWqvqNVuJksx3402zW5oosbdScig725OHd9qY6v%2Bc2ZOLT6Nn88y3e6X1uyk9NexznYd%2BPdi2Mc1lTxl4ztznWu3bKfWZZXbs9T06f0ypdY6J1Hr%2FVH9Wrtpsx6mMqFDS%2F1WisF30XNa5%2B577bf0eyz%2FRV%2BqnHwW1RotDF6xay49Tviks9OHNBAc9g2sfc1m7Zu2%2FoG%2FQxv3PST9Lw2dTblM%2B1W1sdDixoM2vu3f0936Ot3pOZsurp%2FQ5H%2Bj%2FwaJj4GXf052ZjepRjbmOrywNzNjHulh9Meg5zN%2B1lrn%2F4R9fp%2FpFYxcHD6ey6nItdSGAOtdlFwhlh%2FRuHpN3Ppbv8A5xnqemgFOZ1%2FDyMW77T1DIOQy4vra91bqC00en%2BiYx%2F06Nrqnev%2FAIf%2FAEj1WxaG2sxKOo9Mu6iK32UYeOLHML3vLrNrrmu3%2Blv%2FAPRi1cvpl1PUqW3Nfh5VJ34%2BNmO9XEurHu%2FV7t1jGMsYf0noP9n%2FAANqv9Q6W84w630hn2cuFd1jcYGysjS6qzLxmiu3Fyadv896NX%2Bl%2B2eqhSSBQ1u%2Fwed6z9X%2BrtFJH1dZj1agENsqZuIB9EPsvbkW7Wj6eS%2F6fq%2Bj%2BjWOcbNw8hnqdNxq3tizZYXOa4Ty7fkWbmNd%2FObfof4RdpT1fqHUs1rc%2FLfktyRU2vGa4bSHNePtFL3el6VmLlVejZ7f0m%2F1cj%2BZ%2B0WbvSfqn0%2Fq1eTjdRIdlVspsqcxwBqc8PbfW%2BrX376%2FTtf%2FAKH0bcS6v2WJXqulj4YCXEDZqurxn1dxXdRosuw78hnXcR5dSWu22OrY2bqsdn03ZFTt932Oz2ZWL6lVLPWoXS19Hzup9Pq%2BsfTMYty8kn7ZRXDCy5hdVb1DEre%2F9NU79LvxHbLclj7Kf5rIspXE5mPm9J6q%2FLqa82YrmvfVJHqUsd%2BgyqLatln0a%2F03pP8AWxLmerV%2B5j%2Bz%2FU7qvR%2Bp9Cot6QNlLJbZQ5xdZXb9O1l73S99jnu3%2Bq7%2Be%2FnEmN57qv1X6b9c%2Fq99oxWNx%2BuYxcyx7g9rjc2PXxM5t36x6djmt9H1v02L%2Bi9L%2FCVWcz9VPr51npPWX9H%2Bsxuy8bItFNoyDvtot9tIcN%2F06He316P%2FAEKo%2FwAJ9p9hbXW17ntaA98b3AQXQIbuP5y43%2FGB9Q2dfp%2FaXTWtZ1iloEGGjIY3%2FAPe7%2BayG%2F8AafJ%2F6zb%2Bi%2FSUJT2TK66xtraGAAABoAEAbW8fyVJecfUbqP8AjHPV31dXxMjJ6c%2Fay27LaMd1JaNgsoDxX9o9rf0zaW2%2Br%2FPep%2FpPR0lP%2F9T1VJJJJSDNL%2Fsr9geXGABW1rnakD6F36P%2BsuAwumV%2FWXNrxHvcymqh2S7IqLnRa%2B7Jfj2UPcGtqdvyfVspZ7K%2FQ%2By1%2FoaV6Ffj05FZqvYLKyQS13Eg7m%2F9JKimvHprorEV1NDGDwDRtakkEg2NCNnxDqdGb0Lru3qFDHX41rLTWGxVeyR7626tdVmNa%2F1P3LPWr9i2cmzrpY5tdB6gzpL7Kq7WGXPqqf6D8HIc1gZ9upo%2F7T%2FzmVX%2FADXqr0brOF0%2B4135bWVFgc05kD1WMP06ari17q25P81Z%2B%2FX%2Bi%2BnauTysfqnQeoM6h06l91eW2H4jwf1uhgc70Lq3DdV1XGxm78d7%2FwCfo%2FQXfpK7GIRFX4s2fN7vAeGpRjwk93IyOj5VDnN6U5%2FUMa%2FflYlLGuLm%2BqxnpfadrG1tdk302Ufav%2Bs2en%2FNrQ%2Brd9%2BNlNdfS%2FDuDXMy8e7R1bmjfJ%2FkNhl9Nv59KtOeLbMDO6FktJte%2B%2FCstLh%2Bhcaxm4mY5oc5tLMr08XK3st9H7TRd%2FSqPWW11fA%2Fa%2BOOpdOc6jqeMNllYjcdvudjWt9zfVr3b8d%2F%2Fom%2F1E%2B2F5jpf1u6Dj9RyLKcqu3peaf1rF1aGh%2Bhym0XMr91TfZksr%2Fncb%2FSWY9bFTwftfUOpdQwRZvxsDLOLh2uBexrLH21YzLLAHv9K3ZX%2FwAH%2FOLUw%2BnfU%2F6xVDB6lg4%2FTutEFrLaG%2BgLXD%2FC42zY2x%2F%2Blw7f01f8ur9On%2BroyPqllZfThhMsqBZblWhxFjahFLLWE%2B27HZv3sbsr9H9N63%2FBjW1L9J9PDa%2F6udcx%2FU6Ta7bSH6uxLT7W0Oc0%2Fo6HT6mFl1fzX%2BnV9n1R6v07bbhZv2za4w149K0Vk6enkMeWPu2fzn8xVb%2Fwf0F1GVh4mdSW3MD2vbAfA3AH9xyoYmRZ0o%2FY894%2BztBNGS7QbR%2Ba8n6Oz%2FwH%2FttLyRbyPUcXMqzznY2Nfh9TrbZbkkVyxzQBvzm%2Bm04vr7f0d%2Fo2frX%2BD%2FTV2rc%2BrmH0bqHT8fcW%2Fb2Ned1FrmWsaXOZLfRLH01W%2Bpu9L%2BaXUiCJHBWGegM6d1IdU6WzbJi%2FFbAaWuPvdV%2FV%2FnPTStN6U4%2FWfqPk5jhRj2BorDrMXLOjqnge2m1rNrnV3e1lnpf8b%2FO1Urm%2FqLlZH1a%2BseT03IwLa7s97K8nFrY%2Bx9fp%2Bp6OfjupZ6VvT3%2BrY3I%2F0P6Oyn9F%2BjXrKSCFJJJJKUkkkkp%2F%2F9X1VJJJJSkkkklKQM3Dpzcd2PbuAdBa9hLXscNWWVPb9CxjkdJJTxHVfq4Ol5bc%2Bq55dlvLLq2Dax1lprY7IFbP5i63b77Kf9H%2Bk%2FQrpPq%2FcLMAVlgrupcWXM4duBj9I0y7f%2F1f00vrB0hnVunPo%2BjkMmzFtGjq7QC1tlb9Njvd%2FqxS6dWMj0upH9FfbXsyqwIabGwx30%2Ff%2BifW9n9RHopwvrBh4eF1V%2BXkU%2FqmZQQLSB6deYxwux7HAfpGvs9L%2FB%2F8J6ivWVZ2dj4vV8FgfbkY%2Fo5WO8hosrdr3%2Bi6t7nrefWx8b2h20hzZEwR9Fw%2FlIOLg4%2BI652OCxt7vUfWD7Q4%2FScxv5m%2F89K1IujYj8PpWLjWDa%2BusB7SZIcfc5u6XfnFW31seIe0OEzBE6%2FNSSQUpJJJJSkkkklKSSSSUpJJJJT%2FAP%2FW9VSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2Bqkl8qpJKfqpJfKqSSn6qSXyqkkp%2F%2FZADhCSU0EIQAAAAAAVQAAAAEBAAAADwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAAAABMAQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAIABDAFMAMgAAAAEAOEJJTQQGAAAAAAAHAAIAAAABAQD%2F4TkjaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu%2B7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI%2FPgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSIzLjEuMS0xMTIiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyI%2BCiAgICAgICAgIDx4YXBNTTpEb2N1bWVudElEPnV1aWQ6RTcxOTVFNTY1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkRvY3VtZW50SUQ%2BCiAgICAgICAgIDx4YXBNTTpJbnN0YW5jZUlEPnV1aWQ6RTcxOTVFNTc1NzMzMTFERDlFNzJGQ0E2QjkwQUZBRjU8L3hhcE1NOkluc3RhbmNlSUQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eGFwOkNyZWF0ZURhdGU%2BMjAwOC0wNy0xOVQxNDo1Nzo0MS0wNTowMDwveGFwOkNyZWF0ZURhdGU%2BCiAgICAgICAgIDx4YXA6TW9kaWZ5RGF0ZT4yMDA4LTA3LTE5VDE0OjU4OjA1LTA1OjAwPC94YXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhhcDpNZXRhZGF0YURhdGU%2BMjAwOC0wNy0xOVQxNDo1ODowNS0wNTowMDwveGFwOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhhcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1MyIE1hY2ludG9zaDwveGFwOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9qcGVnPC9kYzpmb3JtYXQ%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8cGhvdG9zaG9wOkhpc3RvcnkvPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4xMDAwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpOYXRpdmVEaWdlc3Q%2BMjU2LDI1NywyNTgsMjU5LDI2MiwyNzQsMjc3LDI4NCw1MzAsNTMxLDI4MiwyODMsMjk2LDMwMSwzMTgsMzE5LDUyOSw1MzIsMzA2LDI3MCwyNzEsMjcyLDMwNSwzMTUsMzM0MzI7QzA1QTE5MDRGRjAwQUJEQzA1MUJERkFGMDIwNEVBNTE8L3RpZmY6TmF0aXZlRGlnZXN0PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24%2BNDUwPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjMyNTwvZXhpZjpQaXhlbFlEaW1lbnNpb24%2BCiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U%2BLTE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6TmF0aXZlRGlnZXN0PjM2ODY0LDQwOTYwLDQwOTYxLDM3MTIxLDM3MTIyLDQwOTYyLDQwOTYzLDM3NTEwLDQwOTY0LDM2ODY3LDM2ODY4LDMzNDM0LDMzNDM3LDM0ODUwLDM0ODUyLDM0ODU1LDM0ODU2LDM3Mzc3LDM3Mzc4LDM3Mzc5LDM3MzgwLDM3MzgxLDM3MzgyLDM3MzgzLDM3Mzg0LDM3Mzg1LDM3Mzg2LDM3Mzk2LDQxNDgzLDQxNDg0LDQxNDg2LDQxNDg3LDQxNDg4LDQxNDkyLDQxNDkzLDQxNDk1LDQxNzI4LDQxNzI5LDQxNzMwLDQxOTg1LDQxOTg2LDQxOTg3LDQxOTg4LDQxOTg5LDQxOTkwLDQxOTkxLDQxOTkyLDQxOTkzLDQxOTk0LDQxOTk1LDQxOTk2LDQyMDE2LDAsMiw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwyMCwyMiwyMywyNCwyNSwyNiwyNywyOCwzMDtENDYzN0NCOUQ0MUExMEJBN0VGNUVCQ0RCNjMxODMyOTwvZXhpZjpOYXRpdmVEaWdlc3Q%2BCiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY%2BCjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8%2B%2F%2B4ADkFkb2JlAGSAAAAAAf%2FbAIQACAYGBgYGCAYGCAwIBwgMDgoICAoOEA0NDg0NEBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEJCAgJCgkLCQkLDgsNCw4RDg4ODhERDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM%2F8AAEQgBRQHCAwEiAAIRAQMRAf%2FdAAQAHf%2FEAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPBUtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4%2FPE1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BCk5SVlpeYmZqbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp0%2BPzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1%2Bf3OEhYaHiImKi4yNjo%2BDlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq%2Bv%2FaAAwDAQACEQMRAD8A7%2FmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVdmrlHI2utXn6WltnFESb0RFSp41WjD5q3LCBaslzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2E2rj0LuzvF7PxftUf8AXPLDnC3XI0ewdpOkTK4P08T%2FAMK2Ec1TLNgaxmE9pFIDy%2BEAn3GxwTgV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F%2F0e%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXYUeZpfR0a4kpUAx19h6i74b4X65CbjR76FV5FoJKKe5C1GIVLdDuGhuXs2IKOX4gfsvGdx%2FskKtkiyD6bctHHbXgPImOC4qOpXj6E1ff4Mm4Ndxkpc770BvNmzZFLs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Lv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVokKCT0G%2F3ZgaioNQemANZuhaWLyE0LlY1%2BbGn6sWspA8QA%2FZ%2FUcVRWbNmxV2bNmxV2bNmxV2NZQwKnodj9OOzYqwDT4iiPZsa%2FVLm5sj7I%2F76L%2BOTXTpjPZQSt9pkAb5r8JyKXqfUvMOpIQOFxFDfoP8qFvTl%2F4Q5INDkrFPAf8AdUhI%2FwBV%2FiH8cnLeAPcxHMprmzZsgydmzZsVdmzZsVdmzZsVdmzYyWRIo2kkYKiirMdgAMVX5sjTeaGl1CzsbSAOLuX0w7k14KCzyAD%2BUZJBirebNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV%2F9Pv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVo4CXUFa9e0CbJRWkr%2B0RWlMHZEJ5WtPMtzE5%2BGYJKnyK0%2F4kuEC1ZeM2IW0okjFT8S7H%2BuL4FYz52mMWn2tDTlcpX6FbDHR5ecCH%2BZevywl%2FMM8dJtn7LdJ%2BKvgry9ccrOJ69KVw9E9GS5s2bAh2bNmxV2bNmxV2bNmxVi3miFU1LSbxvsStJYzH%2FJnSi%2F8ADYpoEzLcxq1T68FGr%2FvyE8GrgjzdC0mhXEsY%2Fe2pS5i%2F1omDf8RwttJRHdrcDaNbhZVI6endIG%2F4mcnHeJCDzDL82bNkEuzZs2KuzZs2KuzZs2KurkZ843Zhs4bVTQzvVqfyrvg3zHNPb2UMsLtGBPGJSpIqjEqRUb9ch%2BvSSvp0JlcvJCLyMuxJb4JNvi%2F1SuEBVvkaX9L%2BZbm8Sv1fTbf0Y6%2F78lPxH%2FgFzpeRvyPbWcXlyyubWBIXuoxJOUG7uKjk5%2FaOSSoxPNXZs2bArs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FU7%2FmzZsVQ2osyWM7o3FlQkMOxGPtZhPBHKCDyUE08e%2BM1Bedjcr4xPT%2FgThV5cvBJbpGergEfMDcYa2PkqfZs2bArs2bNirs2bNirs2bNirshfnRGtb7T9TX7LcoJD2qDzSv3vk0wl81WDajodzDGKzRj1oR35R%2FFT6RthHNXaVcrKsUtftDi304dZz7yrqPrQCIncdMnsEnqRK%2Fcjf54yVjP5gwtJ5ckcD%2B5mik%2BivH%2FAI3wD5RnEtpwrWgw983RGby1qiqKlYGkA%2F4x%2FvP%2BNchnke5BIUGoPQ%2FPEJHJ6XG3JFbxAOPxOA1iX7sUwIdmzZsVdmzZsVdmzZsVUbqBbq2mtm%2BzMjRn5MKZDLP4rC2UVq9qYj7SWshWn%2BtxOTnIVG4ttWvdNaiiK7FxGDtWG6Ti%2FwDwMuShzRLky%2B1lE9vFMP8AdiK33gYscKtBmDWhtq%2FHbOyMp68SeSH5UOGpyJ5pYde3moWPmW5KzH0pIo2WNt0A3Wv0ts2D73zJ6FgzxqqXpKpHG9eDMx7EYXed45VeC4gPCdYyqua0I5q5VgOv2cAW8sWo2QMqhwwoyHcVyQFhVOLzvrNrdf6fFHLFX4kVeBH%2Br1%2F4bJlp%2Bt2GqWrXFnICyKWeJtnUgV3XOP67qFjaFLHUrprecy%2BlZajxPDmN1jn8Dv8Aa%2By%2BIaXrclrdtZ34NrfR1USofgeo2K06c%2F8AgcBCXr%2FlvXRrdnzk4rcoSJFXYfMbnDzOV%2BTr82eqAOQIpaBq7AV2r%2BOdTriRSEp8z8RoN9I5AWJPV5HYD0yHr%2BGQg3Ntq1lcLazx3CiZviiYOKzQo9Kjb7YzoWqRevpt5AOskEij5lCOmc60%2BWCK0j9ONYo5IYp%2BEahQWBeNjRafEcMVTvTb%2B80fyHZ3FugE9vSORJBUqPVZW%2BEHw3yVaXeC%2FsobulGkX41HQMNmH%2FBZzC%2B1iTTbadZUkjtJjzkQqSKqNm5fsdMPfyr1%2FRdT8vra2E5N5C8kl3bSMTKpkctz%2BL7SP9peOA7fFkIkgkCwOfkz7NlA1y8DF2bNmxV2bEJLy1injtpJVWeavpREjk3Hc8V64virs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F9Xv%2BbNmxVplDqUbcMKH5HIPokjWsstqx%2BK2lZPf4Wpk5yF6nF9R8xswHGO8QSj%2FAFh8D%2Fqrkoc6VmSMHUOOjAEfTjsAaZMXhMRPxRnYf5J6YPyJV2bNmxV2bNmxVQuzOtu729PVUclBFa07U98DafqsF6i9EkI6ePywwyF6vG2i6oJRUWl6xZCP2JOrr%2FsvtLhG6s0yiK4X6Zfi4QI7Vb9lv5h%2FXDHrgV5c8B0LzLc2Q%2BGF29WDw4SfF%2Fwp%2BHOg6ZMHi4j2YfTkZ%2FMGwpFaazGDytm9GYj%2FAH25%2BEn%2FAFX%2FAOJ4N8uXwliicnps305LmFZDewrc2dxbt0lieNvkylc45%2BX10UCQzHjLATE4P%2BQeNc6L55e5i0J57WVonikRmZDSq7jf2yB2Op%2FVYor2%2FwBNjktpAGjv7ZvU%2BInoy8Vao%2Fa44xCQ9as25RVBqKnfBGRby9rBEsljcIY0aQ%2Bg5FCCQD6bj9lslGAikN5s2bArs2bGyOI0aRuiAsfoFcVS%2B%2F1q2sJltyrSytuyp%2ByDsC3zwxBqAfHfI%2Fodmt2z6pcjnJK5dAexPT%2FgRkhxV2c782mSy82WUgNIdUhNs4PTmlXQ%2FwDBDOiZAvzLb6nHpOrlFkjs7lWdG9yvxVG%2FwiuGJ3Up3YTJFr7op%2BC8t1ljHjxodv8AYtkiyHbxx6XfKx%2FcXBilJ3%2BAsVUV8FRlyYA4Z80DkkPmq3EtlHJSpR%2BJPgHBH66ZBtIufqt9Np8pALHnEpO5p1oM6Xq0P1jTriPoePIfNdxnLtZtrGZluBcG3vF%2BFJYuJfx40IIxHJKzzb5et9ZtZYp1LwygcgPtKy%2FZkT%2FKWuRKKCOC6tNH1CblcWiILDUWHH6wg6wyDejx9Fw4sfOMjEBY5biH1HgLy8VYulOfJV%2By38q4ndH9LlL219K4iilHrWzLxlhI6SgE1%2F2SnFKo0Czxy28zMqcSzspIYBPj2I%2F1cd%2FytnVZdNQ2D1I%2BESMoPw%2FzMftdMG20TSQyyblmjenzoc4TY6ld6ddyKwMUsbFZoHqNwd1KnGXRXs9n5%2Fv7lg98GlWhMjwk1A%2Fm4k%2FF7jDSwSPULTTJI3PGBphGNwG4OHVW%2BgnONX%2BsWFpDFPaSSJcTESG3TcRlf2uRK%2Fazq%2BkR3aeT7e%2BjnX6yoW8ibht%2B9i9Tg%2B%2FQ98QVZHqstutowuSPSdSpV91IPVWzif1i98t%2BZ7m40FjbSWUrNCqEmkex4EH7acT9lv2c6lonmbTvMUTWdwgiumWktrLQhge6H9of6uRLzd5ZurDVP8Q2KetYFUW7jXeSKi%2Bm0hH7UZH7X7OCY4g2YM0sMrjvexB5SHcXsnkPz3Y%2BcdPqKQ6lAB9bta%2F8lI69Y2%2F4XJeDXPJlvPe6JqMeq6NMYLuE842To6ntToyuv2k%2Faz0J5E8%2B2HnGyI2t9VgA%2Bt2ZP0epH%2FNEf%2BEyESeUuff3tmbFAx8bB9H8Uf4sZ8%2F6P82TMMLNb1iDRrQ3EpBkkPC3j7s5%2FwCNV%2B0%2BGVc4n5m8yfpnzJcsr%2F6HYsLe232PBv3j0%2Fy3%2BH%2FY5JxkLourX175%2Ftb28maSZrloqsdlQ1Tgo%2FZUDO755%2B8uxlvPcMI6i6LAe2zZ6BwlS7NmzYFdmzZsVdmzZsVdmzZsVdmzZsVdmzZsVf%2FW7%2FmzZsVdkb83W5%2BrW1%2Bg%2BK1kAc%2F5D%2FCf%2BG45JMC6jare2FxaEf3qMo%2BdPh%2F4bCNiqV6VOOcTV%2BGReB37%2FaX9WHoyFaJMz23BqiWE7juCh%2FsyaRsHRXHRgCPpwy52gLs2bNkUuzZs2Kuwu1rS49W06Wzb4XI5Qv8Ayuu6nDHMemKvONE1KWGVrG7rHPCxRgeqsppk7sb0XC8W2lUbjxHiMhnnnTHtLmPXrZfgakd1TsR9iQ%2FP7LYtomq%2FWI0Iakybof4H55LmFZdqNlFqNjcWMwqk6FD8z9k%2FQc515XuZbW4l0%2B5%2BGWFzE6n%2BZTTOlW063EQkXY9GXwPhnO%2FNsS6T5qtbofBHqaniexmi%2B2v%2BsU4v%2FlfFgHcrPTFbanZNb3caywyApLE3Qj3zjutwW%2FljzBc6Pp6fV9JHpsLNSSgR1HIorV3Vvizq2jXQk%2BAndlBA9xnNvzRiWPzJBJWnr2gJP%2FGNyv8AHAdikJ3YGf0o5pZDIboSD1GJJ9aAgh6%2F5aUzoFnN9YtYZ6gmRFY06VI3zlXk%2FVI5bi2hnlBgdBuxFFahhfr0rSNsnHlXU4JI5NJaSt1avIQm%2B8RaquD0I%2BLjkpbgIZJmzZsirsDagC1jcqvUxOB%2FwJwTjXUMrK32WBB%2BWKpfofE6Xb8f5d%2FnhjkMPmvR%2FKlrJBqkxBSVkjC0PIDpTfI15s%2FMNbu3jbR5plsZVp69swRi9N0eSjMnH%2BRcVpm669cWWtXGnatwjgKma2uPsj0x%2FNXw%2FayOfmLr%2BhX3l%2BPTYrkXM%2BpGtm1uPUUceX7yRx8KLtx%2F1s5xoN%2FefpVr6C8muVVfUuLO8kMrEIeTem7faRk5Iy5FdTuZ9B169trGZvqkc5eFD8SmJzzUcTtsrceWHzTT3fRJv0p5UZvtOYYrgCu%2FJV4P%2FwANHnPrj83vM2lX9zpWoBJYInaJ540pOi1%2BGRQDxf4cln5Z3qT2stjWrK0iexEgE60%2F2XLOUfmHYNZeZbhWP94Ayn%2FV%2BD%2FjVclLlbEdQn955q1wTiU3huLadeQCsfSljO9VNev%2FAA0bYHub1Z7V5yWkhHxpcVHJNwGiuP8AKStVk%2FbyGafqLQxyafO5S2lPJWUAmGQ%2F7uiB8f8Ad0X%2B7F%2Fy8Ctd6jpl3Lb3v%2BkQTpxniqTDcQn7LoR%2FwUb%2FALDZCyyekWl9ZyaFLPelZGN2tqDEtZJHenEs67ckpVXwq1bU7G1iKWvqtcCR4bkkhFYx%2FCHXhvvX48C%2BU7H1SbK3k9Wya5hv4HchSBF8FxBL2WeOJ1k%2F4s9P4cu%2F0j%2Fc1FphmFxPLeOhZBxAiL8jt40%2Fa5YegV6PprvLpcE8sfpTNbh3QVoGK12zluoQ2PnZih42fmWIVt5z8Md4q9I5P5J17Z2A8YrWVl%2BERoaDwoNvupnLtb02LzREdR0hBba7bVe4tEPFZwpr6sH%2FABb%2FAJOSkgPNLqGaG7e3v42iuoTwlicUIK9iM755KnGoeT7ZX6m1CH%2FYSNCf%2BFOctnuIfNkSWeqEWuu249OC8ccfW47elcd%2Bf%2BVnQ%2FyyS5t9Dk067jMVzaSXMLK3hRJlp4r9rjkQl5PbalcaRd%2BlI7PbwysI5lNJIirU%2BH%2FmnOueV%2FOUeo%2BnY6hIpuWX9xPtwnU%2Fhz%2FnTOPeY4zY%2BYNTgpVBcSVQ9CrHkP14Gsb9rFgRWSzY1K1%2BKNh%2B0p%2FZcY2Qdlev%2BZ%2FLKxK19pcdYBUzWqdYx1Lwj%2BT%2BaP8AZ%2FZyHW9xe6ZfQ6ppk7QXsBDRTIevsR%2B0p%2FlyY%2BUPNR1KJLK5lD3KrW3m6esg67f79T9pMD%2BZtCjTnqVilIW%2BKeFRshPWVAP2P9%2BJ%2BzkZRB3DPFlljlxRPz5Edx8mcw%2Fm3aXvkzULyUC3122jET2oNA8kh9NZYT%2FJvzb%2BTOZabIhnWkgaOQcwxO577%2F5fjhKIYndoZvgaUD05v5SN1J%2FyG6YI0RZ4tS%2BoyKQS1HTwYHsffALrdOQwM%2BLGOEHfhu6PWvJ6f5FsfrXnqW8K%2FDBEZD4cmAVf1Z2fOSeSLmfT9RrHEWlvDSZaVagNR0%2BztnW8mWsuzZs2BDs2bNirs2bNirs2bNirs2bNirs2bNir%2F9fv%2BbNmxV2Y5so4qw6WL9HeYLiLpFcUnjHQfH9r%2FhuWSbTnBgMXeJiv0H4l%2FA4T%2Ba4fTW01FRvDJ6chA%2FYfpX5MMGaXcBmHxbSrsCdi6%2F2f8RyZ3j7kdU4zZzrTfO2qQa3eaHrkax6haux%2Br9FkgJ%2FdT2790ZP%2BGydWWoWt%2BnK3erAfHGdmX5rkSEovNm2yiQASTQDqcCt5sL5dZ06Ko9YSMNqRAv8Aiu2Iv5i0qJecsrKo%2FwAkk%2FctTho9yo69htbi2e2vApgmHB1cgA1%2BffOYX%2BnXflXUghJezkNbabxH8jH%2BdcPPN82l65b2j213DN9WdmmtefCRkdeJaNSVb1I%2FtYXWM8cVk2javM95pUv9zcPvLB%2FI3LvwwhIT2x12KCBrxjyjRS06jrxG5YD%2BZcrzzpkXmjyhLPpzCSaFVv8ATZozuXjHP4GH%2B%2FE5JkUmju9BujaTsJYHHKC4G6Sxn9r%2FAJqwJH5g1fyjDaw2KrcaE0zSNE27RiQmtuXPSJ6%2FuW%2FYkxI6hUg8ia9qulatHe3s0k8DgxGKZywBk%2By3%2BTkn%2FN63a8ttG1a3rHL%2B9hIB%2BIdGK%2F8ABA5DNbS0tL%2B4ksJOenzETWrjYiOT4gjD9l4WqjL%2FAJOTTU9XtNc8r6dDP8E8rc4iSP71RwkTfcP%2FALsX%2Bflgq09zFvKeoTMwV2NeCsB0BaNqf8a5N9Zu59K83W2pWb%2Bn9cjBo24ZXUNxI%2F1lyCWsL6fNb3LLxid24tSgINA9Puyb67pd%2Fr2kaPc6bxN5b8owWYKAYW%2BGpP8Ak4RyQU8ufOF7JLD9XRLaAj96ZPiYv4A9An%2FDYOfz9oEbtA0kjXSqG%2Brqh5NtU%2BkW4iQL%2Fk5yK%2FiuNagjEcpTU7Rj6YqaSAbtG3%2FFin4om%2Fa%2BxhXcGeWxlDgpPbfvUFaPDKpFXiI%2FYk%2Fk%2FmwFXr0n5hfXBJFpVtxmC84jOa81%2FaKqv7Sfy5GL7zJq2rwXFhqF40AlWiSQfAEPVW%2BH7Sfz%2FwCRkTl1dLW3t7xi8108C3g9EBArCnI8jtVvtNRcR1zzTdJcQvYwRW7y28dwzFfUblIvI05fAo%2F2OGxSt3zSW9LPXITMlCjiuzofsyRt2YfsPkd0iabTtQksp1Zra4U84X6SJ%2Bw4%2FwAoD7Ei5dzqV7LFCt7KZnVAY%2BRqyg9aj%2BX%2BTJdouuaHrltb2PmCNfrkKmO2vKcT%2FkgsP2v5cjtapfo0Jt%2FMllFGHltZvVeK4ptwWNi6yU%2BzIvRlwm1mUarpNtJHEWutOkuIbh0FSbfkGiZ2%2Fb4MxH%2Bpk6uZNM8saddywStNK605tsKnYcF%2FmbOZy3s2nWaLE%2FG4e4%2BsK43HELxowOzK%2FL4lx5fFWb%2FlprP1TWLQMaLMFRh%2FlRtxr%2FwLYn%2BfNjLp%2Bp2WpwghWLxuf2SGoRX%2FAIDI9peo2kMtjfWQMUi3JM9u24j5rT4D%2B1G5qyfyfYzp%2FwCcdimr%2BUra%2FG%2FwpISOoIpXJDcIPN4HDcR3Scl2I6qeoOGNvcQyw%2Fo%2B%2FJWGpNvP1aBz%2B0PGFv8Adkf%2BzXIxSaym2NCOh7MMNYLhLlOS7H9pfA5FU30vUNQ8uaqjIqsaqHiO8UsZ6EeKsrfA%2BS3yUr6p5iudTl2S1RvRTchTKeCgV%2FlTlkOsvUveOn8VkdatauxoyN%2FID%2B0r%2FwAmTfyYHsrnTdPasc1%2FNczXMZArwhT04g3%2FAD05Yjml6Fditlcmu%2FpvX%2FgTnK5bS4sp1mDtFID6kLioPXZgc61NGTBNH4o1PpUjIpNbyX0Ulvcw%2FV9Tst7i2IqHWn99EP2kZf7xF%2F18nMX1pANMR1TTYfMkRuYYlt%2FMEY5EfYW7UftL%2FwAXjDf8u%2FMFzM8mnX6MJLWRFkMh4yiqtGUYU%2FZP82IzW%2FH4DVQG%2FduPtRP1FG%2Flb9lsG6ZJDJfPcvGI9WCoJZwPhmRGHF2X%2Ffi4AP2peafmBE8Hmq8LgATCOVaeBUL%2BtcjauUPip6qe%2BdJ82x293Pb2GtyL9ZmWRoL5QAUZZGQK47p9nOd39hdaZctaXScXXdSN1YHoynupwFCL0zUX0y4SVGf6uWDqybPG46On%2BWv%2FAA652nRtY%2FTdqJbfjLdqnK4gjpSVen1iBf5G%2FwB3Rf7qfOCxycaqwqjfaH8ck%2Fk%2B61K11AC1kZYIT6gmB%2Bxy2oP%2BMi%2FC6f7LEGlZCbBr%2B%2Bu%2FqqpBCjP6cbtxHwn4ljrX%2FgckOj2EMcC6lK6yTRKYmkIoYl6gE9xT7L5HhcTJqM1jJCEjjQSQsK7qT3rgi%2FuJ7PTDKQ31S5f03ZPi3SrfGP5RiKG6bej%2BQPzB0CG%2BuNHvB9VeZx9WvZKBX7cCf2P8jOvghgGU1B3BHfPHaQrfuEt3DHkAJakKhP8AO37A%2BedX8i%2BYPOen6dNp2qK5t4JFjs5HClyoNJfTdieUaL8S%2FwDCZEcRNEc%2BrfOOKWMTgeGUaEoHfi%2FpRP8Aunt2Ab3UorWqAc5QK8egHzOPhuoTYrdesJYgnJptgDTqdu%2FtkT1C9XnLPIwofjLduJ6fhkgLcYsi0vVRfSSRSUWRd1UeGGgyN%2BVrCSkmrXKlXnHC3RtuMXXlT%2BaTJKMTV7JdmzZsCuzZs2KuzZs2KuzZs2Kv%2F9Dv%2BbNmxV2bNmxVB6rafXtOuLXvIh4HwYbr%2BORbRL%2BsMTMaSQsOSnrseLZNDnIdfXXtP8zXtnZGC2tJWEsUz8pH4yAE8Y14rs3JfibJRPMKyf8AMXye3mKyh1LTH%2Bra1px9S0ulFSV6mNwPtRnIb5e8wXlw%2FwCj9VR9N1u12PGoD9vUgfpJG%2F7UedN8uapcXsH1e7C%2BrAi%2FvV6OPs1K%2FsttgLzP5Ysr%2B3NzHFxmjPMlNj%2FrLTdWHtiNtlU9I82sxa11lAssf2bmMfA9PFf2G%2F4XIt501y81SykEEjRQRMGEaMV5L0%2BKn2sq4ke3j9O4asuyLNSnMduX%2BV%2FxLCfVZ%2FS0u8cDkVhYhfGgxodGQDDZPMculusTzpwryMT7mneh%2B0uTVNL1e%2Bsob1tLmmtJlEkbFW5FGFR8NfUzi2iQ%2FXNXtLjUAXWe6hE3L%2BQyKHG%2FbjnqzzP5ok0H0baxgWVyodi5IRU6KBx74ASrzOzsfL1tcH69ppMtdxM0h4%2F883OS2GLS7239K1pGpGwj%2BEr%2FALHphVcecBcyrc6vBFdabL%2B7lV0UPbt12KDnx%2FlYYGvrWKwP1nTp3kirsT0BpWgcdf8AZDJg%2FFjSanSb8xC2ursXtpG5kt7dkVRGaU4g%2FETy%2FwBbIzc60xSeylsgphDJeafNtIY%2BnqREfCygYcWPmV14x3qkqQDzAo4X%2BYr%2B0ME6h%2BidZZImjM90FLQzQj40BFNn2%2B1X7DYkd2yi%2BrHNIh8uXbLp7yLJdToZbZJDX1EU0NOXxCeL9tf%2BJ4PhbTLya58sXqqt3EoKlV9MSoRUMn8ssf7XH%2FXyD%2BcfKFzoWnRatFqUUU%2BnSGSGAsBcFXZaFeHJVZDu2HOn3See9Kt1%2BsCx8x2y%2BpaXabB2TxH8pP21%2FZwAnu3VQuV1CC2iW9cx%2FwCkS28kMtA5dKLHL1%2B00TJyZPhk%2B1nS%2FKN59Z0GSNno6yI6e1V4v%2Fwy5z9pv8YWj6Hrcf6P836EWmiiHSfiv2ox%2B2kwH7P2ftLk28uxrbeXYLhYXV7gMzxkE0IqPiqNq%2Fy4gb%2BSk7PNdX1m%2BHmqaytJ%2FTtTdx%2FBGoSu6swZqcj8YbCnRmM97drKxKXcslu7tXb1%2BSBq%2FwCSzZK9c06xuNUutStkBls5IFkAIAMoHqUUfzNRkbCPW5Xs70rZcVtL0%2BtCoAFVc1oK%2FwArni2RIShdD0rU9Z0g2UNW1DR5JLG%2BirRlQuXhmp1ZP72M%2FwCph75g0K2sra21G8ch5baGJUpt6yARuvL6OWEQk1eJrq9s55YLxBzuGhJEjr3LKvxSqv7WISanq2oQRXGryvd2MtVhuSQ8aNQch8OyNjsqElhK1hbcr%2Fcv3K%2FyV%2FycRSQBmUiifsfQM6FpfljSbrR0mCy3EjDlDIzN9sGnphU%2FZ%2FlbIrqnl%2F6jM3Cb1VRqOoU8078XoOHPISIiQCd5ckgE3tyS4StK6xSy%2FDJ%2B7HqseO%2FYVw0W2thatp10he2b7YH21cfZljP86f8AD%2FYxO4tbO4so4I7ZUvG5Lpl3PssprUws392JD%2Fut%2FwCbAOh6sLuU6VqYMF4hKRu2x5DrFID0YY7rsh4tMn06%2FkspjzjniaS1nQfDIE%2BJWXwdafEv7Od0ugnmL8tmYipWEOB1oGWp%2FwCH5Zy4hoT9WuU5BTzj7FHp%2FeIe3%2BX%2FADrnR%2FysvRfaHeaJIwZ4RJGo8QDzQ%2F8AAy5OPVBfPNxbpMpifYqaBu4IwFYWlx9fEIJU7lmH7S%2F83ZJ9e0x7K9unRg8azMkoHWJySVR%2F9YH4W%2Bzj%2FKtvFdaxBDLQKzAVO243G%2F8ArYPJUXb2NvDZtdyWxe3B4meCQ%2BtG37Jkjb9lafaXHRXl9q2r6etnWJ7Yxx28h%2B1UNyMjt%2FlH4myX6lp1poPm57CIFLG8jikCsKisqqXWncc2%2BzhLZW0Om35hCuLiCeSgIHFY67KT9rl4YaV63IwMVSakg1pt27eGRuzvrTWILdYbnlcIWXSdQc8W5pXlp91%2FLIP91M%2F94mG9tcfW3AQ14xgsPH4c4Zp%2Btz6HqN2rJ61nNIy3loTTkA54yIf91zR%2FailyRNUinpV0iXqyyxw%2BjdW5Md%2FaN1iPdqf74f8A5Jtka1ZZ4LWYxsySKpaCRT8QI%2BIxkj2Hw5KLe6%2FTsUF%2Fp1wsmrRRk2l0QAL6Fft290g%2Fu7uP7Lo395hFquqaL9XZmmWCRwySWTgs8MgG6Oo%2FY5fZbAUhC%2BZ9JsfMl1SKYW%2BqyQRT2DMf3UvJeTwt4M5%2BJchKyrOr6D5gQwTQEpFK%2FwDeQv8Ayn%2BZDk%2B1Gyj1ew0SaC4gS5ntmCtX0ELQtQAM%2FEcv5Fwv1bQxr%2Bnhr4oms2ymP6xuCStSIbof6v8AdzYOaGAQ%2BXdTm1NdLjj5SN8QkG6FOvqBu%2BTjTrS2sbZLCMcVUmkpFGLn7Rf%2FAFv%2BFxTTme102DTuILIwZpKksW%2BzxWtW41%2FZyU2XlW41HhcahytOQJZVHKaXw%2Fd%2F7rY%2FzviAqQ21ldXtytrDG0k524qKmnj8sO736roNmNIltfVv7hFeaMnkUqTwpxNA2S2MaT5etS9w6WdtEvx1b42A7Symh%2F2C5zTzb%2BZun3swOjacGVKwrqMgoajeiJSr%2FOTDVdVZPYa3pOj%2BW7u31uKKzuZGP1dePP1Iz1UovxtJ%2FlYU%2Fl%2F5hOtyS%2BWrlis1Gm0pyfiR4%2Fi9Kv7SumcrvNYnu5DcXH7yToamrfSf6YL8ratLZ%2BZtJvoT6bwXMbEjuCwVh8uJauPFuFe%2Bx%2BYJ4NMawQiOFzyZOlDX4h%2FwQyQeVtAn1BY9R1QN9WU1toG%2Fa3qGYeGE3lnRLPVfM19LdAyWkTtcW8a7xOGaq1kGz7k%2FAM6moAACigA2AxJ7lojn72wANgKAbDLzZsirs2bNirs2bNirs2bNirs2bNir%2F9Hv%2BbNmxV2bNmxV2Qzz3p3P6rqKbFKwyt%2Fkn4lJPseWTPOVfnX5gmstNtdBtnMbajykuXHX0YyPh%2F2b%2FwDEcbrfm24MRzZI447GR59w6pMfNyWl7EdD1KM3Cp6dwoKldj%2B1zHE%2FRko0rz1rUtz9SvLe2lm2Hp8jC7BhWqV5xvUb%2FDnn01jPEin8pHgckemXmsTaHcxANw05o57O7IIKxliJYll%2FaRT%2B84%2FsNkIZhIkSjRDl6zs%2FwIjJCXFHkb5gp3%2Ba2r%2BbdPuEvYLVbLRpiFL27c2EvWkj0%2Fd8v2VpkGsfN2p3Kra3V2XicgEsQeQJ3qSNs7d%2BkdO1rSbKw1LhN%2BlbRXVJKFZyq8ZV3%2F3YGHLOEecvKFx5TvTLDym0idv3EvdG%2FwB9yf5a%2Fst%2B3lpHUOvsua4iNwbWCruHK%2FB0qN9j0zoy%2BarW48r2Oq3l1Le2sSizuGkqk6zgUVXMda8F%2FwCDTOO2M01rIs0XCRQ4kHqCqGnZl74NgkTlMqSOIZpPVNrXjGG8Qvfj2wXzSyqz1eO%2FtNSjQM8sVubhFbbkIpPiI%2BUR5Yca3q17IdPmtZ2js7yztriONNhyAKSciPtMJUfIZaXDWL%2Bra0jcq0ZYAV4yAq6mv8ynJf5Yex1PRjpUsfO%2F0pnuLJWNPUgkNZ4l%2Fm9Nh6vH%2BVpMRa2uvBcXej2Gp2rSC5tJJbOZkqW4v%2B%2FgY%2Bx%2FeJhtBB5sOi313boLa9ihMlo3EB5ClGkULy%2B16XJk4rhlZarBFAbZljtrS5Tg%2FoIF4fyOT1JjbC1L%2BbSbowyMwu4WrzJryX9h1PQpxw%2FFWFXNut9PB6srS6frlqI4JZHJ%2Br30bCsbOf5phx3%2FAN1T%2FwCRgPQbtreVrEFrW8gfnDU0dJUPF09unHD%2FAFeygjjvbi2haTQbpxcXlpHvLp9x9n6xClfjtjXi1P2P3b%2FGseE99ol9qtyjIKamYlktb6Mn0L5QKJ8Zp6d3x%2BH4vt8OD%2FvciTXPZaZ%2Bkdp5%2Bgt19Yad5p0%2Fe0vU2Y8T0NPiaM%2FtJ%2FuvOj6lcGysFaRlYxJWUjfkUXk3z5MM5p%2BV2l3U2pPdalFHK1sOLyqQxSZaFOdDWOT7W%2F7eTTzK8UdlcxREhXBTf%2BdzWg%2B7JxNji70HnTz%2B51GXyrrFxaapD69nfcRqSftqxHL1oj%2FOjPjtQ0GNYCfrCXWi3QMtlelhyjkYbFfdvsyx4M87Wy6zqemTq4X9KwQnmegkK%2Bmf%2BSi5G9M1PVfLUt3od3CJIGDEQS7iKUD4Zov8%2FjyErqrruPNkK58%2FJN7Sx0%2B0sDe3k0k9xA6JBJACGqwPHiKp8S8fts2F0mrDS3nubPThH6ZLa5YcQsnBvs3kSsCnJeXJuK%2FB%2FwAYmwQ%2FrXdjEsQRizhvjKCrUp8If4uW%2FwCyuK3Fs893p1nezfVdeDCOxmHFi8ZH%2B89wSeBjP2YuX%2BVFiYggA70Pmt9QzfyjdxXeiPeaY3rNYt9ZjdKUkgP2gyj7L8ftL%2FPgTz2tuLdJIT6cN1JFcxzJ2U7Sb%2Fs%2Fa5BsKfLEMvlPXby2sJI40uF%2F0izVuUcb05n0z3gkTlw%2F3237vHeddXN5pEMdnbmOys4BFcy0qDcF6GJa%2FwDFacmyX8Pu2R1QOi6Yupabd2F78dj6xjLVFUlpySaHwkUf7F0%2BDIrrvl6dr42N0eOtRIHs7ldkv4B9ijf8tKgfB%2FP%2FAHX28mPluyb0Vs7OdTL6SSReoK8%2FTZqN%2FrqOPL%2FJwTqdhFr9m1lqUhjnhcm2uv8AdltN%2FMKf7pb9tP8AZrjVhWHaHrEWqxjTb9gt9GKQytsXptxNf2sl35d3J0jznJbCojuQlR26cT%2Btc55qthdyXcyyJ9X8wWfx3ESbC6UbrcwfzS8fjfj%2FAHyfvPt88N%2FKuq3F3q1hqBIEyc4pWZuCkoAwck9MA50VPJV%2FMq2k0TznfCJQUmPJom%2BzJG%2FxcW9t%2FwDY4Q6cILa6ZY2eKRwslv6goaDfjy%2FaK4f%2FAJleadM80a8t1pcZ9GCJYmuG2MrD7TAfsqv2V%2Fmwr0WyuNXUw%2FVxci1%2BKLt%2Fw23wrg6qGVanr1vrK2t3csIry1aESBjxJEYYOQff4cjvm3zLbpZXLWTGC5vr%2FwCswRjfjBGoC8yfi%2BIjCPX2vNMu%2FqZDRNGKSAgUqxqgqKruF%2BH4sjsyPPIZZSXJ7knfG1e9%2Flxrdt5ksbqdSFu7eMLcW5O4%2BE0cV6xvnF75uVzcb14yyBW7%2FaO2KeS9RutC8yWd7DMYLfn6d3L%2Bx6D7SLJ7YhdkNd3UkRDRSXErxMDUFGclT9IwndCtpWrz6ZN8MskcDsGdojxkjcfZmip%2B2v8AL%2B3iWoySfXbiHUmFy14frKXqH4nL14zK%2FVuX7cbYEeJWDPQVpU0Pj0x6yqLL0pJUW4tXE1o5O9SaSRbeP28Cob1Z1T6vPKzxjeNSSQK9aV%2BznXLfUrdtDt9T1U%2BjeRxpa3iMvF5V41jcg%2Ftrx%2BLOd6VbaTqJlS7lMl5Iri3hHwRiQj920snhzODppWsii6zcGeSZg3po3NSy%2FD%2Fen4K9V542r0LyheaXcm5uaCCWNhxkl%2FvClOqcvs4rrn5g2enI9tpKi4uqlWck0rSvxP8Atf7HITazpccriNaLGD%2FozGnBVIJkZP261%2BFuWE4juLqSZo2pbJMjyitAQeVPwrjxbUE01reuXGvCKPUZJ2Cs0iqgUgFtunw%2FCKfDhWLXSzayW73jxuGElWgJUbUoSDhkLcXEjJDSJqkoSd%2BH7OGlh5a1HzDONIit%2FWvZEMkJRlQtGlKsCxVX4%2Fy%2FawWtILTLTTmeMmbTrm1jXe0nmMLOwH2nZlrWv%2BVhlBb6Lql09zpemrbx2cJe5WNqiRi3EKrfyj%2BZR8WJ6x%2BVPnXQrK41i9sljsrUB5pBLGzAVCgiNWLNufs4I8h6hp738sNxRBexei5BoBJWscg%2F2Xw4VZjoMllFbx635Y52k9mvPUdKaRjHIF%2B08PInhJQV6%2Fa%2BHOq6d5%2F0G7toZzK%2FBwKzBCVrTo3GpQ%2F62cYW21DQ%2FMUVrFH%2B5vyInPSIqzfE1f2afawkmtp42klt0f6uzuInWoDqrFQRQjkMJV9Q2ms6VfitpeRS%2BwYV%2FwCBNDg2ozzr5Y1vTI7V9L1PnbTDk8E4Qs7M1KKHBDp9GTfQfOdosSxw6txkp8UN0DxBG37WNea09UzZBNY%2FM3SfLcVrLrDIyXZKwm2bmW40DsF3%2BFa%2FF8eTW1uoby2iu7ducMyCSNh3VhUYEK2bNXNirs2bNirs2bNir%2F%2FS7%2FmzZsVdmzZsVdnE%2FwA9rKYXmj6jT9w0ctuT4OpEgB%2F1lOdsyO%2Bd%2FLUfmvy%2FcaXstxtNZyHosybofk32G%2F1sB5ORpMoxZ4TPIGj7pbPl%2BNPrERi%2FaG6H38MkPlXzh%2BjhHo%2BrmunCqwXFKmDmfiSRf27d%2FwBv9pMJBDcWN7JaXcRhuYHKTRPsVdT0P%2FNWB9RiWO6ag%2FdygSL7cuv3HKpkwImPcXoM2KGaHhy3B3BHf3h6B5qslXQooNOVof0a7Xdi6fDxBPKQQ78vT35xNl6Fr1l5s0yXSNZRHujHxlRhtMv%2B%2FE8JB9r%2FAIfILo2pT6XfLd8mmiKehPAzE8oT%2ByvKtOPWP%2BXKvrafSpl1XT2L6ez84LqLrE1a8WH7PH7NDlkMoluPiHRarRz05F%2BqJ5SHf1CT%2BZ%2FLlz5WvvTUmXT5jW2nP%2FEH%2FwCLB%2Fw2FauD8Sn6c67a3Vh5x0p7G%2BRfrAWskY6EHpLFXp%2FxpnLdc0S88t3ptrir27msE3ZlH6nX9pcmR1HJxFS3uA4oftDBlvcz2lxHc2sjQzxMGjlTYgjCVG6Mh%2BWD4ZRIvv3GC1Z7pdxHraNJCViukq13aswVAO9xCW%2F3Uf8Adkf%2B6%2F8AVw1t5NPkKabe3SyqKG2uIquYDX7Jc7ei37a%2FZ%2Fazm9tdT2dxHdWzcJYzyQ9R4UI7qw%2BFhkwhvDqECTaZbExyHhPbqKmCYivBf%2BKZPtR%2F8DgIkSDxVHqK%2FSyBFbjfvR8k1xY6gVtLb6vJbVWZbhvVLo38yAemYZF%2F4XCjW0McX986%2BX72Uem6V56bekVAYLu0D%2F8AJSL%2FAItjw7W0utVgj0%2B7k9DULc%2BnaSMaFkrvaz%2F8yXP%2Bpgq00iztbkaVcP8AWBer6NzEworLWjRsoJ4yRv8AEjr9jGOMDbn5y3UyJ8vcyfyHpl1puhy31zEE1e9cJfKxXjK8JMaTqfGZCrt%2FN9rCX8wda%2BqyabAGAM85aYA9FUcV%2FwCGyZXElvb20VgHb1LeNDEKmpKDhGS%2FfOK%2BcrhtU1G8vLZ%2BYsz6M0Q%2B0nBh6cwH%2B%2B5af7F8slsAAxG5tkesTm68saddo3GbTZ5bb1B1G%2FrRfrxGTW7LzPpcrahALfzDpir9biI4tJESAZowftJ8Svx%2FY%2F1cD6VMb3RNTsShJmhju4gVP2ovtH%2FgG%2BLBVnb6b5g0ux1JGWDXNDj4SEiongQcGjk%2F34hX7LfsYBukt%2BWba4gWHWmj%2BsWdpK0Dwqy%2BoWkonJE%2FvHZOfNcKdasnk80288TN6EEqxOXNWSOJiS7n2p8eB4bySw1ilv8Au4OQk47kKo%2BLv%2FLX7WK6jr4u9Uee1jItndiIiasyv9sV%2Fl3wWAFZBbvYajqsV%2FDSP1yITPUgSKH9SSinYcIRw%2BH7TSJhr%2BYOr2sOkWmnhHSK6YiRolFF5A%2Bn6ngJif8AWyP2ML6dbiRI%2FrqsAI3SRAsMY%2BxHKrlGhfl%2FefB%2B8%2F3XgXXYppJG1m2unkbj6Op2pUSKVAqksSNsif5L%2FFH9vHoUlrytdtDCgdmV7d5I2boU%2BINGT%2FLhpr3nLTKJ9UT19TB4zNHtCe3Jj3b2XIssp1Y8bUfFOQsix7SCSlAXpTmj4av5OnsdM%2BuzB3Zm9OWaNGD2%2FMgRTolP3sXP4Zv92fyYi6oITDVrG28x6NBeBvqWoWS1ivSeIikU8jFI%2BzLA6%2FGn%2B%2B3yFaq1pcXix28ZUGi3U2wadx%2FuziAEWv8Aq%2FH9vDLV7TzXeWrqbaWO4VhHeNHtFdCP7EhX5D4v9%2BfbwpC3liGgvIoVdSqt6pLPGr0pTj%2Bz8Xw4CUkEGil7RwRu9ZzwjPx8UZiKePShyb%2BRfMdhHM2kLEV%2BsDlDLQFncUCxcRX7WEF1DCs63zCs6r6c1Nkencr7rgXSpFsb5zCForepC9PiUEfZr4DADRVD%2BddUkPmPU4lUgVNtNG4qDw2Bof2kP2GyK1LECpY%2BAqTnUFhsta1Ce%2B1G3inuZCrySsgqwqFNRkwu9R8m%2BWIwscEHrharDBGjSH5tT4f9kcIoop4da6Vqt2GW0tbiQHbikbkH57UwHNFLbSvb3CNFLExSSJxxKsuzKwPQjOu3%2Fmq%2B1mFo1C2NmFMjhTQLGu%2FKRtumQfU%2FMWh3uoTXx0r1pJePKSWSnJlVU5lQNufHnhQxmOYxklSPiFCDvUZQKUIpUn7Jr0%2B7D8eYrBP7nRbUf61W%2FhmPmtkBFvptnEezCMkj78CpRZOY5w%2FBmWhBCjseuSyyn0pIpIr2CSr2gtbYTQt6aylufPp8PBWbCZPNurROskYgVkYOv7tSAVNRtg2780%2BYPNd5CdWuRJHEWkWONFjRaih%2BFAPljsqLeRrVh%2BjQt3GBRoXBBKAfFwag%2BLJ15B17yfealE2taTHcXMG63Eq%2FvbYL%2FvyH%2B6eFK%2F3iJyT9vAXkPygPNEuoxx3KQ3VrAHtYWP8AeOxpv%2FxWqijMv2WZMLdS8vBLx4pg9jqVqTFJIvwup6fvP5lP%2FDLillv5i%2BStPtL867pEEcem6hxkivLWjIk%2FevHb05ftZF9Okd5Et5mayvoWEtrdRmnCUfYmhYfzftp%2B3k3%2FAC68zLfx%2FwCFdWt1eElrbUoW%2BwGIrDPGv7CyU%2BLj%2B18eIeavKM3lq7WqfWNOkYizuXFeNesE9P8AiX7WNbqCncfm2fzRoUmg6zEqa7ZPDPPCv93eQRMC00A%2Fa%2FZaWLCHzf8Al7oOra5b6h5KuBHe3rj61Ywr%2B5Xlu0%2FL%2FdDfzx%2F8Qwpup4VWBrORhfW7iS0YkrJbkdRLKv2om%2FY4fbzsvkXU7fWNHju3jhj1ZAI9UEKhSJvEmg%2BF1%2BPEhXgPm%2B98y%2BWriTyxrM0iCMBo5VVW9aDoJIZm%2BLif5ftRthN5X8zxWXm%2FTZ9dHq6HH%2Foz2z1eNLd1Kq4TvwY%2Bo2el%2FPXkjTPPGkNY3n7q7hq9jeqPjikp%2FwANE%2F8AuxM8mazo%2Bq%2BV9UuNI1KL07y2PFlbdWU%2FZljP7UTfstih9Jy6d%2BVV3f2dja3ltHe6ipezS2mrzAFfh%2B2iMf2K%2FE2Xcfk5ojoTZ311bz1JEjFXG%2FitE%2F4lnlh3USLKCY7lSGLQ7UI3DA9mz0L%2BVP5wLqxi8s%2BaZRHqIpHZX0hAE9NljlPaf%2FK%2F3Z%2FrYqqal%2BS%2BoXb2EYvraWG3kcyvLG3IRuwY%2BkgPFW2PfJjZ%2BRruwuFa21iRYFACKFKsKf6r%2Bmf%2BReTUDxy6Yqo20LQQpE8rzso3lkpyb58QBi2bNirs2bNirs2bNir%2FAP%2FT7%2FmzZsVdmzZsVdlEA9cvNirzb8zvIf6bhOu6REP0tbL%2B%2BjUb3EQ%2FZ%2F4yp%2Bx%2FP9jOHagvqWsMw%2B1ETGwPWh33z1znI%2FzL8hqEutf0qP4JRzvrdR9lwR%2FpCDw%2F37%2FweRnGxTtNBreExw5DsD6Sen9F4gpphto2prYSSQ3Ketp11RbyAiu3QSoP50%2F4ZcK5YzG5Q7eGPEUyRpMykRSEhH7MV2IzGAkDY5h3OSEMkDjyCxL8beaZaglxoOpxTW7qLSWkmn3cX2eJ34nx%2FwApclMsen%2BcdIeC4QCZQPXjH2kanwyxe2RjT7%2B2e0bRtVHLT5SWhl%2Fat5Ozr%2FxWx%2B2uJWtxe6HqSw8wtxDvBL%2BxLGegP8yOMyceQEbcuo7nnNVpZ4JmMtwd4y%2FnD9bENU0y80C%2BazuRyTrHIPsunZh%2FTKil4kSIaj%2BGdZ1HTtM846SXUenKv2gN3glp1%2FykP%2FD5yO9s7vRb2SxvU4sh3I6MOzp7NkyOo5OKmSuGUMvQ9MMdF1m40S%2FjvoAHUfDPA32ZIz9pGH%2FDIf2Gwjt5Qh3%2Bw3%2BdcFnrir0GW5Kyx6hav6ltfqDHddW5Dbi1do5V%2Bw6%2FzZLPLbQ6nP8AWrpAby3oJGI2kXqkrfyyqR9rOU6HrKWHq2N8Gl0y6p66Lu0bjZZ4v%2BLF%2FaX%2FAHYmda8p2i2tk8sjrI7miTITxkj%2B1HJQ7huJ%2BLJR3K3snuq3fo2ruoqQC3idvsgD%2FWpnMJ%2FJ%2Fme4Msq2jC9tuUaXcXER3drJ1japH72NW%2BFmX%2Fit%2FwB5nTdIksyzW0c%2FryxVZgzBmCsa4eCZAKHDIWgbPDvK9jquh6xaW%2BtW81rDL6lozTKaFJQVAB%2BKtfhwvs47myvL%2BNQfTs2kD9UK8gQKlv2Xp8StnR%2FzQ1GW08u%2BlZO0d3dTxxQshKsKHm7hh9jiq%2Fazi6MxEiI5YOa3NyxJMjVrux%2BIrlctmQ3TS91E3jCG2jHI09R1qOdOgFf91r%2Fw2CLKFYxyJBIFZJOwHgMC2NryG3wRnq56t%2FZhusZiihu7cMWt5ir2zpyikUAU9T%2BYcuWR5pdPqiacQrWqXCzR1USVBAb%2FAHYp%2FnwutdVhtdTa%2FgWVBOAk8BcNG9BTqyk4c6rc2dxe2F3c2kcKJGI7qx4kUjpyR0B6Vr%2FNhBqc9haSxpHERaXRaWIt%2FuvcoTRa75PlyQn%2FAJZvYI%2FMUS2SNELiVTEygUjnVW9OlftI8hVWVsnSXVxfTGS6laSViCS2wodjsNs5%2Fo8rrL69qwd6pIrqAw%2Fd%2FYPw9OmSua51GVJ762swQXLCD1AiryNQrMfi2%2FyVwxKkIjW7%2BezjR7PTpr%2BUbv6WyUH8zfa6duOEPnjT7SEWmrxxkSXatazowA5KY%2BScgD9qIrxwQ3mPX7EetqFhAtqPtegzySAewA45F%2FMHm1dcRIGjMdvC%2FqRIKcuVCvJ2%2BR%2BzglLY2yhjnLaESfcEquburW8M5HpzKvIr1FaDl79cRbRr6S8%2Br245GCoac%2FCjKp67%2FwAww%2F8AL3li01qBLgPJO8f7t4wP7s%2FsE9fhOHer%2BVtfgg%2BvabcJe1FJrPjwZVUU%2Fdy%2FR9llyIFixuEzjKEjCYojmGM6jaajZ28RjBiEisJzULTi3iSKR0wboHkTXdWt21OLT5ru2A5RlN1k8SrsVWT%2FAGD5ena1aXA%2Bo6pD%2B9J2WcenL%2FlBJR8D%2FwCrnSfy880W%2Flyzl0m7uJZtJR%2BVmXSsltyNXhYD7cP7ScfiT%2BXDXcxosR1D8rvP2qWUdlZadHZW7kPcPcXEYeSn2EKR8%2BKJ9rh%2FNkRu%2FwArtc026ey1FooJo9yKs4IP7StQclz0brf5jeXtKhR7eYX0sieoiQHYL29Rv2Cf5T8WQ7W%2FMj%2BZrOKd0t1Ct%2B6eDk7xMaj05CaNxb%2FVwEgCy249PlyECMefJ4235fXQ63Uf%2FAt%2FXC7VvKsmkfV7iab1dPlISW7jTeFz%2BxJHWoPg37edQ5kyNDIvpyx%2FbQ%2B%2FQg91OB7hFCurIssUq8JoHFUdD%2Byw%2FU2IIIsMMmKeOZhkiYyHMF5g%2BhCNipcyFf3nwD7cH%2B%2FoT%2B1x%2FwB2J%2BziNyW01%2BNseVtMoMc4G7VH82TCbyxfWMxtUMlnDIPrOli55JIh%2FwCK2ZeMqthYYOMVxBNb%2Fu2HK%2Fsl6JU7Xlp%2B1xDfbT%2FdeFgmPknW7q0eC%2FsZ%2BOoWTck5ftRnrG9PtIfstnatY0iw%2FMfQ4%2FMWh8bfXbdSjxnbmyD47S4%2F5ky55gWcaZqDPp1yZo42Ppz8SvIePHOn%2BTfO2qaXML%2FSHiPqcRf2M9fTYf78Xj8XIfs4qoWsGsQ64Tpp%2Bo31zGbK9WYfFE8Z9TceI4FP9lnpNbWDVdGit9RRbiO4gT1g3QkqCW9jX4lzksE1z5382DU7WzEKoqq5UVAoOIeV9uR%2BL%2Fgc7RDGsMMcS%2FZjUIPkopj0UvHtQ%2FKnV9H1F9X8vXCajyYt9TuQoYLSijkx9OTj%2FlcMS8q%2BaLny95guoNYs2s%2FrfEXsLLxKyJXjLH4pxOdpwl1zy1p%2BvCOSctDcw19K5ioHAOxU1HxJ%2Fk4otNoZYriJJoWDxSKGRh0II2IyF%2FmN%2BXll550z4OMGs2oJsLynfr6Mv80L%2FwDCfayU6RYNplhDYNMZxACqyEBSVqSoIH8uDj0xV8NappV7pd7Np%2BoQNbX9qxSaJuoYfrr9pWwuSNg4NSHBqKbEHxrnrL80Py2g86WX1%2BwCw69aJS3kOyzoN%2Fq8x%2F5NP%2Bw2eXm0q8guZoblGglicpNA4pIroaMjfy0OKvpf8lvMusa5ol1ZazOLqXS3jiiuTvIyOvJRIf2ylKc86eM8y%2Fk35usfK2r3FtfyMtjqoRZZ3qRFNGT6bP4IQ7I%2F%2BxztF1%2BaHke01SDR31aN7mZ%2FTLRVeKNu3qTD4F5dMVZlmylIZQwNQdwRuMvFXZs2bFXZs2bFX%2F%2FU7%2FmzZsVdmzZsVdmzZsVdjXVXVlYclIIIPQg47GSOsaNI5oqgsx9h1xV4R%2BZvkA6VK2r6VH%2FuPlarIv8Aulz%2Bz%2Fxjb%2Fdf%2FA5EoJLK%2FwBFh0yOJU1AyrH6oABboqJItebtyJkjZP8AKVs73qnm%2FwAsyW89les7xzwtSMxMRKG%2BHghpx55w%2FwAy%2BWpbIHWNNjeGKFkDjlVw5%2BIPGwp8S%2FtcfsZGUauQHvdvpNWJxjhyyMZA%2BiXQ%2BUmMXNtcWVzJaXSGOeJisiHsRtll1uLf6rcMeKb20vVoW%2F6pP%2B0v7GHsLr5ptvq7mOPU4ElmEhHH1eCII4kp%2Bz6aO7%2FtephBNBPbytDcRtFNGaPG4oR7EZVKJHrhz%2B92JjDPA4cw3HMdR%2FSiiNG1m7028EiEC4j%2BGWMn4JU7qf8AjVslmvaBp3nLSFvbCiTKCY2P2opP24pKfs%2F9d5BTFFIys5ZGX9pKch9B65JvKmrSaVdevxea1m%2BCcEFQyj9tR%2FvxMtxZBIV8x3Oi1eknp5Ud4n6Zd%2F7XmskVxp11JY3sZikjbiyHsf8Amk%2Fs4caPay6peQadE6rJMwVXboF6k%2B%2FEDOn%2BdPIkfmSyGp6QA12qc4JFpSVPtcG9%2FwDjfI35a8qzaFNa3urKrXLmscfI1gP7NSv2n%2FmywxouIN1DWPKDW95DY6K0t5IfgnaUKgD05cl49I6H7TZ0bynBAmmjSVvhcz2qEM60%2BHnVRw9om%2BH%2FAFsItfhndg1q%2FpNdxmIuDQVU%2FECf8oYReSLk6R5nWBw1bmT6sSD8FGBb4h%2FNyXDyPvbsWITE9%2FVGJkB30jPKV1PpOsrBduRLFcPb3JY9VditW%2F2XxZ0%2B91O2spIoJWL3E54wW0Y5SOf9UdF%2Fmdvhzm%2Fm2w%2BoeapJlBVdRjWdCDsZE2cfeuHdvfQW0BngZptVvEH1u%2FlG6gj%2B5hH7Kr0xHc0pD%2BYg8wa1NDFZWjSWtsrCRoiGJcn46b1YdF2yFWemzxsW1CN4Ej%2FZlUofubOs2WpxpNGl2oMP2eSbEe5yTXGkadqFpJaT26T2860YEVBB6EHx8MeCzdpunlEtpHYQ38GqRrFNaPA8EgJcFa%2FGqhadao2XBGlmbe2uCzevbGeRo2PcNJx%2F2S%2FDht51s3sLpYLoH6ncIq21wRU1UceLt9Hxf8Hhj5f8pXerWc%2Bq2VrHqE1oqQWdvNLwUoijmJB%2FO9W4%2Fs8cjVH3LezEvM2mXWqyabNozB7SS1WJ5SwBrHWnLv8A3ZUbfy4onlazmtrKC%2BJlNoHFFNFbmQaHvtTJ9rPlzU7GOO6vrRbeNioQQMrRxmn938IXj4YE0fQLnXBdQ2062l1CP3SSry9Xav7og0%2F4LDsikps7C3s1WK2iWJB%2Bygpg5lNOX0YAVr7TL0xXsxcxsVlhktwpFPtLVWwbf%2Ban0e8tp7LTYrmyILlpyT6hoRw2%2Fu%2FTbdlw3taoK4v7a1dY2dW5GjQ1qVHj%2FwA24Vah5a03VlNxZEQTtvyX7LH%2FAClyfjyfo3nrTrbV9PRNI1i6gM8qRENC8gb05OUI%2BNR6nR1%2F4HIRqOj655Vu%2FQ1SBogT%2B7mU1ikA7pJ0%2FwBi3xZGwdizhOeOXFCRBSPSZNX8maml1MhNsfgldPijdD1H%2BS37S8s6ZLrEEZt2uEe1W6VWtLsg%2BlKGHIGOReS%2F6wOR9dWtRp11dSQ%2FWHt4Wk%2Br93IGyU%2Fysk%2Fk%2FW5INATT9Z0eAWczGT6gr%2BoIlfcgBxsf2vT%2FAGMYxMSeE2D07m7PqBmjEzjWSO3EOUo%2BY72M%2BYfLcd3FJeQRxyo7EzQU792GQ60bU9Hkf9HTAwts1jdVeNl%2FyX%2B2n%2FEc7ZL5XstVSS58p6kYZqVbTrysif6tWPrRr%2FspVzmuvaDq2jzsup2JtA5NCfjtmNf91Tjb%2FYyccJ8tmgJPqV4JJLJpI3sYLqJ2uY%2FtBgP91q6jpIy8Vw0sNNn8tG11m8KWNnqTrAums5YhTvyct%2B0R8fw%2FYb%2FWwLdRpfaVEkkPO50r1HhjJALRSg9HpX92%2FwCzgSW4TV9Hga5uppdVspFt7a0FOMNshHJm3VuZY8fV%2B0zfBlZHq3BNigOnm52LIfDHCYwMCJmVXI8IqMYnzI4f85l%2BsRQc7eSKVRPHKts4ruUkPAcv9R%2FiwbZaY1p5gtrHUoipjnjWZOo4lhRv8pGwcPL9pcROZo2S6ZkaXgyqoaFVk4hn%2BJ9uPqNxwVrmsWupvYzalF9S1K1lTi6GscsYYMpV%2FFWUNx%2FlwYoSjd8jybO0suLMcUsdmUQROxRrnH75PQtd8vaT5itBZapAJI0YPE6njJGw%2FajcfZzg%2FwCZWh3GhW%2Fr2wH1vSZ0DXlPia1m%2FuZuK7MV%2FuLj%2BbPQ1pdR3ltHcxGqyCtOtD3H0HIF%2BZFnb3k8EMqhxPBJHOh6MnIUDfSdssDq3zfqWmR6lFJqenRCO6iHK%2Fsk3FD0ng%2FmjfC3SNVudJuUvrKQJdQOrxc1DoafaSRGqrK%2FRlyU32i3XlnU4RHOYrF2Isr1hy9Jm%2F495%2F8AimT%2FACsKte0Zp%2FW1Kxg9KaL%2FAI6Nipr6bH%2Fd0X88En2lfFX0%2FwDlz5x0fzbpAlsIYrO%2BgAF%2FYxBVCOR%2FeIBTlE%2F7Lf7HJpniLyz5m1TyrqVtq2ly8ZYzuvVWX9qOQftI37WeufJnnHTfOekJqViwSZaLd2pNXhk7qf8AJP7D%2FtYFZJmzZsVdmzZsVaOct%2FNj8sx5ntJNb0NfT1uBayxrt9ajUfY%2F4zqP7tv2vsZ1PKOKvhz0CsbwMzqSSHPRgw2%2BL3%2FmwrlheB%2BD9exHQjxGeqfPH5Oad5lupdW0icabqU3xTqV5QTN%2FOyr8SOf2nX%2FgM59H%2BQfmu5nWC9ns4rbl8U6OzMB%2FkpwGKr%2Fyk%2FOBtOMPlnzTMWsyRHY6g5qYq9I5j3i%2Flf8A3XnoxWV1VkIZWAKsNwQehGc68sfkv5Q8vBZriE6rdrQ%2BpdAemCO6wj4f%2BD550VVCqFUUVRQAbAAYq3mzZsVdmzZsVf%2FV7%2FmzZsVdmzZsVdmzZsVdiNzNDbwSTXLBIUUmRj0A98WwNfPaJbSm%2BKi2pSUv9mh2pirAPON5pMWiStoiPJfM1bVI4yy1G8jDkCnwrhDrD6jFb%2BWbC7Wt36Ecl%2BCP%2BKiZHbtyJajf5WDvP9xZRaNCfKtxKb4zj04IOR403JKkfAOfH%2FWws84ajNd3EEklFuSOUtK%2FDRVXiKduQOFIeeatpk0F5PeaUj%2BlATLIYwSYhXd%2Fh%2ByleuLP9U12ykmiWO2vrWOW4n3PxgcAFXmaty3cf77%2Bx9jO1%2Flvo0EejT388SvJqDMjFxXlEvw8TX9ls5h%2BY%2FkSTyne%2FpHTVY6LdsVUj%2FdDt1hf%2Fitv91t%2FsMgRW4dxo9X4vDiySqcfon%2FO%2FoyYJsQGHfJL5FsrXUdZk0m6uTbR3UTvHQAgzRjkONSODla5GgcX0%2FUJNL1S0v41DPFINm8G%2BE%2Frym%2BHMD0k52txeLppjqPUPfF6l5X8xWlm995evZlguLSdkjR9gTWjrXovP4XTEPM6wwzKSKCT4tuoIO%2B3vke80xXU2tW13ZQ%2Bo15bq8npJ8UlELVp%2B3sMBWOsXOtWy2iEyXNuCyIw5Myf8VsaseFP7tvizL4tq%2BTzNUfvT%2BOU6npky9ZrciVAO5Xw%2Ba8sis01rp%2FmC01O5YrSWJ4kXcyFiB9nsK%2Ft5fljzLXzMlg0bRQujQESbVlDcl5IenL4kyeebPIp8y6j5e1DSEjX0XWO4QsqKYk%2FfRgV%2Fb5gx8cHMe5lGUom4mjuPnzSW%2F1OfVL6R7sJW2keKFUGygGhIJ3PKmNVy%2FTAk1pdWc9zBdrwuElcTIezA%2FEMj%2FmjXbvQtaW3tEBgCJM6PuCHFQExtizSKI1DHJv5VuxKrWMp%2BwC8JPh%2B0v0ZCNLvrfUrGG9tjWOVQfkf2lP%2BqcPdHme3vIZV24sKn2Ox%2FDJBSyzzBplrqWnSQSxLI0P76EsoIDqO3%2BsMgmlaxceUdRXU7ZS9jJRb62XoUP7QH80f2k%2F4HOgXdyVYgHp1%2BWQW8g4TzQyoQpJIVh1VuhGJCh7FG9hrempKhW4sryMMp6hlYV%2B%2FOWa%2FbXfk%2FU0ZJOEL1ayu2%2By1P91udv3if8OuCPJ%2FmhPL1xaaJetx0y4rFFMx2imJJSvhHLXj%2Fr4N%2FO9G%2FwAJ28o%2FYvY69%2BqOMgdlYzqPmWy8xr615aouoxAA3dk4dJB0%2FfRGjofBl54U%2BnCySRNSa1l%2B2vQq3861%2By65GPKcztqxjY7NEw4jYbU32zoNppF1qfrw2JX6yierHExoJivWIf5fH7DYYnZaY3pN9N5N1n9JJEbuIwyRoisY1kDbpVu3F%2FidM7xpl3Y%2BadFt7m5tle3vIUkaCYBx8Qowof5WB%2BPONG0jvLY28qlRUgqwoyOOu37LpiXl3XbjyZqk7XglmtZIfTEKNQGh5REFvsxr8XLjgIrdWQedvy7GiQPrfl4SNaxVe5s1q7Rp3ki%2FaaNf20%2B1kT07WGCqwcMjdJFNQc9C2N9BqNvHc29WiljSVGI2KyCopkFv%2FwAotHu9cOq2d1JYW0x53dhAo4O53JQt8MYf9ocMFyB23ZwGOQIkeCQGxqwfIsatNQSQrIrmOUbrIhoQfEEb5LLHzPP6X1TV4RqFo4ozFVL0%2FwApD8EmFms%2FlxeWBNxoEpuIhubSQj1B%2FqPsHwo0%2B4ltUmW7Ro5ojRo3BVhT2OWCi1t%2BbPJ1pFCfMXlJgtl%2Fx92VCyRHuwjb4kX%2Bdf2ciOlG2huhcX2n8JI2BE8FHHzMTb%2F8TVc6FpWutaySPblJEmHGeCQVVwP1ZGtcsIbe5N3p0Ui2MlWaM7mB%2FwBpQ4%2B1F%2FLkTGulhnDIYnYprf6tYaxaxxCDlxIaG7iko8Z7kGtWr%2B3ywxsdGl1WwitzGbkgkRzugDGnRm34R0%2FZbIJBZwxv9YhAVx8Qp0JPiBnafJl1eXekLNdyrKOXGNgADQD4g3Gg%2BE7Y8WyTLfiHNJbbQvNHle%2Fe50eQX%2BnXAD3Vg53EoWnKImhQmn7Pwv8AyYRX9xql1dmXWOS3XHiqMnp0QEkKq%2BA5fazrQwHqOmWmqQGC7j5D9lxsynxVsFsLeO39hb39tJbXMYlhlHGSNuhB%2FUffOZXy3%2Fl7UV05n5MgrpN1LTjLCT8VncEj%2FYf5Odt1nQbzR3JcerasfgnA2%2BT%2FAMrYB%2F5V3Y%2BdtAvhefubrn%2FuNux1jkQUYkD7Ubnir%2F6uEq8D1rTFk9XUdNgaHix%2Bu2XVoHPcD%2FfbfstnQfyAeb%2FFktC%2FptaSF1VgFNGTiXFfiA%2BLj%2FlZC9WuNd8p6kNM1e04anYsY2mY7TW%2FZG2pKjfsS4K003mkCHzl5WmDLazercWoB9WCvX1FB%2FeQt9lv8nIofYNRl5FPI3njTfO2li7taRXkQUXlp3Rj0Zf5on%2FYbJXirs2bNirs2bNirs2bNirs2bNirs2bNirs2bNir%2F%2FW7%2FmzZsVdmzZsVdmzZsVdgHVY9PmtHi1JlW3cgEuQBUbr1wdgPUdNttTtzb3IJWoZSOoYdxirzHztP%2Bi20aTyvdm6uDcJSCMJIPTVhRWKj7Bbbi2B9b8keZrnV3FvberbsQsVwHUKFJ6tU8hSvhk%2B%2FwAPGy1GwvLOkqK5ju0cIP3YQ%2BnItAPiif8A4nkkphKQaQOk6eml6ba6fGQVt4whPif2j%2FwWO1LTbPVrGfTr%2BITWtyhSWMjqD%2FEfs4MzEVwIsg2Ni%2BVPOHlm58p65NpU1XhP72znP%2B7IWPwn%2FXX7En%2BVgW28s63f2kWr29m76Ys6xyXQpxUggNUfa4iv2uOen9c8t6J5it0t9as0uo4zyjLVDKf8l1oy5EL7TriGW30Lytp7Q6Dbs0d7xI4Oz%2FFWPlycmNvib%2BfKziufETs7WXahOn8Ph9dVIn6a7%2FewDzPd3ukNplzYtxtEhW2adVBKzRktTkalOdf%2BBw60bydZ%2BaNR%2FwARaPq0VjOIw509bcLIkw%2B16yh%2FjRm%2F3an28de6dLYTXGk6xDztpx8aHoyn7Lqfb9nI3YX%2BreQ9ThS3pcWhcvazMBWSE%2FbgaQ%2FF8P8AJlrrDvunvmryB9buFvzAtnrkQD84z%2B6mKHkGRtu%2F82HWnO%2BoadLpU5aC4ZeUL9Gil%2B0jKR0aOYZOLO80jzho0d3Zv6kMn2WFPUhlGxVh%2By6H7WQWaO80rV1hvwBMjcfUAoskTbLIP%2BNsIr5oSu10tfOt7Ikt4th5ijQC6hkSsdz6fwfWIiCCr7UmTj%2Fl5JG%2FKTSdTjg%2FxDILh4UCUgHD7P8Axafj45GPMdkYtRkvbWf6jewEXNhcr9ppT9pEVatJWnxJx%2BznRPIfmz%2FFujfW5Y%2FSvLZ%2Fq94gBCmQCvNQfiVX%2B1xb7OA2NleaX%2Fkr%2FA19Jb2rO%2BlXbc7UvuFbuvL%2Bb%2FiWC7M7HOuarpdrq9jLY3i8o5Bse6t2df8AKXOP6jbaj5dvpLK5USBd0fcB07Ov8cMT3qkP5l6trkWp2kNi8sVr6CShoyVDyH7RJHXj8OQpfNfmCN1%2BsXcsnBeCrOfUAUdFHP4uP052ny%2Fq2g6veR6T5hgX94Almsp%2Fdsw%2F3W%2F%2BU37GSHUfyp8n6hUpavZse8DkD%2FgH5p%2BGCXNeTwM%2BbzeWxtr%2B3SVHFGMZKMP8oBqr%2FwANh9qv5gpr3kVfLV9zk1O3uIjFOwrzt4w1GZhUeqn2P8rJD5i%2FJJrK2lvNKufrSx%2FEYCnCXiOtCpKPx%2F1M503lq7tpDxDNUUUGlPwyJtWQflfpMWseaFtLgssZtZnDJ1VhxCn3651e38qanp%2Bs2ZX95brKG%2BtR7UVfio6%2Fs16YS%2Fk3pGmWxvNR%2BspJqfEW7WnR4kryLFW3PqN%2FL%2FLnW8I2UsW8x%2BVo71n1LT0CXp3mjGwlp3%2F4yD%2Fhsgl9oyXUaxX1u8LoCY2dStV%2FaG%2Fgc7JTEbiztrr0zcRrIYmDxlhWjDJCXQoeVeW9Rv8Ay1PKL25kuNO9ELEo%2BIjgaoKk%2FAqJyzqtrdQXkCXNs3qQyqGjcdCCK7ZFPMPl1Yg95aLWA7zQjfjXqw%2FycB6JrNzY3BW7uAbARKgUqSQVIC8KfCq8K8vhxq9wlntK4DvtJ07UgBfW6TU6FhvTwqN8FRyRyoHiYOjCoZTUEHH5FDC9Y%2FL6wuSZ9Ic2M3X0tzEfo6p%2FscL9B%2FLy8XVJNS8y3Yuo41aKz0%2BEkQrGwoWlO3N2zomVTDZV4l5n8s3Plq94oS%2BnTk%2FVZj27%2Bk5%2FnX%2FhsMNI893Wj2ht2thNVSEp8PGSlBK%2F%2BSf286nqOnWmqWcllexiSGQbg9QezKf2WGco13yhdaVMUT95A39zL0DDwPg%2BIZc3pPlzU5dStGa4IaeNgGZaAFWHJWoMOc5v5E1B7Wf6tcAoD%2B5PLb3jP0fYzo4xIYrZIo5UaOVQ6MKMrCoIPtidrZ29lAttaoI4UrxQdBU1OL5sCsO8%2FwD5e6V5708RXNINQgB%2Bp3oFStf2JAKc4m%2F4XOIWX5R%2FmVoOpummwIySAxNMssZhZG2q3Mqen80eeoKZqYq8l8h%2Fk%2FceW9Qt9Z1DU3W4gPJLS0JCEGvwTytT1U3%2Bx6arnWs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F1%2B%2F5s2bFXZs2bFXZs2bFXZs2bFXUzZs2KuzZs2KoXUjILG49E0k4EKetK43TYkhsoQp5EqGZvEnvgp1DKVbdW2I9jhDdaDqT%2FuLLWJbOzP8AulEVnAPVVkb4hiqB8wWUXmS%2BXTYWQi3ikZphuUlqOKmn7P8ANnOtRsiPW0TWUKqD9ofajYfZkQ%2B3%2FDLnYtH0Wy0W3aC0BJc8pJHPJ2J8ThV5u8tJrdoZrdQL6EH0z0Lj%2BQ%2F8a4bTbxXQPMGq%2Fl9r7mSs9jcUN3Cv2Zo%2B1xD4Sp%2FzZnaNYhtfNmgRaho7JcMwE1pKCASP246%2Fsn%2BZf58gsugWWtaPFp1xRL21qFkFCyP3U96YR%2BUfMt7%2BX%2BqvpmqEtpUsnGeOtQjE0FxD%2FwAzUxOy%2B5kHmGCOa1s7%2BVeEsFYpHI3SvwyBvDi647RtH1by3qEXmPT5VlgnWmo2C1Amj6rIrH4RMnVcCz3FvJ5x1pIqX2h30cVy3ouv2nQEeka9XZW5ZJNPult7dbZpTLasP9HlYUalP7uVf2JlH2v%2BEw891ZzY3tvqNtHdWz84pBUHoQe6sP2WX9rC7zJoEOu2Xp7LdRVa3lPY90b%2FACHwi0IahBqtdOo9hKf9LjY0Vf8ALU%2F78ybZFD591jS3R3gnRo5Ymp4MjA9snHkr8weRi0LzJII7pQEtdQc0SYdFWQ%2Fsy%2F5X7eH%2FAJw8uLqMDX9qg%2BtRL%2B8Uf7sQf8bLnJbuyjcNFKnND1U%2Fw8Dh5pfQo3Gc487eVFhMmq2KfuHNbmNR%2Fdsf92KP5G%2Fa%2FlyPeXPM%2Fmfy2Y4pmk1PRqfBBKpNwiDr6E3%2B7OH8j51%2B1ubXU7JLiKklvcJWjDqrDdWH%2FEsV5PntoFiuUuQOFxFvHKpKsPpWnLJZ5b8w65p1xEguXuIp3q8d07P1%2FZVm%2Bx%2Fkccbr%2Bhm2125sbPggX95AZq8FRhy3p%2FL8Srk181aDHqempqtvRLu2hDngPheMDmV%2F2P2ozjsrKLW5ju4Eni%2By4rQ9Qe4OL5D%2FACp5hgu7iOwkkUXFxD6yx9DWM8HNMmGJFFDRFRQioPUHIhrmgrAXubdK2z19WOleFepH%2BRkwymCkUIqD1BxBpWIaNq09o31WURrZoiem32ePEheCIB8VV%2BLJcGB3BBHtka1LQXVne0XnC9eUQ%2B0tevHxXA2lxazHfW620rx2atW4gkSqFOPCgdvjDClVwkA7hWYZswzZFXYnNBFPG0UyCSNvtKwqDimbFWE6voE1hIbu0Be3BrQVLIP8rxXJRo92b3T4Z2%2B1Ti3zG1cGkAih3B7ZSRpGvCNQqjsooN8NquzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Dv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxViPmbyo91cfpvQiINVT%2B%2Bh6RXSD9iXwl%2F33N%2FwWQzW9AXXo%2FXaFg7L%2B%2BhK0mjdBuafzACjrnYcDTWNrPKk8kYMsZDI42NR40w3tRW3z1p2l6ho%2BotLAfXVE5OgDVljA%2BLj%2FxZGv7OS2BbeaRbscpI5YuLQq3ETIfiQcv2ZVP90%2F8AsMk3mi1FjqBnt0CpcIHIUU%2BNT8RFP5tuWRDTFEulwPaP9YjVSfVjBIFGPM%2F7BvHCOSXqXlu6trnTI1t7Y2Zj%2BGW1YhmQ%2BJcfb5fzYcZBPKl1I7GRXHKGi3AY%2FajPRvdsnQNd8BFFDjnL%2FPWhJaXguIKRw33KngklPi%2F2Pxcs6jkY892Ul3onqwoZJLWRZeAHIlT8D7fJsAVBaLpUeueS9PtriYPcWykQXkfZ4yVDD%2FJP2WwX5X1NJ2NrQIGXkoXpzQ8JP65GPJfmOTR5G0zXLmGCzlYmzhZPSeE05ceP7UTjfliOhagkWs3CW0gkUXbPZjoZVkY8kQHr8OSHUJZD540vmYtVRBIAvoTo260JrGzU7cvhzaJ5jgm0t9O1u7giu%2FRdY%2BJ48oyCg%2Fd9QyfZ%2FwArJhPBFcwvbzqHikBV0PQg9sgt%2FwCSLpJy9pxniPRiQsgH8rfzYB5ql%2Fkq1hXU4ZigNwjsizftemU3Uf5Jzp%2BRXyloF%2Fpj3FzqYiR3YraxREsyx%2FzTOaL6j%2Fyp8CZKsSUOzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Hv%2BbNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxV2bNmxVg35iPrMEFld6XbR3CRM%2Fro1fUIIHwx%2Fs4U%2FlrqOkz3c1lYQmENFJI8DCgRzIDIg5b1JavTOiajZLf2cls1KsKofBh9k5ydpJPL%2FmzT9ZcBIWY2t5sFoD8Ls5C1%2FwCDkyQ5KyjWdLGi6ml3brSyvKxuo6I58P8AJPVclOiXZurPi5rLAfTf5fsn7sE3drBqFq9vLR4pV2I7dwy%2B%2BF2j6Xf2F5dS3EqNbyhViVa8iV%2Fbfag6%2FZXBdj3KnWURXLzYFYV5n8n3us6ut7btEITGsbc6hl418B8WFd75Ym8svHqVqPrQiCsJSPiikH2jQfsNnScayhwVYBlOxB3BGG1Sby7rf6YgZ5KCZftIBSmHeFllodlp95LeWqlDMKGIfYB7kDDPE%2BSuzZs2BXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F%2F0u%2F5s2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZFfM%2BipLW%2BSJZAf71CtaMPsygf8SyVZRAIIO4PbCDW6pP5YvDd6Wiu1Zbc%2Bi%2B9Tt9mv%2Bxw5xG3tbe1Vlt41jDHkwUUqfE4tgPNXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFXZs2bFX%2F9Pv%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV9%2F5s8AZsVff%2BbPAGbFX3%2FmzwBmxV%2F%2FZ" ); background-position:center center; border:1px solid #00aa00; } .yui-skin-sam .yui-h-slider { background: url(bg-h.gif) no-repeat 5px 0; height: 28px; width: 228px; } yui-compressor-2.4.7/tests/concat-charset.css.min0000644000175000017500000000007611640627104021760 0ustar drazzibdrazzib@charset "utf-8";#foo{border-width:1px}#bar{border-width:10px}yui-compressor-2.4.7/tests/concat-charset.css0000644000175000017500000000054511640627104021177 0ustar drazzibdrazzib/* This is invalid CSS, but frequently happens as a result of concatenation. */ @charset "utf-8"; #foo { border-width:1px; } /* Note that this is erroneous! The actual CSS file can only have a single charset. However, this is the job of the author/application. The compressor should not get involved. */ @charset "another one"; #bar { border-width:10px; }yui-compressor-2.4.7/tests/comment.css.min0000644000175000017500000000003311640627104020515 0ustar drazzibdrazzibhtml>/**/body p{color:blue}yui-compressor-2.4.7/tests/comment.css0000644000175000017500000000005011640627104017732 0ustar drazzibdrazzibhtml >/**/ body p { color: blue; } yui-compressor-2.4.7/tests/color.css.min0000644000175000017500000000121411640627104020173 0ustar drazzibdrazzib.color{me:#7b7b7b;impressed:#fed;again:#abcdef;andagain:#a6c;background-color:#aa66ccc;filter:chroma(color="#FFFFFF");background:none repeat scroll 0 0 #f00;alpha:rgba(1,2,3,4);color:#12a}#AABBCC{background-color:#fe1;filter:chroma(color = #FFFFFF);color:#412;foo:#0f1 #ABC #abc #123344;border-color:#aa66ccC}.foo #AABBCC{background-color:#fe1;color:#412;border-color:#AbC;filter:chroma(color= #FFFFFF)}.bar,#AABBCC{background-color:#fe1;border-color:#0f1 #abcdef;filter:chroma(color=#11FFFFFF);color:#412}.foo,#AABBCC.foobar{background-color:#fe1;border-color:#0f1 #abcdef #abc;color:#412}@media screen{.bar,#AABBCC{background-color:#fe1;color:#412}} yui-compressor-2.4.7/tests/color.css0000644000175000017500000000154211640627104017415 0ustar drazzibdrazzib.color { me: rgb(123, 123, 123); impressed: #FfEedD; again: #ABCDEF; andagain:#aa66cc; background-color:#aa66ccc; filter: chroma(color="#FFFFFF"); background: none repeat scroll 0 0 rgb(255, 0,0); alpha: rgba(1, 2, 3, 4); color:#1122aa } #AABBCC { background-color:#ffee11; filter: chroma(color = #FFFFFF ); color:#441122; foo:#00fF11 #ABC #AABbCc #123344; border-color:#aa66ccC } .foo #AABBCC { background-color:#fFEe11; color:#441122; border-color:#AbC; filter: chroma(color= #FFFFFF) } .bar, #AABBCC { background-color:#FFee11; border-color:#00fF11 #ABCDEF; filter: chroma(color=#11FFFFFF); color:#441122; } .foo, #AABBCC.foobar { background-color:#ffee11; border-color:#00fF11 #ABCDEF #AABbCc; color:#441122; } @media screen { .bar, #AABBCC { background-color:#ffEE11; color:#441122 } } yui-compressor-2.4.7/tests/color-simple.css.min0000644000175000017500000000025611640627104021467 0ustar drazzibdrazzib.foo,#AABBCC{background-color:#abc;border-color:#e6a #abcdef #feab2c;filter:chroma(color = #FFFFFF);filter:chroma(color="#AABBCC");filter:chroma(color='#BBDDEE');color:#123} yui-compressor-2.4.7/tests/color-simple.css0000644000175000017500000000031411640627104020700 0ustar drazzibdrazzib.foo, #AABBCC { background-color:#aabbcc; border-color:#Ee66aA #ABCDEF #FeAb2C; filter:chroma(color = #FFFFFF ); filter:chroma(color="#AABBCC"); filter:chroma(color='#BBDDEE'); color:#112233 }yui-compressor-2.4.7/tests/charset-media.css.min0000644000175000017500000000007011640627104021562 0ustar drazzibdrazzib@charset 'utf-8';@media all{body{background-color:gold}}yui-compressor-2.4.7/tests/charset-media.css0000644000175000017500000000013411640627104021001 0ustar drazzibdrazzib/* re: 2495387 */ @charset 'utf-8'; @media all { body { } body { background-color: gold; } }yui-compressor-2.4.7/tests/bug2528034.css.min0000644000175000017500000000004711640627104020405 0ustar drazzibdrazziba[href$="/test/"] span:first-child{b:1}yui-compressor-2.4.7/tests/bug2528034.css0000644000175000017500000000012611640627104017621 0ustar drazzibdrazziba[href$="/test/"] span:first-child { b:1; } a[href$="/test/"] span:first-child { } yui-compressor-2.4.7/tests/bug2527998.css.min0000644000175000017500000000001611640627104020423 0ustar drazzibdrazzib/*! special */yui-compressor-2.4.7/tests/bug2527998.css0000644000175000017500000000003111640627104017636 0ustar drazzibdrazzib/*! special */ body { } yui-compressor-2.4.7/tests/bug2527991.css.min0000644000175000017500000000030511640627104020415 0ustar drazzibdrazzib@media screen and/*!YUI-Compresser */(-webkit-min-device-pixel-ratio:0){a{b:1}}@media screen and/*! *//*! */(-webkit-min-device-pixel-ratio:0){a{b:1}}@media -webkit-min-device-pixel-ratio:0{a{b:1}}yui-compressor-2.4.7/tests/bug2527991.css0000644000175000017500000000037111640627104017636 0ustar drazzibdrazzib@media screen and/*!YUI-Compresser */(-webkit-min-device-pixel-ratio:0) { a{ b: 1; } } @media screen and/*! */ /*! */(-webkit-min-device-pixel-ratio:0) { a{ b: 1; } } @media -webkit-min-device-pixel-ratio:0 { a{ b: 1; } }yui-compressor-2.4.7/tests/bug2527974.css.min0000644000175000017500000000021511640627104020416 0ustar drazzibdrazzib/*! $LastChangedRevision: 81 $ $LastChangedDate: 2009-05-27 17:41:02 +0100 (Wed, 27 May 2009) $ */body{yo:cats}ul[id$=foo] label:hover{yo:yo}yui-compressor-2.4.7/tests/bug2527974.css0000644000175000017500000000061111640627104017634 0ustar drazzibdrazzib/* this file contains no css, it exists purely to put the revision number into the combined css before uploading it to SiteManager. The exclaimation at the start of the comment informs yuicompressor not to strip the comment out */ /*! $LastChangedRevision: 81 $ $LastChangedDate: 2009-05-27 17:41:02 +0100 (Wed, 27 May 2009) $ */ body { yo: cats; } ul[id$=foo] label:hover {yo: yo;}yui-compressor-2.4.7/tests/box-model-hack.css.min0000644000175000017500000000014411640627104021650 0ustar drazzibdrazzib#elem{width:100px;voice-family:"\"}\"";voice-family:inherit;width:200px}html>body #elem{width:200px}yui-compressor-2.4.7/tests/box-model-hack.css0000644000175000017500000000017611640627104021073 0ustar drazzibdrazzib#elem { width: 100px; voice-family: "\"}\""; voice-family:inherit; width: 200px; } html>body #elem { width: 200px; } yui-compressor-2.4.7/tests/border-none.css.min0000644000175000017500000000005111640627104021265 0ustar drazzibdrazziba{border:0}b{background:0}s{border-top:0}yui-compressor-2.4.7/tests/border-none.css0000644000175000017500000000010111640627104020477 0ustar drazzibdrazziba { border: none; } b {BACKGROUND:none} s {border-top: none;}yui-compressor-2.4.7/tests/background-position.css.min0000644000175000017500000000006411640627104023040 0ustar drazzibdrazziba{background-position:0 0}b{background-position:0 0}yui-compressor-2.4.7/tests/background-position.css0000644000175000017500000000007711640627104022262 0ustar drazzibdrazziba {background-position: 0 0 0 0;} b {BACKGROUND-POSITION: 0 0;}yui-compressor-2.4.7/tests/_syntax_error.js.min0000644000175000017500000000213211640627104021577 0ustar drazzibdrazzibwindow.$=$telerik.$;$(document).ready(function(){movePageElements();var a=$("textarea").val();if(a!=""){$("textarea").attr("style","display: block;")}else{$("textarea").attr("style","display: none;")}a=null});function movePageElements(){var e=null;var b=$(".pagecontrolscontainer");if(b.length>0){var e=b.attr("pagenumber");if((e>5)&&(e<28)){var a=$("div#commentbutton");$("div.buttonContainer").prepend(a)}else{$("div#commentbutton").attr("style","display: none;")}}if((e>5)&&(e<28)){var f=$(".dropshadow-top");var d=$("#dropshadow");var c=$(".dropshadow-bottom");$("#page").prepend(f);$("#topcontainer").after(d);d.append($("#topcontainer"));d.after(c)}e=null;b=null;f=null;d=null;c=null}function expandCollapseDiv(a){$telerik.$(a).slideToggle("slow")}function expandCollapseHelp(){$(".helpitems").slideToggle("slow");if($("#helpcontainer").length){$("#help-dropshadow-bot").insertAfter("#helpcontainer");$("#help-dropshadow-bot").removeAttr("style")}}function expandCollapseComments(){var a=$("textarea").attr("style");if(a=="display: none;"){$("textarea").fadeIn().focus()}else{$("textarea").fadeOut()}a=null};yui-compressor-2.4.7/tests/_syntax_error.js0000644000175000017500000000263511640627104021025 0ustar drazzibdrazzib window.$ = $telerik.$; $(document).ready(function() { movePageElements(); var text = $('textarea').val(); if (text != "") $('textarea').attr("style", "display: block;"); else $('textarea').attr("style", "display: none;"); //cleanup text = null; }); function movePageElements() { var num = null; var pagenum = $(".pagecontrolscontainer"); if (pagenum.length > 0) { var num = pagenum.attr("pagenumber"); if ((num > 5) && (num < 28)) { var x = $('div#commentbutton'); $("div.buttonContainer").prepend(x); } else { $('div#commentbutton').attr("style", "display: none;"); } } //Add in dropshadowing if ((num > 5) && (num < 28)) { var top = $('.dropshadow-top'); var middle = $('#dropshadow'); var bottom = $('.dropshadow-bottom'); $('#page').prepend(top); $('#topcontainer').after(middle); middle.append($('#topcontainer')); middle.after(bottom); } //cleanup num = null; pagenum = null; top = null; middle = null; bottom=null; } function expandCollapseDiv(id) { $telerik.$(id).slideToggle("slow"); } function expandCollapseHelp() { $('.helpitems').slideToggle("slow"); //Add in dropshadowing if ($('#helpcontainer').length) { $('#help-dropshadow-bot').insertAfter('#helpcontainer'); $('#help-dropshadow-bot').removeAttr("style"); } } function expandCollapseComments() { var style = $('textarea').attr("style"); if (style == "display: none;") $('textarea').fadeIn().focus(); else $('textarea').fadeOut(); //cleanup style = null; } yui-compressor-2.4.7/tests/_string_combo.js.min0000644000175000017500000000003511640627104021525 0ustar drazzibdrazzibfunction test(){var b="abc"};yui-compressor-2.4.7/tests/_string_combo.js0000644000175000017500000000007011640627104020742 0ustar drazzibdrazzibfunction test(){ var a = "a" + "b" + "c"; } yui-compressor-2.4.7/tests/_munge.js.min0000644000175000017500000000011111640627104020146 0ustar drazzibdrazzib(function(){var a=window;a.hello=function(a,b){a.alert("Hello, "+a)}})();yui-compressor-2.4.7/tests/_munge.js0000644000175000017500000000020611640627104017371 0ustar drazzibdrazzib(function() { var w = window; w.hello = function(a, abc) { "a:nomunge"; w.alert("Hello, " + a); }; })(); yui-compressor-2.4.7/tests/README0000644000175000017500000000024111640627104016440 0ustar drazzibdrazzibTo add a test: 1. Create a "blah.css" or "blah.js" file. 2. Create a "blah.css.min" or "blah.js.min" file, containing the expected minified output. That's all!yui-compressor-2.4.7/src/0000755000175000017500000000000011640627104015210 5ustar drazzibdrazzibyui-compressor-2.4.7/src/org/0000755000175000017500000000000011640627104015777 5ustar drazzibdrazzibyui-compressor-2.4.7/src/org/mozilla/0000755000175000017500000000000011753547210017452 5ustar drazzibdrazzibyui-compressor-2.4.7/src/org/mozilla/classfile/0000755000175000017500000000000011753547210021417 5ustar drazzibdrazzibyui-compressor-2.4.7/src/org/mozilla/classfile/ByteCode.java0000644000175000017500000001560311753547210023765 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Roger Lawrence * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.classfile; /** * This class provides opcode values expected by the JVM in Java class files. * * It also provides tables for internal use by the ClassFileWriter. * * @author Roger Lawrence */ public class ByteCode { /** * The byte opcodes defined by the Java Virtual Machine. */ public static final int NOP = 0x00, ACONST_NULL = 0x01, ICONST_M1 = 0x02, ICONST_0 = 0x03, ICONST_1 = 0x04, ICONST_2 = 0x05, ICONST_3 = 0x06, ICONST_4 = 0x07, ICONST_5 = 0x08, LCONST_0 = 0x09, LCONST_1 = 0x0A, FCONST_0 = 0x0B, FCONST_1 = 0x0C, FCONST_2 = 0x0D, DCONST_0 = 0x0E, DCONST_1 = 0x0F, BIPUSH = 0x10, SIPUSH = 0x11, LDC = 0x12, LDC_W = 0x13, LDC2_W = 0x14, ILOAD = 0x15, LLOAD = 0x16, FLOAD = 0x17, DLOAD = 0x18, ALOAD = 0x19, ILOAD_0 = 0x1A, ILOAD_1 = 0x1B, ILOAD_2 = 0x1C, ILOAD_3 = 0x1D, LLOAD_0 = 0x1E, LLOAD_1 = 0x1F, LLOAD_2 = 0x20, LLOAD_3 = 0x21, FLOAD_0 = 0x22, FLOAD_1 = 0x23, FLOAD_2 = 0x24, FLOAD_3 = 0x25, DLOAD_0 = 0x26, DLOAD_1 = 0x27, DLOAD_2 = 0x28, DLOAD_3 = 0x29, ALOAD_0 = 0x2A, ALOAD_1 = 0x2B, ALOAD_2 = 0x2C, ALOAD_3 = 0x2D, IALOAD = 0x2E, LALOAD = 0x2F, FALOAD = 0x30, DALOAD = 0x31, AALOAD = 0x32, BALOAD = 0x33, CALOAD = 0x34, SALOAD = 0x35, ISTORE = 0x36, LSTORE = 0x37, FSTORE = 0x38, DSTORE = 0x39, ASTORE = 0x3A, ISTORE_0 = 0x3B, ISTORE_1 = 0x3C, ISTORE_2 = 0x3D, ISTORE_3 = 0x3E, LSTORE_0 = 0x3F, LSTORE_1 = 0x40, LSTORE_2 = 0x41, LSTORE_3 = 0x42, FSTORE_0 = 0x43, FSTORE_1 = 0x44, FSTORE_2 = 0x45, FSTORE_3 = 0x46, DSTORE_0 = 0x47, DSTORE_1 = 0x48, DSTORE_2 = 0x49, DSTORE_3 = 0x4A, ASTORE_0 = 0x4B, ASTORE_1 = 0x4C, ASTORE_2 = 0x4D, ASTORE_3 = 0x4E, IASTORE = 0x4F, LASTORE = 0x50, FASTORE = 0x51, DASTORE = 0x52, AASTORE = 0x53, BASTORE = 0x54, CASTORE = 0x55, SASTORE = 0x56, POP = 0x57, POP2 = 0x58, DUP = 0x59, DUP_X1 = 0x5A, DUP_X2 = 0x5B, DUP2 = 0x5C, DUP2_X1 = 0x5D, DUP2_X2 = 0x5E, SWAP = 0x5F, IADD = 0x60, LADD = 0x61, FADD = 0x62, DADD = 0x63, ISUB = 0x64, LSUB = 0x65, FSUB = 0x66, DSUB = 0x67, IMUL = 0x68, LMUL = 0x69, FMUL = 0x6A, DMUL = 0x6B, IDIV = 0x6C, LDIV = 0x6D, FDIV = 0x6E, DDIV = 0x6F, IREM = 0x70, LREM = 0x71, FREM = 0x72, DREM = 0x73, INEG = 0x74, LNEG = 0x75, FNEG = 0x76, DNEG = 0x77, ISHL = 0x78, LSHL = 0x79, ISHR = 0x7A, LSHR = 0x7B, IUSHR = 0x7C, LUSHR = 0x7D, IAND = 0x7E, LAND = 0x7F, IOR = 0x80, LOR = 0x81, IXOR = 0x82, LXOR = 0x83, IINC = 0x84, I2L = 0x85, I2F = 0x86, I2D = 0x87, L2I = 0x88, L2F = 0x89, L2D = 0x8A, F2I = 0x8B, F2L = 0x8C, F2D = 0x8D, D2I = 0x8E, D2L = 0x8F, D2F = 0x90, I2B = 0x91, I2C = 0x92, I2S = 0x93, LCMP = 0x94, FCMPL = 0x95, FCMPG = 0x96, DCMPL = 0x97, DCMPG = 0x98, IFEQ = 0x99, IFNE = 0x9A, IFLT = 0x9B, IFGE = 0x9C, IFGT = 0x9D, IFLE = 0x9E, IF_ICMPEQ = 0x9F, IF_ICMPNE = 0xA0, IF_ICMPLT = 0xA1, IF_ICMPGE = 0xA2, IF_ICMPGT = 0xA3, IF_ICMPLE = 0xA4, IF_ACMPEQ = 0xA5, IF_ACMPNE = 0xA6, GOTO = 0xA7, JSR = 0xA8, RET = 0xA9, TABLESWITCH = 0xAA, LOOKUPSWITCH = 0xAB, IRETURN = 0xAC, LRETURN = 0xAD, FRETURN = 0xAE, DRETURN = 0xAF, ARETURN = 0xB0, RETURN = 0xB1, GETSTATIC = 0xB2, PUTSTATIC = 0xB3, GETFIELD = 0xB4, PUTFIELD = 0xB5, INVOKEVIRTUAL = 0xB6, INVOKESPECIAL = 0xB7, INVOKESTATIC = 0xB8, INVOKEINTERFACE = 0xB9, NEW = 0xBB, NEWARRAY = 0xBC, ANEWARRAY = 0xBD, ARRAYLENGTH = 0xBE, ATHROW = 0xBF, CHECKCAST = 0xC0, INSTANCEOF = 0xC1, MONITORENTER = 0xC2, MONITOREXIT = 0xC3, WIDE = 0xC4, MULTIANEWARRAY = 0xC5, IFNULL = 0xC6, IFNONNULL = 0xC7, GOTO_W = 0xC8, JSR_W = 0xC9, BREAKPOINT = 0xCA, IMPDEP1 = 0xFE, IMPDEP2 = 0xFF; /** * Types for the NEWARRAY opcode. */ public static final byte T_BOOLEAN = 4, T_CHAR = 5, T_FLOAT = 6, T_DOUBLE = 7, T_BYTE = 8, T_SHORT = 9, T_INT = 10, T_LONG = 11; } yui-compressor-2.4.7/src/org/mozilla/classfile/ClassFileWriter.java0000644000175000017500000032663111753547210025337 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Roger Lawrence * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.classfile; import org.mozilla.javascript.ObjToIntMap; import org.mozilla.javascript.ObjArray; import org.mozilla.javascript.UintMap; import java.io.*; /** * ClassFileWriter * * A ClassFileWriter is used to write a Java class file. Methods are * provided to create fields and methods, and within methods to write * Java bytecodes. * * @author Roger Lawrence */ public class ClassFileWriter { /** * Thrown for cases where the error in generating the class file is * due to a program size constraints rather than a likely bug in the * compiler. */ public static class ClassFileFormatException extends RuntimeException { private static final long serialVersionUID = 1263998431033790599L; ClassFileFormatException(String message) { super(message); } } /** * Construct a ClassFileWriter for a class. * * @param className the name of the class to write, including * full package qualification. * @param superClassName the name of the superclass of the class * to write, including full package qualification. * @param sourceFileName the name of the source file to use for * producing debug information, or null if debug information * is not desired */ public ClassFileWriter(String className, String superClassName, String sourceFileName) { generatedClassName = className; itsConstantPool = new ConstantPool(this); itsThisClassIndex = itsConstantPool.addClass(className); itsSuperClassIndex = itsConstantPool.addClass(superClassName); if (sourceFileName != null) itsSourceFileNameIndex = itsConstantPool.addUtf8(sourceFileName); itsFlags = ACC_PUBLIC; } public final String getClassName() { return generatedClassName; } /** * Add an interface implemented by this class. * * This method may be called multiple times for classes that * implement multiple interfaces. * * @param interfaceName a name of an interface implemented * by the class being written, including full package * qualification. */ public void addInterface(String interfaceName) { short interfaceIndex = itsConstantPool.addClass(interfaceName); itsInterfaces.add(new Short(interfaceIndex)); } public static final short ACC_PUBLIC = 0x0001, ACC_PRIVATE = 0x0002, ACC_PROTECTED = 0x0004, ACC_STATIC = 0x0008, ACC_FINAL = 0x0010, ACC_SYNCHRONIZED = 0x0020, ACC_VOLATILE = 0x0040, ACC_TRANSIENT = 0x0080, ACC_NATIVE = 0x0100, ACC_ABSTRACT = 0x0400; /** * Set the class's flags. * * Flags must be a set of the following flags, bitwise or'd * together: * ACC_PUBLIC * ACC_PRIVATE * ACC_PROTECTED * ACC_FINAL * ACC_ABSTRACT * TODO: check that this is the appropriate set * @param flags the set of class flags to set */ public void setFlags(short flags) { itsFlags = flags; } static String getSlashedForm(String name) { return name.replace('.', '/'); } /** * Convert Java class name in dot notation into * "Lname-with-dots-replaced-by-slashes;" form suitable for use as * JVM type signatures. */ public static String classNameToSignature(String name) { int nameLength = name.length(); int colonPos = 1 + nameLength; char[] buf = new char[colonPos + 1]; buf[0] = 'L'; buf[colonPos] = ';'; name.getChars(0, nameLength, buf, 1); for (int i = 1; i != colonPos; ++i) { if (buf[i] == '.') { buf[i] = '/'; } } return new String(buf, 0, colonPos + 1); } /** * Add a field to the class. * * @param fieldName the name of the field * @param type the type of the field using ... * @param flags the attributes of the field, such as ACC_PUBLIC, etc. * bitwise or'd together */ public void addField(String fieldName, String type, short flags) { short fieldNameIndex = itsConstantPool.addUtf8(fieldName); short typeIndex = itsConstantPool.addUtf8(type); itsFields.add(new ClassFileField(fieldNameIndex, typeIndex, flags)); } /** * Add a field to the class. * * @param fieldName the name of the field * @param type the type of the field using ... * @param flags the attributes of the field, such as ACC_PUBLIC, etc. * bitwise or'd together * @param value an initial integral value */ public void addField(String fieldName, String type, short flags, int value) { short fieldNameIndex = itsConstantPool.addUtf8(fieldName); short typeIndex = itsConstantPool.addUtf8(type); ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex, flags); field.setAttributes(itsConstantPool.addUtf8("ConstantValue"), (short)0, (short)0, itsConstantPool.addConstant(value)); itsFields.add(field); } /** * Add a field to the class. * * @param fieldName the name of the field * @param type the type of the field using ... * @param flags the attributes of the field, such as ACC_PUBLIC, etc. * bitwise or'd together * @param value an initial long value */ public void addField(String fieldName, String type, short flags, long value) { short fieldNameIndex = itsConstantPool.addUtf8(fieldName); short typeIndex = itsConstantPool.addUtf8(type); ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex, flags); field.setAttributes(itsConstantPool.addUtf8("ConstantValue"), (short)0, (short)2, itsConstantPool.addConstant(value)); itsFields.add(field); } /** * Add a field to the class. * * @param fieldName the name of the field * @param type the type of the field using ... * @param flags the attributes of the field, such as ACC_PUBLIC, etc. * bitwise or'd together * @param value an initial double value */ public void addField(String fieldName, String type, short flags, double value) { short fieldNameIndex = itsConstantPool.addUtf8(fieldName); short typeIndex = itsConstantPool.addUtf8(type); ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex, flags); field.setAttributes(itsConstantPool.addUtf8("ConstantValue"), (short)0, (short)2, itsConstantPool.addConstant(value)); itsFields.add(field); } /** * Add Information about java variable to use when generating the local * variable table. * * @param name variable name. * @param type variable type as bytecode descriptor string. * @param startPC the starting bytecode PC where this variable is live, * or -1 if it does not have a Java register. * @param register the Java register number of variable * or -1 if it does not have a Java register. */ public void addVariableDescriptor(String name, String type, int startPC, int register) { int nameIndex = itsConstantPool.addUtf8(name); int descriptorIndex = itsConstantPool.addUtf8(type); int [] chunk = { nameIndex, descriptorIndex, startPC, register }; if (itsVarDescriptors == null) { itsVarDescriptors = new ObjArray(); } itsVarDescriptors.add(chunk); } /** * Add a method and begin adding code. * * This method must be called before other methods for adding code, * exception tables, etc. can be invoked. * * @param methodName the name of the method * @param type a string representing the type * @param flags the attributes of the field, such as ACC_PUBLIC, etc. * bitwise or'd together */ public void startMethod(String methodName, String type, short flags) { short methodNameIndex = itsConstantPool.addUtf8(methodName); short typeIndex = itsConstantPool.addUtf8(type); itsCurrentMethod = new ClassFileMethod(methodNameIndex, typeIndex, flags); itsMethods.add(itsCurrentMethod); } /** * Complete generation of the method. * * After this method is called, no more code can be added to the * method begun with startMethod. * * @param maxLocals the maximum number of local variable slots * (a.k.a. Java registers) used by the method */ public void stopMethod(short maxLocals) { if (itsCurrentMethod == null) throw new IllegalStateException("No method to stop"); fixLabelGotos(); itsMaxLocals = maxLocals; int lineNumberTableLength = 0; if (itsLineNumberTable != null) { // 6 bytes for the attribute header // 2 bytes for the line number count // 4 bytes for each entry lineNumberTableLength = 6 + 2 + (itsLineNumberTableTop * 4); } int variableTableLength = 0; if (itsVarDescriptors != null) { // 6 bytes for the attribute header // 2 bytes for the variable count // 10 bytes for each entry variableTableLength = 6 + 2 + (itsVarDescriptors.size() * 10); } int attrLength = 2 + // attribute_name_index 4 + // attribute_length 2 + // max_stack 2 + // max_locals 4 + // code_length itsCodeBufferTop + 2 + // exception_table_length (itsExceptionTableTop * 8) + 2 + // attributes_count lineNumberTableLength + variableTableLength; if (attrLength > 65536) { // See http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html, // section 4.10, "The amount of code per non-native, non-abstract // method is limited to 65536 bytes... throw new ClassFileFormatException( "generated bytecode for method exceeds 64K limit."); } byte[] codeAttribute = new byte[attrLength]; int index = 0; int codeAttrIndex = itsConstantPool.addUtf8("Code"); index = putInt16(codeAttrIndex, codeAttribute, index); attrLength -= 6; // discount the attribute header index = putInt32(attrLength, codeAttribute, index); index = putInt16(itsMaxStack, codeAttribute, index); index = putInt16(itsMaxLocals, codeAttribute, index); index = putInt32(itsCodeBufferTop, codeAttribute, index); System.arraycopy(itsCodeBuffer, 0, codeAttribute, index, itsCodeBufferTop); index += itsCodeBufferTop; if (itsExceptionTableTop > 0) { index = putInt16(itsExceptionTableTop, codeAttribute, index); for (int i = 0; i < itsExceptionTableTop; i++) { ExceptionTableEntry ete = itsExceptionTable[i]; short startPC = (short)getLabelPC(ete.itsStartLabel); short endPC = (short)getLabelPC(ete.itsEndLabel); short handlerPC = (short)getLabelPC(ete.itsHandlerLabel); short catchType = ete.itsCatchType; if (startPC == -1) throw new IllegalStateException("start label not defined"); if (endPC == -1) throw new IllegalStateException("end label not defined"); if (handlerPC == -1) throw new IllegalStateException( "handler label not defined"); index = putInt16(startPC, codeAttribute, index); index = putInt16(endPC, codeAttribute, index); index = putInt16(handlerPC, codeAttribute, index); index = putInt16(catchType, codeAttribute, index); } } else { // write 0 as exception table length index = putInt16(0, codeAttribute, index); } int attributeCount = 0; if (itsLineNumberTable != null) attributeCount++; if (itsVarDescriptors != null) attributeCount++; index = putInt16(attributeCount, codeAttribute, index); if (itsLineNumberTable != null) { int lineNumberTableAttrIndex = itsConstantPool.addUtf8("LineNumberTable"); index = putInt16(lineNumberTableAttrIndex, codeAttribute, index); int tableAttrLength = 2 + (itsLineNumberTableTop * 4); index = putInt32(tableAttrLength, codeAttribute, index); index = putInt16(itsLineNumberTableTop, codeAttribute, index); for (int i = 0; i < itsLineNumberTableTop; i++) { index = putInt32(itsLineNumberTable[i], codeAttribute, index); } } if (itsVarDescriptors != null) { int variableTableAttrIndex = itsConstantPool.addUtf8("LocalVariableTable"); index = putInt16(variableTableAttrIndex, codeAttribute, index); int varCount = itsVarDescriptors.size(); int tableAttrLength = 2 + (varCount * 10); index = putInt32(tableAttrLength, codeAttribute, index); index = putInt16(varCount, codeAttribute, index); for (int i = 0; i < varCount; i++) { int[] chunk = (int[])itsVarDescriptors.get(i); int nameIndex = chunk[0]; int descriptorIndex = chunk[1]; int startPC = chunk[2]; int register = chunk[3]; int length = itsCodeBufferTop - startPC; index = putInt16(startPC, codeAttribute, index); index = putInt16(length, codeAttribute, index); index = putInt16(nameIndex, codeAttribute, index); index = putInt16(descriptorIndex, codeAttribute, index); index = putInt16(register, codeAttribute, index); } } itsCurrentMethod.setCodeAttribute(codeAttribute); itsExceptionTable = null; itsExceptionTableTop = 0; itsLineNumberTableTop = 0; itsCodeBufferTop = 0; itsCurrentMethod = null; itsMaxStack = 0; itsStackTop = 0; itsLabelTableTop = 0; itsFixupTableTop = 0; itsVarDescriptors = null; } /** * Add the single-byte opcode to the current method. * * @param theOpCode the opcode of the bytecode */ public void add(int theOpCode) { if (opcodeCount(theOpCode) != 0) throw new IllegalArgumentException("Unexpected operands"); int newStack = itsStackTop + stackChange(theOpCode); if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); if (DEBUGCODE) System.out.println("Add " + bytecodeStr(theOpCode)); addToCodeBuffer(theOpCode); itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } /** * Add a single-operand opcode to the current method. * * @param theOpCode the opcode of the bytecode * @param theOperand the operand of the bytecode */ public void add(int theOpCode, int theOperand) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(theOpCode) +", "+Integer.toHexString(theOperand)); } int newStack = itsStackTop + stackChange(theOpCode); if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); switch (theOpCode) { case ByteCode.GOTO : // fallthru... case ByteCode.IFEQ : case ByteCode.IFNE : case ByteCode.IFLT : case ByteCode.IFGE : case ByteCode.IFGT : case ByteCode.IFLE : case ByteCode.IF_ICMPEQ : case ByteCode.IF_ICMPNE : case ByteCode.IF_ICMPLT : case ByteCode.IF_ICMPGE : case ByteCode.IF_ICMPGT : case ByteCode.IF_ICMPLE : case ByteCode.IF_ACMPEQ : case ByteCode.IF_ACMPNE : case ByteCode.JSR : case ByteCode.IFNULL : case ByteCode.IFNONNULL : { if ((theOperand & 0x80000000) != 0x80000000) { if ((theOperand < 0) || (theOperand > 65535)) throw new IllegalArgumentException( "Bad label for branch"); } int branchPC = itsCodeBufferTop; addToCodeBuffer(theOpCode); if ((theOperand & 0x80000000) != 0x80000000) { // hard displacement addToCodeInt16(theOperand); } else { // a label int targetPC = getLabelPC(theOperand); if (DEBUGLABELS) { int theLabel = theOperand & 0x7FFFFFFF; System.out.println("Fixing branch to " + theLabel + " at " + targetPC + " from " + branchPC); } if (targetPC != -1) { int offset = targetPC - branchPC; addToCodeInt16(offset); } else { addLabelFixup(theOperand, branchPC + 1); addToCodeInt16(0); } } } break; case ByteCode.BIPUSH : if ((byte)theOperand != theOperand) throw new IllegalArgumentException("out of range byte"); addToCodeBuffer(theOpCode); addToCodeBuffer((byte)theOperand); break; case ByteCode.SIPUSH : if ((short)theOperand != theOperand) throw new IllegalArgumentException("out of range short"); addToCodeBuffer(theOpCode); addToCodeInt16(theOperand); break; case ByteCode.NEWARRAY : if (!(0 <= theOperand && theOperand < 256)) throw new IllegalArgumentException("out of range index"); addToCodeBuffer(theOpCode); addToCodeBuffer(theOperand); break; case ByteCode.GETFIELD : case ByteCode.PUTFIELD : if (!(0 <= theOperand && theOperand < 65536)) throw new IllegalArgumentException("out of range field"); addToCodeBuffer(theOpCode); addToCodeInt16(theOperand); break; case ByteCode.LDC : case ByteCode.LDC_W : case ByteCode.LDC2_W : if (!(0 <= theOperand && theOperand < 65536)) throw new IllegalArgumentException("out of range index"); if (theOperand >= 256 || theOpCode == ByteCode.LDC_W || theOpCode == ByteCode.LDC2_W) { if (theOpCode == ByteCode.LDC) { addToCodeBuffer(ByteCode.LDC_W); } else { addToCodeBuffer(theOpCode); } addToCodeInt16(theOperand); } else { addToCodeBuffer(theOpCode); addToCodeBuffer(theOperand); } break; case ByteCode.RET : case ByteCode.ILOAD : case ByteCode.LLOAD : case ByteCode.FLOAD : case ByteCode.DLOAD : case ByteCode.ALOAD : case ByteCode.ISTORE : case ByteCode.LSTORE : case ByteCode.FSTORE : case ByteCode.DSTORE : case ByteCode.ASTORE : if (!(0 <= theOperand && theOperand < 65536)) throw new ClassFileFormatException("out of range variable"); if (theOperand >= 256) { addToCodeBuffer(ByteCode.WIDE); addToCodeBuffer(theOpCode); addToCodeInt16(theOperand); } else { addToCodeBuffer(theOpCode); addToCodeBuffer(theOperand); } break; default : throw new IllegalArgumentException( "Unexpected opcode for 1 operand"); } itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } /** * Generate the load constant bytecode for the given integer. * * @param k the constant */ public void addLoadConstant(int k) { switch (k) { case 0: add(ByteCode.ICONST_0); break; case 1: add(ByteCode.ICONST_1); break; case 2: add(ByteCode.ICONST_2); break; case 3: add(ByteCode.ICONST_3); break; case 4: add(ByteCode.ICONST_4); break; case 5: add(ByteCode.ICONST_5); break; default: add(ByteCode.LDC, itsConstantPool.addConstant(k)); break; } } /** * Generate the load constant bytecode for the given long. * * @param k the constant */ public void addLoadConstant(long k) { add(ByteCode.LDC2_W, itsConstantPool.addConstant(k)); } /** * Generate the load constant bytecode for the given float. * * @param k the constant */ public void addLoadConstant(float k) { add(ByteCode.LDC, itsConstantPool.addConstant(k)); } /** * Generate the load constant bytecode for the given double. * * @param k the constant */ public void addLoadConstant(double k) { add(ByteCode.LDC2_W, itsConstantPool.addConstant(k)); } /** * Generate the load constant bytecode for the given string. * * @param k the constant */ public void addLoadConstant(String k) { add(ByteCode.LDC, itsConstantPool.addConstant(k)); } /** * Add the given two-operand bytecode to the current method. * * @param theOpCode the opcode of the bytecode * @param theOperand1 the first operand of the bytecode * @param theOperand2 the second operand of the bytecode */ public void add(int theOpCode, int theOperand1, int theOperand2) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(theOpCode) +", "+Integer.toHexString(theOperand1) +", "+Integer.toHexString(theOperand2)); } int newStack = itsStackTop + stackChange(theOpCode); if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); if (theOpCode == ByteCode.IINC) { if (!(0 <= theOperand1 && theOperand1 < 65536)) throw new ClassFileFormatException("out of range variable"); if (!(0 <= theOperand2 && theOperand2 < 65536)) throw new ClassFileFormatException("out of range increment"); if (theOperand1 > 255 || theOperand2 < -128 || theOperand2 > 127) { addToCodeBuffer(ByteCode.WIDE); addToCodeBuffer(ByteCode.IINC); addToCodeInt16(theOperand1); addToCodeInt16(theOperand2); } else { addToCodeBuffer(ByteCode.WIDE); addToCodeBuffer(ByteCode.IINC); addToCodeBuffer(theOperand1); addToCodeBuffer(theOperand2); } } else if (theOpCode == ByteCode.MULTIANEWARRAY) { if (!(0 <= theOperand1 && theOperand1 < 65536)) throw new IllegalArgumentException("out of range index"); if (!(0 <= theOperand2 && theOperand2 < 256)) throw new IllegalArgumentException("out of range dimensions"); addToCodeBuffer(ByteCode.MULTIANEWARRAY); addToCodeInt16(theOperand1); addToCodeBuffer(theOperand2); } else { throw new IllegalArgumentException( "Unexpected opcode for 2 operands"); } itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } public void add(int theOpCode, String className) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(theOpCode) +", "+className); } int newStack = itsStackTop + stackChange(theOpCode); if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); switch (theOpCode) { case ByteCode.NEW : case ByteCode.ANEWARRAY : case ByteCode.CHECKCAST : case ByteCode.INSTANCEOF : { short classIndex = itsConstantPool.addClass(className); addToCodeBuffer(theOpCode); addToCodeInt16(classIndex); } break; default : throw new IllegalArgumentException( "bad opcode for class reference"); } itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } public void add(int theOpCode, String className, String fieldName, String fieldType) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(theOpCode) +", "+className+", "+fieldName+", "+fieldType); } int newStack = itsStackTop + stackChange(theOpCode); char fieldTypeChar = fieldType.charAt(0); int fieldSize = (fieldTypeChar == 'J' || fieldTypeChar == 'D') ? 2 : 1; switch (theOpCode) { case ByteCode.GETFIELD : case ByteCode.GETSTATIC : newStack += fieldSize; break; case ByteCode.PUTSTATIC : case ByteCode.PUTFIELD : newStack -= fieldSize; break; default : throw new IllegalArgumentException( "bad opcode for field reference"); } if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); short fieldRefIndex = itsConstantPool.addFieldRef(className, fieldName, fieldType); addToCodeBuffer(theOpCode); addToCodeInt16(fieldRefIndex); itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } public void addInvoke(int theOpCode, String className, String methodName, String methodType) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(theOpCode) +", "+className+", "+methodName+", " +methodType); } int parameterInfo = sizeOfParameters(methodType); int parameterCount = parameterInfo >>> 16; int stackDiff = (short)parameterInfo; int newStack = itsStackTop + stackDiff; newStack += stackChange(theOpCode); // adjusts for 'this' if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); switch (theOpCode) { case ByteCode.INVOKEVIRTUAL : case ByteCode.INVOKESPECIAL : case ByteCode.INVOKESTATIC : case ByteCode.INVOKEINTERFACE : { addToCodeBuffer(theOpCode); if (theOpCode == ByteCode.INVOKEINTERFACE) { short ifMethodRefIndex = itsConstantPool.addInterfaceMethodRef( className, methodName, methodType); addToCodeInt16(ifMethodRefIndex); addToCodeBuffer(parameterCount + 1); addToCodeBuffer(0); } else { short methodRefIndex = itsConstantPool.addMethodRef( className, methodName, methodType); addToCodeInt16(methodRefIndex); } } break; default : throw new IllegalArgumentException( "bad opcode for method reference"); } itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } /** * Generate code to load the given integer on stack. * * @param k the constant */ public void addPush(int k) { if ((byte)k == k) { if (k == -1) { add(ByteCode.ICONST_M1); } else if (0 <= k && k <= 5) { add((byte)(ByteCode.ICONST_0 + k)); } else { add(ByteCode.BIPUSH, (byte)k); } } else if ((short)k == k) { add(ByteCode.SIPUSH, (short)k); } else { addLoadConstant(k); } } public void addPush(boolean k) { add(k ? ByteCode.ICONST_1 : ByteCode.ICONST_0); } /** * Generate code to load the given long on stack. * * @param k the constant */ public void addPush(long k) { int ik = (int)k; if (ik == k) { addPush(ik); add(ByteCode.I2L); } else { addLoadConstant(k); } } /** * Generate code to load the given double on stack. * * @param k the constant */ public void addPush(double k) { if (k == 0.0) { // zero add(ByteCode.DCONST_0); if (1.0 / k < 0) { // Negative zero add(ByteCode.DNEG); } } else if (k == 1.0 || k == -1.0) { add(ByteCode.DCONST_1); if (k < 0) { add(ByteCode.DNEG); } } else { addLoadConstant(k); } } /** * Generate the code to leave on stack the given string even if the * string encoding exeeds the class file limit for single string constant * * @param k the constant */ public void addPush(String k) { int length = k.length(); int limit = itsConstantPool.getUtfEncodingLimit(k, 0, length); if (limit == length) { addLoadConstant(k); return; } // Split string into picies fitting the UTF limit and generate code for // StringBuffer sb = new StringBuffer(length); // sb.append(loadConstant(piece_1)); // ... // sb.append(loadConstant(piece_N)); // sb.toString(); final String SB = "java/lang/StringBuffer"; add(ByteCode.NEW, SB); add(ByteCode.DUP); addPush(length); addInvoke(ByteCode.INVOKESPECIAL, SB, "", "(I)V"); int cursor = 0; for (;;) { add(ByteCode.DUP); String s = k.substring(cursor, limit); addLoadConstant(s); addInvoke(ByteCode.INVOKEVIRTUAL, SB, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); add(ByteCode.POP); if (limit == length) { break; } cursor = limit; limit = itsConstantPool.getUtfEncodingLimit(k, limit, length); } addInvoke(ByteCode.INVOKEVIRTUAL, SB, "toString", "()Ljava/lang/String;"); } /** * Check if k fits limit on string constant size imposed by class file * format. * * @param k the string constant */ public boolean isUnderStringSizeLimit(String k) { return itsConstantPool.isUnderUtfEncodingLimit(k); } /** * Store integer from stack top into the given local. * * @param local number of local register */ public void addIStore(int local) { xop(ByteCode.ISTORE_0, ByteCode.ISTORE, local); } /** * Store long from stack top into the given local. * * @param local number of local register */ public void addLStore(int local) { xop(ByteCode.LSTORE_0, ByteCode.LSTORE, local); } /** * Store float from stack top into the given local. * * @param local number of local register */ public void addFStore(int local) { xop(ByteCode.FSTORE_0, ByteCode.FSTORE, local); } /** * Store double from stack top into the given local. * * @param local number of local register */ public void addDStore(int local) { xop(ByteCode.DSTORE_0, ByteCode.DSTORE, local); } /** * Store object from stack top into the given local. * * @param local number of local register */ public void addAStore(int local) { xop(ByteCode.ASTORE_0, ByteCode.ASTORE, local); } /** * Load integer from the given local into stack. * * @param local number of local register */ public void addILoad(int local) { xop(ByteCode.ILOAD_0, ByteCode.ILOAD, local); } /** * Load long from the given local into stack. * * @param local number of local register */ public void addLLoad(int local) { xop(ByteCode.LLOAD_0, ByteCode.LLOAD, local); } /** * Load float from the given local into stack. * * @param local number of local register */ public void addFLoad(int local) { xop(ByteCode.FLOAD_0, ByteCode.FLOAD, local); } /** * Load double from the given local into stack. * * @param local number of local register */ public void addDLoad(int local) { xop(ByteCode.DLOAD_0, ByteCode.DLOAD, local); } /** * Load object from the given local into stack. * * @param local number of local register */ public void addALoad(int local) { xop(ByteCode.ALOAD_0, ByteCode.ALOAD, local); } /** * Load "this" into stack. */ public void addLoadThis() { add(ByteCode.ALOAD_0); } private void xop(int shortOp, int op, int local) { switch (local) { case 0: add(shortOp); break; case 1: add(shortOp + 1); break; case 2: add(shortOp + 2); break; case 3: add(shortOp + 3); break; default: add(op, local); } } public int addTableSwitch(int low, int high) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(ByteCode.TABLESWITCH) +" "+low+" "+high); } if (low > high) throw new ClassFileFormatException("Bad bounds: "+low+' '+ high); int newStack = itsStackTop + stackChange(ByteCode.TABLESWITCH); if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); int entryCount = high - low + 1; int padSize = 3 & ~itsCodeBufferTop; // == 3 - itsCodeBufferTop % 4 int N = addReservedCodeSpace(1 + padSize + 4 * (1 + 2 + entryCount)); int switchStart = N; itsCodeBuffer[N++] = (byte)ByteCode.TABLESWITCH; while (padSize != 0) { itsCodeBuffer[N++] = 0; --padSize; } N += 4; // skip default offset N = putInt32(low, itsCodeBuffer, N); putInt32(high, itsCodeBuffer, N); itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(ByteCode.TABLESWITCH) +" stack = "+itsStackTop); } return switchStart; } public final void markTableSwitchDefault(int switchStart) { setTableSwitchJump(switchStart, -1, itsCodeBufferTop); } public final void markTableSwitchCase(int switchStart, int caseIndex) { setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop); } public final void markTableSwitchCase(int switchStart, int caseIndex, int stackTop) { if (!(0 <= stackTop && stackTop <= itsMaxStack)) throw new IllegalArgumentException("Bad stack index: "+stackTop); itsStackTop = (short)stackTop; setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop); } public void setTableSwitchJump(int switchStart, int caseIndex, int jumpTarget) { if (!(0 <= jumpTarget && jumpTarget <= itsCodeBufferTop)) throw new IllegalArgumentException("Bad jump target: "+jumpTarget); if (!(caseIndex >= -1)) throw new IllegalArgumentException("Bad case index: "+caseIndex); int padSize = 3 & ~switchStart; // == 3 - switchStart % 4 int caseOffset; if (caseIndex < 0) { // default label caseOffset = switchStart + 1 + padSize; } else { caseOffset = switchStart + 1 + padSize + 4 * (3 + caseIndex); } if (!(0 <= switchStart && switchStart <= itsCodeBufferTop - 4 * 4 - padSize - 1)) { throw new IllegalArgumentException( switchStart+" is outside a possible range of tableswitch" +" in already generated code"); } if ((0xFF & itsCodeBuffer[switchStart]) != ByteCode.TABLESWITCH) { throw new IllegalArgumentException( switchStart+" is not offset of tableswitch statement"); } if (!(0 <= caseOffset && caseOffset + 4 <= itsCodeBufferTop)) { // caseIndex >= -1 does not guarantee that caseOffset >= 0 due // to a possible overflow. throw new ClassFileFormatException( "Too big case index: "+caseIndex); } // ALERT: perhaps check against case bounds? putInt32(jumpTarget - switchStart, itsCodeBuffer, caseOffset); } public int acquireLabel() { int top = itsLabelTableTop; if (itsLabelTable == null || top == itsLabelTable.length) { if (itsLabelTable == null) { itsLabelTable = new int[MIN_LABEL_TABLE_SIZE]; }else { int[] tmp = new int[itsLabelTable.length * 2]; System.arraycopy(itsLabelTable, 0, tmp, 0, top); itsLabelTable = tmp; } } itsLabelTableTop = top + 1; itsLabelTable[top] = -1; return top | 0x80000000; } public void markLabel(int label) { if (!(label < 0)) throw new IllegalArgumentException("Bad label, no biscuit"); label &= 0x7FFFFFFF; if (label > itsLabelTableTop) throw new IllegalArgumentException("Bad label"); if (itsLabelTable[label] != -1) { throw new IllegalStateException("Can only mark label once"); } itsLabelTable[label] = itsCodeBufferTop; } public void markLabel(int label, short stackTop) { markLabel(label); itsStackTop = stackTop; } public void markHandler(int theLabel) { itsStackTop = 1; markLabel(theLabel); } private int getLabelPC(int label) { if (!(label < 0)) throw new IllegalArgumentException("Bad label, no biscuit"); label &= 0x7FFFFFFF; if (!(label < itsLabelTableTop)) throw new IllegalArgumentException("Bad label"); return itsLabelTable[label]; } private void addLabelFixup(int label, int fixupSite) { if (!(label < 0)) throw new IllegalArgumentException("Bad label, no biscuit"); label &= 0x7FFFFFFF; if (!(label < itsLabelTableTop)) throw new IllegalArgumentException("Bad label"); int top = itsFixupTableTop; if (itsFixupTable == null || top == itsFixupTable.length) { if (itsFixupTable == null) { itsFixupTable = new long[MIN_FIXUP_TABLE_SIZE]; }else { long[] tmp = new long[itsFixupTable.length * 2]; System.arraycopy(itsFixupTable, 0, tmp, 0, top); itsFixupTable = tmp; } } itsFixupTableTop = top + 1; itsFixupTable[top] = ((long)label << 32) | fixupSite; } private void fixLabelGotos() { byte[] codeBuffer = itsCodeBuffer; for (int i = 0; i < itsFixupTableTop; i++) { long fixup = itsFixupTable[i]; int label = (int)(fixup >> 32); int fixupSite = (int)fixup; int pc = itsLabelTable[label]; if (pc == -1) { // Unlocated label throw new RuntimeException(); } // -1 to get delta from instruction start int offset = pc - (fixupSite - 1); if ((short)offset != offset) { throw new ClassFileFormatException ("Program too complex: too big jump offset"); } codeBuffer[fixupSite] = (byte)(offset >> 8); codeBuffer[fixupSite + 1] = (byte)offset; } itsFixupTableTop = 0; } /** * Get the current offset into the code of the current method. * * @return an integer representing the offset */ public int getCurrentCodeOffset() { return itsCodeBufferTop; } public short getStackTop() { return itsStackTop; } public void setStackTop(short n) { itsStackTop = n; } public void adjustStackTop(int delta) { int newStack = itsStackTop + delta; if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+"adjustStackTop("+delta+")" +" stack = "+itsStackTop); } } private void addToCodeBuffer(int b) { int N = addReservedCodeSpace(1); itsCodeBuffer[N] = (byte)b; } private void addToCodeInt16(int value) { int N = addReservedCodeSpace(2); putInt16(value, itsCodeBuffer, N); } private int addReservedCodeSpace(int size) { if (itsCurrentMethod == null) throw new IllegalArgumentException("No method to add to"); int oldTop = itsCodeBufferTop; int newTop = oldTop + size; if (newTop > itsCodeBuffer.length) { int newSize = itsCodeBuffer.length * 2; if (newTop > newSize) { newSize = newTop; } byte[] tmp = new byte[newSize]; System.arraycopy(itsCodeBuffer, 0, tmp, 0, oldTop); itsCodeBuffer = tmp; } itsCodeBufferTop = newTop; return oldTop; } public void addExceptionHandler(int startLabel, int endLabel, int handlerLabel, String catchClassName) { if ((startLabel & 0x80000000) != 0x80000000) throw new IllegalArgumentException("Bad startLabel"); if ((endLabel & 0x80000000) != 0x80000000) throw new IllegalArgumentException("Bad endLabel"); if ((handlerLabel & 0x80000000) != 0x80000000) throw new IllegalArgumentException("Bad handlerLabel"); /* * If catchClassName is null, use 0 for the catch_type_index; which * means catch everything. (Even when the verifier has let you throw * something other than a Throwable.) */ short catch_type_index = (catchClassName == null) ? 0 : itsConstantPool.addClass(catchClassName); ExceptionTableEntry newEntry = new ExceptionTableEntry( startLabel, endLabel, handlerLabel, catch_type_index); int N = itsExceptionTableTop; if (N == 0) { itsExceptionTable = new ExceptionTableEntry[ExceptionTableSize]; } else if (N == itsExceptionTable.length) { ExceptionTableEntry[] tmp = new ExceptionTableEntry[N * 2]; System.arraycopy(itsExceptionTable, 0, tmp, 0, N); itsExceptionTable = tmp; } itsExceptionTable[N] = newEntry; itsExceptionTableTop = N + 1; } public void addLineNumberEntry(short lineNumber) { if (itsCurrentMethod == null) throw new IllegalArgumentException("No method to stop"); int N = itsLineNumberTableTop; if (N == 0) { itsLineNumberTable = new int[LineNumberTableSize]; } else if (N == itsLineNumberTable.length) { int[] tmp = new int[N * 2]; System.arraycopy(itsLineNumberTable, 0, tmp, 0, N); itsLineNumberTable = tmp; } itsLineNumberTable[N] = (itsCodeBufferTop << 16) + lineNumber; itsLineNumberTableTop = N + 1; } /** * Write the class file to the OutputStream. * * @param oStream the stream to write to * @throws IOException if writing to the stream produces an exception */ public void write(OutputStream oStream) throws IOException { byte[] array = toByteArray(); oStream.write(array); } private int getWriteSize() { int size = 0; if (itsSourceFileNameIndex != 0) { itsConstantPool.addUtf8("SourceFile"); } size += 8; //writeLong(FileHeaderConstant); size += itsConstantPool.getWriteSize(); size += 2; //writeShort(itsFlags); size += 2; //writeShort(itsThisClassIndex); size += 2; //writeShort(itsSuperClassIndex); size += 2; //writeShort(itsInterfaces.size()); size += 2 * itsInterfaces.size(); size += 2; //writeShort(itsFields.size()); for (int i = 0; i < itsFields.size(); i++) { size += ((ClassFileField)(itsFields.get(i))).getWriteSize(); } size += 2; //writeShort(itsMethods.size()); for (int i = 0; i < itsMethods.size(); i++) { size += ((ClassFileMethod)(itsMethods.get(i))).getWriteSize(); } if (itsSourceFileNameIndex != 0) { size += 2; //writeShort(1); attributes count size += 2; //writeShort(sourceFileAttributeNameIndex); size += 4; //writeInt(2); size += 2; //writeShort(itsSourceFileNameIndex); }else { size += 2; //out.writeShort(0); no attributes } return size; } /** * Get the class file as array of bytesto the OutputStream. */ public byte[] toByteArray() { int dataSize = getWriteSize(); byte[] data = new byte[dataSize]; int offset = 0; short sourceFileAttributeNameIndex = 0; if (itsSourceFileNameIndex != 0) { sourceFileAttributeNameIndex = itsConstantPool.addUtf8( "SourceFile"); } offset = putInt64(FileHeaderConstant, data, offset); offset = itsConstantPool.write(data, offset); offset = putInt16(itsFlags, data, offset); offset = putInt16(itsThisClassIndex, data, offset); offset = putInt16(itsSuperClassIndex, data, offset); offset = putInt16(itsInterfaces.size(), data, offset); for (int i = 0; i < itsInterfaces.size(); i++) { int interfaceIndex = ((Short)(itsInterfaces.get(i))).shortValue(); offset = putInt16(interfaceIndex, data, offset); } offset = putInt16(itsFields.size(), data, offset); for (int i = 0; i < itsFields.size(); i++) { ClassFileField field = (ClassFileField)itsFields.get(i); offset = field.write(data, offset); } offset = putInt16(itsMethods.size(), data, offset); for (int i = 0; i < itsMethods.size(); i++) { ClassFileMethod method = (ClassFileMethod)itsMethods.get(i); offset = method.write(data, offset); } if (itsSourceFileNameIndex != 0) { offset = putInt16(1, data, offset); // attributes count offset = putInt16(sourceFileAttributeNameIndex, data, offset); offset = putInt32(2, data, offset); offset = putInt16(itsSourceFileNameIndex, data, offset); } else { offset = putInt16(0, data, offset); // no attributes } if (offset != dataSize) { // Check getWriteSize is consistent with write! throw new RuntimeException(); } return data; } static int putInt64(long value, byte[] array, int offset) { offset = putInt32((int)(value >>> 32), array, offset); return putInt32((int)value, array, offset); } private static void badStack(int value) { String s; if (value < 0) { s = "Stack underflow: "+value; } else { s = "Too big stack: "+value; } throw new IllegalStateException(s); } /* Really weird. Returns an int with # parameters in hi 16 bits, and stack difference removal of parameters from stack and pushing the result (it does not take into account removal of this in case of non-static methods). If Java really supported references we wouldn't have to be this perverted. */ private static int sizeOfParameters(String pString) { int length = pString.length(); int rightParenthesis = pString.lastIndexOf(')'); if (3 <= length /* minimal signature takes at least 3 chars: ()V */ && pString.charAt(0) == '(' && 1 <= rightParenthesis && rightParenthesis + 1 < length) { boolean ok = true; int index = 1; int stackDiff = 0; int count = 0; stringLoop: while (index != rightParenthesis) { switch (pString.charAt(index)) { default: ok = false; break stringLoop; case 'J' : case 'D' : --stackDiff; // fall thru case 'B' : case 'S' : case 'C' : case 'I' : case 'Z' : case 'F' : --stackDiff; ++count; ++index; continue; case '[' : ++index; int c = pString.charAt(index); while (c == '[') { ++index; c = pString.charAt(index); } switch (c) { default: ok = false; break stringLoop; case 'J' : case 'D' : case 'B' : case 'S' : case 'C' : case 'I' : case 'Z' : case 'F' : --stackDiff; ++count; ++index; continue; case 'L': // fall thru } // fall thru case 'L' : { --stackDiff; ++count; ++index; int semicolon = pString.indexOf(';', index); if (!(index + 1 <= semicolon && semicolon < rightParenthesis)) { ok = false; break stringLoop; } index = semicolon + 1; continue; } } } if (ok) { switch (pString.charAt(rightParenthesis + 1)) { default: ok = false; break; case 'J' : case 'D' : ++stackDiff; // fall thru case 'B' : case 'S' : case 'C' : case 'I' : case 'Z' : case 'F' : case 'L' : case '[' : ++stackDiff; // fall thru case 'V' : break; } if (ok) { return ((count << 16) | (0xFFFF & stackDiff)); } } } throw new IllegalArgumentException( "Bad parameter signature: "+pString); } static int putInt16(int value, byte[] array, int offset) { array[offset + 0] = (byte)(value >>> 8); array[offset + 1] = (byte)value; return offset + 2; } static int putInt32(int value, byte[] array, int offset) { array[offset + 0] = (byte)(value >>> 24); array[offset + 1] = (byte)(value >>> 16); array[offset + 2] = (byte)(value >>> 8); array[offset + 3] = (byte)value; return offset + 4; } /** * Number of operands accompanying the opcode. */ static int opcodeCount(int opcode) { switch (opcode) { case ByteCode.AALOAD: case ByteCode.AASTORE: case ByteCode.ACONST_NULL: case ByteCode.ALOAD_0: case ByteCode.ALOAD_1: case ByteCode.ALOAD_2: case ByteCode.ALOAD_3: case ByteCode.ARETURN: case ByteCode.ARRAYLENGTH: case ByteCode.ASTORE_0: case ByteCode.ASTORE_1: case ByteCode.ASTORE_2: case ByteCode.ASTORE_3: case ByteCode.ATHROW: case ByteCode.BALOAD: case ByteCode.BASTORE: case ByteCode.BREAKPOINT: case ByteCode.CALOAD: case ByteCode.CASTORE: case ByteCode.D2F: case ByteCode.D2I: case ByteCode.D2L: case ByteCode.DADD: case ByteCode.DALOAD: case ByteCode.DASTORE: case ByteCode.DCMPG: case ByteCode.DCMPL: case ByteCode.DCONST_0: case ByteCode.DCONST_1: case ByteCode.DDIV: case ByteCode.DLOAD_0: case ByteCode.DLOAD_1: case ByteCode.DLOAD_2: case ByteCode.DLOAD_3: case ByteCode.DMUL: case ByteCode.DNEG: case ByteCode.DREM: case ByteCode.DRETURN: case ByteCode.DSTORE_0: case ByteCode.DSTORE_1: case ByteCode.DSTORE_2: case ByteCode.DSTORE_3: case ByteCode.DSUB: case ByteCode.DUP: case ByteCode.DUP2: case ByteCode.DUP2_X1: case ByteCode.DUP2_X2: case ByteCode.DUP_X1: case ByteCode.DUP_X2: case ByteCode.F2D: case ByteCode.F2I: case ByteCode.F2L: case ByteCode.FADD: case ByteCode.FALOAD: case ByteCode.FASTORE: case ByteCode.FCMPG: case ByteCode.FCMPL: case ByteCode.FCONST_0: case ByteCode.FCONST_1: case ByteCode.FCONST_2: case ByteCode.FDIV: case ByteCode.FLOAD_0: case ByteCode.FLOAD_1: case ByteCode.FLOAD_2: case ByteCode.FLOAD_3: case ByteCode.FMUL: case ByteCode.FNEG: case ByteCode.FREM: case ByteCode.FRETURN: case ByteCode.FSTORE_0: case ByteCode.FSTORE_1: case ByteCode.FSTORE_2: case ByteCode.FSTORE_3: case ByteCode.FSUB: case ByteCode.I2B: case ByteCode.I2C: case ByteCode.I2D: case ByteCode.I2F: case ByteCode.I2L: case ByteCode.I2S: case ByteCode.IADD: case ByteCode.IALOAD: case ByteCode.IAND: case ByteCode.IASTORE: case ByteCode.ICONST_0: case ByteCode.ICONST_1: case ByteCode.ICONST_2: case ByteCode.ICONST_3: case ByteCode.ICONST_4: case ByteCode.ICONST_5: case ByteCode.ICONST_M1: case ByteCode.IDIV: case ByteCode.ILOAD_0: case ByteCode.ILOAD_1: case ByteCode.ILOAD_2: case ByteCode.ILOAD_3: case ByteCode.IMPDEP1: case ByteCode.IMPDEP2: case ByteCode.IMUL: case ByteCode.INEG: case ByteCode.IOR: case ByteCode.IREM: case ByteCode.IRETURN: case ByteCode.ISHL: case ByteCode.ISHR: case ByteCode.ISTORE_0: case ByteCode.ISTORE_1: case ByteCode.ISTORE_2: case ByteCode.ISTORE_3: case ByteCode.ISUB: case ByteCode.IUSHR: case ByteCode.IXOR: case ByteCode.L2D: case ByteCode.L2F: case ByteCode.L2I: case ByteCode.LADD: case ByteCode.LALOAD: case ByteCode.LAND: case ByteCode.LASTORE: case ByteCode.LCMP: case ByteCode.LCONST_0: case ByteCode.LCONST_1: case ByteCode.LDIV: case ByteCode.LLOAD_0: case ByteCode.LLOAD_1: case ByteCode.LLOAD_2: case ByteCode.LLOAD_3: case ByteCode.LMUL: case ByteCode.LNEG: case ByteCode.LOR: case ByteCode.LREM: case ByteCode.LRETURN: case ByteCode.LSHL: case ByteCode.LSHR: case ByteCode.LSTORE_0: case ByteCode.LSTORE_1: case ByteCode.LSTORE_2: case ByteCode.LSTORE_3: case ByteCode.LSUB: case ByteCode.LUSHR: case ByteCode.LXOR: case ByteCode.MONITORENTER: case ByteCode.MONITOREXIT: case ByteCode.NOP: case ByteCode.POP: case ByteCode.POP2: case ByteCode.RETURN: case ByteCode.SALOAD: case ByteCode.SASTORE: case ByteCode.SWAP: case ByteCode.WIDE: return 0; case ByteCode.ALOAD: case ByteCode.ANEWARRAY: case ByteCode.ASTORE: case ByteCode.BIPUSH: case ByteCode.CHECKCAST: case ByteCode.DLOAD: case ByteCode.DSTORE: case ByteCode.FLOAD: case ByteCode.FSTORE: case ByteCode.GETFIELD: case ByteCode.GETSTATIC: case ByteCode.GOTO: case ByteCode.GOTO_W: case ByteCode.IFEQ: case ByteCode.IFGE: case ByteCode.IFGT: case ByteCode.IFLE: case ByteCode.IFLT: case ByteCode.IFNE: case ByteCode.IFNONNULL: case ByteCode.IFNULL: case ByteCode.IF_ACMPEQ: case ByteCode.IF_ACMPNE: case ByteCode.IF_ICMPEQ: case ByteCode.IF_ICMPGE: case ByteCode.IF_ICMPGT: case ByteCode.IF_ICMPLE: case ByteCode.IF_ICMPLT: case ByteCode.IF_ICMPNE: case ByteCode.ILOAD: case ByteCode.INSTANCEOF: case ByteCode.INVOKEINTERFACE: case ByteCode.INVOKESPECIAL: case ByteCode.INVOKESTATIC: case ByteCode.INVOKEVIRTUAL: case ByteCode.ISTORE: case ByteCode.JSR: case ByteCode.JSR_W: case ByteCode.LDC: case ByteCode.LDC2_W: case ByteCode.LDC_W: case ByteCode.LLOAD: case ByteCode.LSTORE: case ByteCode.NEW: case ByteCode.NEWARRAY: case ByteCode.PUTFIELD: case ByteCode.PUTSTATIC: case ByteCode.RET: case ByteCode.SIPUSH: return 1; case ByteCode.IINC: case ByteCode.MULTIANEWARRAY: return 2; case ByteCode.LOOKUPSWITCH: case ByteCode.TABLESWITCH: return -1; } throw new IllegalArgumentException("Bad opcode: "+opcode); } /** * The effect on the operand stack of a given opcode. */ static int stackChange(int opcode) { // For INVOKE... accounts only for popping this (unless static), // ignoring parameters and return type switch (opcode) { case ByteCode.DASTORE: case ByteCode.LASTORE: return -4; case ByteCode.AASTORE: case ByteCode.BASTORE: case ByteCode.CASTORE: case ByteCode.DCMPG: case ByteCode.DCMPL: case ByteCode.FASTORE: case ByteCode.IASTORE: case ByteCode.LCMP: case ByteCode.SASTORE: return -3; case ByteCode.DADD: case ByteCode.DDIV: case ByteCode.DMUL: case ByteCode.DREM: case ByteCode.DRETURN: case ByteCode.DSTORE: case ByteCode.DSTORE_0: case ByteCode.DSTORE_1: case ByteCode.DSTORE_2: case ByteCode.DSTORE_3: case ByteCode.DSUB: case ByteCode.IF_ACMPEQ: case ByteCode.IF_ACMPNE: case ByteCode.IF_ICMPEQ: case ByteCode.IF_ICMPGE: case ByteCode.IF_ICMPGT: case ByteCode.IF_ICMPLE: case ByteCode.IF_ICMPLT: case ByteCode.IF_ICMPNE: case ByteCode.LADD: case ByteCode.LAND: case ByteCode.LDIV: case ByteCode.LMUL: case ByteCode.LOR: case ByteCode.LREM: case ByteCode.LRETURN: case ByteCode.LSTORE: case ByteCode.LSTORE_0: case ByteCode.LSTORE_1: case ByteCode.LSTORE_2: case ByteCode.LSTORE_3: case ByteCode.LSUB: case ByteCode.LXOR: case ByteCode.POP2: return -2; case ByteCode.AALOAD: case ByteCode.ARETURN: case ByteCode.ASTORE: case ByteCode.ASTORE_0: case ByteCode.ASTORE_1: case ByteCode.ASTORE_2: case ByteCode.ASTORE_3: case ByteCode.ATHROW: case ByteCode.BALOAD: case ByteCode.CALOAD: case ByteCode.D2F: case ByteCode.D2I: case ByteCode.FADD: case ByteCode.FALOAD: case ByteCode.FCMPG: case ByteCode.FCMPL: case ByteCode.FDIV: case ByteCode.FMUL: case ByteCode.FREM: case ByteCode.FRETURN: case ByteCode.FSTORE: case ByteCode.FSTORE_0: case ByteCode.FSTORE_1: case ByteCode.FSTORE_2: case ByteCode.FSTORE_3: case ByteCode.FSUB: case ByteCode.GETFIELD: case ByteCode.IADD: case ByteCode.IALOAD: case ByteCode.IAND: case ByteCode.IDIV: case ByteCode.IFEQ: case ByteCode.IFGE: case ByteCode.IFGT: case ByteCode.IFLE: case ByteCode.IFLT: case ByteCode.IFNE: case ByteCode.IFNONNULL: case ByteCode.IFNULL: case ByteCode.IMUL: case ByteCode.INVOKEINTERFACE: // case ByteCode.INVOKESPECIAL: // but needs to account for case ByteCode.INVOKEVIRTUAL: // pops 'this' (unless static) case ByteCode.IOR: case ByteCode.IREM: case ByteCode.IRETURN: case ByteCode.ISHL: case ByteCode.ISHR: case ByteCode.ISTORE: case ByteCode.ISTORE_0: case ByteCode.ISTORE_1: case ByteCode.ISTORE_2: case ByteCode.ISTORE_3: case ByteCode.ISUB: case ByteCode.IUSHR: case ByteCode.IXOR: case ByteCode.L2F: case ByteCode.L2I: case ByteCode.LOOKUPSWITCH: case ByteCode.LSHL: case ByteCode.LSHR: case ByteCode.LUSHR: case ByteCode.MONITORENTER: case ByteCode.MONITOREXIT: case ByteCode.POP: case ByteCode.PUTFIELD: case ByteCode.SALOAD: case ByteCode.TABLESWITCH: return -1; case ByteCode.ANEWARRAY: case ByteCode.ARRAYLENGTH: case ByteCode.BREAKPOINT: case ByteCode.CHECKCAST: case ByteCode.D2L: case ByteCode.DALOAD: case ByteCode.DNEG: case ByteCode.F2I: case ByteCode.FNEG: case ByteCode.GETSTATIC: case ByteCode.GOTO: case ByteCode.GOTO_W: case ByteCode.I2B: case ByteCode.I2C: case ByteCode.I2F: case ByteCode.I2S: case ByteCode.IINC: case ByteCode.IMPDEP1: case ByteCode.IMPDEP2: case ByteCode.INEG: case ByteCode.INSTANCEOF: case ByteCode.INVOKESTATIC: case ByteCode.L2D: case ByteCode.LALOAD: case ByteCode.LNEG: case ByteCode.NEWARRAY: case ByteCode.NOP: case ByteCode.PUTSTATIC: case ByteCode.RET: case ByteCode.RETURN: case ByteCode.SWAP: case ByteCode.WIDE: return 0; case ByteCode.ACONST_NULL: case ByteCode.ALOAD: case ByteCode.ALOAD_0: case ByteCode.ALOAD_1: case ByteCode.ALOAD_2: case ByteCode.ALOAD_3: case ByteCode.BIPUSH: case ByteCode.DUP: case ByteCode.DUP_X1: case ByteCode.DUP_X2: case ByteCode.F2D: case ByteCode.F2L: case ByteCode.FCONST_0: case ByteCode.FCONST_1: case ByteCode.FCONST_2: case ByteCode.FLOAD: case ByteCode.FLOAD_0: case ByteCode.FLOAD_1: case ByteCode.FLOAD_2: case ByteCode.FLOAD_3: case ByteCode.I2D: case ByteCode.I2L: case ByteCode.ICONST_0: case ByteCode.ICONST_1: case ByteCode.ICONST_2: case ByteCode.ICONST_3: case ByteCode.ICONST_4: case ByteCode.ICONST_5: case ByteCode.ICONST_M1: case ByteCode.ILOAD: case ByteCode.ILOAD_0: case ByteCode.ILOAD_1: case ByteCode.ILOAD_2: case ByteCode.ILOAD_3: case ByteCode.JSR: case ByteCode.JSR_W: case ByteCode.LDC: case ByteCode.LDC_W: case ByteCode.MULTIANEWARRAY: case ByteCode.NEW: case ByteCode.SIPUSH: return 1; case ByteCode.DCONST_0: case ByteCode.DCONST_1: case ByteCode.DLOAD: case ByteCode.DLOAD_0: case ByteCode.DLOAD_1: case ByteCode.DLOAD_2: case ByteCode.DLOAD_3: case ByteCode.DUP2: case ByteCode.DUP2_X1: case ByteCode.DUP2_X2: case ByteCode.LCONST_0: case ByteCode.LCONST_1: case ByteCode.LDC2_W: case ByteCode.LLOAD: case ByteCode.LLOAD_0: case ByteCode.LLOAD_1: case ByteCode.LLOAD_2: case ByteCode.LLOAD_3: return 2; } throw new IllegalArgumentException("Bad opcode: "+opcode); } /* * Number of bytes of operands generated after the opcode. * Not in use currently. */ /* int extra(int opcode) { switch (opcode) { case ByteCode.AALOAD: case ByteCode.AASTORE: case ByteCode.ACONST_NULL: case ByteCode.ALOAD_0: case ByteCode.ALOAD_1: case ByteCode.ALOAD_2: case ByteCode.ALOAD_3: case ByteCode.ARETURN: case ByteCode.ARRAYLENGTH: case ByteCode.ASTORE_0: case ByteCode.ASTORE_1: case ByteCode.ASTORE_2: case ByteCode.ASTORE_3: case ByteCode.ATHROW: case ByteCode.BALOAD: case ByteCode.BASTORE: case ByteCode.BREAKPOINT: case ByteCode.CALOAD: case ByteCode.CASTORE: case ByteCode.D2F: case ByteCode.D2I: case ByteCode.D2L: case ByteCode.DADD: case ByteCode.DALOAD: case ByteCode.DASTORE: case ByteCode.DCMPG: case ByteCode.DCMPL: case ByteCode.DCONST_0: case ByteCode.DCONST_1: case ByteCode.DDIV: case ByteCode.DLOAD_0: case ByteCode.DLOAD_1: case ByteCode.DLOAD_2: case ByteCode.DLOAD_3: case ByteCode.DMUL: case ByteCode.DNEG: case ByteCode.DREM: case ByteCode.DRETURN: case ByteCode.DSTORE_0: case ByteCode.DSTORE_1: case ByteCode.DSTORE_2: case ByteCode.DSTORE_3: case ByteCode.DSUB: case ByteCode.DUP2: case ByteCode.DUP2_X1: case ByteCode.DUP2_X2: case ByteCode.DUP: case ByteCode.DUP_X1: case ByteCode.DUP_X2: case ByteCode.F2D: case ByteCode.F2I: case ByteCode.F2L: case ByteCode.FADD: case ByteCode.FALOAD: case ByteCode.FASTORE: case ByteCode.FCMPG: case ByteCode.FCMPL: case ByteCode.FCONST_0: case ByteCode.FCONST_1: case ByteCode.FCONST_2: case ByteCode.FDIV: case ByteCode.FLOAD_0: case ByteCode.FLOAD_1: case ByteCode.FLOAD_2: case ByteCode.FLOAD_3: case ByteCode.FMUL: case ByteCode.FNEG: case ByteCode.FREM: case ByteCode.FRETURN: case ByteCode.FSTORE_0: case ByteCode.FSTORE_1: case ByteCode.FSTORE_2: case ByteCode.FSTORE_3: case ByteCode.FSUB: case ByteCode.I2B: case ByteCode.I2C: case ByteCode.I2D: case ByteCode.I2F: case ByteCode.I2L: case ByteCode.I2S: case ByteCode.IADD: case ByteCode.IALOAD: case ByteCode.IAND: case ByteCode.IASTORE: case ByteCode.ICONST_0: case ByteCode.ICONST_1: case ByteCode.ICONST_2: case ByteCode.ICONST_3: case ByteCode.ICONST_4: case ByteCode.ICONST_5: case ByteCode.ICONST_M1: case ByteCode.IDIV: case ByteCode.ILOAD_0: case ByteCode.ILOAD_1: case ByteCode.ILOAD_2: case ByteCode.ILOAD_3: case ByteCode.IMPDEP1: case ByteCode.IMPDEP2: case ByteCode.IMUL: case ByteCode.INEG: case ByteCode.IOR: case ByteCode.IREM: case ByteCode.IRETURN: case ByteCode.ISHL: case ByteCode.ISHR: case ByteCode.ISTORE_0: case ByteCode.ISTORE_1: case ByteCode.ISTORE_2: case ByteCode.ISTORE_3: case ByteCode.ISUB: case ByteCode.IUSHR: case ByteCode.IXOR: case ByteCode.L2D: case ByteCode.L2F: case ByteCode.L2I: case ByteCode.LADD: case ByteCode.LALOAD: case ByteCode.LAND: case ByteCode.LASTORE: case ByteCode.LCMP: case ByteCode.LCONST_0: case ByteCode.LCONST_1: case ByteCode.LDIV: case ByteCode.LLOAD_0: case ByteCode.LLOAD_1: case ByteCode.LLOAD_2: case ByteCode.LLOAD_3: case ByteCode.LMUL: case ByteCode.LNEG: case ByteCode.LOR: case ByteCode.LREM: case ByteCode.LRETURN: case ByteCode.LSHL: case ByteCode.LSHR: case ByteCode.LSTORE_0: case ByteCode.LSTORE_1: case ByteCode.LSTORE_2: case ByteCode.LSTORE_3: case ByteCode.LSUB: case ByteCode.LUSHR: case ByteCode.LXOR: case ByteCode.MONITORENTER: case ByteCode.MONITOREXIT: case ByteCode.NOP: case ByteCode.POP2: case ByteCode.POP: case ByteCode.RETURN: case ByteCode.SALOAD: case ByteCode.SASTORE: case ByteCode.SWAP: case ByteCode.WIDE: return 0; case ByteCode.ALOAD: case ByteCode.ASTORE: case ByteCode.BIPUSH: case ByteCode.DLOAD: case ByteCode.DSTORE: case ByteCode.FLOAD: case ByteCode.FSTORE: case ByteCode.ILOAD: case ByteCode.ISTORE: case ByteCode.LDC: case ByteCode.LLOAD: case ByteCode.LSTORE: case ByteCode.NEWARRAY: case ByteCode.RET: return 1; case ByteCode.ANEWARRAY: case ByteCode.CHECKCAST: case ByteCode.GETFIELD: case ByteCode.GETSTATIC: case ByteCode.GOTO: case ByteCode.IFEQ: case ByteCode.IFGE: case ByteCode.IFGT: case ByteCode.IFLE: case ByteCode.IFLT: case ByteCode.IFNE: case ByteCode.IFNONNULL: case ByteCode.IFNULL: case ByteCode.IF_ACMPEQ: case ByteCode.IF_ACMPNE: case ByteCode.IF_ICMPEQ: case ByteCode.IF_ICMPGE: case ByteCode.IF_ICMPGT: case ByteCode.IF_ICMPLE: case ByteCode.IF_ICMPLT: case ByteCode.IF_ICMPNE: case ByteCode.IINC: case ByteCode.INSTANCEOF: case ByteCode.INVOKEINTERFACE: case ByteCode.INVOKESPECIAL: case ByteCode.INVOKESTATIC: case ByteCode.INVOKEVIRTUAL: case ByteCode.JSR: case ByteCode.LDC2_W: case ByteCode.LDC_W: case ByteCode.NEW: case ByteCode.PUTFIELD: case ByteCode.PUTSTATIC: case ByteCode.SIPUSH: return 2; case ByteCode.MULTIANEWARRAY: return 3; case ByteCode.GOTO_W: case ByteCode.JSR_W: return 4; case ByteCode.LOOKUPSWITCH: // depends on alignment case ByteCode.TABLESWITCH: // depends on alignment return -1; } throw new IllegalArgumentException("Bad opcode: "+opcode); } */ private static String bytecodeStr(int code) { if (DEBUGSTACK || DEBUGCODE) { switch (code) { case ByteCode.NOP: return "nop"; case ByteCode.ACONST_NULL: return "aconst_null"; case ByteCode.ICONST_M1: return "iconst_m1"; case ByteCode.ICONST_0: return "iconst_0"; case ByteCode.ICONST_1: return "iconst_1"; case ByteCode.ICONST_2: return "iconst_2"; case ByteCode.ICONST_3: return "iconst_3"; case ByteCode.ICONST_4: return "iconst_4"; case ByteCode.ICONST_5: return "iconst_5"; case ByteCode.LCONST_0: return "lconst_0"; case ByteCode.LCONST_1: return "lconst_1"; case ByteCode.FCONST_0: return "fconst_0"; case ByteCode.FCONST_1: return "fconst_1"; case ByteCode.FCONST_2: return "fconst_2"; case ByteCode.DCONST_0: return "dconst_0"; case ByteCode.DCONST_1: return "dconst_1"; case ByteCode.BIPUSH: return "bipush"; case ByteCode.SIPUSH: return "sipush"; case ByteCode.LDC: return "ldc"; case ByteCode.LDC_W: return "ldc_w"; case ByteCode.LDC2_W: return "ldc2_w"; case ByteCode.ILOAD: return "iload"; case ByteCode.LLOAD: return "lload"; case ByteCode.FLOAD: return "fload"; case ByteCode.DLOAD: return "dload"; case ByteCode.ALOAD: return "aload"; case ByteCode.ILOAD_0: return "iload_0"; case ByteCode.ILOAD_1: return "iload_1"; case ByteCode.ILOAD_2: return "iload_2"; case ByteCode.ILOAD_3: return "iload_3"; case ByteCode.LLOAD_0: return "lload_0"; case ByteCode.LLOAD_1: return "lload_1"; case ByteCode.LLOAD_2: return "lload_2"; case ByteCode.LLOAD_3: return "lload_3"; case ByteCode.FLOAD_0: return "fload_0"; case ByteCode.FLOAD_1: return "fload_1"; case ByteCode.FLOAD_2: return "fload_2"; case ByteCode.FLOAD_3: return "fload_3"; case ByteCode.DLOAD_0: return "dload_0"; case ByteCode.DLOAD_1: return "dload_1"; case ByteCode.DLOAD_2: return "dload_2"; case ByteCode.DLOAD_3: return "dload_3"; case ByteCode.ALOAD_0: return "aload_0"; case ByteCode.ALOAD_1: return "aload_1"; case ByteCode.ALOAD_2: return "aload_2"; case ByteCode.ALOAD_3: return "aload_3"; case ByteCode.IALOAD: return "iaload"; case ByteCode.LALOAD: return "laload"; case ByteCode.FALOAD: return "faload"; case ByteCode.DALOAD: return "daload"; case ByteCode.AALOAD: return "aaload"; case ByteCode.BALOAD: return "baload"; case ByteCode.CALOAD: return "caload"; case ByteCode.SALOAD: return "saload"; case ByteCode.ISTORE: return "istore"; case ByteCode.LSTORE: return "lstore"; case ByteCode.FSTORE: return "fstore"; case ByteCode.DSTORE: return "dstore"; case ByteCode.ASTORE: return "astore"; case ByteCode.ISTORE_0: return "istore_0"; case ByteCode.ISTORE_1: return "istore_1"; case ByteCode.ISTORE_2: return "istore_2"; case ByteCode.ISTORE_3: return "istore_3"; case ByteCode.LSTORE_0: return "lstore_0"; case ByteCode.LSTORE_1: return "lstore_1"; case ByteCode.LSTORE_2: return "lstore_2"; case ByteCode.LSTORE_3: return "lstore_3"; case ByteCode.FSTORE_0: return "fstore_0"; case ByteCode.FSTORE_1: return "fstore_1"; case ByteCode.FSTORE_2: return "fstore_2"; case ByteCode.FSTORE_3: return "fstore_3"; case ByteCode.DSTORE_0: return "dstore_0"; case ByteCode.DSTORE_1: return "dstore_1"; case ByteCode.DSTORE_2: return "dstore_2"; case ByteCode.DSTORE_3: return "dstore_3"; case ByteCode.ASTORE_0: return "astore_0"; case ByteCode.ASTORE_1: return "astore_1"; case ByteCode.ASTORE_2: return "astore_2"; case ByteCode.ASTORE_3: return "astore_3"; case ByteCode.IASTORE: return "iastore"; case ByteCode.LASTORE: return "lastore"; case ByteCode.FASTORE: return "fastore"; case ByteCode.DASTORE: return "dastore"; case ByteCode.AASTORE: return "aastore"; case ByteCode.BASTORE: return "bastore"; case ByteCode.CASTORE: return "castore"; case ByteCode.SASTORE: return "sastore"; case ByteCode.POP: return "pop"; case ByteCode.POP2: return "pop2"; case ByteCode.DUP: return "dup"; case ByteCode.DUP_X1: return "dup_x1"; case ByteCode.DUP_X2: return "dup_x2"; case ByteCode.DUP2: return "dup2"; case ByteCode.DUP2_X1: return "dup2_x1"; case ByteCode.DUP2_X2: return "dup2_x2"; case ByteCode.SWAP: return "swap"; case ByteCode.IADD: return "iadd"; case ByteCode.LADD: return "ladd"; case ByteCode.FADD: return "fadd"; case ByteCode.DADD: return "dadd"; case ByteCode.ISUB: return "isub"; case ByteCode.LSUB: return "lsub"; case ByteCode.FSUB: return "fsub"; case ByteCode.DSUB: return "dsub"; case ByteCode.IMUL: return "imul"; case ByteCode.LMUL: return "lmul"; case ByteCode.FMUL: return "fmul"; case ByteCode.DMUL: return "dmul"; case ByteCode.IDIV: return "idiv"; case ByteCode.LDIV: return "ldiv"; case ByteCode.FDIV: return "fdiv"; case ByteCode.DDIV: return "ddiv"; case ByteCode.IREM: return "irem"; case ByteCode.LREM: return "lrem"; case ByteCode.FREM: return "frem"; case ByteCode.DREM: return "drem"; case ByteCode.INEG: return "ineg"; case ByteCode.LNEG: return "lneg"; case ByteCode.FNEG: return "fneg"; case ByteCode.DNEG: return "dneg"; case ByteCode.ISHL: return "ishl"; case ByteCode.LSHL: return "lshl"; case ByteCode.ISHR: return "ishr"; case ByteCode.LSHR: return "lshr"; case ByteCode.IUSHR: return "iushr"; case ByteCode.LUSHR: return "lushr"; case ByteCode.IAND: return "iand"; case ByteCode.LAND: return "land"; case ByteCode.IOR: return "ior"; case ByteCode.LOR: return "lor"; case ByteCode.IXOR: return "ixor"; case ByteCode.LXOR: return "lxor"; case ByteCode.IINC: return "iinc"; case ByteCode.I2L: return "i2l"; case ByteCode.I2F: return "i2f"; case ByteCode.I2D: return "i2d"; case ByteCode.L2I: return "l2i"; case ByteCode.L2F: return "l2f"; case ByteCode.L2D: return "l2d"; case ByteCode.F2I: return "f2i"; case ByteCode.F2L: return "f2l"; case ByteCode.F2D: return "f2d"; case ByteCode.D2I: return "d2i"; case ByteCode.D2L: return "d2l"; case ByteCode.D2F: return "d2f"; case ByteCode.I2B: return "i2b"; case ByteCode.I2C: return "i2c"; case ByteCode.I2S: return "i2s"; case ByteCode.LCMP: return "lcmp"; case ByteCode.FCMPL: return "fcmpl"; case ByteCode.FCMPG: return "fcmpg"; case ByteCode.DCMPL: return "dcmpl"; case ByteCode.DCMPG: return "dcmpg"; case ByteCode.IFEQ: return "ifeq"; case ByteCode.IFNE: return "ifne"; case ByteCode.IFLT: return "iflt"; case ByteCode.IFGE: return "ifge"; case ByteCode.IFGT: return "ifgt"; case ByteCode.IFLE: return "ifle"; case ByteCode.IF_ICMPEQ: return "if_icmpeq"; case ByteCode.IF_ICMPNE: return "if_icmpne"; case ByteCode.IF_ICMPLT: return "if_icmplt"; case ByteCode.IF_ICMPGE: return "if_icmpge"; case ByteCode.IF_ICMPGT: return "if_icmpgt"; case ByteCode.IF_ICMPLE: return "if_icmple"; case ByteCode.IF_ACMPEQ: return "if_acmpeq"; case ByteCode.IF_ACMPNE: return "if_acmpne"; case ByteCode.GOTO: return "goto"; case ByteCode.JSR: return "jsr"; case ByteCode.RET: return "ret"; case ByteCode.TABLESWITCH: return "tableswitch"; case ByteCode.LOOKUPSWITCH: return "lookupswitch"; case ByteCode.IRETURN: return "ireturn"; case ByteCode.LRETURN: return "lreturn"; case ByteCode.FRETURN: return "freturn"; case ByteCode.DRETURN: return "dreturn"; case ByteCode.ARETURN: return "areturn"; case ByteCode.RETURN: return "return"; case ByteCode.GETSTATIC: return "getstatic"; case ByteCode.PUTSTATIC: return "putstatic"; case ByteCode.GETFIELD: return "getfield"; case ByteCode.PUTFIELD: return "putfield"; case ByteCode.INVOKEVIRTUAL: return "invokevirtual"; case ByteCode.INVOKESPECIAL: return "invokespecial"; case ByteCode.INVOKESTATIC: return "invokestatic"; case ByteCode.INVOKEINTERFACE: return "invokeinterface"; case ByteCode.NEW: return "new"; case ByteCode.NEWARRAY: return "newarray"; case ByteCode.ANEWARRAY: return "anewarray"; case ByteCode.ARRAYLENGTH: return "arraylength"; case ByteCode.ATHROW: return "athrow"; case ByteCode.CHECKCAST: return "checkcast"; case ByteCode.INSTANCEOF: return "instanceof"; case ByteCode.MONITORENTER: return "monitorenter"; case ByteCode.MONITOREXIT: return "monitorexit"; case ByteCode.WIDE: return "wide"; case ByteCode.MULTIANEWARRAY: return "multianewarray"; case ByteCode.IFNULL: return "ifnull"; case ByteCode.IFNONNULL: return "ifnonnull"; case ByteCode.GOTO_W: return "goto_w"; case ByteCode.JSR_W: return "jsr_w"; case ByteCode.BREAKPOINT: return "breakpoint"; case ByteCode.IMPDEP1: return "impdep1"; case ByteCode.IMPDEP2: return "impdep2"; } } return ""; } final char[] getCharBuffer(int minimalSize) { if (minimalSize > tmpCharBuffer.length) { int newSize = tmpCharBuffer.length * 2; if (minimalSize > newSize) { newSize = minimalSize; } tmpCharBuffer = new char[newSize]; } return tmpCharBuffer; } private static final int LineNumberTableSize = 16; private static final int ExceptionTableSize = 4; private final static long FileHeaderConstant = 0xCAFEBABE0003002DL; // Set DEBUG flags to true to get better checking and progress info. private static final boolean DEBUGSTACK = false; private static final boolean DEBUGLABELS = false; private static final boolean DEBUGCODE = false; private String generatedClassName; private ExceptionTableEntry itsExceptionTable[]; private int itsExceptionTableTop; private int itsLineNumberTable[]; // pack start_pc & line_number together private int itsLineNumberTableTop; private byte[] itsCodeBuffer = new byte[256]; private int itsCodeBufferTop; private ConstantPool itsConstantPool; private ClassFileMethod itsCurrentMethod; private short itsStackTop; private short itsMaxStack; private short itsMaxLocals; private ObjArray itsMethods = new ObjArray(); private ObjArray itsFields = new ObjArray(); private ObjArray itsInterfaces = new ObjArray(); private short itsFlags; private short itsThisClassIndex; private short itsSuperClassIndex; private short itsSourceFileNameIndex; private static final int MIN_LABEL_TABLE_SIZE = 32; private int[] itsLabelTable; private int itsLabelTableTop; // itsFixupTable[i] = (label_index << 32) | fixup_site private static final int MIN_FIXUP_TABLE_SIZE = 40; private long[] itsFixupTable; private int itsFixupTableTop; private ObjArray itsVarDescriptors; private char[] tmpCharBuffer = new char[64]; } final class ExceptionTableEntry { ExceptionTableEntry(int startLabel, int endLabel, int handlerLabel, short catchType) { itsStartLabel = startLabel; itsEndLabel = endLabel; itsHandlerLabel = handlerLabel; itsCatchType = catchType; } int itsStartLabel; int itsEndLabel; int itsHandlerLabel; short itsCatchType; } final class ClassFileField { ClassFileField(short nameIndex, short typeIndex, short flags) { itsNameIndex = nameIndex; itsTypeIndex = typeIndex; itsFlags = flags; itsHasAttributes = false; } void setAttributes(short attr1, short attr2, short attr3, int index) { itsHasAttributes = true; itsAttr1 = attr1; itsAttr2 = attr2; itsAttr3 = attr3; itsIndex = index; } int write(byte[] data, int offset) { offset = ClassFileWriter.putInt16(itsFlags, data, offset); offset = ClassFileWriter.putInt16(itsNameIndex, data, offset); offset = ClassFileWriter.putInt16(itsTypeIndex, data, offset); if (!itsHasAttributes) { // write 0 attributes offset = ClassFileWriter.putInt16(0, data, offset); } else { offset = ClassFileWriter.putInt16(1, data, offset); offset = ClassFileWriter.putInt16(itsAttr1, data, offset); offset = ClassFileWriter.putInt16(itsAttr2, data, offset); offset = ClassFileWriter.putInt16(itsAttr3, data, offset); offset = ClassFileWriter.putInt16(itsIndex, data, offset); } return offset; } int getWriteSize() { int size = 2 * 3; if (!itsHasAttributes) { size += 2; } else { size += 2 + 2 * 4; } return size; } private short itsNameIndex; private short itsTypeIndex; private short itsFlags; private boolean itsHasAttributes; private short itsAttr1, itsAttr2, itsAttr3; private int itsIndex; } final class ClassFileMethod { ClassFileMethod(short nameIndex, short typeIndex, short flags) { itsNameIndex = nameIndex; itsTypeIndex = typeIndex; itsFlags = flags; } void setCodeAttribute(byte codeAttribute[]) { itsCodeAttribute = codeAttribute; } int write(byte[] data, int offset) { offset = ClassFileWriter.putInt16(itsFlags, data, offset); offset = ClassFileWriter.putInt16(itsNameIndex, data, offset); offset = ClassFileWriter.putInt16(itsTypeIndex, data, offset); // Code attribute only offset = ClassFileWriter.putInt16(1, data, offset); System.arraycopy(itsCodeAttribute, 0, data, offset, itsCodeAttribute.length); offset += itsCodeAttribute.length; return offset; } int getWriteSize() { return 2 * 4 + itsCodeAttribute.length; } private short itsNameIndex; private short itsTypeIndex; private short itsFlags; private byte[] itsCodeAttribute; } final class ConstantPool { ConstantPool(ClassFileWriter cfw) { this.cfw = cfw; itsTopIndex = 1; // the zero'th entry is reserved itsPool = new byte[ConstantPoolSize]; itsTop = 0; } private static final int ConstantPoolSize = 256; private static final byte CONSTANT_Class = 7, CONSTANT_Fieldref = 9, CONSTANT_Methodref = 10, CONSTANT_InterfaceMethodref = 11, CONSTANT_String = 8, CONSTANT_Integer = 3, CONSTANT_Float = 4, CONSTANT_Long = 5, CONSTANT_Double = 6, CONSTANT_NameAndType = 12, CONSTANT_Utf8 = 1; int write(byte[] data, int offset) { offset = ClassFileWriter.putInt16((short)itsTopIndex, data, offset); System.arraycopy(itsPool, 0, data, offset, itsTop); offset += itsTop; return offset; } int getWriteSize() { return 2 + itsTop; } int addConstant(int k) { ensure(5); itsPool[itsTop++] = CONSTANT_Integer; itsTop = ClassFileWriter.putInt32(k, itsPool, itsTop); return (short)(itsTopIndex++); } int addConstant(long k) { ensure(9); itsPool[itsTop++] = CONSTANT_Long; itsTop = ClassFileWriter.putInt64(k, itsPool, itsTop); int index = itsTopIndex; itsTopIndex += 2; return index; } int addConstant(float k) { ensure(5); itsPool[itsTop++] = CONSTANT_Float; int bits = Float.floatToIntBits(k); itsTop = ClassFileWriter.putInt32(bits, itsPool, itsTop); return itsTopIndex++; } int addConstant(double k) { ensure(9); itsPool[itsTop++] = CONSTANT_Double; long bits = Double.doubleToLongBits(k); itsTop = ClassFileWriter.putInt64(bits, itsPool, itsTop); int index = itsTopIndex; itsTopIndex += 2; return index; } int addConstant(String k) { int utf8Index = 0xFFFF & addUtf8(k); int theIndex = itsStringConstHash.getInt(utf8Index, -1); if (theIndex == -1) { theIndex = itsTopIndex++; ensure(3); itsPool[itsTop++] = CONSTANT_String; itsTop = ClassFileWriter.putInt16(utf8Index, itsPool, itsTop); itsStringConstHash.put(utf8Index, theIndex); } return theIndex; } boolean isUnderUtfEncodingLimit(String s) { int strLen = s.length(); if (strLen * 3 <= MAX_UTF_ENCODING_SIZE) { return true; } else if (strLen > MAX_UTF_ENCODING_SIZE) { return false; } return strLen == getUtfEncodingLimit(s, 0, strLen); } /** * Get maximum i such that start <= i <= end and * s.substring(start, i) fits JVM UTF string encoding limit. */ int getUtfEncodingLimit(String s, int start, int end) { if ((end - start) * 3 <= MAX_UTF_ENCODING_SIZE) { return end; } int limit = MAX_UTF_ENCODING_SIZE; for (int i = start; i != end; i++) { int c = s.charAt(i); if (0 != c && c <= 0x7F) { --limit; } else if (c < 0x7FF) { limit -= 2; } else { limit -= 3; } if (limit < 0) { return i; } } return end; } short addUtf8(String k) { int theIndex = itsUtf8Hash.get(k, -1); if (theIndex == -1) { int strLen = k.length(); boolean tooBigString; if (strLen > MAX_UTF_ENCODING_SIZE) { tooBigString = true; } else { tooBigString = false; // Ask for worst case scenario buffer when each char takes 3 // bytes ensure(1 + 2 + strLen * 3); int top = itsTop; itsPool[top++] = CONSTANT_Utf8; top += 2; // skip length char[] chars = cfw.getCharBuffer(strLen); k.getChars(0, strLen, chars, 0); for (int i = 0; i != strLen; i++) { int c = chars[i]; if (c != 0 && c <= 0x7F) { itsPool[top++] = (byte)c; } else if (c > 0x7FF) { itsPool[top++] = (byte)(0xE0 | (c >> 12)); itsPool[top++] = (byte)(0x80 | ((c >> 6) & 0x3F)); itsPool[top++] = (byte)(0x80 | (c & 0x3F)); } else { itsPool[top++] = (byte)(0xC0 | (c >> 6)); itsPool[top++] = (byte)(0x80 | (c & 0x3F)); } } int utfLen = top - (itsTop + 1 + 2); if (utfLen > MAX_UTF_ENCODING_SIZE) { tooBigString = true; } else { // Write back length itsPool[itsTop + 1] = (byte)(utfLen >>> 8); itsPool[itsTop + 2] = (byte)utfLen; itsTop = top; theIndex = itsTopIndex++; itsUtf8Hash.put(k, theIndex); } } if (tooBigString) { throw new IllegalArgumentException("Too big string"); } } return (short)theIndex; } private short addNameAndType(String name, String type) { short nameIndex = addUtf8(name); short typeIndex = addUtf8(type); ensure(5); itsPool[itsTop++] = CONSTANT_NameAndType; itsTop = ClassFileWriter.putInt16(nameIndex, itsPool, itsTop); itsTop = ClassFileWriter.putInt16(typeIndex, itsPool, itsTop); return (short)(itsTopIndex++); } short addClass(String className) { int theIndex = itsClassHash.get(className, -1); if (theIndex == -1) { String slashed = className; if (className.indexOf('.') > 0) { slashed = ClassFileWriter.getSlashedForm(className); theIndex = itsClassHash.get(slashed, -1); if (theIndex != -1) { itsClassHash.put(className, theIndex); } } if (theIndex == -1) { int utf8Index = addUtf8(slashed); ensure(3); itsPool[itsTop++] = CONSTANT_Class; itsTop = ClassFileWriter.putInt16(utf8Index, itsPool, itsTop); theIndex = itsTopIndex++; itsClassHash.put(slashed, theIndex); if (className != slashed) { itsClassHash.put(className, theIndex); } } } return (short)theIndex; } short addFieldRef(String className, String fieldName, String fieldType) { FieldOrMethodRef ref = new FieldOrMethodRef(className, fieldName, fieldType); int theIndex = itsFieldRefHash.get(ref, -1); if (theIndex == -1) { short ntIndex = addNameAndType(fieldName, fieldType); short classIndex = addClass(className); ensure(5); itsPool[itsTop++] = CONSTANT_Fieldref; itsTop = ClassFileWriter.putInt16(classIndex, itsPool, itsTop); itsTop = ClassFileWriter.putInt16(ntIndex, itsPool, itsTop); theIndex = itsTopIndex++; itsFieldRefHash.put(ref, theIndex); } return (short)theIndex; } short addMethodRef(String className, String methodName, String methodType) { FieldOrMethodRef ref = new FieldOrMethodRef(className, methodName, methodType); int theIndex = itsMethodRefHash.get(ref, -1); if (theIndex == -1) { short ntIndex = addNameAndType(methodName, methodType); short classIndex = addClass(className); ensure(5); itsPool[itsTop++] = CONSTANT_Methodref; itsTop = ClassFileWriter.putInt16(classIndex, itsPool, itsTop); itsTop = ClassFileWriter.putInt16(ntIndex, itsPool, itsTop); theIndex = itsTopIndex++; itsMethodRefHash.put(ref, theIndex); } return (short)theIndex; } short addInterfaceMethodRef(String className, String methodName, String methodType) { short ntIndex = addNameAndType(methodName, methodType); short classIndex = addClass(className); ensure(5); itsPool[itsTop++] = CONSTANT_InterfaceMethodref; itsTop = ClassFileWriter.putInt16(classIndex, itsPool, itsTop); itsTop = ClassFileWriter.putInt16(ntIndex, itsPool, itsTop); return (short)(itsTopIndex++); } void ensure(int howMuch) { if (itsTop + howMuch > itsPool.length) { int newCapacity = itsPool.length * 2; if (itsTop + howMuch > newCapacity) { newCapacity = itsTop + howMuch; } byte[] tmp = new byte[newCapacity]; System.arraycopy(itsPool, 0, tmp, 0, itsTop); itsPool = tmp; } } private ClassFileWriter cfw; private static final int MAX_UTF_ENCODING_SIZE = 65535; private UintMap itsStringConstHash = new UintMap(); private ObjToIntMap itsUtf8Hash = new ObjToIntMap(); private ObjToIntMap itsFieldRefHash = new ObjToIntMap(); private ObjToIntMap itsMethodRefHash = new ObjToIntMap(); private ObjToIntMap itsClassHash = new ObjToIntMap(); private int itsTop; private int itsTopIndex; private byte itsPool[]; } final class FieldOrMethodRef { FieldOrMethodRef(String className, String name, String type) { this.className = className; this.name = name; this.type = type; } @Override public boolean equals(Object obj) { if (!(obj instanceof FieldOrMethodRef)) { return false; } FieldOrMethodRef x = (FieldOrMethodRef)obj; return className.equals(x.className) && name.equals(x.name) && type.equals(x.type); } @Override public int hashCode() { if (hashCode == -1) { int h1 = className.hashCode(); int h2 = name.hashCode(); int h3 = type.hashCode(); hashCode = h1 ^ h2 ^ h3; } return hashCode; } private String className; private String name; private String type; private int hashCode = -1; } yui-compressor-2.4.7/src/org/mozilla/javascript/0000755000175000017500000000000011753547210021620 5ustar drazzibdrazzibyui-compressor-2.4.7/src/org/mozilla/javascript/RhinoException.java0000644000175000017500000002327311753547210025430 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.CharArrayWriter; import java.io.File; import java.io.FilenameFilter; import java.io.PrintStream; import java.io.PrintWriter; import java.util.List; /** * The class of exceptions thrown by the JavaScript engine. */ public abstract class RhinoException extends RuntimeException { RhinoException() { Evaluator e = Context.createInterpreter(); if (e != null) e.captureStackInfo(this); } RhinoException(String details) { super(details); Evaluator e = Context.createInterpreter(); if (e != null) e.captureStackInfo(this); } @Override public final String getMessage() { String details = details(); if (sourceName == null || lineNumber <= 0) { return details; } StringBuffer buf = new StringBuffer(details); buf.append(" ("); if (sourceName != null) { buf.append(sourceName); } if (lineNumber > 0) { buf.append('#'); buf.append(lineNumber); } buf.append(')'); return buf.toString(); } public String details() { return super.getMessage(); } /** * Get the uri of the script source containing the error, or null * if that information is not available. */ public final String sourceName() { return sourceName; } /** * Initialize the uri of the script source containing the error. * * @param sourceName the uri of the script source responsible for the error. * It should not be null. * * @throws IllegalStateException if the method is called more then once. */ public final void initSourceName(String sourceName) { if (sourceName == null) throw new IllegalArgumentException(); if (this.sourceName != null) throw new IllegalStateException(); this.sourceName = sourceName; } /** * Returns the line number of the statement causing the error, * or zero if not available. */ public final int lineNumber() { return lineNumber; } /** * Initialize the line number of the script statement causing the error. * * @param lineNumber the line number in the script source. * It should be positive number. * * @throws IllegalStateException if the method is called more then once. */ public final void initLineNumber(int lineNumber) { if (lineNumber <= 0) throw new IllegalArgumentException(String.valueOf(lineNumber)); if (this.lineNumber > 0) throw new IllegalStateException(); this.lineNumber = lineNumber; } /** * The column number of the location of the error, or zero if unknown. */ public final int columnNumber() { return columnNumber; } /** * Initialize the column number of the script statement causing the error. * * @param columnNumber the column number in the script source. * It should be positive number. * * @throws IllegalStateException if the method is called more then once. */ public final void initColumnNumber(int columnNumber) { if (columnNumber <= 0) throw new IllegalArgumentException(String.valueOf(columnNumber)); if (this.columnNumber > 0) throw new IllegalStateException(); this.columnNumber = columnNumber; } /** * The source text of the line causing the error, or null if unknown. */ public final String lineSource() { return lineSource; } /** * Initialize the text of the source line containing the error. * * @param lineSource the text of the source line responsible for the error. * It should not be null. * * @throws IllegalStateException if the method is called more then once. */ public final void initLineSource(String lineSource) { if (lineSource == null) throw new IllegalArgumentException(); if (this.lineSource != null) throw new IllegalStateException(); this.lineSource = lineSource; } final void recordErrorOrigin(String sourceName, int lineNumber, String lineSource, int columnNumber) { // XXX: for compatibility allow for now -1 to mean 0 if (lineNumber == -1) { lineNumber = 0; } if (sourceName != null) { initSourceName(sourceName); } if (lineNumber != 0) { initLineNumber(lineNumber); } if (lineSource != null) { initLineSource(lineSource); } if (columnNumber != 0) { initColumnNumber(columnNumber); } } private String generateStackTrace() { // Get stable reference to work properly with concurrent access CharArrayWriter writer = new CharArrayWriter(); super.printStackTrace(new PrintWriter(writer)); String origStackTrace = writer.toString(); Evaluator e = Context.createInterpreter(); if (e != null) return e.getPatchedStack(this, origStackTrace); return null; } /** * Get a string representing the script stack of this exception. * If optimization is enabled, this corresponds to all java stack elements * with a source name ending with ".js". * @return a script stack dump * @since 1.6R6 */ public String getScriptStackTrace() { return getScriptStackTrace(new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".js"); } }); } /** * Get a string representing the script stack of this exception. * If optimization is enabled, this corresponds to all java stack elements * with a source name matching the filter. * @param filter the file name filter to determine whether a file is a * script file * @return a script stack dump * @since 1.6R6 */ public String getScriptStackTrace(FilenameFilter filter) { List interpreterStack = null; Evaluator interpreter = Context.createInterpreter(); if (interpreter != null) { interpreterStack = interpreter.getScriptStack(this); } int interpreterStackIndex = 0; StringBuffer buffer = new StringBuffer(); String lineSeparator = SecurityUtilities.getSystemProperty("line.separator"); StackTraceElement[] stack = getStackTrace(); for (int i = 0; i < stack.length; i++) { StackTraceElement e = stack[i]; String name = e.getFileName(); if (e.getLineNumber() > -1 && name != null && filter.accept(null, name)) { buffer.append("\tat "); buffer.append(e.getFileName()); buffer.append(':'); buffer.append(e.getLineNumber()); buffer.append(lineSeparator); } else if (interpreterStack != null && interpreterStack.size() > interpreterStackIndex && "org.mozilla.javascript.Interpreter".equals(e.getClassName()) && "interpretLoop".equals(e.getMethodName())) { buffer.append(interpreterStack.get(interpreterStackIndex++)); } } return buffer.toString(); } @Override public void printStackTrace(PrintWriter s) { if (interpreterStackInfo == null) { super.printStackTrace(s); } else { s.print(generateStackTrace()); } } @Override public void printStackTrace(PrintStream s) { if (interpreterStackInfo == null) { super.printStackTrace(s); } else { s.print(generateStackTrace()); } } private String sourceName; private int lineNumber; private String lineSource; private int columnNumber; Object interpreterStackInfo; int[] interpreterLineData; } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeJavaClass.java0000644000175000017500000003020611753547210025502 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Frank Mitchell * Mike Shaver * Kurt Westerfeld * Kemal Bayram * Ulrike Mueller * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.lang.reflect.*; import java.util.Map; /** * This class reflects Java classes into the JavaScript environment, mainly * for constructors and static members. We lazily reflect properties, * and currently do not guarantee that a single j.l.Class is only * reflected once into the JS environment, although we should. * The only known case where multiple reflections * are possible occurs when a j.l.Class is wrapped as part of a * method return or property access, rather than by walking the * Packages/java tree. * * @author Mike Shaver * @see NativeJavaArray * @see NativeJavaObject * @see NativeJavaPackage */ public class NativeJavaClass extends NativeJavaObject implements Function { static final long serialVersionUID = -6460763940409461664L; // Special property for getting the underlying Java class object. static final String javaClassPropertyName = "__javaObject__"; public NativeJavaClass() { } public NativeJavaClass(Scriptable scope, Class cl) { this.parent = scope; this.javaObject = cl; initMembers(); } @Override protected void initMembers() { Class cl = (Class)javaObject; members = JavaMembers.lookupClass(parent, cl, cl, false); staticFieldAndMethods = members.getFieldAndMethodsObjects(this, cl, true); } @Override public String getClassName() { return "JavaClass"; } @Override public boolean has(String name, Scriptable start) { return members.has(name, true) || javaClassPropertyName.equals(name); } @Override public Object get(String name, Scriptable start) { // When used as a constructor, ScriptRuntime.newObject() asks // for our prototype to create an object of the correct type. // We don't really care what the object is, since we're returning // one constructed out of whole cloth, so we return null. if (name.equals("prototype")) return null; if (staticFieldAndMethods != null) { Object result = staticFieldAndMethods.get(name); if (result != null) return result; } if (members.has(name, true)) { return members.get(this, name, javaObject, true); } if (javaClassPropertyName.equals(name)) { Context cx = Context.getContext(); Scriptable scope = ScriptableObject.getTopLevelScope(start); return cx.getWrapFactory().wrap(cx, scope, javaObject, ScriptRuntime.ClassClass); } // experimental: look for nested classes by appending $name to // current class' name. Class nestedClass = findNestedClass(getClassObject(), name); if (nestedClass != null) { NativeJavaClass nestedValue = new NativeJavaClass (ScriptableObject.getTopLevelScope(this), nestedClass); nestedValue.setParentScope(this); return nestedValue; } throw members.reportMemberNotFound(name); } @Override public void put(String name, Scriptable start, Object value) { members.put(this, name, javaObject, value, true); } @Override public Object[] getIds() { return members.getIds(true); } public Class getClassObject() { return (Class) super.unwrap(); } @Override public Object getDefaultValue(Class hint) { if (hint == null || hint == ScriptRuntime.StringClass) return this.toString(); if (hint == ScriptRuntime.BooleanClass) return Boolean.TRUE; if (hint == ScriptRuntime.NumberClass) return ScriptRuntime.NaNobj; return this; } public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { // If it looks like a "cast" of an object to this class type, // walk the prototype chain to see if there's a wrapper of a // object that's an instanceof this class. if (args.length == 1 && args[0] instanceof Scriptable) { Class c = getClassObject(); Scriptable p = (Scriptable) args[0]; do { if (p instanceof Wrapper) { Object o = ((Wrapper) p).unwrap(); if (c.isInstance(o)) return p; } p = p.getPrototype(); } while (p != null); } return construct(cx, scope, args); } public Scriptable construct(Context cx, Scriptable scope, Object[] args) { Class classObject = getClassObject(); int modifiers = classObject.getModifiers(); if (! (Modifier.isInterface(modifiers) || Modifier.isAbstract(modifiers))) { MemberBox[] ctors = members.ctors; int index = NativeJavaMethod.findFunction(cx, ctors, args); if (index < 0) { String sig = NativeJavaMethod.scriptSignature(args); throw Context.reportRuntimeError2( "msg.no.java.ctor", classObject.getName(), sig); } // Found the constructor, so try invoking it. return constructSpecific(cx, scope, args, ctors[index]); } else { Scriptable topLevel = ScriptableObject.getTopLevelScope(this); String msg = ""; try { // trying to construct an interface; use JavaAdapter to // construct a new class on the fly that implements this // interface. Object v = topLevel.get("JavaAdapter", topLevel); if (v != NOT_FOUND) { Function f = (Function) v; Object[] adapterArgs = { this, args[0] }; return f.construct(cx, topLevel,adapterArgs); } } catch (Exception ex) { // fall through to error String m = ex.getMessage(); if (m != null) msg = m; } throw Context.reportRuntimeError2( "msg.cant.instantiate", msg, classObject.getName()); } } static Scriptable constructSpecific(Context cx, Scriptable scope, Object[] args, MemberBox ctor) { Scriptable topLevel = ScriptableObject.getTopLevelScope(scope); Class[] argTypes = ctor.argTypes; if (ctor.vararg) { // marshall the explicit parameter Object[] newArgs = new Object[argTypes.length]; for (int i = 0; i < argTypes.length-1; i++) { newArgs[i] = Context.jsToJava(args[i], argTypes[i]); } Object varArgs; // Handle special situation where a single variable parameter // is given and it is a Java or ECMA array. if (args.length == argTypes.length && (args[args.length-1] == null || args[args.length-1] instanceof NativeArray || args[args.length-1] instanceof NativeJavaArray)) { // convert the ECMA array into a native array varArgs = Context.jsToJava(args[args.length-1], argTypes[argTypes.length - 1]); } else { // marshall the variable parameter Class componentType = argTypes[argTypes.length - 1]. getComponentType(); varArgs = Array.newInstance(componentType, args.length - argTypes.length + 1); for (int i=0; i < Array.getLength(varArgs); i++) { Object value = Context.jsToJava(args[argTypes.length-1 + i], componentType); Array.set(varArgs, i, value); } } // add varargs newArgs[argTypes.length-1] = varArgs; // replace the original args with the new one args = newArgs; } else { Object[] origArgs = args; for (int i = 0; i < args.length; i++) { Object arg = args[i]; Object x = Context.jsToJava(arg, argTypes[i]); if (x != arg) { if (args == origArgs) { args = origArgs.clone(); } args[i] = x; } } } Object instance = ctor.newInstance(args); // we need to force this to be wrapped, because construct _has_ // to return a scriptable return cx.getWrapFactory().wrapNewObject(cx, topLevel, instance); } @Override public String toString() { return "[JavaClass " + getClassObject().getName() + "]"; } /** * Determines if prototype is a wrapped Java object and performs * a Java "instanceof". * Exception: if value is an instance of NativeJavaClass, it isn't * considered an instance of the Java class; this forestalls any * name conflicts between java.lang.Class's methods and the * static methods exposed by a JavaNativeClass. */ @Override public boolean hasInstance(Scriptable value) { if (value instanceof Wrapper && !(value instanceof NativeJavaClass)) { Object instance = ((Wrapper)value).unwrap(); return getClassObject().isInstance(instance); } // value wasn't something we understand return false; } private static Class findNestedClass(Class parentClass, String name) { String nestedClassName = parentClass.getName() + '$' + name; ClassLoader loader = parentClass.getClassLoader(); if (loader == null) { // ALERT: if loader is null, nested class should be loaded // via system class loader which can be different from the // loader that brought Rhino classes that Class.forName() would // use, but ClassLoader.getSystemClassLoader() is Java 2 only return Kit.classOrNull(nestedClassName); } else { return Kit.classOrNull(loader, nestedClassName); } } private Map staticFieldAndMethods; } yui-compressor-2.4.7/src/org/mozilla/javascript/jdk15/0000755000175000017500000000000011753547210022536 5ustar drazzibdrazzibyui-compressor-2.4.7/src/org/mozilla/javascript/jdk15/VMBridge_jdk15.java0000644000175000017500000000675511753547210026053 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript.jdk15; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.util.Iterator; import org.mozilla.javascript.*; public class VMBridge_jdk15 extends org.mozilla.javascript.jdk13.VMBridge_jdk13 { public VMBridge_jdk15() throws SecurityException, InstantiationException { try { // Just try and see if we can access the isVarArgs method. // We want to fail loading if the method does not exist // so that we can load a bridge to an older JDK instead. Method.class.getMethod("isVarArgs", (Class[]) null); } catch (NoSuchMethodException e) { // Throw a fitting exception that is handled by // org.mozilla.javascript.Kit.newInstanceOrNull: throw new InstantiationException(e.getMessage()); } } @Override public boolean isVarArgs(Member member) { if (member instanceof Method) return ((Method) member).isVarArgs(); else if (member instanceof Constructor) return ((Constructor) member).isVarArgs(); else return false; } /** * If "obj" is a java.util.Iterator or a java.lang.Iterable, return a * wrapping as a JavaScript Iterator. Otherwise, return null. * This method is in VMBridge since Iterable is a JDK 1.5 addition. */ @Override public Iterator getJavaIterator(Context cx, Scriptable scope, Object obj) { if (obj instanceof Wrapper) { Object unwrapped = ((Wrapper) obj).unwrap(); Iterator iterator = null; if (unwrapped instanceof Iterator) iterator = (Iterator) unwrapped; if (unwrapped instanceof Iterable) iterator = ((Iterable)unwrapped).iterator(); return iterator; } return null; } } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeFunction.java0000644000175000017500000001255011753547210025422 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * Bob Jervis * Roger Lawrence * Mike McCabe * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import org.mozilla.javascript.debug.DebuggableScript; /** * This class implements the Function native object. * See ECMA 15.3. * @author Norris Boyd */ public abstract class NativeFunction extends BaseFunction { public final void initScriptFunction(Context cx, Scriptable scope) { ScriptRuntime.setFunctionProtoAndParent(this, scope); } /** * @param indent How much to indent the decompiled result * * @param flags Flags specifying format of decompilation output */ @Override final String decompile(int indent, int flags) { String encodedSource = getEncodedSource(); if (encodedSource == null) { return super.decompile(indent, flags); } else { UintMap properties = new UintMap(1); properties.put(Decompiler.INITIAL_INDENT_PROP, indent); return Decompiler.decompile(encodedSource, flags, properties); } } @Override public int getLength() { int paramCount = getParamCount(); if (getLanguageVersion() != Context.VERSION_1_2) { return paramCount; } Context cx = Context.getContext(); NativeCall activation = ScriptRuntime.findFunctionActivation(cx, this); if (activation == null) { return paramCount; } return activation.originalArgs.length; } @Override public int getArity() { return getParamCount(); } /** * @deprecated Use {@link BaseFunction#getFunctionName()} instead. * For backwards compatibility keep an old method name used by * Batik and possibly others. */ public String jsGet_name() { return getFunctionName(); } /** * Get encoded source string. */ public String getEncodedSource() { return null; } public DebuggableScript getDebuggableView() { return null; } /** * Resume execution of a suspended generator. * @param cx The current context * @param scope Scope for the parent generator function * @param operation The resumption operation (next, send, etc.. ) * @param state The generator state (has locals, stack, etc.) * @param value The return value of yield (if required). * @return The next yielded value (if any) */ public Object resumeGenerator(Context cx, Scriptable scope, int operation, Object state, Object value) { throw new EvaluatorException("resumeGenerator() not implemented"); } protected abstract int getLanguageVersion(); /** * Get number of declared parameters. It should be 0 for scripts. */ protected abstract int getParamCount(); /** * Get number of declared parameters and variables defined through var * statements. */ protected abstract int getParamAndVarCount(); /** * Get parameter or variable name. * If index < {@link #getParamCount()}, then return the name of the * corresponding parameter. Otherwise return the name of variable. */ protected abstract String getParamOrVarName(int index); /** * Get parameter or variable const-ness. * If index < {@link #getParamCount()}, then return the const-ness * of the corresponding parameter. Otherwise return whether the variable is * const. */ protected boolean getParamOrVarConst(int index) { // By default return false to preserve compatibility with existing // classes subclassing this class, which are mostly generated by jsc // from earlier Rhino versions. See Bugzilla #396117. return false; } } yui-compressor-2.4.7/src/org/mozilla/javascript/ConstProperties.java0000644000175000017500000001152611753547210025633 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Bob Jervis * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; public interface ConstProperties { /** * Sets a named const property in this object. *

* The property is specified by a string name * as defined for Scriptable.get. *

* The possible values that may be passed in are as defined for * Scriptable.get. A class that implements this method may choose * to ignore calls to set certain properties, in which case those * properties are effectively read-only.

* For properties defined in a prototype chain, * use putProperty in ScriptableObject.

* Note that if a property a is defined in the prototype p * of an object o, then evaluating o.a = 23 will cause * set to be called on the prototype p with * o as the start parameter. * To preserve JavaScript semantics, it is the Scriptable * object's responsibility to modify o.

* This design allows properties to be defined in prototypes and implemented * in terms of getters and setters of Java values without consuming slots * in each instance.

*

* The values that may be set are limited to the following: *

    *
  • java.lang.Boolean objects
  • *
  • java.lang.String objects
  • *
  • java.lang.Number objects
  • *
  • org.mozilla.javascript.Scriptable objects
  • *
  • null
  • *
  • The value returned by Context.getUndefinedValue()
  • *

* Arbitrary Java objects may be wrapped in a Scriptable by first calling * Context.toObject. This allows the property of a JavaScript * object to contain an arbitrary Java object as a value.

* Note that has will be called by the runtime first before * set is called to determine in which object the * property is defined. * Note that this method is not expected to traverse the prototype chain, * which is different from the ECMA [[Put]] operation. * @param name the name of the property * @param start the object whose property is being set * @param value value to set the property to * @see org.mozilla.javascript.Scriptable#has(String, Scriptable) * @see org.mozilla.javascript.Scriptable#get(String, Scriptable) * @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, String, Object) * @see org.mozilla.javascript.Context#toObject(Object, Scriptable) */ public void putConst(String name, Scriptable start, Object value); /** * Reserves a definition spot for a const. This will set up a definition * of the const property, but set its value to undefined. The semantics of * the start parameter is the same as for putConst. * @param name The name of the property. * @param start The object whose property is being reserved. */ public void defineConst(String name, Scriptable start); /** * Returns true if the named property is defined as a const on this object. * @param name * @return true if the named property is defined as a const, false * otherwise. */ public boolean isConst(String name); } yui-compressor-2.4.7/src/org/mozilla/javascript/ObjToIntMap.java0000644000175000017500000005143111753547210024615 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.Serializable; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * Map to associate objects to integers. * The map does not synchronize any of its operation, so either use * it from a single thread or do own synchronization or perform all mutation * operations on one thread before passing the map to others * * @author Igor Bukanov * */ public class ObjToIntMap implements Serializable { static final long serialVersionUID = -1542220580748809402L; // Map implementation via hashtable, // follows "The Art of Computer Programming" by Donald E. Knuth // ObjToIntMap is a copy cat of ObjToIntMap with API adjusted to object keys public static class Iterator { Iterator(ObjToIntMap master) { this.master = master; } final void init(Object[] keys, int[] values, int keyCount) { this.keys = keys; this.values = values; this.cursor = -1; this.remaining = keyCount; } public void start() { master.initIterator(this); next(); } public boolean done() { return remaining < 0; } public void next() { if (remaining == -1) Kit.codeBug(); if (remaining == 0) { remaining = -1; cursor = -1; }else { for (++cursor; ; ++cursor) { Object key = keys[cursor]; if (key != null && key != DELETED) { --remaining; break; } } } } public Object getKey() { Object key = keys[cursor]; if (key == UniqueTag.NULL_VALUE) { key = null; } return key; } public int getValue() { return values[cursor]; } public void setValue(int value) { values[cursor] = value; } ObjToIntMap master; private int cursor; private int remaining; private Object[] keys; private int[] values; } public ObjToIntMap() { this(4); } public ObjToIntMap(int keyCountHint) { if (keyCountHint < 0) Kit.codeBug(); // Table grow when number of stored keys >= 3/4 of max capacity int minimalCapacity = keyCountHint * 4 / 3; int i; for (i = 2; (1 << i) < minimalCapacity; ++i) { } power = i; if (check && power < 2) Kit.codeBug(); } public boolean isEmpty() { return keyCount == 0; } public int size() { return keyCount; } public boolean has(Object key) { if (key == null) { key = UniqueTag.NULL_VALUE; } return 0 <= findIndex(key); } /** * Get integer value assigned with key. * @return key integer value or defaultValue if key is absent */ public int get(Object key, int defaultValue) { if (key == null) { key = UniqueTag.NULL_VALUE; } int index = findIndex(key); if (0 <= index) { return values[index]; } return defaultValue; } /** * Get integer value assigned with key. * @return key integer value * @throws RuntimeException if key does not exist */ public int getExisting(Object key) { if (key == null) { key = UniqueTag.NULL_VALUE; } int index = findIndex(key); if (0 <= index) { return values[index]; } // Key must exist Kit.codeBug(); return 0; } public void put(Object key, int value) { if (key == null) { key = UniqueTag.NULL_VALUE; } int index = ensureIndex(key); values[index] = value; } /** * If table already contains a key that equals to keyArg, return that key * while setting its value to zero, otherwise add keyArg with 0 value to * the table and return it. */ public Object intern(Object keyArg) { boolean nullKey = false; if (keyArg == null) { nullKey = true; keyArg = UniqueTag.NULL_VALUE; } int index = ensureIndex(keyArg); values[index] = 0; return (nullKey) ? null : keys[index]; } public void remove(Object key) { if (key == null) { key = UniqueTag.NULL_VALUE; } int index = findIndex(key); if (0 <= index) { keys[index] = DELETED; --keyCount; } } public void clear() { int i = keys.length; while (i != 0) { keys[--i] = null; } keyCount = 0; occupiedCount = 0; } public Iterator newIterator() { return new Iterator(this); } // The sole purpose of the method is to avoid accessing private fields // from the Iterator inner class to workaround JDK 1.1 compiler bug which // generates code triggering VerifierError on recent JVMs final void initIterator(Iterator i) { i.init(keys, values, keyCount); } /** Return array of present keys */ public Object[] getKeys() { Object[] array = new Object[keyCount]; getKeys(array, 0); return array; } public void getKeys(Object[] array, int offset) { int count = keyCount; for (int i = 0; count != 0; ++i) { Object key = keys[i]; if (key != null && key != DELETED) { if (key == UniqueTag.NULL_VALUE) { key = null; } array[offset] = key; ++offset; --count; } } } private static int tableLookupStep(int fraction, int mask, int power) { int shift = 32 - 2 * power; if (shift >= 0) { return ((fraction >>> shift) & mask) | 1; } else { return (fraction & (mask >>> -shift)) | 1; } } private int findIndex(Object key) { if (keys != null) { int hash = key.hashCode(); int fraction = hash * A; int index = fraction >>> (32 - power); Object test = keys[index]; if (test != null) { int N = 1 << power; if (test == key || (values[N + index] == hash && test.equals(key))) { return index; } // Search in table after first failed attempt int mask = N - 1; int step = tableLookupStep(fraction, mask, power); int n = 0; for (;;) { if (check) { if (n >= occupiedCount) Kit.codeBug(); ++n; } index = (index + step) & mask; test = keys[index]; if (test == null) { break; } if (test == key || (values[N + index] == hash && test.equals(key))) { return index; } } } } return -1; } // Insert key that is not present to table without deleted entries // and enough free space private int insertNewKey(Object key, int hash) { if (check && occupiedCount != keyCount) Kit.codeBug(); if (check && keyCount == 1 << power) Kit.codeBug(); int fraction = hash * A; int index = fraction >>> (32 - power); int N = 1 << power; if (keys[index] != null) { int mask = N - 1; int step = tableLookupStep(fraction, mask, power); int firstIndex = index; do { if (check && keys[index] == DELETED) Kit.codeBug(); index = (index + step) & mask; if (check && firstIndex == index) Kit.codeBug(); } while (keys[index] != null); } keys[index] = key; values[N + index] = hash; ++occupiedCount; ++keyCount; return index; } private void rehashTable() { if (keys == null) { if (check && keyCount != 0) Kit.codeBug(); if (check && occupiedCount != 0) Kit.codeBug(); int N = 1 << power; keys = new Object[N]; values = new int[2 * N]; } else { // Check if removing deleted entries would free enough space if (keyCount * 2 >= occupiedCount) { // Need to grow: less then half of deleted entries ++power; } int N = 1 << power; Object[] oldKeys = keys; int[] oldValues = values; int oldN = oldKeys.length; keys = new Object[N]; values = new int[2 * N]; int remaining = keyCount; occupiedCount = keyCount = 0; for (int i = 0; remaining != 0; ++i) { Object key = oldKeys[i]; if (key != null && key != DELETED) { int keyHash = oldValues[oldN + i]; int index = insertNewKey(key, keyHash); values[index] = oldValues[i]; --remaining; } } } } // Ensure key index creating one if necessary private int ensureIndex(Object key) { int hash = key.hashCode(); int index = -1; int firstDeleted = -1; if (keys != null) { int fraction = hash * A; index = fraction >>> (32 - power); Object test = keys[index]; if (test != null) { int N = 1 << power; if (test == key || (values[N + index] == hash && test.equals(key))) { return index; } if (test == DELETED) { firstDeleted = index; } // Search in table after first failed attempt int mask = N - 1; int step = tableLookupStep(fraction, mask, power); int n = 0; for (;;) { if (check) { if (n >= occupiedCount) Kit.codeBug(); ++n; } index = (index + step) & mask; test = keys[index]; if (test == null) { break; } if (test == key || (values[N + index] == hash && test.equals(key))) { return index; } if (test == DELETED && firstDeleted < 0) { firstDeleted = index; } } } } // Inserting of new key if (check && keys != null && keys[index] != null) Kit.codeBug(); if (firstDeleted >= 0) { index = firstDeleted; } else { // Need to consume empty entry: check occupation level if (keys == null || occupiedCount * 4 >= (1 << power) * 3) { // Too litle unused entries: rehash rehashTable(); return insertNewKey(key, hash); } ++occupiedCount; } keys[index] = key; values[(1 << power) + index] = hash; ++keyCount; return index; } private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); int count = keyCount; for (int i = 0; count != 0; ++i) { Object key = keys[i]; if (key != null && key != DELETED) { --count; out.writeObject(key); out.writeInt(values[i]); } } } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); int writtenKeyCount = keyCount; if (writtenKeyCount != 0) { keyCount = 0; int N = 1 << power; keys = new Object[N]; values = new int[2 * N]; for (int i = 0; i != writtenKeyCount; ++i) { Object key = in.readObject(); int hash = key.hashCode(); int index = insertNewKey(key, hash); values[index] = in.readInt(); } } } // A == golden_ratio * (1 << 32) = ((sqrt(5) - 1) / 2) * (1 << 32) // See Knuth etc. private static final int A = 0x9e3779b9; private static final Object DELETED = new Object(); // Structure of kyes and values arrays (N == 1 << power): // keys[0 <= i < N]: key value or null or DELETED mark // values[0 <= i < N]: value of key at keys[i] // values[N <= i < 2*N]: hash code of key at keys[i-N] private transient Object[] keys; private transient int[] values; private int power; private int keyCount; private transient int occupiedCount; // == keyCount + deleted_count // If true, enables consitency checks private static final boolean check = false; /* TEST START public static void main(String[] args) { if (!check) { System.err.println("Set check to true and re-run"); throw new RuntimeException("Set check to true and re-run"); } ObjToIntMap map; map = new ObjToIntMap(0); testHash(map, 3); map = new ObjToIntMap(0); testHash(map, 10 * 1000); map = new ObjToIntMap(); testHash(map, 10 * 1000); map = new ObjToIntMap(30 * 1000); testHash(map, 10 * 100); map.clear(); testHash(map, 4); map = new ObjToIntMap(0); testHash(map, 10 * 100); } private static void testHash(ObjToIntMap map, int N) { System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i); check(-1 == map.get(key, -1)); map.put(key, i); check(i == map.get(key, -1)); } System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i); map.put(key, i); check(i == map.get(key, -1)); } check(map.size() == N); System.out.print("."); System.out.flush(); Object[] keys = map.getKeys(); check(keys.length == N); for (int i = 0; i != N; ++i) { Object key = keys[i]; check(map.has(key)); } System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i); check(i == map.get(key, -1)); } int Nsqrt = -1; for (int i = 0; ; ++i) { if (i * i >= N) { Nsqrt = i; break; } } System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i * i); map.put(key, i); check(i == map.get(key, -1)); } check(map.size() == 2 * N - Nsqrt); System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i * i); check(i == map.get(key, -1)); } System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(-1 - i * i); map.put(key, i); check(i == map.get(key, -1)); } check(map.size() == 3 * N - Nsqrt); System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(-1 - i * i); map.remove(key); check(!map.has(key)); } check(map.size() == 2 * N - Nsqrt); System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i * i); check(i == map.get(key, -1)); } System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i); int j = intSqrt(i); if (j * j == i) { check(j == map.get(key, -1)); }else { check(i == map.get(key, -1)); } } System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i * i); map.remove(key); check(-2 == map.get(key, -2)); } System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i); map.put(key, i); check(i == map.get(key, -2)); } check(map.size() == N); System.out.print("."); System.out.flush(); for (int i = 0; i != N; ++i) { Object key = testKey(i); check(i == map.get(key, -1)); } System.out.print("."); System.out.flush(); ObjToIntMap copy = (ObjToIntMap)writeAndRead(map); check(copy.size() == N); for (int i = 0; i != N; ++i) { Object key = testKey(i); check(i == copy.get(key, -1)); } System.out.print("."); System.out.flush(); checkSameMaps(copy, map); System.out.println(); System.out.flush(); } private static void checkSameMaps(ObjToIntMap map1, ObjToIntMap map2) { check(map1.size() == map2.size()); Object[] keys = map1.getKeys(); check(keys.length == map1.size()); for (int i = 0; i != keys.length; ++i) { check(map1.get(keys[i], -1) == map2.get(keys[i], -1)); } } private static void check(boolean condition) { if (!condition) Kit.codeBug(); } private static Object[] testPool; private static Object testKey(int i) { int MAX_POOL = 100; if (0 <= i && i < MAX_POOL) { if (testPool != null && testPool[i] != null) { return testPool[i]; } } Object x = new Double(i + 0.5); if (0 <= i && i < MAX_POOL) { if (testPool == null) { testPool = new Object[MAX_POOL]; } testPool[i] = x; } return x; } private static int intSqrt(int i) { int approx = (int)Math.sqrt(i) + 1; while (approx * approx > i) { --approx; } return approx; } private static Object writeAndRead(Object obj) { try { java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream(); java.io.ObjectOutputStream out = new java.io.ObjectOutputStream(bos); out.writeObject(obj); out.close(); byte[] data = bos.toByteArray(); java.io.ByteArrayInputStream bis = new java.io.ByteArrayInputStream(data); java.io.ObjectInputStream in = new java.io.ObjectInputStream(bis); Object result = in.readObject(); in.close(); return result; }catch (Exception ex) { throw new RuntimeException("Unexpected"); } } // TEST END */ } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeDate.java0000644000175000017500000015554411753547210024525 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Peter Annema * Norris Boyd * Mike McCabe * Ilya Frank * * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.util.Date; import java.text.DateFormat; /** * This class implements the Date native object. * See ECMA 15.9. * @author Mike McCabe */ final class NativeDate extends IdScriptableObject { static final long serialVersionUID = -8307438915861678966L; private static final Object DATE_TAG = "Date"; private static final String js_NaN_date_str = "Invalid Date"; static void init(Scriptable scope, boolean sealed) { NativeDate obj = new NativeDate(); // Set the value of the prototype Date to NaN ('invalid date'); obj.date = ScriptRuntime.NaN; obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); } private NativeDate() { if (thisTimeZone == null) { // j.u.TimeZone is synchronized, so setting class statics from it // should be OK. thisTimeZone = java.util.TimeZone.getDefault(); LocalTZA = thisTimeZone.getRawOffset(); } } @Override public String getClassName() { return "Date"; } @Override public Object getDefaultValue(Class typeHint) { if (typeHint == null) typeHint = ScriptRuntime.StringClass; return super.getDefaultValue(typeHint); } double getJSTimeValue() { return date; } @Override protected void fillConstructorProperties(IdFunctionObject ctor) { addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_now, "now", 0); addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_parse, "parse", 1); addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_UTC, "UTC", 1); super.fillConstructorProperties(ctor); } @Override protected void initPrototypeId(int id) { String s; int arity; switch (id) { case Id_constructor: arity=1; s="constructor"; break; case Id_toString: arity=0; s="toString"; break; case Id_toTimeString: arity=0; s="toTimeString"; break; case Id_toDateString: arity=0; s="toDateString"; break; case Id_toLocaleString: arity=0; s="toLocaleString"; break; case Id_toLocaleTimeString: arity=0; s="toLocaleTimeString"; break; case Id_toLocaleDateString: arity=0; s="toLocaleDateString"; break; case Id_toUTCString: arity=0; s="toUTCString"; break; case Id_toSource: arity=0; s="toSource"; break; case Id_valueOf: arity=0; s="valueOf"; break; case Id_getTime: arity=0; s="getTime"; break; case Id_getYear: arity=0; s="getYear"; break; case Id_getFullYear: arity=0; s="getFullYear"; break; case Id_getUTCFullYear: arity=0; s="getUTCFullYear"; break; case Id_getMonth: arity=0; s="getMonth"; break; case Id_getUTCMonth: arity=0; s="getUTCMonth"; break; case Id_getDate: arity=0; s="getDate"; break; case Id_getUTCDate: arity=0; s="getUTCDate"; break; case Id_getDay: arity=0; s="getDay"; break; case Id_getUTCDay: arity=0; s="getUTCDay"; break; case Id_getHours: arity=0; s="getHours"; break; case Id_getUTCHours: arity=0; s="getUTCHours"; break; case Id_getMinutes: arity=0; s="getMinutes"; break; case Id_getUTCMinutes: arity=0; s="getUTCMinutes"; break; case Id_getSeconds: arity=0; s="getSeconds"; break; case Id_getUTCSeconds: arity=0; s="getUTCSeconds"; break; case Id_getMilliseconds: arity=0; s="getMilliseconds"; break; case Id_getUTCMilliseconds: arity=0; s="getUTCMilliseconds"; break; case Id_getTimezoneOffset: arity=0; s="getTimezoneOffset"; break; case Id_setTime: arity=1; s="setTime"; break; case Id_setMilliseconds: arity=1; s="setMilliseconds"; break; case Id_setUTCMilliseconds: arity=1; s="setUTCMilliseconds"; break; case Id_setSeconds: arity=2; s="setSeconds"; break; case Id_setUTCSeconds: arity=2; s="setUTCSeconds"; break; case Id_setMinutes: arity=3; s="setMinutes"; break; case Id_setUTCMinutes: arity=3; s="setUTCMinutes"; break; case Id_setHours: arity=4; s="setHours"; break; case Id_setUTCHours: arity=4; s="setUTCHours"; break; case Id_setDate: arity=1; s="setDate"; break; case Id_setUTCDate: arity=1; s="setUTCDate"; break; case Id_setMonth: arity=2; s="setMonth"; break; case Id_setUTCMonth: arity=2; s="setUTCMonth"; break; case Id_setFullYear: arity=3; s="setFullYear"; break; case Id_setUTCFullYear: arity=3; s="setUTCFullYear"; break; case Id_setYear: arity=1; s="setYear"; break; default: throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(DATE_TAG, id, s, arity); } @Override public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(DATE_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); switch (id) { case ConstructorId_now: return ScriptRuntime.wrapNumber(now()); case ConstructorId_parse: { String dataStr = ScriptRuntime.toString(args, 0); return ScriptRuntime.wrapNumber(date_parseString(dataStr)); } case ConstructorId_UTC: return ScriptRuntime.wrapNumber(jsStaticFunction_UTC(args)); case Id_constructor: { // if called as a function, just return a string // representing the current time. if (thisObj != null) return date_format(now(), Id_toString); return jsConstructor(args); } } // The rest of Date.prototype methods require thisObj to be Date if (!(thisObj instanceof NativeDate)) throw incompatibleCallError(f); NativeDate realThis = (NativeDate)thisObj; double t = realThis.date; switch (id) { case Id_toString: case Id_toTimeString: case Id_toDateString: if (t == t) { return date_format(t, id); } return js_NaN_date_str; case Id_toLocaleString: case Id_toLocaleTimeString: case Id_toLocaleDateString: if (t == t) { return toLocale_helper(t, id); } return js_NaN_date_str; case Id_toUTCString: if (t == t) { return js_toUTCString(t); } return js_NaN_date_str; case Id_toSource: return "(new Date("+ScriptRuntime.toString(t)+"))"; case Id_valueOf: case Id_getTime: return ScriptRuntime.wrapNumber(t); case Id_getYear: case Id_getFullYear: case Id_getUTCFullYear: if (t == t) { if (id != Id_getUTCFullYear) t = LocalTime(t); t = YearFromTime(t); if (id == Id_getYear) { if (cx.hasFeature(Context.FEATURE_NON_ECMA_GET_YEAR)) { if (1900 <= t && t < 2000) { t -= 1900; } } else { t -= 1900; } } } return ScriptRuntime.wrapNumber(t); case Id_getMonth: case Id_getUTCMonth: if (t == t) { if (id == Id_getMonth) t = LocalTime(t); t = MonthFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getDate: case Id_getUTCDate: if (t == t) { if (id == Id_getDate) t = LocalTime(t); t = DateFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getDay: case Id_getUTCDay: if (t == t) { if (id == Id_getDay) t = LocalTime(t); t = WeekDay(t); } return ScriptRuntime.wrapNumber(t); case Id_getHours: case Id_getUTCHours: if (t == t) { if (id == Id_getHours) t = LocalTime(t); t = HourFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getMinutes: case Id_getUTCMinutes: if (t == t) { if (id == Id_getMinutes) t = LocalTime(t); t = MinFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getSeconds: case Id_getUTCSeconds: if (t == t) { if (id == Id_getSeconds) t = LocalTime(t); t = SecFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getMilliseconds: case Id_getUTCMilliseconds: if (t == t) { if (id == Id_getMilliseconds) t = LocalTime(t); t = msFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getTimezoneOffset: if (t == t) { t = (t - LocalTime(t)) / msPerMinute; } return ScriptRuntime.wrapNumber(t); case Id_setTime: t = TimeClip(ScriptRuntime.toNumber(args, 0)); realThis.date = t; return ScriptRuntime.wrapNumber(t); case Id_setMilliseconds: case Id_setUTCMilliseconds: case Id_setSeconds: case Id_setUTCSeconds: case Id_setMinutes: case Id_setUTCMinutes: case Id_setHours: case Id_setUTCHours: t = makeTime(t, args, id); realThis.date = t; return ScriptRuntime.wrapNumber(t); case Id_setDate: case Id_setUTCDate: case Id_setMonth: case Id_setUTCMonth: case Id_setFullYear: case Id_setUTCFullYear: t = makeDate(t, args, id); realThis.date = t; return ScriptRuntime.wrapNumber(t); case Id_setYear: { double year = ScriptRuntime.toNumber(args, 0); if (year != year || Double.isInfinite(year)) { t = ScriptRuntime.NaN; } else { if (t != t) { t = 0; } else { t = LocalTime(t); } if (year >= 0 && year <= 99) year += 1900; double day = MakeDay(year, MonthFromTime(t), DateFromTime(t)); t = MakeDate(day, TimeWithinDay(t)); t = internalUTC(t); t = TimeClip(t); } } realThis.date = t; return ScriptRuntime.wrapNumber(t); default: throw new IllegalArgumentException(String.valueOf(id)); } } /* ECMA helper functions */ private static final double HalfTimeDomain = 8.64e15; private static final double HoursPerDay = 24.0; private static final double MinutesPerHour = 60.0; private static final double SecondsPerMinute = 60.0; private static final double msPerSecond = 1000.0; private static final double MinutesPerDay = (HoursPerDay * MinutesPerHour); private static final double SecondsPerDay = (MinutesPerDay * SecondsPerMinute); private static final double SecondsPerHour = (MinutesPerHour * SecondsPerMinute); private static final double msPerDay = (SecondsPerDay * msPerSecond); private static final double msPerHour = (SecondsPerHour * msPerSecond); private static final double msPerMinute = (SecondsPerMinute * msPerSecond); private static double Day(double t) { return Math.floor(t / msPerDay); } private static double TimeWithinDay(double t) { double result; result = t % msPerDay; if (result < 0) result += msPerDay; return result; } private static boolean IsLeapYear(int year) { return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } /* math here has to be f.p, because we need * floor((1968 - 1969) / 4) == -1 */ private static double DayFromYear(double y) { return ((365 * ((y)-1970) + Math.floor(((y)-1969)/4.0) - Math.floor(((y)-1901)/100.0) + Math.floor(((y)-1601)/400.0))); } private static double TimeFromYear(double y) { return DayFromYear(y) * msPerDay; } private static int YearFromTime(double t) { int lo = (int) Math.floor((t / msPerDay) / 366) + 1970; int hi = (int) Math.floor((t / msPerDay) / 365) + 1970; int mid; /* above doesn't work for negative dates... */ if (hi < lo) { int temp = lo; lo = hi; hi = temp; } /* Use a simple binary search algorithm to find the right year. This seems like brute force... but the computation of hi and lo years above lands within one year of the correct answer for years within a thousand years of 1970; the loop below only requires six iterations for year 270000. */ while (hi > lo) { mid = (hi + lo) / 2; if (TimeFromYear(mid) > t) { hi = mid - 1; } else { lo = mid + 1; if (TimeFromYear(lo) > t) { return mid; } } } return lo; } private static double DayFromMonth(int m, int year) { int day = m * 30; if (m >= 7) { day += m / 2 - 1; } else if (m >= 2) { day += (m - 1) / 2 - 1; } else { day += m; } if (m >= 2 && IsLeapYear(year)) { ++day; } return day; } private static int MonthFromTime(double t) { int year = YearFromTime(t); int d = (int)(Day(t) - DayFromYear(year)); d -= 31 + 28; if (d < 0) { return (d < -28) ? 0 : 1; } if (IsLeapYear(year)) { if (d == 0) return 1; // 29 February --d; } // d: date count from 1 March int estimate = d / 30; // approx number of month since March int mstart; switch (estimate) { case 0: return 2; case 1: mstart = 31; break; case 2: mstart = 31+30; break; case 3: mstart = 31+30+31; break; case 4: mstart = 31+30+31+30; break; case 5: mstart = 31+30+31+30+31; break; case 6: mstart = 31+30+31+30+31+31; break; case 7: mstart = 31+30+31+30+31+31+30; break; case 8: mstart = 31+30+31+30+31+31+30+31; break; case 9: mstart = 31+30+31+30+31+31+30+31+30; break; case 10: return 11; //Late december default: throw Kit.codeBug(); } // if d < mstart then real month since March == estimate - 1 return (d >= mstart) ? estimate + 2 : estimate + 1; } private static int DateFromTime(double t) { int year = YearFromTime(t); int d = (int)(Day(t) - DayFromYear(year)); d -= 31 + 28; if (d < 0) { return (d < -28) ? d + 31 + 28 + 1 : d + 28 + 1; } if (IsLeapYear(year)) { if (d == 0) return 29; // 29 February --d; } // d: date count from 1 March int mdays, mstart; switch (d / 30) { // approx number of month since March case 0: return d + 1; case 1: mdays = 31; mstart = 31; break; case 2: mdays = 30; mstart = 31+30; break; case 3: mdays = 31; mstart = 31+30+31; break; case 4: mdays = 30; mstart = 31+30+31+30; break; case 5: mdays = 31; mstart = 31+30+31+30+31; break; case 6: mdays = 31; mstart = 31+30+31+30+31+31; break; case 7: mdays = 30; mstart = 31+30+31+30+31+31+30; break; case 8: mdays = 31; mstart = 31+30+31+30+31+31+30+31; break; case 9: mdays = 30; mstart = 31+30+31+30+31+31+30+31+30; break; case 10: return d - (31+30+31+30+31+31+30+31+30) + 1; //Late december default: throw Kit.codeBug(); } d -= mstart; if (d < 0) { // wrong estimate: sfhift to previous month d += mdays; } return d + 1; } private static int WeekDay(double t) { double result; result = Day(t) + 4; result = result % 7; if (result < 0) result += 7; return (int) result; } private static double now() { return System.currentTimeMillis(); } /* Should be possible to determine the need for this dynamically * if we go with the workaround... I'm not using it now, because I * can't think of any clean way to make toLocaleString() and the * time zone (comment) in toString match the generated string * values. Currently it's wrong-but-consistent in all but the * most recent betas of the JRE - seems to work in 1.1.7. */ private final static boolean TZO_WORKAROUND = false; private static double DaylightSavingTA(double t) { // Another workaround! The JRE doesn't seem to know about DST // before year 1 AD, so we map to equivalent dates for the // purposes of finding dst. To be safe, we do this for years // outside 1970-2038. if (t < 0.0 || t > 2145916800000.0) { int year = EquivalentYear(YearFromTime(t)); double day = MakeDay(year, MonthFromTime(t), DateFromTime(t)); t = MakeDate(day, TimeWithinDay(t)); } if (!TZO_WORKAROUND) { Date date = new Date((long) t); if (thisTimeZone.inDaylightTime(date)) return msPerHour; else return 0; } else { /* Use getOffset if inDaylightTime() is broken, because it * seems to work acceptably. We don't switch over to it * entirely, because it requires (expensive) exploded date arguments, * and the api makes it impossible to handle dst * changeovers cleanly. */ // Hardcode the assumption that the changeover always // happens at 2:00 AM: t += LocalTZA + (HourFromTime(t) <= 2 ? msPerHour : 0); int year = YearFromTime(t); double offset = thisTimeZone.getOffset(year > 0 ? 1 : 0, year, MonthFromTime(t), DateFromTime(t), WeekDay(t), (int)TimeWithinDay(t)); if ((offset - LocalTZA) != 0) return msPerHour; else return 0; // return offset - LocalTZA; } } /* * Find a year for which any given date will fall on the same weekday. * * This function should be used with caution when used other than * for determining DST; it hasn't been proven not to produce an * incorrect year for times near year boundaries. */ private static int EquivalentYear(int year) { int day = (int) DayFromYear(year) + 4; day = day % 7; if (day < 0) day += 7; // Years and leap years on which Jan 1 is a Sunday, Monday, etc. if (IsLeapYear(year)) { switch (day) { case 0: return 1984; case 1: return 1996; case 2: return 1980; case 3: return 1992; case 4: return 1976; case 5: return 1988; case 6: return 1972; } } else { switch (day) { case 0: return 1978; case 1: return 1973; case 2: return 1974; case 3: return 1975; case 4: return 1981; case 5: return 1971; case 6: return 1977; } } // Unreachable throw Kit.codeBug(); } private static double LocalTime(double t) { return t + LocalTZA + DaylightSavingTA(t); } private static double internalUTC(double t) { return t - LocalTZA - DaylightSavingTA(t - LocalTZA); } private static int HourFromTime(double t) { double result; result = Math.floor(t / msPerHour) % HoursPerDay; if (result < 0) result += HoursPerDay; return (int) result; } private static int MinFromTime(double t) { double result; result = Math.floor(t / msPerMinute) % MinutesPerHour; if (result < 0) result += MinutesPerHour; return (int) result; } private static int SecFromTime(double t) { double result; result = Math.floor(t / msPerSecond) % SecondsPerMinute; if (result < 0) result += SecondsPerMinute; return (int) result; } private static int msFromTime(double t) { double result; result = t % msPerSecond; if (result < 0) result += msPerSecond; return (int) result; } private static double MakeTime(double hour, double min, double sec, double ms) { return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms; } private static double MakeDay(double year, double month, double date) { year += Math.floor(month / 12); month = month % 12; if (month < 0) month += 12; double yearday = Math.floor(TimeFromYear(year) / msPerDay); double monthday = DayFromMonth((int)month, (int)year); return yearday + monthday + date - 1; } private static double MakeDate(double day, double time) { return day * msPerDay + time; } private static double TimeClip(double d) { if (d != d || d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY || Math.abs(d) > HalfTimeDomain) { return ScriptRuntime.NaN; } if (d > 0.0) return Math.floor(d + 0.); else return Math.ceil(d + 0.); } /* end of ECMA helper functions */ /* find UTC time from given date... no 1900 correction! */ private static double date_msecFromDate(double year, double mon, double mday, double hour, double min, double sec, double msec) { double day; double time; double result; day = MakeDay(year, mon, mday); time = MakeTime(hour, min, sec, msec); result = MakeDate(day, time); return result; } /* compute the time in msec (unclipped) from the given args */ private static final int MAXARGS = 7; private static double date_msecFromArgs(Object[] args) { double array[] = new double[MAXARGS]; int loop; double d; for (loop = 0; loop < MAXARGS; loop++) { if (loop < args.length) { d = ScriptRuntime.toNumber(args[loop]); if (d != d || Double.isInfinite(d)) { return ScriptRuntime.NaN; } array[loop] = ScriptRuntime.toInteger(args[loop]); } else { if (loop == 2) { array[loop] = 1; /* Default the date argument to 1. */ } else { array[loop] = 0; } } } /* adjust 2-digit years into the 20th century */ if (array[0] >= 0 && array[0] <= 99) array[0] += 1900; return date_msecFromDate(array[0], array[1], array[2], array[3], array[4], array[5], array[6]); } private static double jsStaticFunction_UTC(Object[] args) { return TimeClip(date_msecFromArgs(args)); } private static double date_parseString(String s) { int year = -1; int mon = -1; int mday = -1; int hour = -1; int min = -1; int sec = -1; char c = 0; char si = 0; int i = 0; int n = -1; double tzoffset = -1; char prevc = 0; int limit = 0; boolean seenplusminus = false; limit = s.length(); while (i < limit) { c = s.charAt(i); i++; if (c <= ' ' || c == ',' || c == '-') { if (i < limit) { si = s.charAt(i); if (c == '-' && '0' <= si && si <= '9') { prevc = c; } } continue; } if (c == '(') { /* comments) */ int depth = 1; while (i < limit) { c = s.charAt(i); i++; if (c == '(') depth++; else if (c == ')') if (--depth <= 0) break; } continue; } if ('0' <= c && c <= '9') { n = c - '0'; while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') { n = n * 10 + c - '0'; i++; } /* allow TZA before the year, so * 'Wed Nov 05 21:49:11 GMT-0800 1997' * works */ /* uses of seenplusminus allow : in TZA, so Java * no-timezone style of GMT+4:30 works */ if ((prevc == '+' || prevc == '-')/* && year>=0 */) { /* make ':' case below change tzoffset */ seenplusminus = true; /* offset */ if (n < 24) n = n * 60; /* EG. "GMT-3" */ else n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */ if (prevc == '+') /* plus means east of GMT */ n = -n; if (tzoffset != 0 && tzoffset != -1) return ScriptRuntime.NaN; tzoffset = n; } else if (n >= 70 || (prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) { if (year >= 0) return ScriptRuntime.NaN; else if (c <= ' ' || c == ',' || c == '/' || i >= limit) year = n < 100 ? n + 1900 : n; else return ScriptRuntime.NaN; } else if (c == ':') { if (hour < 0) hour = /*byte*/ n; else if (min < 0) min = /*byte*/ n; else return ScriptRuntime.NaN; } else if (c == '/') { if (mon < 0) mon = /*byte*/ n-1; else if (mday < 0) mday = /*byte*/ n; else return ScriptRuntime.NaN; } else if (i < limit && c != ',' && c > ' ' && c != '-') { return ScriptRuntime.NaN; } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */ if (tzoffset < 0) tzoffset -= n; else tzoffset += n; } else if (hour >= 0 && min < 0) { min = /*byte*/ n; } else if (min >= 0 && sec < 0) { sec = /*byte*/ n; } else if (mday < 0) { mday = /*byte*/ n; } else { return ScriptRuntime.NaN; } prevc = 0; } else if (c == '/' || c == ':' || c == '+' || c == '-') { prevc = c; } else { int st = i - 1; while (i < limit) { c = s.charAt(i); if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))) break; i++; } int letterCount = i - st; if (letterCount < 2) return ScriptRuntime.NaN; /* * Use ported code from jsdate.c rather than the locale-specific * date-parsing code from Java, to keep js and rhino consistent. * Is this the right strategy? */ String wtb = "am;pm;" +"monday;tuesday;wednesday;thursday;friday;" +"saturday;sunday;" +"january;february;march;april;may;june;" +"july;august;september;october;november;december;" +"gmt;ut;utc;est;edt;cst;cdt;mst;mdt;pst;pdt;"; int index = 0; for (int wtbOffset = 0; ;) { int wtbNext = wtb.indexOf(';', wtbOffset); if (wtbNext < 0) return ScriptRuntime.NaN; if (wtb.regionMatches(true, wtbOffset, s, st, letterCount)) break; wtbOffset = wtbNext + 1; ++index; } if (index < 2) { /* * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as * 12:30, instead of blindly adding 12 if PM. */ if (hour > 12 || hour < 0) { return ScriptRuntime.NaN; } else if (index == 0) { // AM if (hour == 12) hour = 0; } else { // PM if (hour != 12) hour += 12; } } else if ((index -= 2) < 7) { // ignore week days } else if ((index -= 7) < 12) { // month if (mon < 0) { mon = index; } else { return ScriptRuntime.NaN; } } else { index -= 12; // timezones switch (index) { case 0 /* gmt */: tzoffset = 0; break; case 1 /* ut */: tzoffset = 0; break; case 2 /* utc */: tzoffset = 0; break; case 3 /* est */: tzoffset = 5 * 60; break; case 4 /* edt */: tzoffset = 4 * 60; break; case 5 /* cst */: tzoffset = 6 * 60; break; case 6 /* cdt */: tzoffset = 5 * 60; break; case 7 /* mst */: tzoffset = 7 * 60; break; case 8 /* mdt */: tzoffset = 6 * 60; break; case 9 /* pst */: tzoffset = 8 * 60; break; case 10 /* pdt */:tzoffset = 7 * 60; break; default: Kit.codeBug(); } } } } if (year < 0 || mon < 0 || mday < 0) return ScriptRuntime.NaN; if (sec < 0) sec = 0; if (min < 0) min = 0; if (hour < 0) hour = 0; double msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0); if (tzoffset == -1) { /* no time zone specified, have to use local */ return internalUTC(msec); } else { return msec + tzoffset * msPerMinute; } } private static String date_format(double t, int methodId) { StringBuffer result = new StringBuffer(60); double local = LocalTime(t); /* Tue Oct 31 09:41:40 GMT-0800 (PST) 2000 */ /* Tue Oct 31 2000 */ /* 09:41:40 GMT-0800 (PST) */ if (methodId != Id_toTimeString) { appendWeekDayName(result, WeekDay(local)); result.append(' '); appendMonthName(result, MonthFromTime(local)); result.append(' '); append0PaddedUint(result, DateFromTime(local), 2); result.append(' '); int year = YearFromTime(local); if (year < 0) { result.append('-'); year = -year; } append0PaddedUint(result, year, 4); if (methodId != Id_toDateString) result.append(' '); } if (methodId != Id_toDateString) { append0PaddedUint(result, HourFromTime(local), 2); result.append(':'); append0PaddedUint(result, MinFromTime(local), 2); result.append(':'); append0PaddedUint(result, SecFromTime(local), 2); // offset from GMT in minutes. The offset includes daylight // savings, if it applies. int minutes = (int) Math.floor((LocalTZA + DaylightSavingTA(t)) / msPerMinute); // map 510 minutes to 0830 hours int offset = (minutes / 60) * 100 + minutes % 60; if (offset > 0) { result.append(" GMT+"); } else { result.append(" GMT-"); offset = -offset; } append0PaddedUint(result, offset, 4); if (timeZoneFormatter == null) timeZoneFormatter = new java.text.SimpleDateFormat("zzz"); // Find an equivalent year before getting the timezone // comment. See DaylightSavingTA. if (t < 0.0 || t > 2145916800000.0) { int equiv = EquivalentYear(YearFromTime(local)); double day = MakeDay(equiv, MonthFromTime(t), DateFromTime(t)); t = MakeDate(day, TimeWithinDay(t)); } result.append(" ("); java.util.Date date = new Date((long) t); synchronized (timeZoneFormatter) { result.append(timeZoneFormatter.format(date)); } result.append(')'); } return result.toString(); } /* the javascript constructor */ private static Object jsConstructor(Object[] args) { NativeDate obj = new NativeDate(); // if called as a constructor with no args, // return a new Date with the current time. if (args.length == 0) { obj.date = now(); return obj; } // if called with just one arg - if (args.length == 1) { Object arg0 = args[0]; if (arg0 instanceof Scriptable) arg0 = ((Scriptable) arg0).getDefaultValue(null); double date; if (arg0 instanceof String) { // it's a string; parse it. date = date_parseString((String)arg0); } else { // if it's not a string, use it as a millisecond date date = ScriptRuntime.toNumber(arg0); } obj.date = TimeClip(date); return obj; } double time = date_msecFromArgs(args); if (!Double.isNaN(time) && !Double.isInfinite(time)) time = TimeClip(internalUTC(time)); obj.date = time; return obj; } private static String toLocale_helper(double t, int methodId) { java.text.DateFormat formatter; switch (methodId) { case Id_toLocaleString: if (localeDateTimeFormatter == null) { localeDateTimeFormatter = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); } formatter = localeDateTimeFormatter; break; case Id_toLocaleTimeString: if (localeTimeFormatter == null) { localeTimeFormatter = DateFormat.getTimeInstance(DateFormat.LONG); } formatter = localeTimeFormatter; break; case Id_toLocaleDateString: if (localeDateFormatter == null) { localeDateFormatter = DateFormat.getDateInstance(DateFormat.LONG); } formatter = localeDateFormatter; break; default: formatter = null; // unreachable } synchronized (formatter) { return formatter.format(new Date((long) t)); } } private static String js_toUTCString(double date) { StringBuffer result = new StringBuffer(60); appendWeekDayName(result, WeekDay(date)); result.append(", "); append0PaddedUint(result, DateFromTime(date), 2); result.append(' '); appendMonthName(result, MonthFromTime(date)); result.append(' '); int year = YearFromTime(date); if (year < 0) { result.append('-'); year = -year; } append0PaddedUint(result, year, 4); result.append(' '); append0PaddedUint(result, HourFromTime(date), 2); result.append(':'); append0PaddedUint(result, MinFromTime(date), 2); result.append(':'); append0PaddedUint(result, SecFromTime(date), 2); result.append(" GMT"); return result.toString(); } private static void append0PaddedUint(StringBuffer sb, int i, int minWidth) { if (i < 0) Kit.codeBug(); int scale = 1; --minWidth; if (i >= 10) { if (i < 1000 * 1000 * 1000) { for (;;) { int newScale = scale * 10; if (i < newScale) { break; } --minWidth; scale = newScale; } } else { // Separated case not to check against 10 * 10^9 overflow minWidth -= 9; scale = 1000 * 1000 * 1000; } } while (minWidth > 0) { sb.append('0'); --minWidth; } while (scale != 1) { sb.append((char)('0' + (i / scale))); i %= scale; scale /= 10; } sb.append((char)('0' + i)); } private static void appendMonthName(StringBuffer sb, int index) { // Take advantage of the fact that all month abbreviations // have the same length to minimize amount of strings runtime has // to keep in memory String months = "Jan"+"Feb"+"Mar"+"Apr"+"May"+"Jun" +"Jul"+"Aug"+"Sep"+"Oct"+"Nov"+"Dec"; index *= 3; for (int i = 0; i != 3; ++i) { sb.append(months.charAt(index + i)); } } private static void appendWeekDayName(StringBuffer sb, int index) { String days = "Sun"+"Mon"+"Tue"+"Wed"+"Thu"+"Fri"+"Sat"; index *= 3; for (int i = 0; i != 3; ++i) { sb.append(days.charAt(index + i)); } } private static double makeTime(double date, Object[] args, int methodId) { int maxargs; boolean local = true; switch (methodId) { case Id_setUTCMilliseconds: local = false; // fallthrough case Id_setMilliseconds: maxargs = 1; break; case Id_setUTCSeconds: local = false; // fallthrough case Id_setSeconds: maxargs = 2; break; case Id_setUTCMinutes: local = false; // fallthrough case Id_setMinutes: maxargs = 3; break; case Id_setUTCHours: local = false; // fallthrough case Id_setHours: maxargs = 4; break; default: Kit.codeBug(); maxargs = 0; } int i; double conv[] = new double[4]; double hour, min, sec, msec; double lorutime; /* Local or UTC version of date */ double time; double result; /* just return NaN if the date is already NaN */ if (date != date) return date; /* Satisfy the ECMA rule that if a function is called with * fewer arguments than the specified formal arguments, the * remaining arguments are set to undefined. Seems like all * the Date.setWhatever functions in ECMA are only varargs * beyond the first argument; this should be set to undefined * if it's not given. This means that "d = new Date(); * d.setMilliseconds()" returns NaN. Blech. */ if (args.length == 0) args = ScriptRuntime.padArguments(args, 1); for (i = 0; i < args.length && i < maxargs; i++) { conv[i] = ScriptRuntime.toNumber(args[i]); // limit checks that happen in MakeTime in ECMA. if (conv[i] != conv[i] || Double.isInfinite(conv[i])) { return ScriptRuntime.NaN; } conv[i] = ScriptRuntime.toInteger(conv[i]); } if (local) lorutime = LocalTime(date); else lorutime = date; i = 0; int stop = args.length; if (maxargs >= 4 && i < stop) hour = conv[i++]; else hour = HourFromTime(lorutime); if (maxargs >= 3 && i < stop) min = conv[i++]; else min = MinFromTime(lorutime); if (maxargs >= 2 && i < stop) sec = conv[i++]; else sec = SecFromTime(lorutime); if (maxargs >= 1 && i < stop) msec = conv[i++]; else msec = msFromTime(lorutime); time = MakeTime(hour, min, sec, msec); result = MakeDate(Day(lorutime), time); if (local) result = internalUTC(result); date = TimeClip(result); return date; } private static double makeDate(double date, Object[] args, int methodId) { int maxargs; boolean local = true; switch (methodId) { case Id_setUTCDate: local = false; // fallthrough case Id_setDate: maxargs = 1; break; case Id_setUTCMonth: local = false; // fallthrough case Id_setMonth: maxargs = 2; break; case Id_setUTCFullYear: local = false; // fallthrough case Id_setFullYear: maxargs = 3; break; default: Kit.codeBug(); maxargs = 0; } int i; double conv[] = new double[3]; double year, month, day; double lorutime; /* local or UTC version of date */ double result; /* See arg padding comment in makeTime.*/ if (args.length == 0) args = ScriptRuntime.padArguments(args, 1); for (i = 0; i < args.length && i < maxargs; i++) { conv[i] = ScriptRuntime.toNumber(args[i]); // limit checks that happen in MakeDate in ECMA. if (conv[i] != conv[i] || Double.isInfinite(conv[i])) { return ScriptRuntime.NaN; } conv[i] = ScriptRuntime.toInteger(conv[i]); } /* return NaN if date is NaN and we're not setting the year, * If we are, use 0 as the time. */ if (date != date) { if (args.length < 3) { return ScriptRuntime.NaN; } else { lorutime = 0; } } else { if (local) lorutime = LocalTime(date); else lorutime = date; } i = 0; int stop = args.length; if (maxargs >= 3 && i < stop) year = conv[i++]; else year = YearFromTime(lorutime); if (maxargs >= 2 && i < stop) month = conv[i++]; else month = MonthFromTime(lorutime); if (maxargs >= 1 && i < stop) day = conv[i++]; else day = DateFromTime(lorutime); day = MakeDay(year, month, day); /* day within year */ result = MakeDate(day, TimeWithinDay(lorutime)); if (local) result = internalUTC(result); date = TimeClip(result); return date; } // #string_id_map# @Override protected int findPrototypeId(String s) { int id; // #generated# Last update: 2007-05-09 08:15:38 EDT L0: { id = 0; String X = null; int c; L: switch (s.length()) { case 6: X="getDay";id=Id_getDay; break L; case 7: switch (s.charAt(3)) { case 'D': c=s.charAt(0); if (c=='g') { X="getDate";id=Id_getDate; } else if (c=='s') { X="setDate";id=Id_setDate; } break L; case 'T': c=s.charAt(0); if (c=='g') { X="getTime";id=Id_getTime; } else if (c=='s') { X="setTime";id=Id_setTime; } break L; case 'Y': c=s.charAt(0); if (c=='g') { X="getYear";id=Id_getYear; } else if (c=='s') { X="setYear";id=Id_setYear; } break L; case 'u': X="valueOf";id=Id_valueOf; break L; } break L; case 8: switch (s.charAt(3)) { case 'H': c=s.charAt(0); if (c=='g') { X="getHours";id=Id_getHours; } else if (c=='s') { X="setHours";id=Id_setHours; } break L; case 'M': c=s.charAt(0); if (c=='g') { X="getMonth";id=Id_getMonth; } else if (c=='s') { X="setMonth";id=Id_setMonth; } break L; case 'o': X="toSource";id=Id_toSource; break L; case 't': X="toString";id=Id_toString; break L; } break L; case 9: X="getUTCDay";id=Id_getUTCDay; break L; case 10: c=s.charAt(3); if (c=='M') { c=s.charAt(0); if (c=='g') { X="getMinutes";id=Id_getMinutes; } else if (c=='s') { X="setMinutes";id=Id_setMinutes; } } else if (c=='S') { c=s.charAt(0); if (c=='g') { X="getSeconds";id=Id_getSeconds; } else if (c=='s') { X="setSeconds";id=Id_setSeconds; } } else if (c=='U') { c=s.charAt(0); if (c=='g') { X="getUTCDate";id=Id_getUTCDate; } else if (c=='s') { X="setUTCDate";id=Id_setUTCDate; } } break L; case 11: switch (s.charAt(3)) { case 'F': c=s.charAt(0); if (c=='g') { X="getFullYear";id=Id_getFullYear; } else if (c=='s') { X="setFullYear";id=Id_setFullYear; } break L; case 'M': X="toGMTString";id=Id_toGMTString; break L; case 'T': X="toUTCString";id=Id_toUTCString; break L; case 'U': c=s.charAt(0); if (c=='g') { c=s.charAt(9); if (c=='r') { X="getUTCHours";id=Id_getUTCHours; } else if (c=='t') { X="getUTCMonth";id=Id_getUTCMonth; } } else if (c=='s') { c=s.charAt(9); if (c=='r') { X="setUTCHours";id=Id_setUTCHours; } else if (c=='t') { X="setUTCMonth";id=Id_setUTCMonth; } } break L; case 's': X="constructor";id=Id_constructor; break L; } break L; case 12: c=s.charAt(2); if (c=='D') { X="toDateString";id=Id_toDateString; } else if (c=='T') { X="toTimeString";id=Id_toTimeString; } break L; case 13: c=s.charAt(0); if (c=='g') { c=s.charAt(6); if (c=='M') { X="getUTCMinutes";id=Id_getUTCMinutes; } else if (c=='S') { X="getUTCSeconds";id=Id_getUTCSeconds; } } else if (c=='s') { c=s.charAt(6); if (c=='M') { X="setUTCMinutes";id=Id_setUTCMinutes; } else if (c=='S') { X="setUTCSeconds";id=Id_setUTCSeconds; } } break L; case 14: c=s.charAt(0); if (c=='g') { X="getUTCFullYear";id=Id_getUTCFullYear; } else if (c=='s') { X="setUTCFullYear";id=Id_setUTCFullYear; } else if (c=='t') { X="toLocaleString";id=Id_toLocaleString; } break L; case 15: c=s.charAt(0); if (c=='g') { X="getMilliseconds";id=Id_getMilliseconds; } else if (c=='s') { X="setMilliseconds";id=Id_setMilliseconds; } break L; case 17: X="getTimezoneOffset";id=Id_getTimezoneOffset; break L; case 18: c=s.charAt(0); if (c=='g') { X="getUTCMilliseconds";id=Id_getUTCMilliseconds; } else if (c=='s') { X="setUTCMilliseconds";id=Id_setUTCMilliseconds; } else if (c=='t') { c=s.charAt(8); if (c=='D') { X="toLocaleDateString";id=Id_toLocaleDateString; } else if (c=='T') { X="toLocaleTimeString";id=Id_toLocaleTimeString; } } break L; } if (X!=null && X!=s && !X.equals(s)) id = 0; break L0; } // #/generated# return id; } private static final int ConstructorId_now = -3, ConstructorId_parse = -2, ConstructorId_UTC = -1, Id_constructor = 1, Id_toString = 2, Id_toTimeString = 3, Id_toDateString = 4, Id_toLocaleString = 5, Id_toLocaleTimeString = 6, Id_toLocaleDateString = 7, Id_toUTCString = 8, Id_toSource = 9, Id_valueOf = 10, Id_getTime = 11, Id_getYear = 12, Id_getFullYear = 13, Id_getUTCFullYear = 14, Id_getMonth = 15, Id_getUTCMonth = 16, Id_getDate = 17, Id_getUTCDate = 18, Id_getDay = 19, Id_getUTCDay = 20, Id_getHours = 21, Id_getUTCHours = 22, Id_getMinutes = 23, Id_getUTCMinutes = 24, Id_getSeconds = 25, Id_getUTCSeconds = 26, Id_getMilliseconds = 27, Id_getUTCMilliseconds = 28, Id_getTimezoneOffset = 29, Id_setTime = 30, Id_setMilliseconds = 31, Id_setUTCMilliseconds = 32, Id_setSeconds = 33, Id_setUTCSeconds = 34, Id_setMinutes = 35, Id_setUTCMinutes = 36, Id_setHours = 37, Id_setUTCHours = 38, Id_setDate = 39, Id_setUTCDate = 40, Id_setMonth = 41, Id_setUTCMonth = 42, Id_setFullYear = 43, Id_setUTCFullYear = 44, Id_setYear = 45, MAX_PROTOTYPE_ID = 45; private static final int Id_toGMTString = Id_toUTCString; // Alias, see Ecma B.2.6 // #/string_id_map# /* cached values */ private static java.util.TimeZone thisTimeZone; private static double LocalTZA; private static java.text.DateFormat timeZoneFormatter; private static java.text.DateFormat localeDateTimeFormatter; private static java.text.DateFormat localeDateFormatter; private static java.text.DateFormat localeTimeFormatter; private double date; } yui-compressor-2.4.7/src/org/mozilla/javascript/ContextListener.java0000644000175000017500000000414211753547210025616 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * @deprecated Embeddings that wish to customize newly created * {@link Context} instances should implement * {@link ContextFactory.Listener}. */ public interface ContextListener extends ContextFactory.Listener { /** * @deprecated Rhino runtime never calls the method. */ public void contextEntered(Context cx); /** * @deprecated Rhino runtime never calls the method. */ public void contextExited(Context cx); } yui-compressor-2.4.7/src/org/mozilla/javascript/Interpreter.java0000644000175000017500000051601711753547210025000 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Patrick Beard * Norris Boyd * Igor Bukanov * Ethan Hugg * Bob Jervis * Terry Lucas * Roger Lawrence * Milen Nankov * Hannes Wallnoefer * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.PrintStream; import java.io.Serializable; import java.util.List; import java.util.ArrayList; import org.mozilla.javascript.ScriptRuntime.NoSuchMethodShim; import org.mozilla.javascript.debug.DebugFrame; public class Interpreter implements Evaluator { // Additional interpreter-specific codes private static final int // Stack: ... value1 -> ... value1 value1 Icode_DUP = -1, // Stack: ... value2 value1 -> ... value2 value1 value2 value1 Icode_DUP2 = -2, // Stack: ... value2 value1 -> ... value1 value2 Icode_SWAP = -3, // Stack: ... value1 -> ... Icode_POP = -4, // Store stack top into return register and then pop it Icode_POP_RESULT = -5, // To jump conditionally and pop additional stack value Icode_IFEQ_POP = -6, // various types of ++/-- Icode_VAR_INC_DEC = -7, Icode_NAME_INC_DEC = -8, Icode_PROP_INC_DEC = -9, Icode_ELEM_INC_DEC = -10, Icode_REF_INC_DEC = -11, // load/save scope from/to local Icode_SCOPE_LOAD = -12, Icode_SCOPE_SAVE = -13, Icode_TYPEOFNAME = -14, // helper for function calls Icode_NAME_AND_THIS = -15, Icode_PROP_AND_THIS = -16, Icode_ELEM_AND_THIS = -17, Icode_VALUE_AND_THIS = -18, // Create closure object for nested functions Icode_CLOSURE_EXPR = -19, Icode_CLOSURE_STMT = -20, // Special calls Icode_CALLSPECIAL = -21, // To return undefined value Icode_RETUNDEF = -22, // Exception handling implementation Icode_GOSUB = -23, Icode_STARTSUB = -24, Icode_RETSUB = -25, // To indicating a line number change in icodes. Icode_LINE = -26, // To store shorts and ints inline Icode_SHORTNUMBER = -27, Icode_INTNUMBER = -28, // To create and populate array to hold values for [] and {} literals Icode_LITERAL_NEW = -29, Icode_LITERAL_SET = -30, // Array literal with skipped index like [1,,2] Icode_SPARE_ARRAYLIT = -31, // Load index register to prepare for the following index operation Icode_REG_IND_C0 = -32, Icode_REG_IND_C1 = -33, Icode_REG_IND_C2 = -34, Icode_REG_IND_C3 = -35, Icode_REG_IND_C4 = -36, Icode_REG_IND_C5 = -37, Icode_REG_IND1 = -38, Icode_REG_IND2 = -39, Icode_REG_IND4 = -40, // Load string register to prepare for the following string operation Icode_REG_STR_C0 = -41, Icode_REG_STR_C1 = -42, Icode_REG_STR_C2 = -43, Icode_REG_STR_C3 = -44, Icode_REG_STR1 = -45, Icode_REG_STR2 = -46, Icode_REG_STR4 = -47, // Version of getvar/setvar that read var index directly from bytecode Icode_GETVAR1 = -48, Icode_SETVAR1 = -49, // Load unefined Icode_UNDEF = -50, Icode_ZERO = -51, Icode_ONE = -52, // entrance and exit from .() Icode_ENTERDQ = -53, Icode_LEAVEDQ = -54, Icode_TAIL_CALL = -55, // Clear local to allow GC its context Icode_LOCAL_CLEAR = -56, // Literal get/set Icode_LITERAL_GETTER = -57, Icode_LITERAL_SETTER = -58, // const Icode_SETCONST = -59, Icode_SETCONSTVAR = -60, Icode_SETCONSTVAR1 = -61, // Generator opcodes (along with Token.YIELD) Icode_GENERATOR = -62, Icode_GENERATOR_END = -63, Icode_DEBUGGER = -64, // Last icode MIN_ICODE = -64; // data for parsing private CompilerEnvirons compilerEnv; private boolean itsInFunctionFlag; private boolean itsInTryFlag; private InterpreterData itsData; private ScriptOrFnNode scriptOrFn; private int itsICodeTop; private int itsStackDepth; private int itsLineNumber; private int itsDoubleTableTop; private ObjToIntMap itsStrings = new ObjToIntMap(20); private int itsLocalTop; private static final int MIN_LABEL_TABLE_SIZE = 32; private static final int MIN_FIXUP_TABLE_SIZE = 40; private int[] itsLabelTable; private int itsLabelTableTop; // itsFixupTable[i] = (label_index << 32) | fixup_site private long[] itsFixupTable; private int itsFixupTableTop; private ObjArray itsLiteralIds = new ObjArray(); private int itsExceptionTableTop; private static final int EXCEPTION_TRY_START_SLOT = 0; private static final int EXCEPTION_TRY_END_SLOT = 1; private static final int EXCEPTION_HANDLER_SLOT = 2; private static final int EXCEPTION_TYPE_SLOT = 3; private static final int EXCEPTION_LOCAL_SLOT = 4; private static final int EXCEPTION_SCOPE_SLOT = 5; // SLOT_SIZE: space for try start/end, handler, start, handler type, // exception local and scope local private static final int EXCEPTION_SLOT_SIZE = 6; // ECF_ or Expression Context Flags constants: for now only TAIL is available private static final int ECF_TAIL = 1 << 0; /** * Class to hold data corresponding to one interpreted call stack frame. */ private static class CallFrame implements Cloneable, Serializable { static final long serialVersionUID = -2843792508994958978L; CallFrame parentFrame; // amount of stack frames before this one on the interpretation stack int frameIndex; // If true indicates read-only frame that is a part of continuation boolean frozen; InterpretedFunction fnOrScript; InterpreterData idata; // Stack structure // stack[0 <= i < localShift]: arguments and local variables // stack[localShift <= i <= emptyStackTop]: used for local temporaries // stack[emptyStackTop < i < stack.length]: stack data // sDbl[i]: if stack[i] is UniqueTag.DOUBLE_MARK, sDbl[i] holds the number value Object[] stack; int[] stackAttributes; double[] sDbl; CallFrame varSource; // defaults to this unless continuation frame int localShift; int emptyStackTop; DebugFrame debuggerFrame; boolean useActivation; boolean isContinuationsTopFrame; Scriptable thisObj; Scriptable[] scriptRegExps; // The values that change during interpretation Object result; double resultDbl; int pc; int pcPrevBranch; int pcSourceLineStart; Scriptable scope; int savedStackTop; int savedCallOp; Object throwable; CallFrame cloneFrozen() { if (!frozen) Kit.codeBug(); CallFrame copy; try { copy = (CallFrame)clone(); } catch (CloneNotSupportedException ex) { throw new IllegalStateException(); } // clone stack but keep varSource to point to values // from this frame to share variables. copy.stack = stack.clone(); copy.stackAttributes = stackAttributes.clone(); copy.sDbl = sDbl.clone(); copy.frozen = false; return copy; } } private static final class ContinuationJump implements Serializable { static final long serialVersionUID = 7687739156004308247L; CallFrame capturedFrame; CallFrame branchFrame; Object result; double resultDbl; ContinuationJump(NativeContinuation c, CallFrame current) { this.capturedFrame = (CallFrame)c.getImplementation(); if (this.capturedFrame == null || current == null) { // Continuation and current execution does not share // any frames if there is nothing to capture or // if there is no currently executed frames this.branchFrame = null; } else { // Search for branch frame where parent frame chains starting // from captured and current meet. CallFrame chain1 = this.capturedFrame; CallFrame chain2 = current; // First work parents of chain1 or chain2 until the same // frame depth. int diff = chain1.frameIndex - chain2.frameIndex; if (diff != 0) { if (diff < 0) { // swap to make sure that // chain1.frameIndex > chain2.frameIndex and diff > 0 chain1 = current; chain2 = this.capturedFrame; diff = -diff; } do { chain1 = chain1.parentFrame; } while (--diff != 0); if (chain1.frameIndex != chain2.frameIndex) Kit.codeBug(); } // Now walk parents in parallel until a shared frame is found // or until the root is reached. while (chain1 != chain2 && chain1 != null) { chain1 = chain1.parentFrame; chain2 = chain2.parentFrame; } this.branchFrame = chain1; if (this.branchFrame != null && !this.branchFrame.frozen) Kit.codeBug(); } } } private static CallFrame captureFrameForGenerator(CallFrame frame) { frame.frozen = true; CallFrame result = frame.cloneFrozen(); frame.frozen = false; // now isolate this frame from its previous context result.parentFrame = null; result.frameIndex = 0; return result; } static { // Checks for byte code consistencies, good compiler can eliminate them if (Token.LAST_BYTECODE_TOKEN > 127) { String str = "Violation of Token.LAST_BYTECODE_TOKEN <= 127"; System.err.println(str); throw new IllegalStateException(str); } if (MIN_ICODE < -128) { String str = "Violation of Interpreter.MIN_ICODE >= -128"; System.err.println(str); throw new IllegalStateException(str); } } private static String bytecodeName(int bytecode) { if (!validBytecode(bytecode)) { throw new IllegalArgumentException(String.valueOf(bytecode)); } if (!Token.printICode) { return String.valueOf(bytecode); } if (validTokenCode(bytecode)) { return Token.name(bytecode); } switch (bytecode) { case Icode_DUP: return "DUP"; case Icode_DUP2: return "DUP2"; case Icode_SWAP: return "SWAP"; case Icode_POP: return "POP"; case Icode_POP_RESULT: return "POP_RESULT"; case Icode_IFEQ_POP: return "IFEQ_POP"; case Icode_VAR_INC_DEC: return "VAR_INC_DEC"; case Icode_NAME_INC_DEC: return "NAME_INC_DEC"; case Icode_PROP_INC_DEC: return "PROP_INC_DEC"; case Icode_ELEM_INC_DEC: return "ELEM_INC_DEC"; case Icode_REF_INC_DEC: return "REF_INC_DEC"; case Icode_SCOPE_LOAD: return "SCOPE_LOAD"; case Icode_SCOPE_SAVE: return "SCOPE_SAVE"; case Icode_TYPEOFNAME: return "TYPEOFNAME"; case Icode_NAME_AND_THIS: return "NAME_AND_THIS"; case Icode_PROP_AND_THIS: return "PROP_AND_THIS"; case Icode_ELEM_AND_THIS: return "ELEM_AND_THIS"; case Icode_VALUE_AND_THIS: return "VALUE_AND_THIS"; case Icode_CLOSURE_EXPR: return "CLOSURE_EXPR"; case Icode_CLOSURE_STMT: return "CLOSURE_STMT"; case Icode_CALLSPECIAL: return "CALLSPECIAL"; case Icode_RETUNDEF: return "RETUNDEF"; case Icode_GOSUB: return "GOSUB"; case Icode_STARTSUB: return "STARTSUB"; case Icode_RETSUB: return "RETSUB"; case Icode_LINE: return "LINE"; case Icode_SHORTNUMBER: return "SHORTNUMBER"; case Icode_INTNUMBER: return "INTNUMBER"; case Icode_LITERAL_NEW: return "LITERAL_NEW"; case Icode_LITERAL_SET: return "LITERAL_SET"; case Icode_SPARE_ARRAYLIT: return "SPARE_ARRAYLIT"; case Icode_REG_IND_C0: return "REG_IND_C0"; case Icode_REG_IND_C1: return "REG_IND_C1"; case Icode_REG_IND_C2: return "REG_IND_C2"; case Icode_REG_IND_C3: return "REG_IND_C3"; case Icode_REG_IND_C4: return "REG_IND_C4"; case Icode_REG_IND_C5: return "REG_IND_C5"; case Icode_REG_IND1: return "LOAD_IND1"; case Icode_REG_IND2: return "LOAD_IND2"; case Icode_REG_IND4: return "LOAD_IND4"; case Icode_REG_STR_C0: return "REG_STR_C0"; case Icode_REG_STR_C1: return "REG_STR_C1"; case Icode_REG_STR_C2: return "REG_STR_C2"; case Icode_REG_STR_C3: return "REG_STR_C3"; case Icode_REG_STR1: return "LOAD_STR1"; case Icode_REG_STR2: return "LOAD_STR2"; case Icode_REG_STR4: return "LOAD_STR4"; case Icode_GETVAR1: return "GETVAR1"; case Icode_SETVAR1: return "SETVAR1"; case Icode_UNDEF: return "UNDEF"; case Icode_ZERO: return "ZERO"; case Icode_ONE: return "ONE"; case Icode_ENTERDQ: return "ENTERDQ"; case Icode_LEAVEDQ: return "LEAVEDQ"; case Icode_TAIL_CALL: return "TAIL_CALL"; case Icode_LOCAL_CLEAR: return "LOCAL_CLEAR"; case Icode_LITERAL_GETTER: return "LITERAL_GETTER"; case Icode_LITERAL_SETTER: return "LITERAL_SETTER"; case Icode_SETCONST: return "SETCONST"; case Icode_SETCONSTVAR: return "SETCONSTVAR"; case Icode_SETCONSTVAR1: return "SETCONSTVAR1"; case Icode_GENERATOR: return "GENERATOR"; case Icode_GENERATOR_END: return "GENERATOR_END"; case Icode_DEBUGGER: return "DEBUGGER"; } // icode without name throw new IllegalStateException(String.valueOf(bytecode)); } private static boolean validIcode(int icode) { return MIN_ICODE <= icode && icode <= -1; } private static boolean validTokenCode(int token) { return Token.FIRST_BYTECODE_TOKEN <= token && token <= Token.LAST_BYTECODE_TOKEN; } private static boolean validBytecode(int bytecode) { return validIcode(bytecode) || validTokenCode(bytecode); } public Object compile(CompilerEnvirons compilerEnv, ScriptOrFnNode tree, String encodedSource, boolean returnFunction) { this.compilerEnv = compilerEnv; new NodeTransformer().transform(tree); if (Token.printTrees) { System.out.println(tree.toStringTree(tree)); } if (returnFunction) { tree = tree.getFunctionNode(0); } scriptOrFn = tree; itsData = new InterpreterData(compilerEnv.getLanguageVersion(), scriptOrFn.getSourceName(), encodedSource); itsData.topLevel = true; if (returnFunction) { generateFunctionICode(); } else { generateICodeFromTree(scriptOrFn); } return itsData; } public Script createScriptObject(Object bytecode, Object staticSecurityDomain) { if(bytecode != itsData) { Kit.codeBug(); } return InterpretedFunction.createScript(itsData, staticSecurityDomain); } public void setEvalScriptFlag(Script script) { ((InterpretedFunction)script).idata.evalScriptFlag = true; } public Function createFunctionObject(Context cx, Scriptable scope, Object bytecode, Object staticSecurityDomain) { if(bytecode != itsData) { Kit.codeBug(); } return InterpretedFunction.createFunction(cx, scope, itsData, staticSecurityDomain); } private void generateFunctionICode() { itsInFunctionFlag = true; FunctionNode theFunction = (FunctionNode)scriptOrFn; itsData.itsFunctionType = theFunction.getFunctionType(); itsData.itsNeedsActivation = theFunction.requiresActivation(); itsData.itsName = theFunction.getFunctionName(); if (!theFunction.getIgnoreDynamicScope()) { if (compilerEnv.isUseDynamicScope()) { itsData.useDynamicScope = true; } } if (theFunction.isGenerator()) { addIcode(Icode_GENERATOR); addUint16(theFunction.getBaseLineno() & 0xFFFF); } generateICodeFromTree(theFunction.getLastChild()); } private void generateICodeFromTree(Node tree) { generateNestedFunctions(); generateRegExpLiterals(); visitStatement(tree, 0); fixLabelGotos(); // add RETURN_RESULT only to scripts as function always ends with RETURN if (itsData.itsFunctionType == 0) { addToken(Token.RETURN_RESULT); } if (itsData.itsICode.length != itsICodeTop) { // Make itsData.itsICode length exactly itsICodeTop to save memory // and catch bugs with jumps beyond icode as early as possible byte[] tmp = new byte[itsICodeTop]; System.arraycopy(itsData.itsICode, 0, tmp, 0, itsICodeTop); itsData.itsICode = tmp; } if (itsStrings.size() == 0) { itsData.itsStringTable = null; } else { itsData.itsStringTable = new String[itsStrings.size()]; ObjToIntMap.Iterator iter = itsStrings.newIterator(); for (iter.start(); !iter.done(); iter.next()) { String str = (String)iter.getKey(); int index = iter.getValue(); if (itsData.itsStringTable[index] != null) Kit.codeBug(); itsData.itsStringTable[index] = str; } } if (itsDoubleTableTop == 0) { itsData.itsDoubleTable = null; } else if (itsData.itsDoubleTable.length != itsDoubleTableTop) { double[] tmp = new double[itsDoubleTableTop]; System.arraycopy(itsData.itsDoubleTable, 0, tmp, 0, itsDoubleTableTop); itsData.itsDoubleTable = tmp; } if (itsExceptionTableTop != 0 && itsData.itsExceptionTable.length != itsExceptionTableTop) { int[] tmp = new int[itsExceptionTableTop]; System.arraycopy(itsData.itsExceptionTable, 0, tmp, 0, itsExceptionTableTop); itsData.itsExceptionTable = tmp; } itsData.itsMaxVars = scriptOrFn.getParamAndVarCount(); // itsMaxFrameArray: interpret method needs this amount for its // stack and sDbl arrays itsData.itsMaxFrameArray = itsData.itsMaxVars + itsData.itsMaxLocals + itsData.itsMaxStack; itsData.argNames = scriptOrFn.getParamAndVarNames(); itsData.argIsConst = scriptOrFn.getParamAndVarConst(); itsData.argCount = scriptOrFn.getParamCount(); itsData.encodedSourceStart = scriptOrFn.getEncodedSourceStart(); itsData.encodedSourceEnd = scriptOrFn.getEncodedSourceEnd(); if (itsLiteralIds.size() != 0) { itsData.literalIds = itsLiteralIds.toArray(); } if (Token.printICode) dumpICode(itsData); } private void generateNestedFunctions() { int functionCount = scriptOrFn.getFunctionCount(); if (functionCount == 0) return; InterpreterData[] array = new InterpreterData[functionCount]; for (int i = 0; i != functionCount; i++) { FunctionNode def = scriptOrFn.getFunctionNode(i); Interpreter jsi = new Interpreter(); jsi.compilerEnv = compilerEnv; jsi.scriptOrFn = def; jsi.itsData = new InterpreterData(itsData); jsi.generateFunctionICode(); array[i] = jsi.itsData; } itsData.itsNestedFunctions = array; } private void generateRegExpLiterals() { int N = scriptOrFn.getRegexpCount(); if (N == 0) return; Context cx = Context.getContext(); RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx); Object[] array = new Object[N]; for (int i = 0; i != N; i++) { String string = scriptOrFn.getRegexpString(i); String flags = scriptOrFn.getRegexpFlags(i); array[i] = rep.compileRegExp(cx, string, flags); } itsData.itsRegExpLiterals = array; } private void updateLineNumber(Node node) { int lineno = node.getLineno(); if (lineno != itsLineNumber && lineno >= 0) { if (itsData.firstLinePC < 0) { itsData.firstLinePC = lineno; } itsLineNumber = lineno; addIcode(Icode_LINE); addUint16(lineno & 0xFFFF); } } private RuntimeException badTree(Node node) { throw new RuntimeException(node.toString()); } private void visitStatement(Node node, int initialStackDepth) { int type = node.getType(); Node child = node.getFirstChild(); switch (type) { case Token.FUNCTION: { int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP); int fnType = scriptOrFn.getFunctionNode(fnIndex). getFunctionType(); // Only function expressions or function expression // statements need closure code creating new function // object on stack as function statements are initialized // at script/function start. // In addition, function expressions can not be present here // at statement level, they must only be present as expressions. if (fnType == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) { addIndexOp(Icode_CLOSURE_STMT, fnIndex); } else { if (fnType != FunctionNode.FUNCTION_STATEMENT) { throw Kit.codeBug(); } } // For function statements or function expression statements // in scripts, we need to ensure that the result of the script // is the function if it is the last statement in the script. // For example, eval("function () {}") should return a // function, not undefined. if (!itsInFunctionFlag) { addIndexOp(Icode_CLOSURE_EXPR, fnIndex); stackChange(1); addIcode(Icode_POP_RESULT); stackChange(-1); } } break; case Token.LABEL: case Token.LOOP: case Token.BLOCK: case Token.EMPTY: case Token.WITH: updateLineNumber(node); case Token.SCRIPT: // fall through while (child != null) { visitStatement(child, initialStackDepth); child = child.getNext(); } break; case Token.ENTERWITH: visitExpression(child, 0); addToken(Token.ENTERWITH); stackChange(-1); break; case Token.LEAVEWITH: addToken(Token.LEAVEWITH); break; case Token.LOCAL_BLOCK: { int local = allocLocal(); node.putIntProp(Node.LOCAL_PROP, local); updateLineNumber(node); while (child != null) { visitStatement(child, initialStackDepth); child = child.getNext(); } addIndexOp(Icode_LOCAL_CLEAR, local); releaseLocal(local); } break; case Token.DEBUGGER: addIcode(Icode_DEBUGGER); break; case Token.SWITCH: updateLineNumber(node); // See comments in IRFactory.createSwitch() for description // of SWITCH node { visitExpression(child, 0); for (Node.Jump caseNode = (Node.Jump)child.getNext(); caseNode != null; caseNode = (Node.Jump)caseNode.getNext()) { if (caseNode.getType() != Token.CASE) throw badTree(caseNode); Node test = caseNode.getFirstChild(); addIcode(Icode_DUP); stackChange(1); visitExpression(test, 0); addToken(Token.SHEQ); stackChange(-1); // If true, Icode_IFEQ_POP will jump and remove case // value from stack addGoto(caseNode.target, Icode_IFEQ_POP); stackChange(-1); } addIcode(Icode_POP); stackChange(-1); } break; case Token.TARGET: markTargetLabel(node); break; case Token.IFEQ : case Token.IFNE : { Node target = ((Node.Jump)node).target; visitExpression(child, 0); addGoto(target, type); stackChange(-1); } break; case Token.GOTO: { Node target = ((Node.Jump)node).target; addGoto(target, type); } break; case Token.JSR: { Node target = ((Node.Jump)node).target; addGoto(target, Icode_GOSUB); } break; case Token.FINALLY: { // Account for incomming GOTOSUB address stackChange(1); int finallyRegister = getLocalBlockRef(node); addIndexOp(Icode_STARTSUB, finallyRegister); stackChange(-1); while (child != null) { visitStatement(child, initialStackDepth); child = child.getNext(); } addIndexOp(Icode_RETSUB, finallyRegister); } break; case Token.EXPR_VOID: case Token.EXPR_RESULT: updateLineNumber(node); visitExpression(child, 0); addIcode((type == Token.EXPR_VOID) ? Icode_POP : Icode_POP_RESULT); stackChange(-1); break; case Token.TRY: { Node.Jump tryNode = (Node.Jump)node; int exceptionObjectLocal = getLocalBlockRef(tryNode); int scopeLocal = allocLocal(); addIndexOp(Icode_SCOPE_SAVE, scopeLocal); int tryStart = itsICodeTop; boolean savedFlag = itsInTryFlag; itsInTryFlag = true; while (child != null) { visitStatement(child, initialStackDepth); child = child.getNext(); } itsInTryFlag = savedFlag; Node catchTarget = tryNode.target; if (catchTarget != null) { int catchStartPC = itsLabelTable[getTargetLabel(catchTarget)]; addExceptionHandler( tryStart, catchStartPC, catchStartPC, false, exceptionObjectLocal, scopeLocal); } Node finallyTarget = tryNode.getFinally(); if (finallyTarget != null) { int finallyStartPC = itsLabelTable[getTargetLabel(finallyTarget)]; addExceptionHandler( tryStart, finallyStartPC, finallyStartPC, true, exceptionObjectLocal, scopeLocal); } addIndexOp(Icode_LOCAL_CLEAR, scopeLocal); releaseLocal(scopeLocal); } break; case Token.CATCH_SCOPE: { int localIndex = getLocalBlockRef(node); int scopeIndex = node.getExistingIntProp(Node.CATCH_SCOPE_PROP); String name = child.getString(); child = child.getNext(); visitExpression(child, 0); // load expression object addStringPrefix(name); addIndexPrefix(localIndex); addToken(Token.CATCH_SCOPE); addUint8(scopeIndex != 0 ? 1 : 0); stackChange(-1); } break; case Token.THROW: updateLineNumber(node); visitExpression(child, 0); addToken(Token.THROW); addUint16(itsLineNumber & 0xFFFF); stackChange(-1); break; case Token.RETHROW: updateLineNumber(node); addIndexOp(Token.RETHROW, getLocalBlockRef(node)); break; case Token.RETURN: updateLineNumber(node); if (node.getIntProp(Node.GENERATOR_END_PROP, 0) != 0) { // We're in a generator, so change RETURN to GENERATOR_END addIcode(Icode_GENERATOR_END); addUint16(itsLineNumber & 0xFFFF); } else if (child != null) { visitExpression(child, ECF_TAIL); addToken(Token.RETURN); stackChange(-1); } else { addIcode(Icode_RETUNDEF); } break; case Token.RETURN_RESULT: updateLineNumber(node); addToken(Token.RETURN_RESULT); break; case Token.ENUM_INIT_KEYS: case Token.ENUM_INIT_VALUES: case Token.ENUM_INIT_ARRAY: visitExpression(child, 0); addIndexOp(type, getLocalBlockRef(node)); stackChange(-1); break; case Icode_GENERATOR: break; default: throw badTree(node); } if (itsStackDepth != initialStackDepth) { throw Kit.codeBug(); } } private void visitExpression(Node node, int contextFlags) { int type = node.getType(); Node child = node.getFirstChild(); int savedStackDepth = itsStackDepth; switch (type) { case Token.FUNCTION: { int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP); FunctionNode fn = scriptOrFn.getFunctionNode(fnIndex); // See comments in visitStatement for Token.FUNCTION case if (fn.getFunctionType() != FunctionNode.FUNCTION_EXPRESSION) { throw Kit.codeBug(); } addIndexOp(Icode_CLOSURE_EXPR, fnIndex); stackChange(1); } break; case Token.LOCAL_LOAD: { int localIndex = getLocalBlockRef(node); addIndexOp(Token.LOCAL_LOAD, localIndex); stackChange(1); } break; case Token.COMMA: { Node lastChild = node.getLastChild(); while (child != lastChild) { visitExpression(child, 0); addIcode(Icode_POP); stackChange(-1); child = child.getNext(); } // Preserve tail context flag if any visitExpression(child, contextFlags & ECF_TAIL); } break; case Token.USE_STACK: // Indicates that stack was modified externally, // like placed catch object stackChange(1); break; case Token.REF_CALL: case Token.CALL: case Token.NEW: { if (type == Token.NEW) { visitExpression(child, 0); } else { generateCallFunAndThis(child); } int argCount = 0; while ((child = child.getNext()) != null) { visitExpression(child, 0); ++argCount; } int callType = node.getIntProp(Node.SPECIALCALL_PROP, Node.NON_SPECIALCALL); if (callType != Node.NON_SPECIALCALL) { // embed line number and source filename addIndexOp(Icode_CALLSPECIAL, argCount); addUint8(callType); addUint8(type == Token.NEW ? 1 : 0); addUint16(itsLineNumber & 0xFFFF); } else { // Only use the tail call optimization if we're not in a try // or we're not generating debug info (since the // optimization will confuse the debugger) if (type == Token.CALL && (contextFlags & ECF_TAIL) != 0 && !compilerEnv.isGenerateDebugInfo() && !itsInTryFlag) { type = Icode_TAIL_CALL; } addIndexOp(type, argCount); } // adjust stack if (type == Token.NEW) { // new: f, args -> result stackChange(-argCount); } else { // call: f, thisObj, args -> result // ref_call: f, thisObj, args -> ref stackChange(-1 - argCount); } if (argCount > itsData.itsMaxCalleeArgs) { itsData.itsMaxCalleeArgs = argCount; } } break; case Token.AND: case Token.OR: { visitExpression(child, 0); addIcode(Icode_DUP); stackChange(1); int afterSecondJumpStart = itsICodeTop; int jump = (type == Token.AND) ? Token.IFNE : Token.IFEQ; addGotoOp(jump); stackChange(-1); addIcode(Icode_POP); stackChange(-1); child = child.getNext(); // Preserve tail context flag if any visitExpression(child, contextFlags & ECF_TAIL); resolveForwardGoto(afterSecondJumpStart); } break; case Token.HOOK: { Node ifThen = child.getNext(); Node ifElse = ifThen.getNext(); visitExpression(child, 0); int elseJumpStart = itsICodeTop; addGotoOp(Token.IFNE); stackChange(-1); // Preserve tail context flag if any visitExpression(ifThen, contextFlags & ECF_TAIL); int afterElseJumpStart = itsICodeTop; addGotoOp(Token.GOTO); resolveForwardGoto(elseJumpStart); itsStackDepth = savedStackDepth; // Preserve tail context flag if any visitExpression(ifElse, contextFlags & ECF_TAIL); resolveForwardGoto(afterElseJumpStart); } break; case Token.GETPROP: case Token.GETPROPNOWARN: visitExpression(child, 0); child = child.getNext(); addStringOp(type, child.getString()); break; case Token.GETELEM: case Token.DELPROP: case Token.BITAND: case Token.BITOR: case Token.BITXOR: case Token.LSH: case Token.RSH: case Token.URSH: case Token.ADD: case Token.SUB: case Token.MOD: case Token.DIV: case Token.MUL: case Token.EQ: case Token.NE: case Token.SHEQ: case Token.SHNE: case Token.IN: case Token.INSTANCEOF: case Token.LE: case Token.LT: case Token.GE: case Token.GT: visitExpression(child, 0); child = child.getNext(); visitExpression(child, 0); addToken(type); stackChange(-1); break; case Token.POS: case Token.NEG: case Token.NOT: case Token.BITNOT: case Token.TYPEOF: case Token.VOID: visitExpression(child, 0); if (type == Token.VOID) { addIcode(Icode_POP); addIcode(Icode_UNDEF); } else { addToken(type); } break; case Token.GET_REF: case Token.DEL_REF: visitExpression(child, 0); addToken(type); break; case Token.SETPROP: case Token.SETPROP_OP: { visitExpression(child, 0); child = child.getNext(); String property = child.getString(); child = child.getNext(); if (type == Token.SETPROP_OP) { addIcode(Icode_DUP); stackChange(1); addStringOp(Token.GETPROP, property); // Compensate for the following USE_STACK stackChange(-1); } visitExpression(child, 0); addStringOp(Token.SETPROP, property); stackChange(-1); } break; case Token.SETELEM: case Token.SETELEM_OP: visitExpression(child, 0); child = child.getNext(); visitExpression(child, 0); child = child.getNext(); if (type == Token.SETELEM_OP) { addIcode(Icode_DUP2); stackChange(2); addToken(Token.GETELEM); stackChange(-1); // Compensate for the following USE_STACK stackChange(-1); } visitExpression(child, 0); addToken(Token.SETELEM); stackChange(-2); break; case Token.SET_REF: case Token.SET_REF_OP: visitExpression(child, 0); child = child.getNext(); if (type == Token.SET_REF_OP) { addIcode(Icode_DUP); stackChange(1); addToken(Token.GET_REF); // Compensate for the following USE_STACK stackChange(-1); } visitExpression(child, 0); addToken(Token.SET_REF); stackChange(-1); break; case Token.SETNAME: { String name = child.getString(); visitExpression(child, 0); child = child.getNext(); visitExpression(child, 0); addStringOp(Token.SETNAME, name); stackChange(-1); } break; case Token.SETCONST: { String name = child.getString(); visitExpression(child, 0); child = child.getNext(); visitExpression(child, 0); addStringOp(Icode_SETCONST, name); stackChange(-1); } break; case Token.TYPEOFNAME: { int index = -1; // use typeofname if an activation frame exists // since the vars all exist there instead of in jregs if (itsInFunctionFlag && !itsData.itsNeedsActivation) index = scriptOrFn.getIndexForNameNode(node); if (index == -1) { addStringOp(Icode_TYPEOFNAME, node.getString()); stackChange(1); } else { addVarOp(Token.GETVAR, index); stackChange(1); addToken(Token.TYPEOF); } } break; case Token.BINDNAME: case Token.NAME: case Token.STRING: addStringOp(type, node.getString()); stackChange(1); break; case Token.INC: case Token.DEC: visitIncDec(node, child); break; case Token.NUMBER: { double num = node.getDouble(); int inum = (int)num; if (inum == num) { if (inum == 0) { addIcode(Icode_ZERO); // Check for negative zero if (1.0 / num < 0.0) { addToken(Token.NEG); } } else if (inum == 1) { addIcode(Icode_ONE); } else if ((short)inum == inum) { addIcode(Icode_SHORTNUMBER); // write short as uin16 bit pattern addUint16(inum & 0xFFFF); } else { addIcode(Icode_INTNUMBER); addInt(inum); } } else { int index = getDoubleIndex(num); addIndexOp(Token.NUMBER, index); } stackChange(1); } break; case Token.GETVAR: { if (itsData.itsNeedsActivation) Kit.codeBug(); int index = scriptOrFn.getIndexForNameNode(node); addVarOp(Token.GETVAR, index); stackChange(1); } break; case Token.SETVAR: { if (itsData.itsNeedsActivation) Kit.codeBug(); int index = scriptOrFn.getIndexForNameNode(child); child = child.getNext(); visitExpression(child, 0); addVarOp(Token.SETVAR, index); } break; case Token.SETCONSTVAR: { if (itsData.itsNeedsActivation) Kit.codeBug(); int index = scriptOrFn.getIndexForNameNode(child); child = child.getNext(); visitExpression(child, 0); addVarOp(Token.SETCONSTVAR, index); } break; case Token.NULL: case Token.THIS: case Token.THISFN: case Token.FALSE: case Token.TRUE: addToken(type); stackChange(1); break; case Token.ENUM_NEXT: case Token.ENUM_ID: addIndexOp(type, getLocalBlockRef(node)); stackChange(1); break; case Token.REGEXP: { int index = node.getExistingIntProp(Node.REGEXP_PROP); addIndexOp(Token.REGEXP, index); stackChange(1); } break; case Token.ARRAYLIT: case Token.OBJECTLIT: visitLiteral(node, child); break; case Token.ARRAYCOMP: visitArrayComprehension(node, child, child.getNext()); break; case Token.REF_SPECIAL: visitExpression(child, 0); addStringOp(type, (String)node.getProp(Node.NAME_PROP)); break; case Token.REF_MEMBER: case Token.REF_NS_MEMBER: case Token.REF_NAME: case Token.REF_NS_NAME: { int memberTypeFlags = node.getIntProp(Node.MEMBER_TYPE_PROP, 0); // generate possible target, possible namespace and member int childCount = 0; do { visitExpression(child, 0); ++childCount; child = child.getNext(); } while (child != null); addIndexOp(type, memberTypeFlags); stackChange(1 - childCount); } break; case Token.DOTQUERY: { int queryPC; updateLineNumber(node); visitExpression(child, 0); addIcode(Icode_ENTERDQ); stackChange(-1); queryPC = itsICodeTop; visitExpression(child.getNext(), 0); addBackwardGoto(Icode_LEAVEDQ, queryPC); } break; case Token.DEFAULTNAMESPACE : case Token.ESCXMLATTR : case Token.ESCXMLTEXT : visitExpression(child, 0); addToken(type); break; case Token.YIELD: if (child != null) { visitExpression(child, 0); } else { addIcode(Icode_UNDEF); stackChange(1); } addToken(Token.YIELD); addUint16(node.getLineno() & 0xFFFF); break; case Token.WITHEXPR: { Node enterWith = node.getFirstChild(); Node with = enterWith.getNext(); visitExpression(enterWith.getFirstChild(), 0); addToken(Token.ENTERWITH); stackChange(-1); visitExpression(with.getFirstChild(), 0); addToken(Token.LEAVEWITH); break; } default: throw badTree(node); } if (savedStackDepth + 1 != itsStackDepth) { Kit.codeBug(); } } private void generateCallFunAndThis(Node left) { // Generate code to place on stack function and thisObj int type = left.getType(); switch (type) { case Token.NAME: { String name = left.getString(); // stack: ... -> ... function thisObj addStringOp(Icode_NAME_AND_THIS, name); stackChange(2); break; } case Token.GETPROP: case Token.GETELEM: { Node target = left.getFirstChild(); visitExpression(target, 0); Node id = target.getNext(); if (type == Token.GETPROP) { String property = id.getString(); // stack: ... target -> ... function thisObj addStringOp(Icode_PROP_AND_THIS, property); stackChange(1); } else { visitExpression(id, 0); // stack: ... target id -> ... function thisObj addIcode(Icode_ELEM_AND_THIS); } break; } default: // Including Token.GETVAR visitExpression(left, 0); // stack: ... value -> ... function thisObj addIcode(Icode_VALUE_AND_THIS); stackChange(1); break; } } private void visitIncDec(Node node, Node child) { int incrDecrMask = node.getExistingIntProp(Node.INCRDECR_PROP); int childType = child.getType(); switch (childType) { case Token.GETVAR : { if (itsData.itsNeedsActivation) Kit.codeBug(); int i = scriptOrFn.getIndexForNameNode(child); addVarOp(Icode_VAR_INC_DEC, i); addUint8(incrDecrMask); stackChange(1); break; } case Token.NAME : { String name = child.getString(); addStringOp(Icode_NAME_INC_DEC, name); addUint8(incrDecrMask); stackChange(1); break; } case Token.GETPROP : { Node object = child.getFirstChild(); visitExpression(object, 0); String property = object.getNext().getString(); addStringOp(Icode_PROP_INC_DEC, property); addUint8(incrDecrMask); break; } case Token.GETELEM : { Node object = child.getFirstChild(); visitExpression(object, 0); Node index = object.getNext(); visitExpression(index, 0); addIcode(Icode_ELEM_INC_DEC); addUint8(incrDecrMask); stackChange(-1); break; } case Token.GET_REF : { Node ref = child.getFirstChild(); visitExpression(ref, 0); addIcode(Icode_REF_INC_DEC); addUint8(incrDecrMask); break; } default : { throw badTree(node); } } } private void visitLiteral(Node node, Node child) { int type = node.getType(); int count; Object[] propertyIds = null; if (type == Token.ARRAYLIT) { count = 0; for (Node n = child; n != null; n = n.getNext()) { ++count; } } else if (type == Token.OBJECTLIT) { propertyIds = (Object[])node.getProp(Node.OBJECT_IDS_PROP); count = propertyIds.length; } else { throw badTree(node); } addIndexOp(Icode_LITERAL_NEW, count); stackChange(2); while (child != null) { int childType = child.getType(); if (childType == Token.GET) { visitExpression(child.getFirstChild(), 0); addIcode(Icode_LITERAL_GETTER); } else if (childType == Token.SET) { visitExpression(child.getFirstChild(), 0); addIcode(Icode_LITERAL_SETTER); } else { visitExpression(child, 0); addIcode(Icode_LITERAL_SET); } stackChange(-1); child = child.getNext(); } if (type == Token.ARRAYLIT) { int[] skipIndexes = (int[])node.getProp(Node.SKIP_INDEXES_PROP); if (skipIndexes == null) { addToken(Token.ARRAYLIT); } else { int index = itsLiteralIds.size(); itsLiteralIds.add(skipIndexes); addIndexOp(Icode_SPARE_ARRAYLIT, index); } } else { int index = itsLiteralIds.size(); itsLiteralIds.add(propertyIds); addIndexOp(Token.OBJECTLIT, index); } stackChange(-1); } private void visitArrayComprehension(Node node, Node initStmt, Node expr) { // A bit of a hack: array comprehensions are implemented using // statement nodes for the iteration, yet they appear in an // expression context. So we pass the current stack depth to // visitStatement so it can check that the depth is not altered // by statements. visitStatement(initStmt, itsStackDepth); visitExpression(expr, 0); } private int getLocalBlockRef(Node node) { Node localBlock = (Node)node.getProp(Node.LOCAL_BLOCK_PROP); return localBlock.getExistingIntProp(Node.LOCAL_PROP); } private int getTargetLabel(Node target) { int label = target.labelId(); if (label != -1) { return label; } label = itsLabelTableTop; if (itsLabelTable == null || label == itsLabelTable.length) { if (itsLabelTable == null) { itsLabelTable = new int[MIN_LABEL_TABLE_SIZE]; }else { int[] tmp = new int[itsLabelTable.length * 2]; System.arraycopy(itsLabelTable, 0, tmp, 0, label); itsLabelTable = tmp; } } itsLabelTableTop = label + 1; itsLabelTable[label] = -1; target.labelId(label); return label; } private void markTargetLabel(Node target) { int label = getTargetLabel(target); if (itsLabelTable[label] != -1) { // Can mark label only once Kit.codeBug(); } itsLabelTable[label] = itsICodeTop; } private void addGoto(Node target, int gotoOp) { int label = getTargetLabel(target); if (!(label < itsLabelTableTop)) Kit.codeBug(); int targetPC = itsLabelTable[label]; if (targetPC != -1) { addBackwardGoto(gotoOp, targetPC); } else { int gotoPC = itsICodeTop; addGotoOp(gotoOp); int top = itsFixupTableTop; if (itsFixupTable == null || top == itsFixupTable.length) { if (itsFixupTable == null) { itsFixupTable = new long[MIN_FIXUP_TABLE_SIZE]; } else { long[] tmp = new long[itsFixupTable.length * 2]; System.arraycopy(itsFixupTable, 0, tmp, 0, top); itsFixupTable = tmp; } } itsFixupTableTop = top + 1; itsFixupTable[top] = ((long)label << 32) | gotoPC; } } private void fixLabelGotos() { for (int i = 0; i < itsFixupTableTop; i++) { long fixup = itsFixupTable[i]; int label = (int)(fixup >> 32); int jumpSource = (int)fixup; int pc = itsLabelTable[label]; if (pc == -1) { // Unlocated label throw Kit.codeBug(); } resolveGoto(jumpSource, pc); } itsFixupTableTop = 0; } private void addBackwardGoto(int gotoOp, int jumpPC) { int fromPC = itsICodeTop; // Ensure that this is a jump backward if (fromPC <= jumpPC) throw Kit.codeBug(); addGotoOp(gotoOp); resolveGoto(fromPC, jumpPC); } private void resolveForwardGoto(int fromPC) { // Ensure that forward jump skips at least self bytecode if (itsICodeTop < fromPC + 3) throw Kit.codeBug(); resolveGoto(fromPC, itsICodeTop); } private void resolveGoto(int fromPC, int jumpPC) { int offset = jumpPC - fromPC; // Ensure that jumps do not overlap if (0 <= offset && offset <= 2) throw Kit.codeBug(); int offsetSite = fromPC + 1; if (offset != (short)offset) { if (itsData.longJumps == null) { itsData.longJumps = new UintMap(); } itsData.longJumps.put(offsetSite, jumpPC); offset = 0; } byte[] array = itsData.itsICode; array[offsetSite] = (byte)(offset >> 8); array[offsetSite + 1] = (byte)offset; } private void addToken(int token) { if (!validTokenCode(token)) throw Kit.codeBug(); addUint8(token); } private void addIcode(int icode) { if (!validIcode(icode)) throw Kit.codeBug(); // Write negative icode as uint8 bits addUint8(icode & 0xFF); } private void addUint8(int value) { if ((value & ~0xFF) != 0) throw Kit.codeBug(); byte[] array = itsData.itsICode; int top = itsICodeTop; if (top == array.length) { array = increaseICodeCapacity(1); } array[top] = (byte)value; itsICodeTop = top + 1; } private void addUint16(int value) { if ((value & ~0xFFFF) != 0) throw Kit.codeBug(); byte[] array = itsData.itsICode; int top = itsICodeTop; if (top + 2 > array.length) { array = increaseICodeCapacity(2); } array[top] = (byte)(value >>> 8); array[top + 1] = (byte)value; itsICodeTop = top + 2; } private void addInt(int i) { byte[] array = itsData.itsICode; int top = itsICodeTop; if (top + 4 > array.length) { array = increaseICodeCapacity(4); } array[top] = (byte)(i >>> 24); array[top + 1] = (byte)(i >>> 16); array[top + 2] = (byte)(i >>> 8); array[top + 3] = (byte)i; itsICodeTop = top + 4; } private int getDoubleIndex(double num) { int index = itsDoubleTableTop; if (index == 0) { itsData.itsDoubleTable = new double[64]; } else if (itsData.itsDoubleTable.length == index) { double[] na = new double[index * 2]; System.arraycopy(itsData.itsDoubleTable, 0, na, 0, index); itsData.itsDoubleTable = na; } itsData.itsDoubleTable[index] = num; itsDoubleTableTop = index + 1; return index; } private void addGotoOp(int gotoOp) { byte[] array = itsData.itsICode; int top = itsICodeTop; if (top + 3 > array.length) { array = increaseICodeCapacity(3); } array[top] = (byte)gotoOp; // Offset would written later itsICodeTop = top + 1 + 2; } private void addVarOp(int op, int varIndex) { switch (op) { case Token.SETCONSTVAR: if (varIndex < 128) { addIcode(Icode_SETCONSTVAR1); addUint8(varIndex); return; } addIndexOp(Icode_SETCONSTVAR, varIndex); return; case Token.GETVAR: case Token.SETVAR: if (varIndex < 128) { addIcode(op == Token.GETVAR ? Icode_GETVAR1 : Icode_SETVAR1); addUint8(varIndex); return; } // fallthrough case Icode_VAR_INC_DEC: addIndexOp(op, varIndex); return; } throw Kit.codeBug(); } private void addStringOp(int op, String str) { addStringPrefix(str); if (validIcode(op)) { addIcode(op); } else { addToken(op); } } private void addIndexOp(int op, int index) { addIndexPrefix(index); if (validIcode(op)) { addIcode(op); } else { addToken(op); } } private void addStringPrefix(String str) { int index = itsStrings.get(str, -1); if (index == -1) { index = itsStrings.size(); itsStrings.put(str, index); } if (index < 4) { addIcode(Icode_REG_STR_C0 - index); } else if (index <= 0xFF) { addIcode(Icode_REG_STR1); addUint8(index); } else if (index <= 0xFFFF) { addIcode(Icode_REG_STR2); addUint16(index); } else { addIcode(Icode_REG_STR4); addInt(index); } } private void addIndexPrefix(int index) { if (index < 0) Kit.codeBug(); if (index < 6) { addIcode(Icode_REG_IND_C0 - index); } else if (index <= 0xFF) { addIcode(Icode_REG_IND1); addUint8(index); } else if (index <= 0xFFFF) { addIcode(Icode_REG_IND2); addUint16(index); } else { addIcode(Icode_REG_IND4); addInt(index); } } private void addExceptionHandler(int icodeStart, int icodeEnd, int handlerStart, boolean isFinally, int exceptionObjectLocal, int scopeLocal) { int top = itsExceptionTableTop; int[] table = itsData.itsExceptionTable; if (table == null) { if (top != 0) Kit.codeBug(); table = new int[EXCEPTION_SLOT_SIZE * 2]; itsData.itsExceptionTable = table; } else if (table.length == top) { table = new int[table.length * 2]; System.arraycopy(itsData.itsExceptionTable, 0, table, 0, top); itsData.itsExceptionTable = table; } table[top + EXCEPTION_TRY_START_SLOT] = icodeStart; table[top + EXCEPTION_TRY_END_SLOT] = icodeEnd; table[top + EXCEPTION_HANDLER_SLOT] = handlerStart; table[top + EXCEPTION_TYPE_SLOT] = isFinally ? 1 : 0; table[top + EXCEPTION_LOCAL_SLOT] = exceptionObjectLocal; table[top + EXCEPTION_SCOPE_SLOT] = scopeLocal; itsExceptionTableTop = top + EXCEPTION_SLOT_SIZE; } private byte[] increaseICodeCapacity(int extraSize) { int capacity = itsData.itsICode.length; int top = itsICodeTop; if (top + extraSize <= capacity) throw Kit.codeBug(); capacity *= 2; if (top + extraSize > capacity) { capacity = top + extraSize; } byte[] array = new byte[capacity]; System.arraycopy(itsData.itsICode, 0, array, 0, top); itsData.itsICode = array; return array; } private void stackChange(int change) { if (change <= 0) { itsStackDepth += change; } else { int newDepth = itsStackDepth + change; if (newDepth > itsData.itsMaxStack) { itsData.itsMaxStack = newDepth; } itsStackDepth = newDepth; } } private int allocLocal() { int localSlot = itsLocalTop; ++itsLocalTop; if (itsLocalTop > itsData.itsMaxLocals) { itsData.itsMaxLocals = itsLocalTop; } return localSlot; } private void releaseLocal(int localSlot) { --itsLocalTop; if (localSlot != itsLocalTop) Kit.codeBug(); } private static int getShort(byte[] iCode, int pc) { return (iCode[pc] << 8) | (iCode[pc + 1] & 0xFF); } private static int getIndex(byte[] iCode, int pc) { return ((iCode[pc] & 0xFF) << 8) | (iCode[pc + 1] & 0xFF); } private static int getInt(byte[] iCode, int pc) { return (iCode[pc] << 24) | ((iCode[pc + 1] & 0xFF) << 16) | ((iCode[pc + 2] & 0xFF) << 8) | (iCode[pc + 3] & 0xFF); } private static int getExceptionHandler(CallFrame frame, boolean onlyFinally) { int[] exceptionTable = frame.idata.itsExceptionTable; if (exceptionTable == null) { // No exception handlers return -1; } // Icode switch in the interpreter increments PC immediately // and it is necessary to subtract 1 from the saved PC // to point it before the start of the next instruction. int pc = frame.pc - 1; // OPT: use binary search int best = -1, bestStart = 0, bestEnd = 0; for (int i = 0; i != exceptionTable.length; i += EXCEPTION_SLOT_SIZE) { int start = exceptionTable[i + EXCEPTION_TRY_START_SLOT]; int end = exceptionTable[i + EXCEPTION_TRY_END_SLOT]; if (!(start <= pc && pc < end)) { continue; } if (onlyFinally && exceptionTable[i + EXCEPTION_TYPE_SLOT] != 1) { continue; } if (best >= 0) { // Since handlers always nest and they never have shared end // although they can share start it is sufficient to compare // handlers ends if (bestEnd < end) { continue; } // Check the above assumption if (bestStart > start) Kit.codeBug(); // should be nested if (bestEnd == end) Kit.codeBug(); // no ens sharing } best = i; bestStart = start; bestEnd = end; } return best; } private static void dumpICode(InterpreterData idata) { if (!Token.printICode) { return; } byte iCode[] = idata.itsICode; int iCodeLength = iCode.length; String[] strings = idata.itsStringTable; PrintStream out = System.out; out.println("ICode dump, for " + idata.itsName + ", length = " + iCodeLength); out.println("MaxStack = " + idata.itsMaxStack); int indexReg = 0; for (int pc = 0; pc < iCodeLength; ) { out.flush(); out.print(" [" + pc + "] "); int token = iCode[pc]; int icodeLength = bytecodeSpan(token); String tname = bytecodeName(token); int old_pc = pc; ++pc; switch (token) { default: if (icodeLength != 1) Kit.codeBug(); out.println(tname); break; case Icode_GOSUB : case Token.GOTO : case Token.IFEQ : case Token.IFNE : case Icode_IFEQ_POP : case Icode_LEAVEDQ : { int newPC = pc + getShort(iCode, pc) - 1; out.println(tname + " " + newPC); pc += 2; break; } case Icode_VAR_INC_DEC : case Icode_NAME_INC_DEC : case Icode_PROP_INC_DEC : case Icode_ELEM_INC_DEC : case Icode_REF_INC_DEC: { int incrDecrType = iCode[pc]; out.println(tname + " " + incrDecrType); ++pc; break; } case Icode_CALLSPECIAL : { int callType = iCode[pc] & 0xFF; boolean isNew = (iCode[pc + 1] != 0); int line = getIndex(iCode, pc+2); out.println(tname+" "+callType+" "+isNew+" "+indexReg+" "+line); pc += 4; break; } case Token.CATCH_SCOPE: { boolean afterFisrtFlag = (iCode[pc] != 0); out.println(tname+" "+afterFisrtFlag); ++pc; } break; case Token.REGEXP : out.println(tname+" "+idata.itsRegExpLiterals[indexReg]); break; case Token.OBJECTLIT : case Icode_SPARE_ARRAYLIT : out.println(tname+" "+idata.literalIds[indexReg]); break; case Icode_CLOSURE_EXPR : case Icode_CLOSURE_STMT : out.println(tname+" "+idata.itsNestedFunctions[indexReg]); break; case Token.CALL : case Icode_TAIL_CALL : case Token.REF_CALL : case Token.NEW : out.println(tname+' '+indexReg); break; case Token.THROW : case Token.YIELD : case Icode_GENERATOR : case Icode_GENERATOR_END : { int line = getIndex(iCode, pc); out.println(tname + " : " + line); pc += 2; break; } case Icode_SHORTNUMBER : { int value = getShort(iCode, pc); out.println(tname + " " + value); pc += 2; break; } case Icode_INTNUMBER : { int value = getInt(iCode, pc); out.println(tname + " " + value); pc += 4; break; } case Token.NUMBER : { double value = idata.itsDoubleTable[indexReg]; out.println(tname + " " + value); break; } case Icode_LINE : { int line = getIndex(iCode, pc); out.println(tname + " : " + line); pc += 2; break; } case Icode_REG_STR1: { String str = strings[0xFF & iCode[pc]]; out.println(tname + " \"" + str + '"'); ++pc; break; } case Icode_REG_STR2: { String str = strings[getIndex(iCode, pc)]; out.println(tname + " \"" + str + '"'); pc += 2; break; } case Icode_REG_STR4: { String str = strings[getInt(iCode, pc)]; out.println(tname + " \"" + str + '"'); pc += 4; break; } case Icode_REG_IND_C0: indexReg = 0; out.println(tname); break; case Icode_REG_IND_C1: indexReg = 1; out.println(tname); break; case Icode_REG_IND_C2: indexReg = 2; out.println(tname); break; case Icode_REG_IND_C3: indexReg = 3; out.println(tname); break; case Icode_REG_IND_C4: indexReg = 4; out.println(tname); break; case Icode_REG_IND_C5: indexReg = 5; out.println(tname); break; case Icode_REG_IND1: { indexReg = 0xFF & iCode[pc]; out.println(tname+" "+indexReg); ++pc; break; } case Icode_REG_IND2: { indexReg = getIndex(iCode, pc); out.println(tname+" "+indexReg); pc += 2; break; } case Icode_REG_IND4: { indexReg = getInt(iCode, pc); out.println(tname+" "+indexReg); pc += 4; break; } case Icode_GETVAR1: case Icode_SETVAR1: case Icode_SETCONSTVAR1: indexReg = iCode[pc]; out.println(tname+" "+indexReg); ++pc; break; } if (old_pc + icodeLength != pc) Kit.codeBug(); } int[] table = idata.itsExceptionTable; if (table != null) { out.println("Exception handlers: " +table.length / EXCEPTION_SLOT_SIZE); for (int i = 0; i != table.length; i += EXCEPTION_SLOT_SIZE) { int tryStart = table[i + EXCEPTION_TRY_START_SLOT]; int tryEnd = table[i + EXCEPTION_TRY_END_SLOT]; int handlerStart = table[i + EXCEPTION_HANDLER_SLOT]; int type = table[i + EXCEPTION_TYPE_SLOT]; int exceptionLocal = table[i + EXCEPTION_LOCAL_SLOT]; int scopeLocal = table[i + EXCEPTION_SCOPE_SLOT]; out.println(" tryStart="+tryStart+" tryEnd="+tryEnd +" handlerStart="+handlerStart +" type="+(type == 0 ? "catch" : "finally") +" exceptionLocal="+exceptionLocal); } } out.flush(); } private static int bytecodeSpan(int bytecode) { switch (bytecode) { case Token.THROW : case Token.YIELD: case Icode_GENERATOR: case Icode_GENERATOR_END: // source line return 1 + 2; case Icode_GOSUB : case Token.GOTO : case Token.IFEQ : case Token.IFNE : case Icode_IFEQ_POP : case Icode_LEAVEDQ : // target pc offset return 1 + 2; case Icode_CALLSPECIAL : // call type // is new // line number return 1 + 1 + 1 + 2; case Token.CATCH_SCOPE: // scope flag return 1 + 1; case Icode_VAR_INC_DEC: case Icode_NAME_INC_DEC: case Icode_PROP_INC_DEC: case Icode_ELEM_INC_DEC: case Icode_REF_INC_DEC: // type of ++/-- return 1 + 1; case Icode_SHORTNUMBER : // short number return 1 + 2; case Icode_INTNUMBER : // int number return 1 + 4; case Icode_REG_IND1: // ubyte index return 1 + 1; case Icode_REG_IND2: // ushort index return 1 + 2; case Icode_REG_IND4: // int index return 1 + 4; case Icode_REG_STR1: // ubyte string index return 1 + 1; case Icode_REG_STR2: // ushort string index return 1 + 2; case Icode_REG_STR4: // int string index return 1 + 4; case Icode_GETVAR1: case Icode_SETVAR1: case Icode_SETCONSTVAR1: // byte var index return 1 + 1; case Icode_LINE : // line number return 1 + 2; } if (!validBytecode(bytecode)) throw Kit.codeBug(); return 1; } static int[] getLineNumbers(InterpreterData data) { UintMap presentLines = new UintMap(); byte[] iCode = data.itsICode; int iCodeLength = iCode.length; for (int pc = 0; pc != iCodeLength;) { int bytecode = iCode[pc]; int span = bytecodeSpan(bytecode); if (bytecode == Icode_LINE) { if (span != 3) Kit.codeBug(); int line = getIndex(iCode, pc + 1); presentLines.put(line, 0); } pc += span; } return presentLines.getKeys(); } public void captureStackInfo(RhinoException ex) { Context cx = Context.getCurrentContext(); if (cx == null || cx.lastInterpreterFrame == null) { // No interpreter invocations ex.interpreterStackInfo = null; ex.interpreterLineData = null; return; } // has interpreter frame on the stack CallFrame[] array; if (cx.previousInterpreterInvocations == null || cx.previousInterpreterInvocations.size() == 0) { array = new CallFrame[1]; } else { int previousCount = cx.previousInterpreterInvocations.size(); if (cx.previousInterpreterInvocations.peek() == cx.lastInterpreterFrame) { // It can happen if exception was generated after // frame was pushed to cx.previousInterpreterInvocations // but before assignment to cx.lastInterpreterFrame. // In this case frames has to be ignored. --previousCount; } array = new CallFrame[previousCount + 1]; cx.previousInterpreterInvocations.toArray(array); } array[array.length - 1] = (CallFrame)cx.lastInterpreterFrame; int interpreterFrameCount = 0; for (int i = 0; i != array.length; ++i) { interpreterFrameCount += 1 + array[i].frameIndex; } int[] linePC = new int[interpreterFrameCount]; // Fill linePC with pc positions from all interpreter frames. // Start from the most nested frame int linePCIndex = interpreterFrameCount; for (int i = array.length; i != 0;) { --i; CallFrame frame = array[i]; while (frame != null) { --linePCIndex; linePC[linePCIndex] = frame.pcSourceLineStart; frame = frame.parentFrame; } } if (linePCIndex != 0) Kit.codeBug(); ex.interpreterStackInfo = array; ex.interpreterLineData = linePC; } public String getSourcePositionFromStack(Context cx, int[] linep) { CallFrame frame = (CallFrame)cx.lastInterpreterFrame; InterpreterData idata = frame.idata; if (frame.pcSourceLineStart >= 0) { linep[0] = getIndex(idata.itsICode, frame.pcSourceLineStart); } else { linep[0] = 0; } return idata.itsSourceFile; } public String getPatchedStack(RhinoException ex, String nativeStackTrace) { String tag = "org.mozilla.javascript.Interpreter.interpretLoop"; StringBuffer sb = new StringBuffer(nativeStackTrace.length() + 1000); String lineSeparator = SecurityUtilities.getSystemProperty("line.separator"); CallFrame[] array = (CallFrame[])ex.interpreterStackInfo; int[] linePC = ex.interpreterLineData; int arrayIndex = array.length; int linePCIndex = linePC.length; int offset = 0; while (arrayIndex != 0) { --arrayIndex; int pos = nativeStackTrace.indexOf(tag, offset); if (pos < 0) { break; } // Skip tag length pos += tag.length(); // Skip until the end of line for (; pos != nativeStackTrace.length(); ++pos) { char c = nativeStackTrace.charAt(pos); if (c == '\n' || c == '\r') { break; } } sb.append(nativeStackTrace.substring(offset, pos)); offset = pos; CallFrame frame = array[arrayIndex]; while (frame != null) { if (linePCIndex == 0) Kit.codeBug(); --linePCIndex; InterpreterData idata = frame.idata; sb.append(lineSeparator); sb.append("\tat script"); if (idata.itsName != null && idata.itsName.length() != 0) { sb.append('.'); sb.append(idata.itsName); } sb.append('('); sb.append(idata.itsSourceFile); int pc = linePC[linePCIndex]; if (pc >= 0) { // Include line info only if available sb.append(':'); sb.append(getIndex(idata.itsICode, pc)); } sb.append(')'); frame = frame.parentFrame; } } sb.append(nativeStackTrace.substring(offset)); return sb.toString(); } public List getScriptStack(RhinoException ex) { if (ex.interpreterStackInfo == null) { return null; } List list = new ArrayList(); String lineSeparator = SecurityUtilities.getSystemProperty("line.separator"); CallFrame[] array = (CallFrame[])ex.interpreterStackInfo; int[] linePC = ex.interpreterLineData; int arrayIndex = array.length; int linePCIndex = linePC.length; while (arrayIndex != 0) { --arrayIndex; StringBuilder sb = new StringBuilder(); CallFrame frame = array[arrayIndex]; while (frame != null) { if (linePCIndex == 0) Kit.codeBug(); --linePCIndex; InterpreterData idata = frame.idata; sb.append("\tat "); sb.append(idata.itsSourceFile); int pc = linePC[linePCIndex]; if (pc >= 0) { // Include line info only if available sb.append(':'); sb.append(getIndex(idata.itsICode, pc)); } if (idata.itsName != null && idata.itsName.length() != 0) { sb.append(" ("); sb.append(idata.itsName); sb.append(')'); } sb.append(lineSeparator); frame = frame.parentFrame; } list.add(sb.toString()); } return list; } static String getEncodedSource(InterpreterData idata) { if (idata.encodedSource == null) { return null; } return idata.encodedSource.substring(idata.encodedSourceStart, idata.encodedSourceEnd); } private static void initFunction(Context cx, Scriptable scope, InterpretedFunction parent, int index) { InterpretedFunction fn; fn = InterpretedFunction.createFunction(cx, scope, parent, index); ScriptRuntime.initFunction(cx, scope, fn, fn.idata.itsFunctionType, parent.idata.evalScriptFlag); } static Object interpret(InterpretedFunction ifun, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!ScriptRuntime.hasTopCall(cx)) Kit.codeBug(); if (cx.interpreterSecurityDomain != ifun.securityDomain) { Object savedDomain = cx.interpreterSecurityDomain; cx.interpreterSecurityDomain = ifun.securityDomain; try { return ifun.securityController.callWithDomain( ifun.securityDomain, cx, ifun, scope, thisObj, args); } finally { cx.interpreterSecurityDomain = savedDomain; } } CallFrame frame = new CallFrame(); initFrame(cx, scope, thisObj, args, null, 0, args.length, ifun, null, frame); frame.isContinuationsTopFrame = cx.isContinuationsTopCall; cx.isContinuationsTopCall = false; return interpretLoop(cx, frame, null); } static class GeneratorState { GeneratorState(int operation, Object value) { this.operation = operation; this.value = value; } int operation; Object value; RuntimeException returnedException; } public static Object resumeGenerator(Context cx, Scriptable scope, int operation, Object savedState, Object value) { CallFrame frame = (CallFrame) savedState; GeneratorState generatorState = new GeneratorState(operation, value); if (operation == NativeGenerator.GENERATOR_CLOSE) { try { return interpretLoop(cx, frame, generatorState); } catch (RuntimeException e) { // Only propagate exceptions other than closingException if (e != value) throw e; } return Undefined.instance; } Object result = interpretLoop(cx, frame, generatorState); if (generatorState.returnedException != null) throw generatorState.returnedException; return result; } public static Object restartContinuation(NativeContinuation c, Context cx, Scriptable scope, Object[] args) { if (!ScriptRuntime.hasTopCall(cx)) { return ScriptRuntime.doTopCall(c, cx, scope, null, args); } Object arg; if (args.length == 0) { arg = Undefined.instance; } else { arg = args[0]; } CallFrame capturedFrame = (CallFrame)c.getImplementation(); if (capturedFrame == null) { // No frames to restart return arg; } ContinuationJump cjump = new ContinuationJump(c, null); cjump.result = arg; return interpretLoop(cx, null, cjump); } private static Object interpretLoop(Context cx, CallFrame frame, Object throwable) { // throwable holds exception object to rethrow or catch // It is also used for continuation restart in which case // it holds ContinuationJump final Object DBL_MRK = UniqueTag.DOUBLE_MARK; final Object undefined = Undefined.instance; final boolean instructionCounting = (cx.instructionThreshold != 0); // arbitrary number to add to instructionCount when calling // other functions final int INVOCATION_COST = 100; // arbitrary exception cost for instruction counting final int EXCEPTION_COST = 100; String stringReg = null; int indexReg = -1; if (cx.lastInterpreterFrame != null) { // save the top frame from the previous interpretLoop // invocation on the stack if (cx.previousInterpreterInvocations == null) { cx.previousInterpreterInvocations = new ObjArray(); } cx.previousInterpreterInvocations.push(cx.lastInterpreterFrame); } // When restarting continuation throwable is not null and to jump // to the code that rewind continuation state indexReg should be set // to -1. // With the normal call throwable == null and indexReg == -1 allows to // catch bugs with using indeReg to access array elements before // initializing indexReg. GeneratorState generatorState = null; if (throwable != null) { if (throwable instanceof GeneratorState) { generatorState = (GeneratorState) throwable; // reestablish this call frame enterFrame(cx, frame, ScriptRuntime.emptyArgs, true); throwable = null; } else if (!(throwable instanceof ContinuationJump)) { // It should be continuation Kit.codeBug(); } } Object interpreterResult = null; double interpreterResultDbl = 0.0; StateLoop: for (;;) { withoutExceptions: try { if (throwable != null) { // Need to return both 'frame' and 'throwable' from // 'processThrowable', so just added a 'throwable' // member in 'frame'. frame = processThrowable(cx, throwable, frame, indexReg, instructionCounting); throwable = frame.throwable; frame.throwable = null; } else { if (generatorState == null && frame.frozen) Kit.codeBug(); } // Use local variables for constant values in frame // for faster access Object[] stack = frame.stack; double[] sDbl = frame.sDbl; Object[] vars = frame.varSource.stack; double[] varDbls = frame.varSource.sDbl; int[] varAttributes = frame.varSource.stackAttributes; byte[] iCode = frame.idata.itsICode; String[] strings = frame.idata.itsStringTable; // Use local for stackTop as well. Since execption handlers // can only exist at statement level where stack is empty, // it is necessary to save/restore stackTop only across // function calls and normal returns. int stackTop = frame.savedStackTop; // Store new frame in cx which is used for error reporting etc. cx.lastInterpreterFrame = frame; Loop: for (;;) { // Exception handler assumes that PC is already incremented // pass the instruction start when it searches the // exception handler int op = iCode[frame.pc++]; jumplessRun: { // Back indent to ease implementation reading switch (op) { case Icode_GENERATOR: { if (!frame.frozen) { // First time encountering this opcode: create new generator // object and return frame.pc--; // we want to come back here when we resume CallFrame generatorFrame = captureFrameForGenerator(frame); generatorFrame.frozen = true; NativeGenerator generator = new NativeGenerator(frame.scope, generatorFrame.fnOrScript, generatorFrame); frame.result = generator; break Loop; } else { // We are now resuming execution. Fall through to YIELD case. } } // fall through... case Token.YIELD: { if (!frame.frozen) { return freezeGenerator(cx, frame, stackTop, generatorState); } else { Object obj = thawGenerator(frame, stackTop, generatorState, op); if (obj != Scriptable.NOT_FOUND) { throwable = obj; break withoutExceptions; } continue Loop; } } case Icode_GENERATOR_END: { // throw StopIteration frame.frozen = true; int sourceLine = getIndex(iCode, frame.pc); generatorState.returnedException = new JavaScriptException( NativeIterator.getStopIterationObject(frame.scope), frame.idata.itsSourceFile, sourceLine); break Loop; } case Token.THROW: { Object value = stack[stackTop]; if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; int sourceLine = getIndex(iCode, frame.pc); throwable = new JavaScriptException(value, frame.idata.itsSourceFile, sourceLine); break withoutExceptions; } case Token.RETHROW: { indexReg += frame.localShift; throwable = stack[indexReg]; break withoutExceptions; } case Token.GE : case Token.LE : case Token.GT : case Token.LT : { --stackTop; Object rhs = stack[stackTop + 1]; Object lhs = stack[stackTop]; boolean valBln; object_compare: { number_compare: { double rDbl, lDbl; if (rhs == DBL_MRK) { rDbl = sDbl[stackTop + 1]; lDbl = stack_double(frame, stackTop); } else if (lhs == DBL_MRK) { rDbl = ScriptRuntime.toNumber(rhs); lDbl = sDbl[stackTop]; } else { break number_compare; } switch (op) { case Token.GE: valBln = (lDbl >= rDbl); break object_compare; case Token.LE: valBln = (lDbl <= rDbl); break object_compare; case Token.GT: valBln = (lDbl > rDbl); break object_compare; case Token.LT: valBln = (lDbl < rDbl); break object_compare; default: throw Kit.codeBug(); } } switch (op) { case Token.GE: valBln = ScriptRuntime.cmp_LE(rhs, lhs); break; case Token.LE: valBln = ScriptRuntime.cmp_LE(lhs, rhs); break; case Token.GT: valBln = ScriptRuntime.cmp_LT(rhs, lhs); break; case Token.LT: valBln = ScriptRuntime.cmp_LT(lhs, rhs); break; default: throw Kit.codeBug(); } } stack[stackTop] = ScriptRuntime.wrapBoolean(valBln); continue Loop; } case Token.IN : case Token.INSTANCEOF : { Object rhs = stack[stackTop]; if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); boolean valBln; if (op == Token.IN) { valBln = ScriptRuntime.in(lhs, rhs, cx); } else { valBln = ScriptRuntime.instanceOf(lhs, rhs, cx); } stack[stackTop] = ScriptRuntime.wrapBoolean(valBln); continue Loop; } case Token.EQ : case Token.NE : { --stackTop; boolean valBln; Object rhs = stack[stackTop + 1]; Object lhs = stack[stackTop]; if (rhs == DBL_MRK) { if (lhs == DBL_MRK) { valBln = (sDbl[stackTop] == sDbl[stackTop + 1]); } else { valBln = ScriptRuntime.eqNumber(sDbl[stackTop + 1], lhs); } } else { if (lhs == DBL_MRK) { valBln = ScriptRuntime.eqNumber(sDbl[stackTop], rhs); } else { valBln = ScriptRuntime.eq(lhs, rhs); } } valBln ^= (op == Token.NE); stack[stackTop] = ScriptRuntime.wrapBoolean(valBln); continue Loop; } case Token.SHEQ : case Token.SHNE : { --stackTop; boolean valBln = shallowEquals(stack, sDbl, stackTop); valBln ^= (op == Token.SHNE); stack[stackTop] = ScriptRuntime.wrapBoolean(valBln); continue Loop; } case Token.IFNE : if (stack_boolean(frame, stackTop--)) { frame.pc += 2; continue Loop; } break jumplessRun; case Token.IFEQ : if (!stack_boolean(frame, stackTop--)) { frame.pc += 2; continue Loop; } break jumplessRun; case Icode_IFEQ_POP : if (!stack_boolean(frame, stackTop--)) { frame.pc += 2; continue Loop; } stack[stackTop--] = null; break jumplessRun; case Token.GOTO : break jumplessRun; case Icode_GOSUB : ++stackTop; stack[stackTop] = DBL_MRK; sDbl[stackTop] = frame.pc + 2; break jumplessRun; case Icode_STARTSUB : if (stackTop == frame.emptyStackTop + 1) { // Call from Icode_GOSUB: store return PC address in the local indexReg += frame.localShift; stack[indexReg] = stack[stackTop]; sDbl[indexReg] = sDbl[stackTop]; --stackTop; } else { // Call from exception handler: exception object is already stored // in the local if (stackTop != frame.emptyStackTop) Kit.codeBug(); } continue Loop; case Icode_RETSUB : { // indexReg: local to store return address if (instructionCounting) { addInstructionCount(cx, frame, 0); } indexReg += frame.localShift; Object value = stack[indexReg]; if (value != DBL_MRK) { // Invocation from exception handler, restore object to rethrow throwable = value; break withoutExceptions; } // Normal return from GOSUB frame.pc = (int)sDbl[indexReg]; if (instructionCounting) { frame.pcPrevBranch = frame.pc; } continue Loop; } case Icode_POP : stack[stackTop] = null; stackTop--; continue Loop; case Icode_POP_RESULT : frame.result = stack[stackTop]; frame.resultDbl = sDbl[stackTop]; stack[stackTop] = null; --stackTop; continue Loop; case Icode_DUP : stack[stackTop + 1] = stack[stackTop]; sDbl[stackTop + 1] = sDbl[stackTop]; stackTop++; continue Loop; case Icode_DUP2 : stack[stackTop + 1] = stack[stackTop - 1]; sDbl[stackTop + 1] = sDbl[stackTop - 1]; stack[stackTop + 2] = stack[stackTop]; sDbl[stackTop + 2] = sDbl[stackTop]; stackTop += 2; continue Loop; case Icode_SWAP : { Object o = stack[stackTop]; stack[stackTop] = stack[stackTop - 1]; stack[stackTop - 1] = o; double d = sDbl[stackTop]; sDbl[stackTop] = sDbl[stackTop - 1]; sDbl[stackTop - 1] = d; continue Loop; } case Token.RETURN : frame.result = stack[stackTop]; frame.resultDbl = sDbl[stackTop]; --stackTop; break Loop; case Token.RETURN_RESULT : break Loop; case Icode_RETUNDEF : frame.result = undefined; break Loop; case Token.BITNOT : { int rIntValue = stack_int32(frame, stackTop); stack[stackTop] = DBL_MRK; sDbl[stackTop] = ~rIntValue; continue Loop; } case Token.BITAND : case Token.BITOR : case Token.BITXOR : case Token.LSH : case Token.RSH : { int lIntValue = stack_int32(frame, stackTop-1); int rIntValue = stack_int32(frame, stackTop); stack[--stackTop] = DBL_MRK; switch (op) { case Token.BITAND: lIntValue &= rIntValue; break; case Token.BITOR: lIntValue |= rIntValue; break; case Token.BITXOR: lIntValue ^= rIntValue; break; case Token.LSH: lIntValue <<= rIntValue; break; case Token.RSH: lIntValue >>= rIntValue; break; } sDbl[stackTop] = lIntValue; continue Loop; } case Token.URSH : { double lDbl = stack_double(frame, stackTop-1); int rIntValue = stack_int32(frame, stackTop) & 0x1F; stack[--stackTop] = DBL_MRK; sDbl[stackTop] = ScriptRuntime.toUint32(lDbl) >>> rIntValue; continue Loop; } case Token.NEG : case Token.POS : { double rDbl = stack_double(frame, stackTop); stack[stackTop] = DBL_MRK; if (op == Token.NEG) { rDbl = -rDbl; } sDbl[stackTop] = rDbl; continue Loop; } case Token.ADD : --stackTop; do_add(stack, sDbl, stackTop, cx); continue Loop; case Token.SUB : case Token.MUL : case Token.DIV : case Token.MOD : { double rDbl = stack_double(frame, stackTop); --stackTop; double lDbl = stack_double(frame, stackTop); stack[stackTop] = DBL_MRK; switch (op) { case Token.SUB: lDbl -= rDbl; break; case Token.MUL: lDbl *= rDbl; break; case Token.DIV: lDbl /= rDbl; break; case Token.MOD: lDbl %= rDbl; break; } sDbl[stackTop] = lDbl; continue Loop; } case Token.NOT : stack[stackTop] = ScriptRuntime.wrapBoolean( !stack_boolean(frame, stackTop)); continue Loop; case Token.BINDNAME : stack[++stackTop] = ScriptRuntime.bind(cx, frame.scope, stringReg); continue Loop; case Token.SETNAME : { Object rhs = stack[stackTop]; if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Scriptable lhs = (Scriptable)stack[stackTop]; stack[stackTop] = ScriptRuntime.setName(lhs, rhs, cx, frame.scope, stringReg); continue Loop; } case Icode_SETCONST: { Object rhs = stack[stackTop]; if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Scriptable lhs = (Scriptable)stack[stackTop]; stack[stackTop] = ScriptRuntime.setConst(lhs, rhs, cx, stringReg); continue Loop; } case Token.DELPROP : { Object rhs = stack[stackTop]; if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.delete(lhs, rhs, cx); continue Loop; } case Token.GETPROPNOWARN : { Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.getObjectPropNoWarn(lhs, stringReg, cx); continue Loop; } case Token.GETPROP : { Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.getObjectProp(lhs, stringReg, cx, frame.scope); continue Loop; } case Token.SETPROP : { Object rhs = stack[stackTop]; if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.setObjectProp(lhs, stringReg, rhs, cx); continue Loop; } case Icode_PROP_INC_DEC : { Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.propIncrDecr(lhs, stringReg, cx, iCode[frame.pc]); ++frame.pc; continue Loop; } case Token.GETELEM : { --stackTop; Object lhs = stack[stackTop]; if (lhs == DBL_MRK) { lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); } Object value; Object id = stack[stackTop + 1]; if (id != DBL_MRK) { value = ScriptRuntime.getObjectElem(lhs, id, cx, frame.scope); } else { double d = sDbl[stackTop + 1]; value = ScriptRuntime.getObjectIndex(lhs, d, cx); } stack[stackTop] = value; continue Loop; } case Token.SETELEM : { stackTop -= 2; Object rhs = stack[stackTop + 2]; if (rhs == DBL_MRK) { rhs = ScriptRuntime.wrapNumber(sDbl[stackTop + 2]); } Object lhs = stack[stackTop]; if (lhs == DBL_MRK) { lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); } Object value; Object id = stack[stackTop + 1]; if (id != DBL_MRK) { value = ScriptRuntime.setObjectElem(lhs, id, rhs, cx); } else { double d = sDbl[stackTop + 1]; value = ScriptRuntime.setObjectIndex(lhs, d, rhs, cx); } stack[stackTop] = value; continue Loop; } case Icode_ELEM_INC_DEC: { Object rhs = stack[stackTop]; if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.elemIncrDecr(lhs, rhs, cx, iCode[frame.pc]); ++frame.pc; continue Loop; } case Token.GET_REF : { Ref ref = (Ref)stack[stackTop]; stack[stackTop] = ScriptRuntime.refGet(ref, cx); continue Loop; } case Token.SET_REF : { Object value = stack[stackTop]; if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Ref ref = (Ref)stack[stackTop]; stack[stackTop] = ScriptRuntime.refSet(ref, value, cx); continue Loop; } case Token.DEL_REF : { Ref ref = (Ref)stack[stackTop]; stack[stackTop] = ScriptRuntime.refDel(ref, cx); continue Loop; } case Icode_REF_INC_DEC : { Ref ref = (Ref)stack[stackTop]; stack[stackTop] = ScriptRuntime.refIncrDecr(ref, cx, iCode[frame.pc]); ++frame.pc; continue Loop; } case Token.LOCAL_LOAD : ++stackTop; indexReg += frame.localShift; stack[stackTop] = stack[indexReg]; sDbl[stackTop] = sDbl[indexReg]; continue Loop; case Icode_LOCAL_CLEAR : indexReg += frame.localShift; stack[indexReg] = null; continue Loop; case Icode_NAME_AND_THIS : // stringReg: name ++stackTop; stack[stackTop] = ScriptRuntime.getNameFunctionAndThis(stringReg, cx, frame.scope); ++stackTop; stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx); continue Loop; case Icode_PROP_AND_THIS: { Object obj = stack[stackTop]; if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]); // stringReg: property stack[stackTop] = ScriptRuntime.getPropFunctionAndThis(obj, stringReg, cx, frame.scope); ++stackTop; stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx); continue Loop; } case Icode_ELEM_AND_THIS: { Object obj = stack[stackTop - 1]; if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop - 1]); Object id = stack[stackTop]; if (id == DBL_MRK) id = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop - 1] = ScriptRuntime.getElemFunctionAndThis(obj, id, cx); stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx); continue Loop; } case Icode_VALUE_AND_THIS : { Object value = stack[stackTop]; if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.getValueFunctionAndThis(value, cx); ++stackTop; stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx); continue Loop; } case Icode_CALLSPECIAL : { if (instructionCounting) { cx.instructionCount += INVOCATION_COST; } int callType = iCode[frame.pc] & 0xFF; boolean isNew = (iCode[frame.pc + 1] != 0); int sourceLine = getIndex(iCode, frame.pc + 2); // indexReg: number of arguments if (isNew) { // stack change: function arg0 .. argN -> newResult stackTop -= indexReg; Object function = stack[stackTop]; if (function == DBL_MRK) function = ScriptRuntime.wrapNumber(sDbl[stackTop]); Object[] outArgs = getArgsArray( stack, sDbl, stackTop + 1, indexReg); stack[stackTop] = ScriptRuntime.newSpecial( cx, function, outArgs, frame.scope, callType); } else { // stack change: function thisObj arg0 .. argN -> result stackTop -= 1 + indexReg; // Call code generation ensure that stack here // is ... Callable Scriptable Scriptable functionThis = (Scriptable)stack[stackTop + 1]; Callable function = (Callable)stack[stackTop]; Object[] outArgs = getArgsArray( stack, sDbl, stackTop + 2, indexReg); stack[stackTop] = ScriptRuntime.callSpecial( cx, function, functionThis, outArgs, frame.scope, frame.thisObj, callType, frame.idata.itsSourceFile, sourceLine); } frame.pc += 4; continue Loop; } case Token.CALL : case Icode_TAIL_CALL : case Token.REF_CALL : { if (instructionCounting) { cx.instructionCount += INVOCATION_COST; } // stack change: function thisObj arg0 .. argN -> result // indexReg: number of arguments stackTop -= 1 + indexReg; // CALL generation ensures that fun and funThisObj // are already Scriptable and Callable objects respectively Callable fun = (Callable)stack[stackTop]; Scriptable funThisObj = (Scriptable)stack[stackTop + 1]; if (op == Token.REF_CALL) { Object[] outArgs = getArgsArray(stack, sDbl, stackTop + 2, indexReg); stack[stackTop] = ScriptRuntime.callRef(fun, funThisObj, outArgs, cx); continue Loop; } Scriptable calleeScope = frame.scope; if (frame.useActivation) { calleeScope = ScriptableObject.getTopLevelScope(frame.scope); } if (fun instanceof InterpretedFunction) { InterpretedFunction ifun = (InterpretedFunction)fun; if (frame.fnOrScript.securityDomain == ifun.securityDomain) { CallFrame callParentFrame = frame; CallFrame calleeFrame = new CallFrame(); if (op == Icode_TAIL_CALL) { // In principle tail call can re-use the current // frame and its stack arrays but it is hard to // do properly. Any exceptions that can legally // happen during frame re-initialization including // StackOverflowException during innocent looking // System.arraycopy may leave the current frame // data corrupted leading to undefined behaviour // in the catch code bellow that unwinds JS stack // on exceptions. Then there is issue about frame release // end exceptions there. // To avoid frame allocation a released frame // can be cached for re-use which would also benefit // non-tail calls but it is not clear that this caching // would gain in performance due to potentially // bad interaction with GC. callParentFrame = frame.parentFrame; // Release the current frame. See Bug #344501 to see why // it is being done here. exitFrame(cx, frame, null); } initFrame(cx, calleeScope, funThisObj, stack, sDbl, stackTop + 2, indexReg, ifun, callParentFrame, calleeFrame); if (op != Icode_TAIL_CALL) { frame.savedStackTop = stackTop; frame.savedCallOp = op; } frame = calleeFrame; continue StateLoop; } } if (fun instanceof NativeContinuation) { // Jump to the captured continuation ContinuationJump cjump; cjump = new ContinuationJump((NativeContinuation)fun, frame); // continuation result is the first argument if any // of continuation call if (indexReg == 0) { cjump.result = undefined; } else { cjump.result = stack[stackTop + 2]; cjump.resultDbl = sDbl[stackTop + 2]; } // Start the real unwind job throwable = cjump; break withoutExceptions; } if (fun instanceof IdFunctionObject) { IdFunctionObject ifun = (IdFunctionObject)fun; if (NativeContinuation.isContinuationConstructor(ifun)) { frame.stack[stackTop] = captureContinuation(cx, frame.parentFrame, false); continue Loop; } // Bug 405654 -- make best effort to keep Function.apply and // Function.call within this interpreter loop invocation if (BaseFunction.isApplyOrCall(ifun)) { Callable applyCallable = ScriptRuntime.getCallable(funThisObj); if (applyCallable instanceof InterpretedFunction) { InterpretedFunction iApplyCallable = (InterpretedFunction)applyCallable; if (frame.fnOrScript.securityDomain == iApplyCallable.securityDomain) { frame = initFrameForApplyOrCall(cx, frame, indexReg, stack, sDbl, stackTop, op, calleeScope, ifun, iApplyCallable); continue StateLoop; } } } } // Bug 447697 -- make best effort to keep __noSuchMethod__ within this // interpreter loop invocation if (fun instanceof NoSuchMethodShim) { // get the shim and the actual method NoSuchMethodShim noSuchMethodShim = (NoSuchMethodShim) fun; Callable noSuchMethodMethod = noSuchMethodShim.noSuchMethodMethod; // if the method is in fact an InterpretedFunction if (noSuchMethodMethod instanceof InterpretedFunction) { InterpretedFunction ifun = (InterpretedFunction) noSuchMethodMethod; if (frame.fnOrScript.securityDomain == ifun.securityDomain) { frame = initFrameForNoSuchMethod(cx, frame, indexReg, stack, sDbl, stackTop, op, funThisObj, calleeScope, noSuchMethodShim, ifun); continue StateLoop; } } } cx.lastInterpreterFrame = frame; frame.savedCallOp = op; frame.savedStackTop = stackTop; stack[stackTop] = fun.call(cx, calleeScope, funThisObj, getArgsArray(stack, sDbl, stackTop + 2, indexReg)); cx.lastInterpreterFrame = null; continue Loop; } case Token.NEW : { if (instructionCounting) { cx.instructionCount += INVOCATION_COST; } // stack change: function arg0 .. argN -> newResult // indexReg: number of arguments stackTop -= indexReg; Object lhs = stack[stackTop]; if (lhs instanceof InterpretedFunction) { InterpretedFunction f = (InterpretedFunction)lhs; if (frame.fnOrScript.securityDomain == f.securityDomain) { Scriptable newInstance = f.createObject(cx, frame.scope); CallFrame calleeFrame = new CallFrame(); initFrame(cx, frame.scope, newInstance, stack, sDbl, stackTop + 1, indexReg, f, frame, calleeFrame); stack[stackTop] = newInstance; frame.savedStackTop = stackTop; frame.savedCallOp = op; frame = calleeFrame; continue StateLoop; } } if (!(lhs instanceof Function)) { if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); throw ScriptRuntime.notFunctionError(lhs); } Function fun = (Function)lhs; if (fun instanceof IdFunctionObject) { IdFunctionObject ifun = (IdFunctionObject)fun; if (NativeContinuation.isContinuationConstructor(ifun)) { frame.stack[stackTop] = captureContinuation(cx, frame.parentFrame, false); continue Loop; } } Object[] outArgs = getArgsArray(stack, sDbl, stackTop + 1, indexReg); stack[stackTop] = fun.construct(cx, frame.scope, outArgs); continue Loop; } case Token.TYPEOF : { Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.typeof(lhs); continue Loop; } case Icode_TYPEOFNAME : stack[++stackTop] = ScriptRuntime.typeofName(frame.scope, stringReg); continue Loop; case Token.STRING : stack[++stackTop] = stringReg; continue Loop; case Icode_SHORTNUMBER : ++stackTop; stack[stackTop] = DBL_MRK; sDbl[stackTop] = getShort(iCode, frame.pc); frame.pc += 2; continue Loop; case Icode_INTNUMBER : ++stackTop; stack[stackTop] = DBL_MRK; sDbl[stackTop] = getInt(iCode, frame.pc); frame.pc += 4; continue Loop; case Token.NUMBER : ++stackTop; stack[stackTop] = DBL_MRK; sDbl[stackTop] = frame.idata.itsDoubleTable[indexReg]; continue Loop; case Token.NAME : stack[++stackTop] = ScriptRuntime.name(cx, frame.scope, stringReg); continue Loop; case Icode_NAME_INC_DEC : stack[++stackTop] = ScriptRuntime.nameIncrDecr(frame.scope, stringReg, cx, iCode[frame.pc]); ++frame.pc; continue Loop; case Icode_SETCONSTVAR1: indexReg = iCode[frame.pc++]; // fallthrough case Token.SETCONSTVAR : if (!frame.useActivation) { if ((varAttributes[indexReg] & ScriptableObject.READONLY) == 0) { throw Context.reportRuntimeError1("msg.var.redecl", frame.idata.argNames[indexReg]); } if ((varAttributes[indexReg] & ScriptableObject.UNINITIALIZED_CONST) != 0) { vars[indexReg] = stack[stackTop]; varAttributes[indexReg] &= ~ScriptableObject.UNINITIALIZED_CONST; varDbls[indexReg] = sDbl[stackTop]; } } else { Object val = stack[stackTop]; if (val == DBL_MRK) val = ScriptRuntime.wrapNumber(sDbl[stackTop]); stringReg = frame.idata.argNames[indexReg]; if (frame.scope instanceof ConstProperties) { ConstProperties cp = (ConstProperties)frame.scope; cp.putConst(stringReg, frame.scope, val); } else throw Kit.codeBug(); } continue Loop; case Icode_SETVAR1: indexReg = iCode[frame.pc++]; // fallthrough case Token.SETVAR : if (!frame.useActivation) { if ((varAttributes[indexReg] & ScriptableObject.READONLY) == 0) { vars[indexReg] = stack[stackTop]; varDbls[indexReg] = sDbl[stackTop]; } } else { Object val = stack[stackTop]; if (val == DBL_MRK) val = ScriptRuntime.wrapNumber(sDbl[stackTop]); stringReg = frame.idata.argNames[indexReg]; frame.scope.put(stringReg, frame.scope, val); } continue Loop; case Icode_GETVAR1: indexReg = iCode[frame.pc++]; // fallthrough case Token.GETVAR : ++stackTop; if (!frame.useActivation) { stack[stackTop] = vars[indexReg]; sDbl[stackTop] = varDbls[indexReg]; } else { stringReg = frame.idata.argNames[indexReg]; stack[stackTop] = frame.scope.get(stringReg, frame.scope); } continue Loop; case Icode_VAR_INC_DEC : { // indexReg : varindex ++stackTop; int incrDecrMask = iCode[frame.pc]; if (!frame.useActivation) { stack[stackTop] = DBL_MRK; Object varValue = vars[indexReg]; double d; if (varValue == DBL_MRK) { d = varDbls[indexReg]; } else { d = ScriptRuntime.toNumber(varValue); vars[indexReg] = DBL_MRK; } double d2 = ((incrDecrMask & Node.DECR_FLAG) == 0) ? d + 1.0 : d - 1.0; varDbls[indexReg] = d2; sDbl[stackTop] = ((incrDecrMask & Node.POST_FLAG) == 0) ? d2 : d; } else { String varName = frame.idata.argNames[indexReg]; stack[stackTop] = ScriptRuntime.nameIncrDecr(frame.scope, varName, cx, incrDecrMask); } ++frame.pc; continue Loop; } case Icode_ZERO : ++stackTop; stack[stackTop] = DBL_MRK; sDbl[stackTop] = 0; continue Loop; case Icode_ONE : ++stackTop; stack[stackTop] = DBL_MRK; sDbl[stackTop] = 1; continue Loop; case Token.NULL : stack[++stackTop] = null; continue Loop; case Token.THIS : stack[++stackTop] = frame.thisObj; continue Loop; case Token.THISFN : stack[++stackTop] = frame.fnOrScript; continue Loop; case Token.FALSE : stack[++stackTop] = Boolean.FALSE; continue Loop; case Token.TRUE : stack[++stackTop] = Boolean.TRUE; continue Loop; case Icode_UNDEF : stack[++stackTop] = undefined; continue Loop; case Token.ENTERWITH : { Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; frame.scope = ScriptRuntime.enterWith(lhs, cx, frame.scope); continue Loop; } case Token.LEAVEWITH : frame.scope = ScriptRuntime.leaveWith(frame.scope); continue Loop; case Token.CATCH_SCOPE : { // stack top: exception object // stringReg: name of exception variable // indexReg: local for exception scope --stackTop; indexReg += frame.localShift; boolean afterFirstScope = (frame.idata.itsICode[frame.pc] != 0); Throwable caughtException = (Throwable)stack[stackTop + 1]; Scriptable lastCatchScope; if (!afterFirstScope) { lastCatchScope = null; } else { lastCatchScope = (Scriptable)stack[indexReg]; } stack[indexReg] = ScriptRuntime.newCatchScope(caughtException, lastCatchScope, stringReg, cx, frame.scope); ++frame.pc; continue Loop; } case Token.ENUM_INIT_KEYS : case Token.ENUM_INIT_VALUES : case Token.ENUM_INIT_ARRAY : { Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; indexReg += frame.localShift; int enumType = op == Token.ENUM_INIT_KEYS ? ScriptRuntime.ENUMERATE_KEYS : op == Token.ENUM_INIT_VALUES ? ScriptRuntime.ENUMERATE_VALUES : ScriptRuntime.ENUMERATE_ARRAY; stack[indexReg] = ScriptRuntime.enumInit(lhs, cx, enumType); continue Loop; } case Token.ENUM_NEXT : case Token.ENUM_ID : { indexReg += frame.localShift; Object val = stack[indexReg]; ++stackTop; stack[stackTop] = (op == Token.ENUM_NEXT) ? (Object)ScriptRuntime.enumNext(val) : (Object)ScriptRuntime.enumId(val, cx); continue Loop; } case Token.REF_SPECIAL : { //stringReg: name of special property Object obj = stack[stackTop]; if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.specialRef(obj, stringReg, cx); continue Loop; } case Token.REF_MEMBER: { //indexReg: flags Object elem = stack[stackTop]; if (elem == DBL_MRK) elem = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Object obj = stack[stackTop]; if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.memberRef(obj, elem, cx, indexReg); continue Loop; } case Token.REF_NS_MEMBER: { //indexReg: flags Object elem = stack[stackTop]; if (elem == DBL_MRK) elem = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Object ns = stack[stackTop]; if (ns == DBL_MRK) ns = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Object obj = stack[stackTop]; if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.memberRef(obj, ns, elem, cx, indexReg); continue Loop; } case Token.REF_NAME: { //indexReg: flags Object name = stack[stackTop]; if (name == DBL_MRK) name = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.nameRef(name, cx, frame.scope, indexReg); continue Loop; } case Token.REF_NS_NAME: { //indexReg: flags Object name = stack[stackTop]; if (name == DBL_MRK) name = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; Object ns = stack[stackTop]; if (ns == DBL_MRK) ns = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.nameRef(ns, name, cx, frame.scope, indexReg); continue Loop; } case Icode_SCOPE_LOAD : indexReg += frame.localShift; frame.scope = (Scriptable)stack[indexReg]; continue Loop; case Icode_SCOPE_SAVE : indexReg += frame.localShift; stack[indexReg] = frame.scope; continue Loop; case Icode_CLOSURE_EXPR : stack[++stackTop] = InterpretedFunction.createFunction(cx, frame.scope, frame.fnOrScript, indexReg); continue Loop; case Icode_CLOSURE_STMT : initFunction(cx, frame.scope, frame.fnOrScript, indexReg); continue Loop; case Token.REGEXP : stack[++stackTop] = frame.scriptRegExps[indexReg]; continue Loop; case Icode_LITERAL_NEW : // indexReg: number of values in the literal ++stackTop; stack[stackTop] = new int[indexReg]; ++stackTop; stack[stackTop] = new Object[indexReg]; sDbl[stackTop] = 0; continue Loop; case Icode_LITERAL_SET : { Object value = stack[stackTop]; if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; int i = (int)sDbl[stackTop]; ((Object[])stack[stackTop])[i] = value; sDbl[stackTop] = i + 1; continue Loop; } case Icode_LITERAL_GETTER : { Object value = stack[stackTop]; --stackTop; int i = (int)sDbl[stackTop]; ((Object[])stack[stackTop])[i] = value; ((int[])stack[stackTop - 1])[i] = -1; sDbl[stackTop] = i + 1; continue Loop; } case Icode_LITERAL_SETTER : { Object value = stack[stackTop]; --stackTop; int i = (int)sDbl[stackTop]; ((Object[])stack[stackTop])[i] = value; ((int[])stack[stackTop - 1])[i] = +1; sDbl[stackTop] = i + 1; continue Loop; } case Token.ARRAYLIT : case Icode_SPARE_ARRAYLIT : case Token.OBJECTLIT : { Object[] data = (Object[])stack[stackTop]; --stackTop; int[] getterSetters = (int[])stack[stackTop]; Object val; if (op == Token.OBJECTLIT) { Object[] ids = (Object[])frame.idata.literalIds[indexReg]; val = ScriptRuntime.newObjectLiteral(ids, data, getterSetters, cx, frame.scope); } else { int[] skipIndexces = null; if (op == Icode_SPARE_ARRAYLIT) { skipIndexces = (int[])frame.idata.literalIds[indexReg]; } val = ScriptRuntime.newArrayLiteral(data, skipIndexces, cx, frame.scope); } stack[stackTop] = val; continue Loop; } case Icode_ENTERDQ : { Object lhs = stack[stackTop]; if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); --stackTop; frame.scope = ScriptRuntime.enterDotQuery(lhs, frame.scope); continue Loop; } case Icode_LEAVEDQ : { boolean valBln = stack_boolean(frame, stackTop); Object x = ScriptRuntime.updateDotQuery(valBln, frame.scope); if (x != null) { stack[stackTop] = x; frame.scope = ScriptRuntime.leaveDotQuery(frame.scope); frame.pc += 2; continue Loop; } // reset stack and PC to code after ENTERDQ --stackTop; break jumplessRun; } case Token.DEFAULTNAMESPACE : { Object value = stack[stackTop]; if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]); stack[stackTop] = ScriptRuntime.setDefaultNamespace(value, cx); continue Loop; } case Token.ESCXMLATTR : { Object value = stack[stackTop]; if (value != DBL_MRK) { stack[stackTop] = ScriptRuntime.escapeAttributeValue(value, cx); } continue Loop; } case Token.ESCXMLTEXT : { Object value = stack[stackTop]; if (value != DBL_MRK) { stack[stackTop] = ScriptRuntime.escapeTextValue(value, cx); } continue Loop; } case Icode_DEBUGGER: if (frame.debuggerFrame != null) { frame.debuggerFrame.onDebuggerStatement(cx); } continue Loop; case Icode_LINE : frame.pcSourceLineStart = frame.pc; if (frame.debuggerFrame != null) { int line = getIndex(iCode, frame.pc); frame.debuggerFrame.onLineChange(cx, line); } frame.pc += 2; continue Loop; case Icode_REG_IND_C0: indexReg = 0; continue Loop; case Icode_REG_IND_C1: indexReg = 1; continue Loop; case Icode_REG_IND_C2: indexReg = 2; continue Loop; case Icode_REG_IND_C3: indexReg = 3; continue Loop; case Icode_REG_IND_C4: indexReg = 4; continue Loop; case Icode_REG_IND_C5: indexReg = 5; continue Loop; case Icode_REG_IND1: indexReg = 0xFF & iCode[frame.pc]; ++frame.pc; continue Loop; case Icode_REG_IND2: indexReg = getIndex(iCode, frame.pc); frame.pc += 2; continue Loop; case Icode_REG_IND4: indexReg = getInt(iCode, frame.pc); frame.pc += 4; continue Loop; case Icode_REG_STR_C0: stringReg = strings[0]; continue Loop; case Icode_REG_STR_C1: stringReg = strings[1]; continue Loop; case Icode_REG_STR_C2: stringReg = strings[2]; continue Loop; case Icode_REG_STR_C3: stringReg = strings[3]; continue Loop; case Icode_REG_STR1: stringReg = strings[0xFF & iCode[frame.pc]]; ++frame.pc; continue Loop; case Icode_REG_STR2: stringReg = strings[getIndex(iCode, frame.pc)]; frame.pc += 2; continue Loop; case Icode_REG_STR4: stringReg = strings[getInt(iCode, frame.pc)]; frame.pc += 4; continue Loop; default : dumpICode(frame.idata); throw new RuntimeException( "Unknown icode : "+op+" @ pc : "+(frame.pc-1)); } // end of interpreter switch } // end of jumplessRun label block // This should be reachable only for jump implementation // when pc points to encoded target offset if (instructionCounting) { addInstructionCount(cx, frame, 2); } int offset = getShort(iCode, frame.pc); if (offset != 0) { // -1 accounts for pc pointing to jump opcode + 1 frame.pc += offset - 1; } else { frame.pc = frame.idata.longJumps. getExistingInt(frame.pc); } if (instructionCounting) { frame.pcPrevBranch = frame.pc; } continue Loop; } // end of Loop: for exitFrame(cx, frame, null); interpreterResult = frame.result; interpreterResultDbl = frame.resultDbl; if (frame.parentFrame != null) { frame = frame.parentFrame; if (frame.frozen) { frame = frame.cloneFrozen(); } setCallResult( frame, interpreterResult, interpreterResultDbl); interpreterResult = null; // Help GC continue StateLoop; } break StateLoop; } // end of interpreter withoutExceptions: try catch (Throwable ex) { if (throwable != null) { // This is serious bug and it is better to track it ASAP ex.printStackTrace(System.err); throw new IllegalStateException(); } throwable = ex; } // This should be reachable only after above catch or from // finally when it needs to propagate exception or from // explicit throw if (throwable == null) Kit.codeBug(); // Exception type final int EX_CATCH_STATE = 2; // Can execute JS catch final int EX_FINALLY_STATE = 1; // Can execute JS finally final int EX_NO_JS_STATE = 0; // Terminate JS execution int exState; ContinuationJump cjump = null; if (generatorState != null && generatorState.operation == NativeGenerator.GENERATOR_CLOSE && throwable == generatorState.value) { exState = EX_FINALLY_STATE; } else if (throwable instanceof JavaScriptException) { exState = EX_CATCH_STATE; } else if (throwable instanceof EcmaError) { // an offical ECMA error object, exState = EX_CATCH_STATE; } else if (throwable instanceof EvaluatorException) { exState = EX_CATCH_STATE; } else if (throwable instanceof RuntimeException) { exState = cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) ? EX_CATCH_STATE : EX_FINALLY_STATE; } else if (throwable instanceof Error) { exState = cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) ? EX_CATCH_STATE : EX_NO_JS_STATE; } else if (throwable instanceof ContinuationJump) { // It must be ContinuationJump exState = EX_FINALLY_STATE; cjump = (ContinuationJump)throwable; } else { exState = cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) ? EX_CATCH_STATE : EX_FINALLY_STATE; } if (instructionCounting) { try { addInstructionCount(cx, frame, EXCEPTION_COST); } catch (RuntimeException ex) { throwable = ex; exState = EX_FINALLY_STATE; } catch (Error ex) { // Error from instruction counting // => unconditionally terminate JS throwable = ex; cjump = null; exState = EX_NO_JS_STATE; } } if (frame.debuggerFrame != null && throwable instanceof RuntimeException) { // Call debugger only for RuntimeException RuntimeException rex = (RuntimeException)throwable; try { frame.debuggerFrame.onExceptionThrown(cx, rex); } catch (Throwable ex) { // Any exception from debugger // => unconditionally terminate JS throwable = ex; cjump = null; exState = EX_NO_JS_STATE; } } for (;;) { if (exState != EX_NO_JS_STATE) { boolean onlyFinally = (exState != EX_CATCH_STATE); indexReg = getExceptionHandler(frame, onlyFinally); if (indexReg >= 0) { // We caught an exception, restart the loop // with exception pending the processing at the loop // start continue StateLoop; } } // No allowed exception handlers in this frame, unwind // to parent and try to look there exitFrame(cx, frame, throwable); frame = frame.parentFrame; if (frame == null) { break; } if (cjump != null && cjump.branchFrame == frame) { // Continuation branch point was hit, // restart the state loop to reenter continuation indexReg = -1; continue StateLoop; } } // No more frames, rethrow the exception or deal with continuation if (cjump != null) { if (cjump.branchFrame != null) { // The above loop should locate the top frame Kit.codeBug(); } if (cjump.capturedFrame != null) { // Restarting detached continuation indexReg = -1; continue StateLoop; } // Return continuation result to the caller interpreterResult = cjump.result; interpreterResultDbl = cjump.resultDbl; throwable = null; } break StateLoop; } // end of StateLoop: for(;;) // Do cleanups/restorations before the final return or throw if (cx.previousInterpreterInvocations != null && cx.previousInterpreterInvocations.size() != 0) { cx.lastInterpreterFrame = cx.previousInterpreterInvocations.pop(); } else { // It was the last interpreter frame on the stack cx.lastInterpreterFrame = null; // Force GC of the value cx.previousInterpreterInvocations cx.previousInterpreterInvocations = null; } if (throwable != null) { if (throwable instanceof RuntimeException) { throw (RuntimeException)throwable; } else { // Must be instance of Error or code bug throw (Error)throwable; } } return (interpreterResult != DBL_MRK) ? interpreterResult : ScriptRuntime.wrapNumber(interpreterResultDbl); } /** * Call __noSuchMethod__. */ private static CallFrame initFrameForNoSuchMethod(Context cx, CallFrame frame, int indexReg, Object[] stack, double[] sDbl, int stackTop, int op, Scriptable funThisObj, Scriptable calleeScope, NoSuchMethodShim noSuchMethodShim, InterpretedFunction ifun) { // create an args array from the stack Object[] argsArray = null; // exactly like getArgsArray except that the first argument // is the method name from the shim int shift = stackTop + 2; Object[] elements = new Object[indexReg]; for (int i=0; i < indexReg; ++i, ++shift) { Object val = stack[shift]; if (val == UniqueTag.DOUBLE_MARK) { val = ScriptRuntime.wrapNumber(sDbl[shift]); } elements[i] = val; } argsArray = new Object[2]; argsArray[0] = noSuchMethodShim.methodName; argsArray[1] = cx.newArray(calleeScope, elements); // exactly the same as if it's a regular InterpretedFunction CallFrame callParentFrame = frame; CallFrame calleeFrame = new CallFrame(); if (op == Icode_TAIL_CALL) { callParentFrame = frame.parentFrame; exitFrame(cx, frame, null); } // init the frame with the underlying method with the // adjusted args array and shim's function initFrame(cx, calleeScope, funThisObj, argsArray, null, 0, 2, ifun, callParentFrame, calleeFrame); if (op != Icode_TAIL_CALL) { frame.savedStackTop = stackTop; frame.savedCallOp = op; } return calleeFrame; } private static boolean shallowEquals(Object[] stack, double[] sDbl, int stackTop) { Object rhs = stack[stackTop + 1]; Object lhs = stack[stackTop]; final Object DBL_MRK = UniqueTag.DOUBLE_MARK; double rdbl, ldbl; if (rhs == DBL_MRK) { rdbl = sDbl[stackTop + 1]; if (lhs == DBL_MRK) { ldbl = sDbl[stackTop]; } else if (lhs instanceof Number) { ldbl = ((Number)lhs).doubleValue(); } else { return false; } } else if (lhs == DBL_MRK) { ldbl = sDbl[stackTop]; if (rhs == DBL_MRK) { rdbl = sDbl[stackTop + 1]; } else if (rhs instanceof Number) { rdbl = ((Number)rhs).doubleValue(); } else { return false; } } else { return ScriptRuntime.shallowEq(lhs, rhs); } return (ldbl == rdbl); } private static CallFrame processThrowable(Context cx, Object throwable, CallFrame frame, int indexReg, boolean instructionCounting) { // Recovering from exception, indexReg contains // the index of handler if (indexReg >= 0) { // Normal exception handler, transfer // control appropriately if (frame.frozen) { // XXX Deal with exceptios!!! frame = frame.cloneFrozen(); } int[] table = frame.idata.itsExceptionTable; frame.pc = table[indexReg + EXCEPTION_HANDLER_SLOT]; if (instructionCounting) { frame.pcPrevBranch = frame.pc; } frame.savedStackTop = frame.emptyStackTop; int scopeLocal = frame.localShift + table[indexReg + EXCEPTION_SCOPE_SLOT]; int exLocal = frame.localShift + table[indexReg + EXCEPTION_LOCAL_SLOT]; frame.scope = (Scriptable)frame.stack[scopeLocal]; frame.stack[exLocal] = throwable; throwable = null; } else { // Continuation restoration ContinuationJump cjump = (ContinuationJump)throwable; // Clear throwable to indicate that exceptions are OK throwable = null; if (cjump.branchFrame != frame) Kit.codeBug(); // Check that we have at least one frozen frame // in the case of detached continuation restoration: // unwind code ensure that if (cjump.capturedFrame == null) Kit.codeBug(); // Need to rewind branchFrame, capturedFrame // and all frames in between int rewindCount = cjump.capturedFrame.frameIndex + 1; if (cjump.branchFrame != null) { rewindCount -= cjump.branchFrame.frameIndex; } int enterCount = 0; CallFrame[] enterFrames = null; CallFrame x = cjump.capturedFrame; for (int i = 0; i != rewindCount; ++i) { if (!x.frozen) Kit.codeBug(); if (isFrameEnterExitRequired(x)) { if (enterFrames == null) { // Allocate enough space to store the rest // of rewind frames in case all of them // would require to enter enterFrames = new CallFrame[rewindCount - i]; } enterFrames[enterCount] = x; ++enterCount; } x = x.parentFrame; } while (enterCount != 0) { // execute enter: walk enterFrames in the reverse // order since they were stored starting from // the capturedFrame, not branchFrame --enterCount; x = enterFrames[enterCount]; enterFrame(cx, x, ScriptRuntime.emptyArgs, true); } // Continuation jump is almost done: capturedFrame // points to the call to the function that captured // continuation, so clone capturedFrame and // emulate return that function with the suplied result frame = cjump.capturedFrame.cloneFrozen(); setCallResult(frame, cjump.result, cjump.resultDbl); // restart the execution } frame.throwable = throwable; return frame; } private static Object freezeGenerator(Context cx, CallFrame frame, int stackTop, GeneratorState generatorState) { if (generatorState.operation == NativeGenerator.GENERATOR_CLOSE) { // Error: no yields when generator is closing throw ScriptRuntime.typeError0("msg.yield.closing"); } // return to our caller (which should be a method of NativeGenerator) frame.frozen = true; frame.result = frame.stack[stackTop]; frame.resultDbl = frame.sDbl[stackTop]; frame.savedStackTop = stackTop; frame.pc--; // we want to come back here when we resume ScriptRuntime.exitActivationFunction(cx); return (frame.result != UniqueTag.DOUBLE_MARK) ? frame.result : ScriptRuntime.wrapNumber(frame.resultDbl); } private static Object thawGenerator(CallFrame frame, int stackTop, GeneratorState generatorState, int op) { // we are resuming execution frame.frozen = false; int sourceLine = getIndex(frame.idata.itsICode, frame.pc); frame.pc += 2; // skip line number data if (generatorState.operation == NativeGenerator.GENERATOR_THROW) { // processing a call to .throw(exception): must // act as if exception was thrown from resumption point return new JavaScriptException(generatorState.value, frame.idata.itsSourceFile, sourceLine); } if (generatorState.operation == NativeGenerator.GENERATOR_CLOSE) { return generatorState.value; } if (generatorState.operation != NativeGenerator.GENERATOR_SEND) throw Kit.codeBug(); if (op == Token.YIELD) frame.stack[stackTop] = generatorState.value; return Scriptable.NOT_FOUND; } private static CallFrame initFrameForApplyOrCall(Context cx, CallFrame frame, int indexReg, Object[] stack, double[] sDbl, int stackTop, int op, Scriptable calleeScope, IdFunctionObject ifun, InterpretedFunction iApplyCallable) { Scriptable applyThis; if (indexReg != 0) { Object obj = stack[stackTop + 2]; if (obj == UniqueTag.DOUBLE_MARK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop + 2]); applyThis = ScriptRuntime.toObjectOrNull(cx, obj); } else { applyThis = null; } if (applyThis == null) { // This covers the case of args[0] == (null|undefined) as well. applyThis = ScriptRuntime.getTopCallScope(cx); } if(op == Icode_TAIL_CALL) { exitFrame(cx, frame, null); frame = frame.parentFrame; } else { frame.savedStackTop = stackTop; frame.savedCallOp = op; } CallFrame calleeFrame = new CallFrame(); if(BaseFunction.isApply(ifun)) { Object[] callArgs = indexReg < 2 ? ScriptRuntime.emptyArgs : ScriptRuntime.getApplyArguments(cx, stack[stackTop + 3]); initFrame(cx, calleeScope, applyThis, callArgs, null, 0, callArgs.length, iApplyCallable, frame, calleeFrame); } else { // Shift args left for(int i = 1; i < indexReg; ++i) { stack[stackTop + 1 + i] = stack[stackTop + 2 + i]; sDbl[stackTop + 1 + i] = sDbl[stackTop + 2 + i]; } int argCount = indexReg < 2 ? 0 : indexReg - 1; initFrame(cx, calleeScope, applyThis, stack, sDbl, stackTop + 2, argCount, iApplyCallable, frame, calleeFrame); } frame = calleeFrame; return frame; } private static void initFrame(Context cx, Scriptable callerScope, Scriptable thisObj, Object[] args, double[] argsDbl, int argShift, int argCount, InterpretedFunction fnOrScript, CallFrame parentFrame, CallFrame frame) { InterpreterData idata = fnOrScript.idata; boolean useActivation = idata.itsNeedsActivation; DebugFrame debuggerFrame = null; if (cx.debugger != null) { debuggerFrame = cx.debugger.getFrame(cx, idata); if (debuggerFrame != null) { useActivation = true; } } if (useActivation) { // Copy args to new array to pass to enterActivationFunction // or debuggerFrame.onEnter if (argsDbl != null) { args = getArgsArray(args, argsDbl, argShift, argCount); } argShift = 0; argsDbl = null; } Scriptable scope; if (idata.itsFunctionType != 0) { if (!idata.useDynamicScope) { scope = fnOrScript.getParentScope(); } else { scope = callerScope; } if (useActivation) { scope = ScriptRuntime.createFunctionActivation( fnOrScript, scope, args); } } else { scope = callerScope; ScriptRuntime.initScript(fnOrScript, thisObj, cx, scope, fnOrScript.idata.evalScriptFlag); } if (idata.itsNestedFunctions != null) { if (idata.itsFunctionType != 0 && !idata.itsNeedsActivation) Kit.codeBug(); for (int i = 0; i < idata.itsNestedFunctions.length; i++) { InterpreterData fdata = idata.itsNestedFunctions[i]; if (fdata.itsFunctionType == FunctionNode.FUNCTION_STATEMENT) { initFunction(cx, scope, fnOrScript, i); } } } Scriptable[] scriptRegExps = null; if (idata.itsRegExpLiterals != null) { // Wrapped regexps for functions are stored in // InterpretedFunction // but for script which should not contain references to scope // the regexps re-wrapped during each script execution if (idata.itsFunctionType != 0) { scriptRegExps = fnOrScript.functionRegExps; } else { scriptRegExps = fnOrScript.createRegExpWraps(cx, scope); } } // Initialize args, vars, locals and stack int emptyStackTop = idata.itsMaxVars + idata.itsMaxLocals - 1; int maxFrameArray = idata.itsMaxFrameArray; if (maxFrameArray != emptyStackTop + idata.itsMaxStack + 1) Kit.codeBug(); Object[] stack; int[] stackAttributes; double[] sDbl; boolean stackReuse; if (frame.stack != null && maxFrameArray <= frame.stack.length) { // Reuse stacks from old frame stackReuse = true; stack = frame.stack; stackAttributes = frame.stackAttributes; sDbl = frame.sDbl; } else { stackReuse = false; stack = new Object[maxFrameArray]; stackAttributes = new int[maxFrameArray]; sDbl = new double[maxFrameArray]; } int varCount = idata.getParamAndVarCount(); for (int i = 0; i < varCount; i++) { if (idata.getParamOrVarConst(i)) stackAttributes[i] = ScriptableObject.CONST; } int definedArgs = idata.argCount; if (definedArgs > argCount) { definedArgs = argCount; } // Fill the frame structure frame.parentFrame = parentFrame; frame.frameIndex = (parentFrame == null) ? 0 : parentFrame.frameIndex + 1; if(frame.frameIndex > cx.getMaximumInterpreterStackDepth()) { throw Context.reportRuntimeError("Exceeded maximum stack depth"); } frame.frozen = false; frame.fnOrScript = fnOrScript; frame.idata = idata; frame.stack = stack; frame.stackAttributes = stackAttributes; frame.sDbl = sDbl; frame.varSource = frame; frame.localShift = idata.itsMaxVars; frame.emptyStackTop = emptyStackTop; frame.debuggerFrame = debuggerFrame; frame.useActivation = useActivation; frame.thisObj = thisObj; frame.scriptRegExps = scriptRegExps; // Initialize initial values of variables that change during // interpretation. frame.result = Undefined.instance; frame.pc = 0; frame.pcPrevBranch = 0; frame.pcSourceLineStart = idata.firstLinePC; frame.scope = scope; frame.savedStackTop = emptyStackTop; frame.savedCallOp = 0; System.arraycopy(args, argShift, stack, 0, definedArgs); if (argsDbl != null) { System.arraycopy(argsDbl, argShift, sDbl, 0, definedArgs); } for (int i = definedArgs; i != idata.itsMaxVars; ++i) { stack[i] = Undefined.instance; } if (stackReuse) { // Clean the stack part and space beyond stack if any // of the old array to allow to GC objects there for (int i = emptyStackTop + 1; i != stack.length; ++i) { stack[i] = null; } } enterFrame(cx, frame, args, false); } private static boolean isFrameEnterExitRequired(CallFrame frame) { return frame.debuggerFrame != null || frame.idata.itsNeedsActivation; } private static void enterFrame(Context cx, CallFrame frame, Object[] args, boolean continuationRestart) { boolean usesActivation = frame.idata.itsNeedsActivation; boolean isDebugged = frame.debuggerFrame != null; if(usesActivation || isDebugged) { Scriptable scope = frame.scope; if(scope == null) { Kit.codeBug(); } else if (continuationRestart) { // Walk the parent chain of frame.scope until a NativeCall is // found. Normally, frame.scope is a NativeCall when called // from initFrame() for a debugged or activatable function. // However, when called from interpretLoop() as part of // restarting a continuation, it can also be a NativeWith if // the continuation was captured within a "with" or "catch" // block ("catch" implicitly uses NativeWith to create a scope // to expose the exception variable). for(;;) { if(scope instanceof NativeWith) { scope = scope.getParentScope(); if (scope == null || (frame.parentFrame != null && frame.parentFrame.scope == scope)) { // If we get here, we didn't find a NativeCall in // the call chain before reaching parent frame's // scope. This should not be possible. Kit.codeBug(); break; // Never reached, but keeps the static analyzer happy about "scope" not being null 5 lines above. } } else { break; } } } if (isDebugged) { frame.debuggerFrame.onEnter(cx, scope, frame.thisObj, args); } // Enter activation only when itsNeedsActivation true, // since debugger should not interfere with activation // chaining if (usesActivation) { ScriptRuntime.enterActivationFunction(cx, scope); } } } private static void exitFrame(Context cx, CallFrame frame, Object throwable) { if (frame.idata.itsNeedsActivation) { ScriptRuntime.exitActivationFunction(cx); } if (frame.debuggerFrame != null) { try { if (throwable instanceof Throwable) { frame.debuggerFrame.onExit(cx, true, throwable); } else { Object result; ContinuationJump cjump = (ContinuationJump)throwable; if (cjump == null) { result = frame.result; } else { result = cjump.result; } if (result == UniqueTag.DOUBLE_MARK) { double resultDbl; if (cjump == null) { resultDbl = frame.resultDbl; } else { resultDbl = cjump.resultDbl; } result = ScriptRuntime.wrapNumber(resultDbl); } frame.debuggerFrame.onExit(cx, false, result); } } catch (Throwable ex) { System.err.println( "RHINO USAGE WARNING: onExit terminated with exception"); ex.printStackTrace(System.err); } } } private static void setCallResult(CallFrame frame, Object callResult, double callResultDbl) { if (frame.savedCallOp == Token.CALL) { frame.stack[frame.savedStackTop] = callResult; frame.sDbl[frame.savedStackTop] = callResultDbl; } else if (frame.savedCallOp == Token.NEW) { // If construct returns scriptable, // then it replaces on stack top saved original instance // of the object. if (callResult instanceof Scriptable) { frame.stack[frame.savedStackTop] = callResult; } } else { Kit.codeBug(); } frame.savedCallOp = 0; } public static NativeContinuation captureContinuation(Context cx) { if (cx.lastInterpreterFrame == null || !(cx.lastInterpreterFrame instanceof CallFrame)) { throw new IllegalStateException("Interpreter frames not found"); } return captureContinuation(cx, (CallFrame)cx.lastInterpreterFrame, true); } private static NativeContinuation captureContinuation(Context cx, CallFrame frame, boolean requireContinuationsTopFrame) { NativeContinuation c = new NativeContinuation(); ScriptRuntime.setObjectProtoAndParent( c, ScriptRuntime.getTopCallScope(cx)); // Make sure that all frames are frozen CallFrame x = frame; CallFrame outermost = frame; while (x != null && !x.frozen) { x.frozen = true; // Allow to GC unused stack space for (int i = x.savedStackTop + 1; i != x.stack.length; ++i) { // Allow to GC unused stack space x.stack[i] = null; x.stackAttributes[i] = ScriptableObject.EMPTY; } if (x.savedCallOp == Token.CALL) { // the call will always overwrite the stack top with the result x.stack[x.savedStackTop] = null; } else { if (x.savedCallOp != Token.NEW) Kit.codeBug(); // the new operator uses stack top to store the constructed // object so it shall not be cleared: see comments in // setCallResult } outermost = x; x = x.parentFrame; } if (requireContinuationsTopFrame) { while (outermost.parentFrame != null) outermost = outermost.parentFrame; if (!outermost.isContinuationsTopFrame) { throw new IllegalStateException("Cannot capture continuation " + "from JavaScript code not called directly by " + "executeScriptWithContinuations or " + "callFunctionWithContinuations"); } } c.initImplementation(frame); return c; } private static int stack_int32(CallFrame frame, int i) { Object x = frame.stack[i]; double value; if (x == UniqueTag.DOUBLE_MARK) { value = frame.sDbl[i]; } else { value = ScriptRuntime.toNumber(x); } return ScriptRuntime.toInt32(value); } private static double stack_double(CallFrame frame, int i) { Object x = frame.stack[i]; if (x != UniqueTag.DOUBLE_MARK) { return ScriptRuntime.toNumber(x); } else { return frame.sDbl[i]; } } private static boolean stack_boolean(CallFrame frame, int i) { Object x = frame.stack[i]; if (x == Boolean.TRUE) { return true; } else if (x == Boolean.FALSE) { return false; } else if (x == UniqueTag.DOUBLE_MARK) { double d = frame.sDbl[i]; return d == d && d != 0.0; } else if (x == null || x == Undefined.instance) { return false; } else if (x instanceof Number) { double d = ((Number)x).doubleValue(); return (d == d && d != 0.0); } else if (x instanceof Boolean) { return ((Boolean)x).booleanValue(); } else { return ScriptRuntime.toBoolean(x); } } private static void do_add(Object[] stack, double[] sDbl, int stackTop, Context cx) { Object rhs = stack[stackTop + 1]; Object lhs = stack[stackTop]; double d; boolean leftRightOrder; if (rhs == UniqueTag.DOUBLE_MARK) { d = sDbl[stackTop + 1]; if (lhs == UniqueTag.DOUBLE_MARK) { sDbl[stackTop] += d; return; } leftRightOrder = true; // fallthrough to object + number code } else if (lhs == UniqueTag.DOUBLE_MARK) { d = sDbl[stackTop]; lhs = rhs; leftRightOrder = false; // fallthrough to object + number code } else { if (lhs instanceof Scriptable || rhs instanceof Scriptable) { stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx); } else if (lhs instanceof String) { String lstr = (String)lhs; String rstr = ScriptRuntime.toString(rhs); stack[stackTop] = lstr.concat(rstr); } else if (rhs instanceof String) { String lstr = ScriptRuntime.toString(lhs); String rstr = (String)rhs; stack[stackTop] = lstr.concat(rstr); } else { double lDbl = (lhs instanceof Number) ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs); double rDbl = (rhs instanceof Number) ? ((Number)rhs).doubleValue() : ScriptRuntime.toNumber(rhs); stack[stackTop] = UniqueTag.DOUBLE_MARK; sDbl[stackTop] = lDbl + rDbl; } return; } // handle object(lhs) + number(d) code if (lhs instanceof Scriptable) { rhs = ScriptRuntime.wrapNumber(d); if (!leftRightOrder) { Object tmp = lhs; lhs = rhs; rhs = tmp; } stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx); } else if (lhs instanceof String) { String lstr = (String)lhs; String rstr = ScriptRuntime.toString(d); if (leftRightOrder) { stack[stackTop] = lstr.concat(rstr); } else { stack[stackTop] = rstr.concat(lstr); } } else { double lDbl = (lhs instanceof Number) ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs); stack[stackTop] = UniqueTag.DOUBLE_MARK; sDbl[stackTop] = lDbl + d; } } private static Object[] getArgsArray(Object[] stack, double[] sDbl, int shift, int count) { if (count == 0) { return ScriptRuntime.emptyArgs; } Object[] args = new Object[count]; for (int i = 0; i != count; ++i, ++shift) { Object val = stack[shift]; if (val == UniqueTag.DOUBLE_MARK) { val = ScriptRuntime.wrapNumber(sDbl[shift]); } args[i] = val; } return args; } private static void addInstructionCount(Context cx, CallFrame frame, int extra) { cx.instructionCount += frame.pc - frame.pcPrevBranch + extra; if (cx.instructionCount > cx.instructionThreshold) { cx.observeInstructionCount(cx.instructionCount); cx.instructionCount = 0; } } } yui-compressor-2.4.7/src/org/mozilla/javascript/PolicySecurityController.java0000644000175000017500000002104211753547210027515 0ustar drazzibdrazzib/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.lang.ref.SoftReference; import java.lang.reflect.UndeclaredThrowableException; import java.security.AccessController; import java.security.CodeSource; import java.security.Policy; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.security.SecureClassLoader; import java.util.Map; import java.util.WeakHashMap; import org.mozilla.classfile.ByteCode; import org.mozilla.classfile.ClassFileWriter; /** * A security controller relying on Java {@link Policy} in effect. When you use * this security controller, your securityDomain objects must be instances of * {@link CodeSource} representing the location from where you load your * scripts. Any Java policy "grant" statements matching the URL and certificate * in code sources will apply to the scripts. If you specify any certificates * within your {@link CodeSource} objects, it is your responsibility to verify * (or not) that the script source files are signed in whatever * implementation-specific way you're using. * @author Attila Szegedi */ public class PolicySecurityController extends SecurityController { private static final byte[] secureCallerImplBytecode = loadBytecode(); // We're storing a CodeSource -> (ClassLoader -> SecureRenderer), since we // need to have one renderer per class loader. We're using weak hash maps // and soft references all the way, since we don't want to interfere with // cleanup of either CodeSource or ClassLoader objects. private static final Map>> callers = new WeakHashMap>>(); @Override public Class getStaticSecurityDomainClassInternal() { return CodeSource.class; } private static class Loader extends SecureClassLoader implements GeneratedClassLoader { private final CodeSource codeSource; Loader(ClassLoader parent, CodeSource codeSource) { super(parent); this.codeSource = codeSource; } public Class defineClass(String name, byte[] data) { return defineClass(name, data, 0, data.length, codeSource); } public void linkClass(Class cl) { resolveClass(cl); } } @Override public GeneratedClassLoader createClassLoader(final ClassLoader parent, final Object securityDomain) { return (Loader)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return new Loader(parent, (CodeSource)securityDomain); } }); } @Override public Object getDynamicSecurityDomain(Object securityDomain) { // No separate notion of dynamic security domain - just return what was // passed in. return securityDomain; } @Override public Object callWithDomain(final Object securityDomain, final Context cx, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args) { // Run in doPrivileged as we might be checked for "getClassLoader" // runtime permission final ClassLoader classLoader = (ClassLoader)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return cx.getApplicationClassLoader(); } }); final CodeSource codeSource = (CodeSource)securityDomain; Map> classLoaderMap; synchronized (callers) { classLoaderMap = callers.get(codeSource); if(classLoaderMap == null) { classLoaderMap = new WeakHashMap>(); callers.put(codeSource, classLoaderMap); } } SecureCaller caller; synchronized (classLoaderMap) { SoftReference ref = classLoaderMap.get(classLoader); if (ref != null) { caller = ref.get(); } else { caller = null; } if (caller == null) { try { // Run in doPrivileged as we'll be checked for // "createClassLoader" runtime permission caller = (SecureCaller)AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws Exception { Loader loader = new Loader(classLoader, codeSource); Class c = loader.defineClass( SecureCaller.class.getName() + "Impl", secureCallerImplBytecode); return c.newInstance(); } }); classLoaderMap.put(classLoader, new SoftReference(caller)); } catch(PrivilegedActionException ex) { throw new UndeclaredThrowableException(ex.getCause()); } } } return caller.call(callable, cx, scope, thisObj, args); } public abstract static class SecureCaller { public abstract Object call(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args); } private static byte[] loadBytecode() { String secureCallerClassName = SecureCaller.class.getName(); ClassFileWriter cfw = new ClassFileWriter( secureCallerClassName + "Impl", secureCallerClassName, ""); cfw.startMethod("", "()V", ClassFileWriter.ACC_PUBLIC); cfw.addALoad(0); cfw.addInvoke(ByteCode.INVOKESPECIAL, secureCallerClassName, "", "()V"); cfw.add(ByteCode.RETURN); cfw.stopMethod((short)1); String callableCallSig = "Lorg/mozilla/javascript/Context;" + "Lorg/mozilla/javascript/Scriptable;" + "Lorg/mozilla/javascript/Scriptable;" + "[Ljava/lang/Object;)Ljava/lang/Object;"; cfw.startMethod("call", "(Lorg/mozilla/javascript/Callable;" + callableCallSig, (short)(ClassFileWriter.ACC_PUBLIC | ClassFileWriter.ACC_FINAL)); for(int i = 1; i < 6; ++i) { cfw.addALoad(i); } cfw.addInvoke(ByteCode.INVOKEINTERFACE, "org/mozilla/javascript/Callable", "call", "(" + callableCallSig); cfw.add(ByteCode.ARETURN); cfw.stopMethod((short)6); return cfw.toByteArray(); } }yui-compressor-2.4.7/src/org/mozilla/javascript/NativeContinuation.java0000644000175000017500000001037111753547210026306 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; public final class NativeContinuation extends IdScriptableObject implements Function { static final long serialVersionUID = 1794167133757605367L; private static final Object FTAG = "Continuation"; private Object implementation; public static void init(Context cx, Scriptable scope, boolean sealed) { NativeContinuation obj = new NativeContinuation(); obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); } public Object getImplementation() { return implementation; } public void initImplementation(Object implementation) { this.implementation = implementation; } @Override public String getClassName() { return "Continuation"; } public Scriptable construct(Context cx, Scriptable scope, Object[] args) { throw Context.reportRuntimeError("Direct call is not supported"); } public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { return Interpreter.restartContinuation(this, cx, scope, args); } public static boolean isContinuationConstructor(IdFunctionObject f) { if (f.hasTag(FTAG) && f.methodId() == Id_constructor) { return true; } return false; } @Override protected void initPrototypeId(int id) { String s; int arity; switch (id) { case Id_constructor: arity=0; s="constructor"; break; default: throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(FTAG, id, s, arity); } @Override public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(FTAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); switch (id) { case Id_constructor: throw Context.reportRuntimeError("Direct call is not supported"); } throw new IllegalArgumentException(String.valueOf(id)); } // #string_id_map# @Override protected int findPrototypeId(String s) { int id; // #generated# Last update: 2007-05-09 08:16:40 EDT L0: { id = 0; String X = null; if (s.length()==11) { X="constructor";id=Id_constructor; } if (X!=null && X!=s && !X.equals(s)) id = 0; break L0; } // #/generated# return id; } private static final int Id_constructor = 1, MAX_PROTOTYPE_ID = 1; // #/string_id_map# } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeGlobal.java0000644000175000017500000006570611753547210025050 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * Mike McCabe * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.Serializable; import org.mozilla.javascript.xml.XMLLib; /** * This class implements the global native object (function and value * properties only). * * See ECMA 15.1.[12]. * * @author Mike Shaver */ public class NativeGlobal implements Serializable, IdFunctionCall { static final long serialVersionUID = 6080442165748707530L; public static void init(Context cx, Scriptable scope, boolean sealed) { NativeGlobal obj = new NativeGlobal(); for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) { String name; int arity = 1; switch (id) { case Id_decodeURI: name = "decodeURI"; break; case Id_decodeURIComponent: name = "decodeURIComponent"; break; case Id_encodeURI: name = "encodeURI"; break; case Id_encodeURIComponent: name = "encodeURIComponent"; break; case Id_escape: name = "escape"; break; case Id_eval: name = "eval"; break; case Id_isFinite: name = "isFinite"; break; case Id_isNaN: name = "isNaN"; break; case Id_isXMLName: name = "isXMLName"; break; case Id_parseFloat: name = "parseFloat"; break; case Id_parseInt: name = "parseInt"; arity = 2; break; case Id_unescape: name = "unescape"; break; case Id_uneval: name = "uneval"; break; default: throw Kit.codeBug(); } IdFunctionObject f = new IdFunctionObject(obj, FTAG, id, name, arity, scope); if (sealed) { f.sealObject(); } f.exportAsScopeProperty(); } ScriptableObject.defineProperty( scope, "NaN", ScriptRuntime.NaNobj, ScriptableObject.DONTENUM); ScriptableObject.defineProperty( scope, "Infinity", ScriptRuntime.wrapNumber(Double.POSITIVE_INFINITY), ScriptableObject.DONTENUM); ScriptableObject.defineProperty( scope, "undefined", Undefined.instance, ScriptableObject.DONTENUM); String[] errorMethods = { "ConversionError", "EvalError", "RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError", "InternalError", "JavaException" }; /* Each error constructor gets its own Error object as a prototype, with the 'name' property set to the name of the error. */ for (int i = 0; i < errorMethods.length; i++) { String name = errorMethods[i]; Scriptable errorProto = ScriptRuntime. newObject(cx, scope, "Error", ScriptRuntime.emptyArgs); errorProto.put("name", errorProto, name); if (sealed) { if (errorProto instanceof ScriptableObject) { ((ScriptableObject)errorProto).sealObject(); } } IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_new_CommonError, name, 1, scope); ctor.markAsConstructor(errorProto); if (sealed) { ctor.sealObject(); } ctor.exportAsScopeProperty(); } } public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (f.hasTag(FTAG)) { int methodId = f.methodId(); switch (methodId) { case Id_decodeURI: case Id_decodeURIComponent: { String str = ScriptRuntime.toString(args, 0); return decode(str, methodId == Id_decodeURI); } case Id_encodeURI: case Id_encodeURIComponent: { String str = ScriptRuntime.toString(args, 0); return encode(str, methodId == Id_encodeURI); } case Id_escape: return js_escape(args); case Id_eval: return js_eval(cx, scope, thisObj, args); case Id_isFinite: { boolean result; if (args.length < 1) { result = false; } else { double d = ScriptRuntime.toNumber(args[0]); result = (d == d && d != Double.POSITIVE_INFINITY && d != Double.NEGATIVE_INFINITY); } return ScriptRuntime.wrapBoolean(result); } case Id_isNaN: { // The global method isNaN, as per ECMA-262 15.1.2.6. boolean result; if (args.length < 1) { result = true; } else { double d = ScriptRuntime.toNumber(args[0]); result = (d != d); } return ScriptRuntime.wrapBoolean(result); } case Id_isXMLName: { Object name = (args.length == 0) ? Undefined.instance : args[0]; XMLLib xmlLib = XMLLib.extractFromScope(scope); return ScriptRuntime.wrapBoolean( xmlLib.isXMLName(cx, name)); } case Id_parseFloat: return js_parseFloat(args); case Id_parseInt: return js_parseInt(args); case Id_unescape: return js_unescape(args); case Id_uneval: { Object value = (args.length != 0) ? args[0] : Undefined.instance; return ScriptRuntime.uneval(cx, scope, value); } case Id_new_CommonError: // The implementation of all the ECMA error constructors // (SyntaxError, TypeError, etc.) return NativeError.make(cx, scope, f, args); } } throw f.unknown(); } /** * The global method parseInt, as per ECMA-262 15.1.2.2. */ private Object js_parseInt(Object[] args) { String s = ScriptRuntime.toString(args, 0); int radix = ScriptRuntime.toInt32(args, 1); int len = s.length(); if (len == 0) return ScriptRuntime.NaNobj; boolean negative = false; int start = 0; char c; do { c = s.charAt(start); if (!Character.isWhitespace(c)) break; start++; } while (start < len); if (c == '+' || (negative = (c == '-'))) start++; final int NO_RADIX = -1; if (radix == 0) { radix = NO_RADIX; } else if (radix < 2 || radix > 36) { return ScriptRuntime.NaNobj; } else if (radix == 16 && len - start > 1 && s.charAt(start) == '0') { c = s.charAt(start+1); if (c == 'x' || c == 'X') start += 2; } if (radix == NO_RADIX) { radix = 10; if (len - start > 1 && s.charAt(start) == '0') { c = s.charAt(start+1); if (c == 'x' || c == 'X') { radix = 16; start += 2; } else if ('0' <= c && c <= '9') { radix = 8; start++; } } } double d = ScriptRuntime.stringToNumber(s, start, radix); return ScriptRuntime.wrapNumber(negative ? -d : d); } /** * The global method parseFloat, as per ECMA-262 15.1.2.3. * * @param args the arguments to parseFloat, ignoring args[>=1] */ private Object js_parseFloat(Object[] args) { if (args.length < 1) return ScriptRuntime.NaNobj; String s = ScriptRuntime.toString(args[0]); int len = s.length(); int start = 0; // Scan forward to skip whitespace char c; for (;;) { if (start == len) { return ScriptRuntime.NaNobj; } c = s.charAt(start); if (!TokenStream.isJSSpace(c)) { break; } ++start; } int i = start; if (c == '+' || c == '-') { ++i; if (i == len) { return ScriptRuntime.NaNobj; } c = s.charAt(i); } if (c == 'I') { // check for "Infinity" if (i+8 <= len && s.regionMatches(i, "Infinity", 0, 8)) { double d; if (s.charAt(start) == '-') { d = Double.NEGATIVE_INFINITY; } else { d = Double.POSITIVE_INFINITY; } return ScriptRuntime.wrapNumber(d); } return ScriptRuntime.NaNobj; } // Find the end of the legal bit int decimal = -1; int exponent = -1; for (; i < len; i++) { switch (s.charAt(i)) { case '.': if (decimal != -1) // Only allow a single decimal point. break; decimal = i; continue; case 'e': case 'E': if (exponent != -1) break; exponent = i; continue; case '+': case '-': // Only allow '+' or '-' after 'e' or 'E' if (exponent != i-1) break; continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': continue; default: break; } break; } s = s.substring(start, i); try { return Double.valueOf(s); } catch (NumberFormatException ex) { return ScriptRuntime.NaNobj; } } /** * The global method escape, as per ECMA-262 15.1.2.4. * Includes code for the 'mask' argument supported by the C escape * method, which used to be part of the browser imbedding. Blame * for the strange constant names should be directed there. */ private Object js_escape(Object[] args) { final int URL_XALPHAS = 1, URL_XPALPHAS = 2, URL_PATH = 4; String s = ScriptRuntime.toString(args, 0); int mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH; if (args.length > 1) { // the 'mask' argument. Non-ECMA. double d = ScriptRuntime.toNumber(args[1]); if (d != d || ((mask = (int) d) != d) || 0 != (mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH))) { throw Context.reportRuntimeError0("msg.bad.esc.mask"); } } StringBuffer sb = null; for (int k = 0, L = s.length(); k != L; ++k) { int c = s.charAt(k); if (mask != 0 && ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '@' || c == '*' || c == '_' || c == '-' || c == '.' || (0 != (mask & URL_PATH) && (c == '/' || c == '+')))) { if (sb != null) { sb.append((char)c); } } else { if (sb == null) { sb = new StringBuffer(L + 3); sb.append(s); sb.setLength(k); } int hexSize; if (c < 256) { if (c == ' ' && mask == URL_XPALPHAS) { sb.append('+'); continue; } sb.append('%'); hexSize = 2; } else { sb.append('%'); sb.append('u'); hexSize = 4; } // append hexadecimal form of c left-padded with 0 for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) { int digit = 0xf & (c >> shift); int hc = (digit < 10) ? '0' + digit : 'A' - 10 + digit; sb.append((char)hc); } } } return (sb == null) ? s : sb.toString(); } /** * The global unescape method, as per ECMA-262 15.1.2.5. */ private Object js_unescape(Object[] args) { String s = ScriptRuntime.toString(args, 0); int firstEscapePos = s.indexOf('%'); if (firstEscapePos >= 0) { int L = s.length(); char[] buf = s.toCharArray(); int destination = firstEscapePos; for (int k = firstEscapePos; k != L;) { char c = buf[k]; ++k; if (c == '%' && k != L) { int end, start; if (buf[k] == 'u') { start = k + 1; end = k + 5; } else { start = k; end = k + 2; } if (end <= L) { int x = 0; for (int i = start; i != end; ++i) { x = Kit.xDigitToInt(buf[i], x); } if (x >= 0) { c = (char)x; k = end; } } } buf[destination] = c; ++destination; } s = new String(buf, 0, destination); } return s; } private Object js_eval(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (thisObj.getParentScope() == null) { // We allow indirect calls to eval as long as the script will execute in // the global scope. return ScriptRuntime.evalSpecial(cx, scope, thisObj, args, "eval code", 1); } String m = ScriptRuntime.getMessage1("msg.cant.call.indirect", "eval"); throw NativeGlobal.constructError(cx, "EvalError", m, scope); } static boolean isEvalFunction(Object functionObj) { if (functionObj instanceof IdFunctionObject) { IdFunctionObject function = (IdFunctionObject)functionObj; if (function.hasTag(FTAG) && function.methodId() == Id_eval) { return true; } } return false; } /** * @deprecated Use {@link ScriptRuntime#constructError(String,String)} * instead. */ public static EcmaError constructError(Context cx, String error, String message, Scriptable scope) { return ScriptRuntime.constructError(error, message); } /** * @deprecated Use * {@link ScriptRuntime#constructError(String,String,String,int,String,int)} * instead. */ public static EcmaError constructError(Context cx, String error, String message, Scriptable scope, String sourceName, int lineNumber, int columnNumber, String lineSource) { return ScriptRuntime.constructError(error, message, sourceName, lineNumber, lineSource, columnNumber); } /* * ECMA 3, 15.1.3 URI Handling Function Properties * * The following are implementations of the algorithms * given in the ECMA specification for the hidden functions * 'Encode' and 'Decode'. */ private static String encode(String str, boolean fullUri) { byte[] utf8buf = null; StringBuffer sb = null; for (int k = 0, length = str.length(); k != length; ++k) { char C = str.charAt(k); if (encodeUnescaped(C, fullUri)) { if (sb != null) { sb.append(C); } } else { if (sb == null) { sb = new StringBuffer(length + 3); sb.append(str); sb.setLength(k); utf8buf = new byte[6]; } if (0xDC00 <= C && C <= 0xDFFF) { throw Context.reportRuntimeError0("msg.bad.uri"); } int V; if (C < 0xD800 || 0xDBFF < C) { V = C; } else { k++; if (k == length) { throw Context.reportRuntimeError0("msg.bad.uri"); } char C2 = str.charAt(k); if (!(0xDC00 <= C2 && C2 <= 0xDFFF)) { throw Context.reportRuntimeError0("msg.bad.uri"); } V = ((C - 0xD800) << 10) + (C2 - 0xDC00) + 0x10000; } int L = oneUcs4ToUtf8Char(utf8buf, V); for (int j = 0; j < L; j++) { int d = 0xff & utf8buf[j]; sb.append('%'); sb.append(toHexChar(d >>> 4)); sb.append(toHexChar(d & 0xf)); } } } return (sb == null) ? str : sb.toString(); } private static char toHexChar(int i) { if (i >> 4 != 0) Kit.codeBug(); return (char)((i < 10) ? i + '0' : i - 10 + 'A'); } private static int unHex(char c) { if ('A' <= c && c <= 'F') { return c - 'A' + 10; } else if ('a' <= c && c <= 'f') { return c - 'a' + 10; } else if ('0' <= c && c <= '9') { return c - '0'; } else { return -1; } } private static int unHex(char c1, char c2) { int i1 = unHex(c1); int i2 = unHex(c2); if (i1 >= 0 && i2 >= 0) { return (i1 << 4) | i2; } return -1; } private static String decode(String str, boolean fullUri) { char[] buf = null; int bufTop = 0; for (int k = 0, length = str.length(); k != length;) { char C = str.charAt(k); if (C != '%') { if (buf != null) { buf[bufTop++] = C; } ++k; } else { if (buf == null) { // decode always compress so result can not be bigger then // str.length() buf = new char[length]; str.getChars(0, k, buf, 0); bufTop = k; } int start = k; if (k + 3 > length) throw Context.reportRuntimeError0("msg.bad.uri"); int B = unHex(str.charAt(k + 1), str.charAt(k + 2)); if (B < 0) throw Context.reportRuntimeError0("msg.bad.uri"); k += 3; if ((B & 0x80) == 0) { C = (char)B; } else { // Decode UTF-8 sequence into ucs4Char and encode it into // UTF-16 int utf8Tail, ucs4Char, minUcs4Char; if ((B & 0xC0) == 0x80) { // First UTF-8 should be ouside 0x80..0xBF throw Context.reportRuntimeError0("msg.bad.uri"); } else if ((B & 0x20) == 0) { utf8Tail = 1; ucs4Char = B & 0x1F; minUcs4Char = 0x80; } else if ((B & 0x10) == 0) { utf8Tail = 2; ucs4Char = B & 0x0F; minUcs4Char = 0x800; } else if ((B & 0x08) == 0) { utf8Tail = 3; ucs4Char = B & 0x07; minUcs4Char = 0x10000; } else if ((B & 0x04) == 0) { utf8Tail = 4; ucs4Char = B & 0x03; minUcs4Char = 0x200000; } else if ((B & 0x02) == 0) { utf8Tail = 5; ucs4Char = B & 0x01; minUcs4Char = 0x4000000; } else { // First UTF-8 can not be 0xFF or 0xFE throw Context.reportRuntimeError0("msg.bad.uri"); } if (k + 3 * utf8Tail > length) throw Context.reportRuntimeError0("msg.bad.uri"); for (int j = 0; j != utf8Tail; j++) { if (str.charAt(k) != '%') throw Context.reportRuntimeError0("msg.bad.uri"); B = unHex(str.charAt(k + 1), str.charAt(k + 2)); if (B < 0 || (B & 0xC0) != 0x80) throw Context.reportRuntimeError0("msg.bad.uri"); ucs4Char = (ucs4Char << 6) | (B & 0x3F); k += 3; } // Check for overlongs and other should-not-present codes if (ucs4Char < minUcs4Char || ucs4Char == 0xFFFE || ucs4Char == 0xFFFF) { ucs4Char = 0xFFFD; } if (ucs4Char >= 0x10000) { ucs4Char -= 0x10000; if (ucs4Char > 0xFFFFF) throw Context.reportRuntimeError0("msg.bad.uri"); char H = (char)((ucs4Char >>> 10) + 0xD800); C = (char)((ucs4Char & 0x3FF) + 0xDC00); buf[bufTop++] = H; } else { C = (char)ucs4Char; } } if (fullUri && URI_DECODE_RESERVED.indexOf(C) >= 0) { for (int x = start; x != k; x++) { buf[bufTop++] = str.charAt(x); } } else { buf[bufTop++] = C; } } } return (buf == null) ? str : new String(buf, 0, bufTop); } private static boolean encodeUnescaped(char c, boolean fullUri) { if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) { return true; } if ("-_.!~*'()".indexOf(c) >= 0) return true; if (fullUri) { return URI_DECODE_RESERVED.indexOf(c) >= 0; } return false; } private static final String URI_DECODE_RESERVED = ";/?:@&=+$,#"; /* Convert one UCS-4 char and write it into a UTF-8 buffer, which must be * at least 6 bytes long. Return the number of UTF-8 bytes of data written. */ private static int oneUcs4ToUtf8Char(byte[] utf8Buffer, int ucs4Char) { int utf8Length = 1; //JS_ASSERT(ucs4Char <= 0x7FFFFFFF); if ((ucs4Char & ~0x7F) == 0) utf8Buffer[0] = (byte)ucs4Char; else { int i; int a = ucs4Char >>> 11; utf8Length = 2; while (a != 0) { a >>>= 5; utf8Length++; } i = utf8Length; while (--i > 0) { utf8Buffer[i] = (byte)((ucs4Char & 0x3F) | 0x80); ucs4Char >>>= 6; } utf8Buffer[0] = (byte)(0x100 - (1 << (8-utf8Length)) + ucs4Char); } return utf8Length; } private static final Object FTAG = "Global"; private static final int Id_decodeURI = 1, Id_decodeURIComponent = 2, Id_encodeURI = 3, Id_encodeURIComponent = 4, Id_escape = 5, Id_eval = 6, Id_isFinite = 7, Id_isNaN = 8, Id_isXMLName = 9, Id_parseFloat = 10, Id_parseInt = 11, Id_unescape = 12, Id_uneval = 13, LAST_SCOPE_FUNCTION_ID = 13, Id_new_CommonError = 14; } yui-compressor-2.4.7/src/org/mozilla/javascript/WrapFactory.java0000644000175000017500000001540011753547210024724 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * Embeddings that wish to provide their own custom wrappings for Java * objects may extend this class and call * {@link Context#setWrapFactory(WrapFactory)} * Once an instance of this class or an extension of this class is enabled * for a given context (by calling setWrapFactory on that context), Rhino * will call the methods of this class whenever it needs to wrap a value * resulting from a call to a Java method or an access to a Java field. * * @see org.mozilla.javascript.Context#setWrapFactory(WrapFactory) * @since 1.5 Release 4 */ public class WrapFactory { /** * Wrap the object. *

* The value returned must be one of *

    *
  • java.lang.Boolean
  • *
  • java.lang.String
  • *
  • java.lang.Number
  • *
  • org.mozilla.javascript.Scriptable objects
  • *
  • The value returned by Context.getUndefinedValue()
  • *
  • null
  • *
* @param cx the current Context for this thread * @param scope the scope of the executing script * @param obj the object to be wrapped. Note it can be null. * @param staticType type hint. If security restrictions prevent to wrap object based on its class, staticType will be used instead. * @return the wrapped value. */ public Object wrap(Context cx, Scriptable scope, Object obj, Class staticType) { if (obj == null || obj == Undefined.instance || obj instanceof Scriptable) { return obj; } if (staticType != null && staticType.isPrimitive()) { if (staticType == Void.TYPE) return Undefined.instance; if (staticType == Character.TYPE) return new Integer(((Character) obj).charValue()); return obj; } if (!isJavaPrimitiveWrap()) { if (obj instanceof String || obj instanceof Number || obj instanceof Boolean) { return obj; } else if (obj instanceof Character) { return String.valueOf(((Character)obj).charValue()); } } Class cls = obj.getClass(); if (cls.isArray()) { return NativeJavaArray.wrap(scope, obj); } return wrapAsJavaObject(cx, scope, obj, staticType); } /** * Wrap an object newly created by a constructor call. * @param cx the current Context for this thread * @param scope the scope of the executing script * @param obj the object to be wrapped * @return the wrapped value. */ public Scriptable wrapNewObject(Context cx, Scriptable scope, Object obj) { if (obj instanceof Scriptable) { return (Scriptable)obj; } Class cls = obj.getClass(); if (cls.isArray()) { return NativeJavaArray.wrap(scope, obj); } return wrapAsJavaObject(cx, scope, obj, null); } /** * Wrap Java object as Scriptable instance to allow full access to its * methods and fields from JavaScript. *

* {@link #wrap(Context, Scriptable, Object, Class)} and * {@link #wrapNewObject(Context, Scriptable, Object)} call this method * when they can not convert javaObject to JavaScript primitive * value or JavaScript array. *

* Subclasses can override the method to provide custom wrappers * for Java objects. * @param cx the current Context for this thread * @param scope the scope of the executing script * @param javaObject the object to be wrapped * @param staticType type hint. If security restrictions prevent to wrap object based on its class, staticType will be used instead. * @return the wrapped value which shall not be null */ public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class staticType) { Scriptable wrap; wrap = new NativeJavaObject(scope, javaObject, staticType); return wrap; } /** * Return false if result of Java method, which is instance of * String, Number, Boolean and * Character, should be used directly as JavaScript primitive * type. * By default the method returns true to indicate that instances of * String, Number, Boolean and * Character should be wrapped as any other Java object and * scripts can access any Java method available in these objects. * Use {@link #setJavaPrimitiveWrap(boolean)} to change this. */ public final boolean isJavaPrimitiveWrap() { return javaPrimitiveWrap; } /** * @see #isJavaPrimitiveWrap() */ public final void setJavaPrimitiveWrap(boolean value) { Context cx = Context.getCurrentContext(); if (cx != null && cx.isSealed()) { Context.onSealedMutation(); } javaPrimitiveWrap = value; } private boolean javaPrimitiveWrap = true; } yui-compressor-2.4.7/src/org/mozilla/javascript/xml/0000755000175000017500000000000011753547210022420 5ustar drazzibdrazzibyui-compressor-2.4.7/src/org/mozilla/javascript/xml/XMLLib.java0000644000175000017500000001300111753547210024345 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript.xml; import org.mozilla.javascript.*; public abstract class XMLLib { private static final Object XML_LIB_KEY = new Object(); /** An object which specifies an XMLLib implementation to be used at runtime. This interface should be considered experimental. It may be better (and certainly more flexible) to write an interface that returns an XMLLib object rather than a class name, for example. But that would cause many more ripple effects in the code, all the way back to {@link ScriptRuntime}. */ public static abstract class Factory { public static Factory create(final String className) { return new Factory() { @Override public String getImplementationClassName() { return className; } }; } public abstract String getImplementationClassName(); } public static XMLLib extractFromScopeOrNull(Scriptable scope) { ScriptableObject so = ScriptRuntime.getLibraryScopeOrNull(scope); if (so == null) { // If library is not yet initialized, return null return null; } // Ensure lazily initialization of real XML library instance // which is done on first access to XML property ScriptableObject.getProperty(so, "XML"); return (XMLLib)so.getAssociatedValue(XML_LIB_KEY); } public static XMLLib extractFromScope(Scriptable scope) { XMLLib lib = extractFromScopeOrNull(scope); if (lib != null) { return lib; } String msg = ScriptRuntime.getMessage0("msg.XML.not.available"); throw Context.reportRuntimeError(msg); } protected final XMLLib bindToScope(Scriptable scope) { ScriptableObject so = ScriptRuntime.getLibraryScopeOrNull(scope); if (so == null) { // standard library should be initialized at this point throw new IllegalStateException(); } return (XMLLib)so.associateValue(XML_LIB_KEY, this); } public abstract boolean isXMLName(Context cx, Object name); public abstract Ref nameRef(Context cx, Object name, Scriptable scope, int memberTypeFlags); public abstract Ref nameRef(Context cx, Object namespace, Object name, Scriptable scope, int memberTypeFlags); /** * Escapes the reserved characters in a value of an attribute. * * @param value Unescaped text * @return The escaped text */ public abstract String escapeAttributeValue(Object value); /** * Escapes the reserved characters in a value of a text node. * * @param value Unescaped text * @return The escaped text */ public abstract String escapeTextValue(Object value); /** * Construct namespace for default xml statement. */ public abstract Object toDefaultXmlNamespace(Context cx, Object uriValue); public void setIgnoreComments(boolean b) { throw new UnsupportedOperationException(); } public void setIgnoreWhitespace(boolean b) { throw new UnsupportedOperationException(); } public void setIgnoreProcessingInstructions(boolean b) { throw new UnsupportedOperationException(); } public void setPrettyPrinting(boolean b) { throw new UnsupportedOperationException(); } public void setPrettyIndent(int i) { throw new UnsupportedOperationException(); } public boolean isIgnoreComments() { throw new UnsupportedOperationException(); } public boolean isIgnoreProcessingInstructions() { throw new UnsupportedOperationException(); } public boolean isIgnoreWhitespace() { throw new UnsupportedOperationException(); } public boolean isPrettyPrinting() { throw new UnsupportedOperationException(); } public int getPrettyIndent() { throw new UnsupportedOperationException(); } } yui-compressor-2.4.7/src/org/mozilla/javascript/xml/XMLObject.java0000644000175000017500000001031011753547210025045 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * Ethan Hugg * Terry Lucas * Milen Nankov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript.xml; import org.mozilla.javascript.*; /** * This Interface describes what all XML objects (XML, XMLList) should have in common. * */ public abstract class XMLObject extends IdScriptableObject { public XMLObject() { } public XMLObject(Scriptable scope, Scriptable prototype) { super(scope, prototype); } /** * Implementation of ECMAScript [[Has]]. */ public abstract boolean ecmaHas(Context cx, Object id); /** * Implementation of ECMAScript [[Get]]. */ public abstract Object ecmaGet(Context cx, Object id); /** * Implementation of ECMAScript [[Put]]. */ public abstract void ecmaPut(Context cx, Object id, Object value); /** * Implementation of ECMAScript [[Delete]]. */ public abstract boolean ecmaDelete(Context cx, Object id); /** * Return an additional object to look for methods that runtime should * consider during method search. Return null if no such object available. */ public abstract Scriptable getExtraMethodSource(Context cx); /** * Generic reference to implement x.@y, x..y etc. */ public abstract Ref memberRef(Context cx, Object elem, int memberTypeFlags); /** * Generic reference to implement x::ns, x.@ns::y, x..@ns::y etc. */ public abstract Ref memberRef(Context cx, Object namespace, Object elem, int memberTypeFlags); /** * Wrap this object into NativeWith to implement the with statement. */ public abstract NativeWith enterWith(Scriptable scope); /** * Wrap this object into NativeWith to implement the .() query. */ public abstract NativeWith enterDotQuery(Scriptable scope); /** * Custom + operator. * Should return {@link Scriptable#NOT_FOUND} if this object does not have * custom addition operator for the given value, * or the result of the addition operation. *

* The default implementation returns {@link Scriptable#NOT_FOUND} * to indicate no custom addition operation. * * @param cx the Context object associated with the current thread. * @param thisIsLeft if true, the object should calculate this + value * if false, the object should calculate value + this. * @param value the second argument for addition operation. */ public Object addValues(Context cx, boolean thisIsLeft, Object value) { return Scriptable.NOT_FOUND; } } yui-compressor-2.4.7/src/org/mozilla/javascript/regexp/0000755000175000017500000000000011753547210023112 5ustar drazzibdrazzibyui-compressor-2.4.7/src/org/mozilla/javascript/regexp/RegExpImpl.java0000644000175000017500000004753611753547210026010 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript.regexp; import org.mozilla.javascript.*; /** * */ public class RegExpImpl implements RegExpProxy { public boolean isRegExp(Scriptable obj) { return obj instanceof NativeRegExp; } public Object compileRegExp(Context cx, String source, String flags) { return NativeRegExp.compileRE(cx, source, flags, false); } public Scriptable wrapRegExp(Context cx, Scriptable scope, Object compiled) { return new NativeRegExp(scope, compiled); } public Object action(Context cx, Scriptable scope, Scriptable thisObj, Object[] args, int actionType) { GlobData data = new GlobData(); data.mode = actionType; switch (actionType) { case RA_MATCH: { Object rval; data.optarg = 1; rval = matchOrReplace(cx, scope, thisObj, args, this, data, false); return data.arrayobj == null ? rval : data.arrayobj; } case RA_SEARCH: data.optarg = 1; return matchOrReplace(cx, scope, thisObj, args, this, data, false); case RA_REPLACE: { Object arg1 = args.length < 2 ? Undefined.instance : args[1]; String repstr = null; Function lambda = null; if (arg1 instanceof Function) { lambda = (Function) arg1; } else { repstr = ScriptRuntime.toString(arg1); } data.optarg = 2; data.lambda = lambda; data.repstr = repstr; data.dollar = repstr == null ? -1 : repstr.indexOf('$'); data.charBuf = null; data.leftIndex = 0; Object val = matchOrReplace(cx, scope, thisObj, args, this, data, true); SubString rc = this.rightContext; if (data.charBuf == null) { if (data.global || val == null || !val.equals(Boolean.TRUE)) { /* Didn't match even once. */ return data.str; } SubString lc = this.leftContext; replace_glob(data, cx, scope, this, lc.index, lc.length); } data.charBuf.append(rc.charArray, rc.index, rc.length); return data.charBuf.toString(); } default: throw Kit.codeBug(); } } /** * Analog of C match_or_replace. */ private static Object matchOrReplace(Context cx, Scriptable scope, Scriptable thisObj, Object[] args, RegExpImpl reImpl, GlobData data, boolean forceFlat) { NativeRegExp re; String str = ScriptRuntime.toString(thisObj); data.str = str; Scriptable topScope = ScriptableObject.getTopLevelScope(scope); if (args.length == 0) { Object compiled = NativeRegExp.compileRE(cx, "", "", false); re = new NativeRegExp(topScope, compiled); } else if (args[0] instanceof NativeRegExp) { re = (NativeRegExp) args[0]; } else { String src = ScriptRuntime.toString(args[0]); String opt; if (data.optarg < args.length) { args[0] = src; opt = ScriptRuntime.toString(args[data.optarg]); } else { opt = null; } Object compiled = NativeRegExp.compileRE(cx, src, opt, forceFlat); re = new NativeRegExp(topScope, compiled); } data.regexp = re; data.global = (re.getFlags() & NativeRegExp.JSREG_GLOB) != 0; int[] indexp = { 0 }; Object result = null; if (data.mode == RA_SEARCH) { result = re.executeRegExp(cx, scope, reImpl, str, indexp, NativeRegExp.TEST); if (result != null && result.equals(Boolean.TRUE)) result = new Integer(reImpl.leftContext.length); else result = new Integer(-1); } else if (data.global) { re.lastIndex = 0; for (int count = 0; indexp[0] <= str.length(); count++) { result = re.executeRegExp(cx, scope, reImpl, str, indexp, NativeRegExp.TEST); if (result == null || !result.equals(Boolean.TRUE)) break; if (data.mode == RA_MATCH) { match_glob(data, cx, scope, count, reImpl); } else { if (data.mode != RA_REPLACE) Kit.codeBug(); SubString lastMatch = reImpl.lastMatch; int leftIndex = data.leftIndex; int leftlen = lastMatch.index - leftIndex; data.leftIndex = lastMatch.index + lastMatch.length; replace_glob(data, cx, scope, reImpl, leftIndex, leftlen); } if (reImpl.lastMatch.length == 0) { if (indexp[0] == str.length()) break; indexp[0]++; } } } else { result = re.executeRegExp(cx, scope, reImpl, str, indexp, ((data.mode == RA_REPLACE) ? NativeRegExp.TEST : NativeRegExp.MATCH)); } return result; } public int find_split(Context cx, Scriptable scope, String target, String separator, Scriptable reObj, int[] ip, int[] matchlen, boolean[] matched, String[][] parensp) { int i = ip[0]; int length = target.length(); int result; int version = cx.getLanguageVersion(); NativeRegExp re = (NativeRegExp) reObj; again: while (true) { // imitating C label /* JS1.2 deviated from Perl by never matching at end of string. */ int ipsave = ip[0]; // reuse ip to save object creation ip[0] = i; Object ret = re.executeRegExp(cx, scope, this, target, ip, NativeRegExp.TEST); if (ret != Boolean.TRUE) { // Mismatch: ensure our caller advances i past end of string. ip[0] = ipsave; matchlen[0] = 1; matched[0] = false; return length; } i = ip[0]; ip[0] = ipsave; matched[0] = true; SubString sep = this.lastMatch; matchlen[0] = sep.length; if (matchlen[0] == 0) { /* * Empty string match: never split on an empty * match at the start of a find_split cycle. Same * rule as for an empty global match in * match_or_replace. */ if (i == ip[0]) { /* * "Bump-along" to avoid sticking at an empty * match, but don't bump past end of string -- * our caller must do that by adding * sep->length to our return value. */ if (i == length) { if (version == Context.VERSION_1_2) { matchlen[0] = 1; result = i; } else result = -1; break; } i++; continue again; // imitating C goto } } // PR_ASSERT((size_t)i >= sep->length); result = i - matchlen[0]; break; } int size = (parens == null) ? 0 : parens.length; parensp[0] = new String[size]; for (int num = 0; num < size; num++) { SubString parsub = getParenSubString(num); parensp[0][num] = parsub.toString(); } return result; } /** * Analog of REGEXP_PAREN_SUBSTRING in C jsregexp.h. * Assumes zero-based; i.e., for $3, i==2 */ SubString getParenSubString(int i) { if (parens != null && i < parens.length) { SubString parsub = parens[i]; if (parsub != null) { return parsub; } } return SubString.emptySubString; } /* * Analog of match_glob() in jsstr.c */ private static void match_glob(GlobData mdata, Context cx, Scriptable scope, int count, RegExpImpl reImpl) { if (mdata.arrayobj == null) { Scriptable s = ScriptableObject.getTopLevelScope(scope); mdata.arrayobj = ScriptRuntime.newObject(cx, s, "Array", null); } SubString matchsub = reImpl.lastMatch; String matchstr = matchsub.toString(); mdata.arrayobj.put(count, mdata.arrayobj, matchstr); } /* * Analog of replace_glob() in jsstr.c */ private static void replace_glob(GlobData rdata, Context cx, Scriptable scope, RegExpImpl reImpl, int leftIndex, int leftlen) { int replen; String lambdaStr; if (rdata.lambda != null) { // invoke lambda function with args lastMatch, $1, $2, ... $n, // leftContext.length, whole string. SubString[] parens = reImpl.parens; int parenCount = (parens == null) ? 0 : parens.length; Object[] args = new Object[parenCount + 3]; args[0] = reImpl.lastMatch.toString(); for (int i=0; i < parenCount; i++) { SubString sub = parens[i]; if (sub != null) { args[i+1] = sub.toString(); } else { args[i+1] = Undefined.instance; } } args[parenCount+1] = new Integer(reImpl.leftContext.length); args[parenCount+2] = rdata.str; // This is a hack to prevent expose of reImpl data to // JS function which can run new regexps modifing // regexp that are used later by the engine. // TODO: redesign is necessary if (reImpl != ScriptRuntime.getRegExpProxy(cx)) Kit.codeBug(); RegExpImpl re2 = new RegExpImpl(); re2.multiline = reImpl.multiline; re2.input = reImpl.input; ScriptRuntime.setRegExpProxy(cx, re2); try { Scriptable parent = ScriptableObject.getTopLevelScope(scope); Object result = rdata.lambda.call(cx, parent, parent, args); lambdaStr = ScriptRuntime.toString(result); } finally { ScriptRuntime.setRegExpProxy(cx, reImpl); } replen = lambdaStr.length(); } else { lambdaStr = null; replen = rdata.repstr.length(); if (rdata.dollar >= 0) { int[] skip = new int[1]; int dp = rdata.dollar; do { SubString sub = interpretDollar(cx, reImpl, rdata.repstr, dp, skip); if (sub != null) { replen += sub.length - skip[0]; dp += skip[0]; } else { ++dp; } dp = rdata.repstr.indexOf('$', dp); } while (dp >= 0); } } int growth = leftlen + replen + reImpl.rightContext.length; StringBuffer charBuf = rdata.charBuf; if (charBuf == null) { charBuf = new StringBuffer(growth); rdata.charBuf = charBuf; } else { charBuf.ensureCapacity(rdata.charBuf.length() + growth); } charBuf.append(reImpl.leftContext.charArray, leftIndex, leftlen); if (rdata.lambda != null) { charBuf.append(lambdaStr); } else { do_replace(rdata, cx, reImpl); } } private static SubString interpretDollar(Context cx, RegExpImpl res, String da, int dp, int[] skip) { char dc; int num, tmp; if (da.charAt(dp) != '$') Kit.codeBug(); /* Allow a real backslash (literal "\\") to escape "$1" etc. */ int version = cx.getLanguageVersion(); if (version != Context.VERSION_DEFAULT && version <= Context.VERSION_1_4) { if (dp > 0 && da.charAt(dp - 1) == '\\') return null; } int daL = da.length(); if (dp + 1 >= daL) return null; /* Interpret all Perl match-induced dollar variables. */ dc = da.charAt(dp + 1); if (NativeRegExp.isDigit(dc)) { int cp; if (version != Context.VERSION_DEFAULT && version <= Context.VERSION_1_4) { if (dc == '0') return null; /* Check for overflow to avoid gobbling arbitrary decimal digits. */ num = 0; cp = dp; while (++cp < daL && NativeRegExp.isDigit(dc = da.charAt(cp))) { tmp = 10 * num + (dc - '0'); if (tmp < num) break; num = tmp; } } else { /* ECMA 3, 1-9 or 01-99 */ int parenCount = (res.parens == null) ? 0 : res.parens.length; num = dc - '0'; if (num > parenCount) return null; cp = dp + 2; if ((dp + 2) < daL) { dc = da.charAt(dp + 2); if (NativeRegExp.isDigit(dc)) { tmp = 10 * num + (dc - '0'); if (tmp <= parenCount) { cp++; num = tmp; } } } if (num == 0) return null; /* $0 or $00 is not valid */ } /* Adjust num from 1 $n-origin to 0 array-index-origin. */ num--; skip[0] = cp - dp; return res.getParenSubString(num); } skip[0] = 2; switch (dc) { case '$': return new SubString("$"); case '&': return res.lastMatch; case '+': return res.lastParen; case '`': if (version == Context.VERSION_1_2) { /* * JS1.2 imitated the Perl4 bug where left context at each step * in an iterative use of a global regexp started from last match, * not from the start of the target string. But Perl4 does start * $` at the beginning of the target string when it is used in a * substitution, so we emulate that special case here. */ res.leftContext.index = 0; res.leftContext.length = res.lastMatch.index; } return res.leftContext; case '\'': return res.rightContext; } return null; } /** * Analog of do_replace in jsstr.c */ private static void do_replace(GlobData rdata, Context cx, RegExpImpl regExpImpl) { StringBuffer charBuf = rdata.charBuf; int cp = 0; String da = rdata.repstr; int dp = rdata.dollar; if (dp != -1) { int[] skip = new int[1]; do { int len = dp - cp; charBuf.append(da.substring(cp, dp)); cp = dp; SubString sub = interpretDollar(cx, regExpImpl, da, dp, skip); if (sub != null) { len = sub.length; if (len > 0) { charBuf.append(sub.charArray, sub.index, len); } cp += skip[0]; dp += skip[0]; } else { ++dp; } dp = da.indexOf('$', dp); } while (dp >= 0); } int daL = da.length(); if (daL > cp) { charBuf.append(da.substring(cp, daL)); } } String input; /* input string to match (perl $_, GC root) */ boolean multiline; /* whether input contains newlines (perl $*) */ SubString[] parens; /* Vector of SubString; last set of parens matched (perl $1, $2) */ SubString lastMatch; /* last string matched (perl $&) */ SubString lastParen; /* last paren matched (perl $+) */ SubString leftContext; /* input to left of last match (perl $`) */ SubString rightContext; /* input to right of last match (perl $') */ } final class GlobData { int mode; /* input: return index, match object, or void */ int optarg; /* input: index of optional flags argument */ boolean global; /* output: whether regexp was global */ String str; /* output: 'this' parameter object as string */ NativeRegExp regexp;/* output: regexp parameter object private data */ // match-specific data Scriptable arrayobj; // replace-specific data Function lambda; /* replacement function object or null */ String repstr; /* replacement string */ int dollar = -1; /* -1 or index of first $ in repstr */ StringBuffer charBuf; /* result characters, null initially */ int leftIndex; /* leftContext index, always 0 for JS1.2 */ } yui-compressor-2.4.7/src/org/mozilla/javascript/regexp/SubString.java0000644000175000017500000000456211753547210025704 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript.regexp; class SubString { public SubString() { } public SubString(String str) { index = 0; charArray = str.toCharArray(); length = str.length(); } public SubString(char[] source, int start, int len) { // there must be a better way of doing this?? index = 0; length = len; charArray = new char[len]; for (int j = 0; j < len; j++) charArray[j] = source[start + j]; } @Override public String toString() { return charArray == null ? "" : new String(charArray, index, length); } static final SubString emptySubString = new SubString(); char[] charArray; int index; int length; } yui-compressor-2.4.7/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java0000644000175000017500000002373411753547210027157 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * Brendan Eich * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript.regexp; import org.mozilla.javascript.*; /** * This class implements the RegExp constructor native object. * * Revision History: * Implementation in C by Brendan Eich * Initial port to Java by Norris Boyd from jsregexp.c version 1.36 * Merged up to version 1.38, which included Unicode support. * Merged bug fixes in version 1.39. * Merged JSFUN13_BRANCH changes up to 1.32.2.11 * * @author Brendan Eich * @author Norris Boyd */ class NativeRegExpCtor extends BaseFunction { static final long serialVersionUID = -5733330028285400526L; NativeRegExpCtor() { } @Override public String getFunctionName() { return "RegExp"; } @Override public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (args.length > 0 && args[0] instanceof NativeRegExp && (args.length == 1 || args[1] == Undefined.instance)) { return args[0]; } return construct(cx, scope, args); } @Override public Scriptable construct(Context cx, Scriptable scope, Object[] args) { NativeRegExp re = new NativeRegExp(); re.compile(cx, scope, args); ScriptRuntime.setObjectProtoAndParent(re, scope); return re; } private static RegExpImpl getImpl() { Context cx = Context.getCurrentContext(); return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx); } // #string_id_map# private static final int Id_multiline = 1, Id_STAR = 2, // #string=$*# Id_input = 3, Id_UNDERSCORE = 4, // #string=$_# Id_lastMatch = 5, Id_AMPERSAND = 6, // #string=$&# Id_lastParen = 7, Id_PLUS = 8, // #string=$+# Id_leftContext = 9, Id_BACK_QUOTE = 10, // #string=$`# Id_rightContext = 11, Id_QUOTE = 12, // #string=$'# DOLLAR_ID_BASE = 12; private static final int Id_DOLLAR_1 = DOLLAR_ID_BASE + 1, // #string=$1# Id_DOLLAR_2 = DOLLAR_ID_BASE + 2, // #string=$2# Id_DOLLAR_3 = DOLLAR_ID_BASE + 3, // #string=$3# Id_DOLLAR_4 = DOLLAR_ID_BASE + 4, // #string=$4# Id_DOLLAR_5 = DOLLAR_ID_BASE + 5, // #string=$5# Id_DOLLAR_6 = DOLLAR_ID_BASE + 6, // #string=$6# Id_DOLLAR_7 = DOLLAR_ID_BASE + 7, // #string=$7# Id_DOLLAR_8 = DOLLAR_ID_BASE + 8, // #string=$8# Id_DOLLAR_9 = DOLLAR_ID_BASE + 9, // #string=$9# MAX_INSTANCE_ID = DOLLAR_ID_BASE + 9; @Override protected int getMaxInstanceId() { return super.getMaxInstanceId() + MAX_INSTANCE_ID; } @Override protected int findInstanceIdInfo(String s) { int id; // #generated# Last update: 2001-05-24 16:09:31 GMT+02:00 L0: { id = 0; String X = null; int c; L: switch (s.length()) { case 2: switch (s.charAt(1)) { case '&': if (s.charAt(0)=='$') {id=Id_AMPERSAND; break L0;} break L; case '\'': if (s.charAt(0)=='$') {id=Id_QUOTE; break L0;} break L; case '*': if (s.charAt(0)=='$') {id=Id_STAR; break L0;} break L; case '+': if (s.charAt(0)=='$') {id=Id_PLUS; break L0;} break L; case '1': if (s.charAt(0)=='$') {id=Id_DOLLAR_1; break L0;} break L; case '2': if (s.charAt(0)=='$') {id=Id_DOLLAR_2; break L0;} break L; case '3': if (s.charAt(0)=='$') {id=Id_DOLLAR_3; break L0;} break L; case '4': if (s.charAt(0)=='$') {id=Id_DOLLAR_4; break L0;} break L; case '5': if (s.charAt(0)=='$') {id=Id_DOLLAR_5; break L0;} break L; case '6': if (s.charAt(0)=='$') {id=Id_DOLLAR_6; break L0;} break L; case '7': if (s.charAt(0)=='$') {id=Id_DOLLAR_7; break L0;} break L; case '8': if (s.charAt(0)=='$') {id=Id_DOLLAR_8; break L0;} break L; case '9': if (s.charAt(0)=='$') {id=Id_DOLLAR_9; break L0;} break L; case '_': if (s.charAt(0)=='$') {id=Id_UNDERSCORE; break L0;} break L; case '`': if (s.charAt(0)=='$') {id=Id_BACK_QUOTE; break L0;} break L; } break L; case 5: X="input";id=Id_input; break L; case 9: c=s.charAt(4); if (c=='M') { X="lastMatch";id=Id_lastMatch; } else if (c=='P') { X="lastParen";id=Id_lastParen; } else if (c=='i') { X="multiline";id=Id_multiline; } break L; case 11: X="leftContext";id=Id_leftContext; break L; case 12: X="rightContext";id=Id_rightContext; break L; } if (X!=null && X!=s && !X.equals(s)) id = 0; } // #/generated# if (id == 0) return super.findInstanceIdInfo(s); int attr; switch (id) { case Id_multiline: case Id_STAR: case Id_input: case Id_UNDERSCORE: attr = PERMANENT; break; default: attr = PERMANENT | READONLY; break; } return instanceIdInfo(attr, super.getMaxInstanceId() + id); } // #/string_id_map# @Override protected String getInstanceIdName(int id) { int shifted = id - super.getMaxInstanceId(); if (1 <= shifted && shifted <= MAX_INSTANCE_ID) { switch (shifted) { case Id_multiline: return "multiline"; case Id_STAR: return "$*"; case Id_input: return "input"; case Id_UNDERSCORE: return "$_"; case Id_lastMatch: return "lastMatch"; case Id_AMPERSAND: return "$&"; case Id_lastParen: return "lastParen"; case Id_PLUS: return "$+"; case Id_leftContext: return "leftContext"; case Id_BACK_QUOTE: return "$`"; case Id_rightContext: return "rightContext"; case Id_QUOTE: return "$'"; } // Must be one of $1..$9, convert to 0..8 int substring_number = shifted - DOLLAR_ID_BASE - 1; char[] buf = { '$', (char)('1' + substring_number) }; return new String(buf); } return super.getInstanceIdName(id); } @Override protected Object getInstanceIdValue(int id) { int shifted = id - super.getMaxInstanceId(); if (1 <= shifted && shifted <= MAX_INSTANCE_ID) { RegExpImpl impl = getImpl(); Object stringResult; switch (shifted) { case Id_multiline: case Id_STAR: return ScriptRuntime.wrapBoolean(impl.multiline); case Id_input: case Id_UNDERSCORE: stringResult = impl.input; break; case Id_lastMatch: case Id_AMPERSAND: stringResult = impl.lastMatch; break; case Id_lastParen: case Id_PLUS: stringResult = impl.lastParen; break; case Id_leftContext: case Id_BACK_QUOTE: stringResult = impl.leftContext; break; case Id_rightContext: case Id_QUOTE: stringResult = impl.rightContext; break; default: { // Must be one of $1..$9, convert to 0..8 int substring_number = shifted - DOLLAR_ID_BASE - 1; stringResult = impl.getParenSubString(substring_number); break; } } return (stringResult == null) ? "" : stringResult.toString(); } return super.getInstanceIdValue(id); } @Override protected void setInstanceIdValue(int id, Object value) { int shifted = id - super.getMaxInstanceId(); switch (shifted) { case Id_multiline: case Id_STAR: getImpl().multiline = ScriptRuntime.toBoolean(value); return; case Id_input: case Id_UNDERSCORE: getImpl().input = ScriptRuntime.toString(value); return; } super.setInstanceIdValue(id, value); } } yui-compressor-2.4.7/src/org/mozilla/javascript/regexp/NativeRegExp.java0000644000175000017500000030733211753547210026326 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * Brendan Eich * Matthias Radestock * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript.regexp; import java.io.Serializable; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.IdFunctionObject; import org.mozilla.javascript.IdScriptableObject; import org.mozilla.javascript.Kit; import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.Undefined; /** * This class implements the RegExp native object. * * Revision History: * Implementation in C by Brendan Eich * Initial port to Java by Norris Boyd from jsregexp.c version 1.36 * Merged up to version 1.38, which included Unicode support. * Merged bug fixes in version 1.39. * Merged JSFUN13_BRANCH changes up to 1.32.2.13 * * @author Brendan Eich * @author Norris Boyd */ public class NativeRegExp extends IdScriptableObject implements Function { static final long serialVersionUID = 4965263491464903264L; private static final Object REGEXP_TAG = new Object(); public static final int JSREG_GLOB = 0x1; // 'g' flag: global public static final int JSREG_FOLD = 0x2; // 'i' flag: fold public static final int JSREG_MULTILINE = 0x4; // 'm' flag: multiline //type of match to perform public static final int TEST = 0; public static final int MATCH = 1; public static final int PREFIX = 2; private static final boolean debug = false; private static final byte REOP_EMPTY = 0; /* match rest of input against rest of r.e. */ private static final byte REOP_ALT = 1; /* alternative subexpressions in kid and next */ private static final byte REOP_BOL = 2; /* beginning of input (or line if multiline) */ private static final byte REOP_EOL = 3; /* end of input (or line if multiline) */ private static final byte REOP_WBDRY = 4; /* match "" at word boundary */ private static final byte REOP_WNONBDRY = 5; /* match "" at word non-boundary */ private static final byte REOP_QUANT = 6; /* quantified atom: atom{1,2} */ private static final byte REOP_STAR = 7; /* zero or more occurrences of kid */ private static final byte REOP_PLUS = 8; /* one or more occurrences of kid */ private static final byte REOP_OPT = 9; /* optional subexpression in kid */ private static final byte REOP_LPAREN = 10; /* left paren bytecode: kid is u.num'th sub-regexp */ private static final byte REOP_RPAREN = 11; /* right paren bytecode */ private static final byte REOP_DOT = 12; /* stands for any character */ // private static final byte REOP_CCLASS = 13; /* character class: [a-f] */ private static final byte REOP_DIGIT = 14; /* match a digit char: [0-9] */ private static final byte REOP_NONDIGIT = 15; /* match a non-digit char: [^0-9] */ private static final byte REOP_ALNUM = 16; /* match an alphanumeric char: [0-9a-z_A-Z] */ private static final byte REOP_NONALNUM = 17; /* match a non-alphanumeric char: [^0-9a-z_A-Z] */ private static final byte REOP_SPACE = 18; /* match a whitespace char */ private static final byte REOP_NONSPACE = 19; /* match a non-whitespace char */ private static final byte REOP_BACKREF = 20; /* back-reference (e.g., \1) to a parenthetical */ private static final byte REOP_FLAT = 21; /* match a flat string */ private static final byte REOP_FLAT1 = 22; /* match a single char */ private static final byte REOP_JUMP = 23; /* for deoptimized closure loops */ // private static final byte REOP_DOTSTAR = 24; /* optimize .* to use a single opcode */ // private static final byte REOP_ANCHOR = 25; /* like .* but skips left context to unanchored r.e. */ // private static final byte REOP_EOLONLY = 26; /* $ not preceded by any pattern */ // private static final byte REOP_UCFLAT = 27; /* flat Unicode string; len immediate counts chars */ private static final byte REOP_UCFLAT1 = 28; /* single Unicode char */ // private static final byte REOP_UCCLASS = 29; /* Unicode character class, vector of chars to match */ // private static final byte REOP_NUCCLASS = 30; /* negated Unicode character class */ // private static final byte REOP_BACKREFi = 31; /* case-independent REOP_BACKREF */ private static final byte REOP_FLATi = 32; /* case-independent REOP_FLAT */ private static final byte REOP_FLAT1i = 33; /* case-independent REOP_FLAT1 */ // private static final byte REOP_UCFLATi = 34; /* case-independent REOP_UCFLAT */ private static final byte REOP_UCFLAT1i = 35; /* case-independent REOP_UCFLAT1 */ // private static final byte REOP_ANCHOR1 = 36; /* first-char discriminating REOP_ANCHOR */ // private static final byte REOP_NCCLASS = 37; /* negated 8-bit character class */ // private static final byte REOP_DOTSTARMIN = 38; /* ungreedy version of REOP_DOTSTAR */ // private static final byte REOP_LPARENNON = 39; /* non-capturing version of REOP_LPAREN */ // private static final byte REOP_RPARENNON = 40; /* non-capturing version of REOP_RPAREN */ private static final byte REOP_ASSERT = 41; /* zero width positive lookahead assertion */ private static final byte REOP_ASSERT_NOT = 42; /* zero width negative lookahead assertion */ private static final byte REOP_ASSERTTEST = 43; /* sentinel at end of assertion child */ private static final byte REOP_ASSERTNOTTEST = 44; /* sentinel at end of !assertion child */ private static final byte REOP_MINIMALSTAR = 45; /* non-greedy version of * */ private static final byte REOP_MINIMALPLUS = 46; /* non-greedy version of + */ private static final byte REOP_MINIMALOPT = 47; /* non-greedy version of ? */ private static final byte REOP_MINIMALQUANT = 48; /* non-greedy version of {} */ private static final byte REOP_ENDCHILD = 49; /* sentinel at end of quantifier child */ private static final byte REOP_CLASS = 50; /* character class with index */ private static final byte REOP_REPEAT = 51; /* directs execution of greedy quantifier */ private static final byte REOP_MINIMALREPEAT = 52; /* directs execution of non-greedy quantifier */ private static final byte REOP_END = 53; public static void init(Context cx, Scriptable scope, boolean sealed) { NativeRegExp proto = new NativeRegExp(); proto.re = (RECompiled)compileRE(cx, "", null, false); proto.activatePrototypeMap(MAX_PROTOTYPE_ID); proto.setParentScope(scope); proto.setPrototype(getObjectPrototype(scope)); NativeRegExpCtor ctor = new NativeRegExpCtor(); // Bug #324006: ECMA-262 15.10.6.1 says "The initial value of // RegExp.prototype.constructor is the builtin RegExp constructor." proto.put("constructor", proto, ctor); ScriptRuntime.setFunctionProtoAndParent(ctor, scope); ctor.setImmunePrototypeProperty(proto); if (sealed) { proto.sealObject(); ctor.sealObject(); } defineProperty(scope, "RegExp", ctor, ScriptableObject.DONTENUM); } NativeRegExp(Scriptable scope, Object regexpCompiled) { this.re = (RECompiled)regexpCompiled; this.lastIndex = 0; ScriptRuntime.setObjectProtoAndParent(this, scope); } @Override public String getClassName() { return "RegExp"; } public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { return execSub(cx, scope, args, MATCH); } public Scriptable construct(Context cx, Scriptable scope, Object[] args) { return (Scriptable)execSub(cx, scope, args, MATCH); } Scriptable compile(Context cx, Scriptable scope, Object[] args) { if (args.length > 0 && args[0] instanceof NativeRegExp) { if (args.length > 1 && args[1] != Undefined.instance) { // report error throw ScriptRuntime.typeError0("msg.bad.regexp.compile"); } NativeRegExp thatObj = (NativeRegExp) args[0]; this.re = thatObj.re; this.lastIndex = thatObj.lastIndex; return this; } String s = args.length == 0 ? "" : ScriptRuntime.toString(args[0]); String global = args.length > 1 && args[1] != Undefined.instance ? ScriptRuntime.toString(args[1]) : null; this.re = (RECompiled)compileRE(cx, s, global, false); this.lastIndex = 0; return this; } @Override public String toString() { StringBuffer buf = new StringBuffer(); buf.append('/'); if (re.source.length != 0) { buf.append(re.source); } else { // See bugzilla 226045 buf.append("(?:)"); } buf.append('/'); if ((re.flags & JSREG_GLOB) != 0) buf.append('g'); if ((re.flags & JSREG_FOLD) != 0) buf.append('i'); if ((re.flags & JSREG_MULTILINE) != 0) buf.append('m'); return buf.toString(); } NativeRegExp() { } private static RegExpImpl getImpl(Context cx) { return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx); } private Object execSub(Context cx, Scriptable scopeObj, Object[] args, int matchType) { RegExpImpl reImpl = getImpl(cx); String str; if (args.length == 0) { str = reImpl.input; if (str == null) { reportError("msg.no.re.input.for", toString()); } } else { str = ScriptRuntime.toString(args[0]); } double d = ((re.flags & JSREG_GLOB) != 0) ? lastIndex : 0; Object rval; if (d < 0 || str.length() < d) { lastIndex = 0; rval = null; } else { int indexp[] = { (int)d }; rval = executeRegExp(cx, scopeObj, reImpl, str, indexp, matchType); if ((re.flags & JSREG_GLOB) != 0) { lastIndex = (rval == null || rval == Undefined.instance) ? 0 : indexp[0]; } } return rval; } static Object compileRE(Context cx, String str, String global, boolean flat) { RECompiled regexp = new RECompiled(); regexp.source = str.toCharArray(); int length = str.length(); int flags = 0; if (global != null) { for (int i = 0; i < global.length(); i++) { char c = global.charAt(i); if (c == 'g') { flags |= JSREG_GLOB; } else if (c == 'i') { flags |= JSREG_FOLD; } else if (c == 'm') { flags |= JSREG_MULTILINE; } else { reportError("msg.invalid.re.flag", String.valueOf(c)); } } } regexp.flags = flags; CompilerState state = new CompilerState(cx, regexp.source, length, flags); if (flat && length > 0) { if (debug) { System.out.println("flat = \"" + str + "\""); } state.result = new RENode(REOP_FLAT); state.result.chr = state.cpbegin[0]; state.result.length = length; state.result.flatIndex = 0; state.progLength += 5; } else if (!parseDisjunction(state)) return null; regexp.program = new byte[state.progLength + 1]; if (state.classCount != 0) { regexp.classList = new RECharSet[state.classCount]; regexp.classCount = state.classCount; } int endPC = emitREBytecode(state, regexp, 0, state.result); regexp.program[endPC++] = REOP_END; if (debug) { System.out.println("Prog. length = " + endPC); for (int i = 0; i < endPC; i++) { System.out.print(regexp.program[i]); if (i < (endPC - 1)) System.out.print(", "); } System.out.println(); } regexp.parenCount = state.parenCount; // If re starts with literal, init anchorCh accordingly switch (regexp.program[0]) { case REOP_UCFLAT1: case REOP_UCFLAT1i: regexp.anchorCh = (char)getIndex(regexp.program, 1); break; case REOP_FLAT1: case REOP_FLAT1i: regexp.anchorCh = (char)(regexp.program[1] & 0xFF); break; case REOP_FLAT: case REOP_FLATi: int k = getIndex(regexp.program, 1); regexp.anchorCh = regexp.source[k]; break; } if (debug) { if (regexp.anchorCh >= 0) { System.out.println("Anchor ch = '" + (char)regexp.anchorCh + "'"); } } return regexp; } static boolean isDigit(char c) { return '0' <= c && c <= '9'; } private static boolean isWord(char c) { return Character.isLetter(c) || isDigit(c) || c == '_'; } private static boolean isLineTerm(char c) { return ScriptRuntime.isJSLineTerminator(c); } private static boolean isREWhiteSpace(int c) { return (c == '\u0020' || c == '\u0009' || c == '\n' || c == '\r' || c == 0x2028 || c == 0x2029 || c == '\u000C' || c == '\u000B' || c == '\u00A0' || Character.getType((char)c) == Character.SPACE_SEPARATOR); } /* * * 1. If IgnoreCase is false, return ch. * 2. Let u be ch converted to upper case as if by calling * String.prototype.toUpperCase on the one-character string ch. * 3. If u does not consist of a single character, return ch. * 4. Let cu be u's character. * 5. If ch's code point value is greater than or equal to decimal 128 and cu's * code point value is less than decimal 128, then return ch. * 6. Return cu. */ private static char upcase(char ch) { if (ch < 128) { if ('a' <= ch && ch <= 'z') { return (char)(ch + ('A' - 'a')); } return ch; } char cu = Character.toUpperCase(ch); if ((ch >= 128) && (cu < 128)) return ch; return cu; } private static char downcase(char ch) { if (ch < 128) { if ('A' <= ch && ch <= 'Z') { return (char)(ch + ('a' - 'A')); } return ch; } char cl = Character.toLowerCase(ch); if ((ch >= 128) && (cl < 128)) return ch; return cl; } /* * Validates and converts hex ascii value. */ private static int toASCIIHexDigit(int c) { if (c < '0') return -1; if (c <= '9') { return c - '0'; } c |= 0x20; if ('a' <= c && c <= 'f') { return c - 'a' + 10; } return -1; } /* * Top-down regular expression grammar, based closely on Perl4. * * regexp: altern A regular expression is one or more * altern '|' regexp alternatives separated by vertical bar. */ private static boolean parseDisjunction(CompilerState state) { if (!parseAlternative(state)) return false; char[] source = state.cpbegin; int index = state.cp; if (index != source.length && source[index] == '|') { RENode altResult; ++state.cp; altResult = new RENode(REOP_ALT); altResult.kid = state.result; if (!parseDisjunction(state)) return false; altResult.kid2 = state.result; state.result = altResult; /* ALT, , ..., JUMP, ... JUMP */ state.progLength += 9; } return true; } /* * altern: item An alternative is one or more items, * item altern concatenated together. */ private static boolean parseAlternative(CompilerState state) { RENode headTerm = null; RENode tailTerm = null; char[] source = state.cpbegin; while (true) { if (state.cp == state.cpend || source[state.cp] == '|' || (state.parenNesting != 0 && source[state.cp] == ')')) { if (headTerm == null) { state.result = new RENode(REOP_EMPTY); } else state.result = headTerm; return true; } if (!parseTerm(state)) return false; if (headTerm == null) headTerm = state.result; else { if (tailTerm == null) { headTerm.next = state.result; tailTerm = state.result; while (tailTerm.next != null) tailTerm = tailTerm.next; } else { tailTerm.next = state.result; tailTerm = tailTerm.next; while (tailTerm.next != null) tailTerm = tailTerm.next; } } } } /* calculate the total size of the bitmap required for a class expression */ private static boolean calculateBitmapSize(CompilerState state, RENode target, char[] src, int index, int end) { char rangeStart = 0; char c; int n; int nDigits; int i; int max = 0; boolean inRange = false; target.bmsize = 0; if (index == end) return true; if (src[index] == '^') ++index; while (index != end) { int localMax = 0; nDigits = 2; switch (src[index]) { case '\\': ++index; c = src[index++]; switch (c) { case 'b': localMax = 0x8; break; case 'f': localMax = 0xC; break; case 'n': localMax = 0xA; break; case 'r': localMax = 0xD; break; case 't': localMax = 0x9; break; case 'v': localMax = 0xB; break; case 'c': if (((index + 1) < end) && Character.isLetter(src[index + 1])) localMax = (char)(src[index++] & 0x1F); else localMax = '\\'; break; case 'u': nDigits += 2; // fall thru... case 'x': n = 0; for (i = 0; (i < nDigits) && (index < end); i++) { c = src[index++]; n = Kit.xDigitToInt(c, n); if (n < 0) { // Back off to accepting the original // '\' as a literal index -= (i + 1); n = '\\'; break; } } localMax = n; break; case 'd': if (inRange) { reportError("msg.bad.range", ""); return false; } localMax = '9'; break; case 'D': case 's': case 'S': case 'w': case 'W': if (inRange) { reportError("msg.bad.range", ""); return false; } target.bmsize = 65535; return true; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': /* * This is a non-ECMA extension - decimal escapes (in this * case, octal!) are supposed to be an error inside class * ranges, but supported here for backwards compatibility. * */ n = (c - '0'); c = src[index]; if ('0' <= c && c <= '7') { index++; n = 8 * n + (c - '0'); c = src[index]; if ('0' <= c && c <= '7') { index++; i = 8 * n + (c - '0'); if (i <= 0377) n = i; else index--; } } localMax = n; break; default: localMax = c; break; } break; default: localMax = src[index++]; break; } if (inRange) { if (rangeStart > localMax) { reportError("msg.bad.range", ""); return false; } inRange = false; } else { if (index < (end - 1)) { if (src[index] == '-') { ++index; inRange = true; rangeStart = (char)localMax; continue; } } } if ((state.flags & JSREG_FOLD) != 0){ char cu = upcase((char)localMax); char cd = downcase((char)localMax); localMax = (cu >= cd) ? cu : cd; } if (localMax > max) max = localMax; } target.bmsize = max; return true; } /* * item: assertion An item is either an assertion or * quantatom a quantified atom. * * assertion: '^' Assertions match beginning of string * (or line if the class static property * RegExp.multiline is true). * '$' End of string (or line if the class * static property RegExp.multiline is * true). * '\b' Word boundary (between \w and \W). * '\B' Word non-boundary. * * quantatom: atom An unquantified atom. * quantatom '{' n ',' m '}' * Atom must occur between n and m times. * quantatom '{' n ',' '}' Atom must occur at least n times. * quantatom '{' n '}' Atom must occur exactly n times. * quantatom '*' Zero or more times (same as {0,}). * quantatom '+' One or more times (same as {1,}). * quantatom '?' Zero or one time (same as {0,1}). * * any of which can be optionally followed by '?' for ungreedy * * atom: '(' regexp ')' A parenthesized regexp (what matched * can be addressed using a backreference, * see '\' n below). * '.' Matches any char except '\n'. * '[' classlist ']' A character class. * '[' '^' classlist ']' A negated character class. * '\f' Form Feed. * '\n' Newline (Line Feed). * '\r' Carriage Return. * '\t' Horizontal Tab. * '\v' Vertical Tab. * '\d' A digit (same as [0-9]). * '\D' A non-digit. * '\w' A word character, [0-9a-z_A-Z]. * '\W' A non-word character. * '\s' A whitespace character, [ \b\f\n\r\t\v]. * '\S' A non-whitespace character. * '\' n A backreference to the nth (n decimal * and positive) parenthesized expression. * '\' octal An octal escape sequence (octal must be * two or three digits long, unless it is * 0 for the null character). * '\x' hex A hex escape (hex must be two digits). * '\c' ctrl A control character, ctrl is a letter. * '\' literalatomchar Any character except one of the above * that follow '\' in an atom. * otheratomchar Any character not first among the other * atom right-hand sides. */ private static void doFlat(CompilerState state, char c) { state.result = new RENode(REOP_FLAT); state.result.chr = c; state.result.length = 1; state.result.flatIndex = -1; state.progLength += 3; } private static int getDecimalValue(char c, CompilerState state, int maxValue, String overflowMessageId) { boolean overflow = false; int start = state.cp; char[] src = state.cpbegin; int value = c - '0'; for (; state.cp != state.cpend; ++state.cp) { c = src[state.cp]; if (!isDigit(c)) { break; } if (!overflow) { int digit = c - '0'; if (value < (maxValue - digit) / 10) { value = value * 10 + digit; } else { overflow = true; value = maxValue; } } } if (overflow) { reportError(overflowMessageId, String.valueOf(src, start, state.cp - start)); } return value; } private static boolean parseTerm(CompilerState state) { char[] src = state.cpbegin; char c = src[state.cp++]; int nDigits = 2; int parenBaseCount = state.parenCount; int num, tmp; RENode term; int termStart; switch (c) { /* assertions and atoms */ case '^': state.result = new RENode(REOP_BOL); state.progLength++; return true; case '$': state.result = new RENode(REOP_EOL); state.progLength++; return true; case '\\': if (state.cp < state.cpend) { c = src[state.cp++]; switch (c) { /* assertion escapes */ case 'b' : state.result = new RENode(REOP_WBDRY); state.progLength++; return true; case 'B': state.result = new RENode(REOP_WNONBDRY); state.progLength++; return true; /* Decimal escape */ case '0': /* * Under 'strict' ECMA 3, we interpret \0 as NUL and don't accept octal. * However, (XXX and since Rhino doesn't have a 'strict' mode) we'll just * behave the old way for compatibility reasons. * (see http://bugzilla.mozilla.org/show_bug.cgi?id=141078) * */ reportWarning(state.cx, "msg.bad.backref", ""); /* octal escape */ num = 0; while (state.cp < state.cpend) { c = src[state.cp]; if ((c >= '0') && (c <= '7')) { state.cp++; tmp = 8 * num + (c - '0'); if (tmp > 0377) break; num = tmp; } else break; } c = (char)(num); doFlat(state, c); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': termStart = state.cp - 1; num = getDecimalValue(c, state, 0xFFFF, "msg.overlarge.backref"); if (num > state.parenCount) reportWarning(state.cx, "msg.bad.backref", ""); /* * n > 9 or > count of parentheses, * then treat as octal instead. */ if ((num > 9) && (num > state.parenCount)) { state.cp = termStart; num = 0; while (state.cp < state.cpend) { c = src[state.cp]; if ((c >= '0') && (c <= '7')) { state.cp++; tmp = 8 * num + (c - '0'); if (tmp > 0377) break; num = tmp; } else break; } c = (char)(num); doFlat(state, c); break; } /* otherwise, it's a back-reference */ state.result = new RENode(REOP_BACKREF); state.result.parenIndex = num - 1; state.progLength += 3; break; /* Control escape */ case 'f': c = 0xC; doFlat(state, c); break; case 'n': c = 0xA; doFlat(state, c); break; case 'r': c = 0xD; doFlat(state, c); break; case 't': c = 0x9; doFlat(state, c); break; case 'v': c = 0xB; doFlat(state, c); break; /* Control letter */ case 'c': if (((state.cp + 1) < state.cpend) && Character.isLetter(src[state.cp + 1])) c = (char)(src[state.cp++] & 0x1F); else { /* back off to accepting the original '\' as a literal */ --state.cp; c = '\\'; } doFlat(state, c); break; /* UnicodeEscapeSequence */ case 'u': nDigits += 2; // fall thru... /* HexEscapeSequence */ case 'x': { int n = 0; int i; for (i = 0; (i < nDigits) && (state.cp < state.cpend); i++) { c = src[state.cp++]; n = Kit.xDigitToInt(c, n); if (n < 0) { // Back off to accepting the original // 'u' or 'x' as a literal state.cp -= (i + 2); n = src[state.cp++]; break; } } c = (char)(n); } doFlat(state, c); break; /* Character class escapes */ case 'd': state.result = new RENode(REOP_DIGIT); state.progLength++; break; case 'D': state.result = new RENode(REOP_NONDIGIT); state.progLength++; break; case 's': state.result = new RENode(REOP_SPACE); state.progLength++; break; case 'S': state.result = new RENode(REOP_NONSPACE); state.progLength++; break; case 'w': state.result = new RENode(REOP_ALNUM); state.progLength++; break; case 'W': state.result = new RENode(REOP_NONALNUM); state.progLength++; break; /* IdentityEscape */ default: state.result = new RENode(REOP_FLAT); state.result.chr = c; state.result.length = 1; state.result.flatIndex = state.cp - 1; state.progLength += 3; break; } break; } else { /* a trailing '\' is an error */ reportError("msg.trail.backslash", ""); return false; } case '(': { RENode result = null; termStart = state.cp; if (state.cp + 1 < state.cpend && src[state.cp] == '?' && ((c = src[state.cp + 1]) == '=' || c == '!' || c == ':')) { state.cp += 2; if (c == '=') { result = new RENode(REOP_ASSERT); /* ASSERT, , ... ASSERTTEST */ state.progLength += 4; } else if (c == '!') { result = new RENode(REOP_ASSERT_NOT); /* ASSERTNOT, , ... ASSERTNOTTEST */ state.progLength += 4; } } else { result = new RENode(REOP_LPAREN); /* LPAREN, , ... RPAREN, */ state.progLength += 6; result.parenIndex = state.parenCount++; } ++state.parenNesting; if (!parseDisjunction(state)) return false; if (state.cp == state.cpend || src[state.cp] != ')') { reportError("msg.unterm.paren", ""); return false; } ++state.cp; --state.parenNesting; if (result != null) { result.kid = state.result; state.result = result; } break; } case ')': reportError("msg.re.unmatched.right.paren", ""); return false; case '[': state.result = new RENode(REOP_CLASS); termStart = state.cp; state.result.startIndex = termStart; while (true) { if (state.cp == state.cpend) { reportError("msg.unterm.class", ""); return false; } if (src[state.cp] == '\\') state.cp++; else { if (src[state.cp] == ']') { state.result.kidlen = state.cp - termStart; break; } } state.cp++; } state.result.index = state.classCount++; /* * Call calculateBitmapSize now as we want any errors it finds * to be reported during the parse phase, not at execution. */ if (!calculateBitmapSize(state, state.result, src, termStart, state.cp++)) return false; state.progLength += 3; /* CLASS, */ break; case '.': state.result = new RENode(REOP_DOT); state.progLength++; break; case '*': case '+': case '?': reportError("msg.bad.quant", String.valueOf(src[state.cp - 1])); return false; default: state.result = new RENode(REOP_FLAT); state.result.chr = c; state.result.length = 1; state.result.flatIndex = state.cp - 1; state.progLength += 3; break; } term = state.result; if (state.cp == state.cpend) { return true; } boolean hasQ = false; switch (src[state.cp]) { case '+': state.result = new RENode(REOP_QUANT); state.result.min = 1; state.result.max = -1; /* , , , ... */ state.progLength += 8; hasQ = true; break; case '*': state.result = new RENode(REOP_QUANT); state.result.min = 0; state.result.max = -1; /* , , , ... */ state.progLength += 8; hasQ = true; break; case '?': state.result = new RENode(REOP_QUANT); state.result.min = 0; state.result.max = 1; /* , , , ... */ state.progLength += 8; hasQ = true; break; case '{': /* balance '}' */ { int min = 0; int max = -1; int leftCurl = state.cp; /* For Perl etc. compatibility, if quntifier does not match * \{\d+(,\d*)?\} exactly back off from it * being a quantifier, and chew it up as a literal * atom next time instead. */ c = src[++state.cp]; if (isDigit(c)) { ++state.cp; min = getDecimalValue(c, state, 0xFFFF, "msg.overlarge.min"); c = src[state.cp]; if (c == ',') { c = src[++state.cp]; if (isDigit(c)) { ++state.cp; max = getDecimalValue(c, state, 0xFFFF, "msg.overlarge.max"); c = src[state.cp]; if (min > max) { reportError("msg.max.lt.min", String.valueOf(src[state.cp])); return false; } } } else { max = min; } /* balance '{' */ if (c == '}') { state.result = new RENode(REOP_QUANT); state.result.min = min; state.result.max = max; // QUANT, , , , // , ... state.progLength += 12; hasQ = true; } } if (!hasQ) { state.cp = leftCurl; } break; } } if (!hasQ) return true; ++state.cp; state.result.kid = term; state.result.parenIndex = parenBaseCount; state.result.parenCount = state.parenCount - parenBaseCount; if ((state.cp < state.cpend) && (src[state.cp] == '?')) { ++state.cp; state.result.greedy = false; } else state.result.greedy = true; return true; } private static void resolveForwardJump(byte[] array, int from, int pc) { if (from > pc) throw Kit.codeBug(); addIndex(array, from, pc - from); } private static int getOffset(byte[] array, int pc) { return getIndex(array, pc); } private static int addIndex(byte[] array, int pc, int index) { if (index < 0) throw Kit.codeBug(); if (index > 0xFFFF) throw Context.reportRuntimeError("Too complex regexp"); array[pc] = (byte)(index >> 8); array[pc + 1] = (byte)(index); return pc + 2; } private static int getIndex(byte[] array, int pc) { return ((array[pc] & 0xFF) << 8) | (array[pc + 1] & 0xFF); } private static final int OFFSET_LEN = 2; private static final int INDEX_LEN = 2; private static int emitREBytecode(CompilerState state, RECompiled re, int pc, RENode t) { RENode nextAlt; int nextAltFixup, nextTermFixup; byte[] program = re.program; while (t != null) { program[pc++] = t.op; switch (t.op) { case REOP_EMPTY: --pc; break; case REOP_ALT: nextAlt = t.kid2; nextAltFixup = pc; /* address of next alternate */ pc += OFFSET_LEN; pc = emitREBytecode(state, re, pc, t.kid); program[pc++] = REOP_JUMP; nextTermFixup = pc; /* address of following term */ pc += OFFSET_LEN; resolveForwardJump(program, nextAltFixup, pc); pc = emitREBytecode(state, re, pc, nextAlt); program[pc++] = REOP_JUMP; nextAltFixup = pc; pc += OFFSET_LEN; resolveForwardJump(program, nextTermFixup, pc); resolveForwardJump(program, nextAltFixup, pc); break; case REOP_FLAT: /* * Consecutize FLAT's if possible. */ if (t.flatIndex != -1) { while ((t.next != null) && (t.next.op == REOP_FLAT) && ((t.flatIndex + t.length) == t.next.flatIndex)) { t.length += t.next.length; t.next = t.next.next; } } if ((t.flatIndex != -1) && (t.length > 1)) { if ((state.flags & JSREG_FOLD) != 0) program[pc - 1] = REOP_FLATi; else program[pc - 1] = REOP_FLAT; pc = addIndex(program, pc, t.flatIndex); pc = addIndex(program, pc, t.length); } else { if (t.chr < 256) { if ((state.flags & JSREG_FOLD) != 0) program[pc - 1] = REOP_FLAT1i; else program[pc - 1] = REOP_FLAT1; program[pc++] = (byte)(t.chr); } else { if ((state.flags & JSREG_FOLD) != 0) program[pc - 1] = REOP_UCFLAT1i; else program[pc - 1] = REOP_UCFLAT1; pc = addIndex(program, pc, t.chr); } } break; case REOP_LPAREN: pc = addIndex(program, pc, t.parenIndex); pc = emitREBytecode(state, re, pc, t.kid); program[pc++] = REOP_RPAREN; pc = addIndex(program, pc, t.parenIndex); break; case REOP_BACKREF: pc = addIndex(program, pc, t.parenIndex); break; case REOP_ASSERT: nextTermFixup = pc; pc += OFFSET_LEN; pc = emitREBytecode(state, re, pc, t.kid); program[pc++] = REOP_ASSERTTEST; resolveForwardJump(program, nextTermFixup, pc); break; case REOP_ASSERT_NOT: nextTermFixup = pc; pc += OFFSET_LEN; pc = emitREBytecode(state, re, pc, t.kid); program[pc++] = REOP_ASSERTNOTTEST; resolveForwardJump(program, nextTermFixup, pc); break; case REOP_QUANT: if ((t.min == 0) && (t.max == -1)) program[pc - 1] = (t.greedy) ? REOP_STAR : REOP_MINIMALSTAR; else if ((t.min == 0) && (t.max == 1)) program[pc - 1] = (t.greedy) ? REOP_OPT : REOP_MINIMALOPT; else if ((t.min == 1) && (t.max == -1)) program[pc - 1] = (t.greedy) ? REOP_PLUS : REOP_MINIMALPLUS; else { if (!t.greedy) program[pc - 1] = REOP_MINIMALQUANT; pc = addIndex(program, pc, t.min); // max can be -1 which addIndex does not accept pc = addIndex(program, pc, t.max + 1); } pc = addIndex(program, pc, t.parenCount); pc = addIndex(program, pc, t.parenIndex); nextTermFixup = pc; pc += OFFSET_LEN; pc = emitREBytecode(state, re, pc, t.kid); program[pc++] = REOP_ENDCHILD; resolveForwardJump(program, nextTermFixup, pc); break; case REOP_CLASS: pc = addIndex(program, pc, t.index); re.classList[t.index] = new RECharSet(t.bmsize, t.startIndex, t.kidlen); break; default: break; } t = t.next; } return pc; } private static void pushProgState(REGlobalData gData, int min, int max, REBackTrackData backTrackLastToSave, int continuation_pc, int continuation_op) { gData.stateStackTop = new REProgState(gData.stateStackTop, min, max, gData.cp, backTrackLastToSave, continuation_pc, continuation_op); } private static REProgState popProgState(REGlobalData gData) { REProgState state = gData.stateStackTop; gData.stateStackTop = state.previous; return state; } private static void pushBackTrackState(REGlobalData gData, byte op, int target) { gData.backTrackStackTop = new REBackTrackData(gData, op, target); } /* * Consecutive literal characters. */ private static boolean flatNMatcher(REGlobalData gData, int matchChars, int length, char[] chars, int end) { if ((gData.cp + length) > end) return false; for (int i = 0; i < length; i++) { if (gData.regexp.source[matchChars + i] != chars[gData.cp + i]) { return false; } } gData.cp += length; return true; } private static boolean flatNIMatcher(REGlobalData gData, int matchChars, int length, char[] chars, int end) { if ((gData.cp + length) > end) return false; for (int i = 0; i < length; i++) { if (upcase(gData.regexp.source[matchChars + i]) != upcase(chars[gData.cp + i])) { return false; } } gData.cp += length; return true; } /* 1. Evaluate DecimalEscape to obtain an EscapeValue E. 2. If E is not a character then go to step 6. 3. Let ch be E's character. 4. Let A be a one-element RECharSet containing the character ch. 5. Call CharacterSetMatcher(A, false) and return its Matcher result. 6. E must be an integer. Let n be that integer. 7. If n=0 or n>NCapturingParens then throw a SyntaxError exception. 8. Return an internal Matcher closure that takes two arguments, a State x and a Continuation c, and performs the following: 1. Let cap be x's captures internal array. 2. Let s be cap[n]. 3. If s is undefined, then call c(x) and return its result. 4. Let e be x's endIndex. 5. Let len be s's length. 6. Let f be e+len. 7. If f>InputLength, return failure. 8. If there exists an integer i between 0 (inclusive) and len (exclusive) such that Canonicalize(s[i]) is not the same character as Canonicalize(Input [e+i]), then return failure. 9. Let y be the State (f, cap). 10. Call c(y) and return its result. */ private static boolean backrefMatcher(REGlobalData gData, int parenIndex, char[] chars, int end) { int len; int i; int parenContent = gData.parens_index(parenIndex); if (parenContent == -1) return true; len = gData.parens_length(parenIndex); if ((gData.cp + len) > end) return false; if ((gData.regexp.flags & JSREG_FOLD) != 0) { for (i = 0; i < len; i++) { if (upcase(chars[parenContent + i]) != upcase(chars[gData.cp + i])) return false; } } else { for (i = 0; i < len; i++) { if (chars[parenContent + i] != chars[gData.cp + i]) return false; } } gData.cp += len; return true; } /* Add a single character to the RECharSet */ private static void addCharacterToCharSet(RECharSet cs, char c) { int byteIndex = (c / 8); if (c > cs.length) throw new RuntimeException(); cs.bits[byteIndex] |= 1 << (c & 0x7); } /* Add a character range, c1 to c2 (inclusive) to the RECharSet */ private static void addCharacterRangeToCharSet(RECharSet cs, char c1, char c2) { int i; int byteIndex1 = (c1 / 8); int byteIndex2 = (c2 / 8); if ((c2 > cs.length) || (c1 > c2)) throw new RuntimeException(); c1 &= 0x7; c2 &= 0x7; if (byteIndex1 == byteIndex2) { cs.bits[byteIndex1] |= ((0xFF) >> (7 - (c2 - c1))) << c1; } else { cs.bits[byteIndex1] |= 0xFF << c1; for (i = byteIndex1 + 1; i < byteIndex2; i++) cs.bits[i] = (byte)0xFF; cs.bits[byteIndex2] |= (0xFF) >> (7 - c2); } } /* Compile the source of the class into a RECharSet */ private static void processCharSet(REGlobalData gData, RECharSet charSet) { synchronized (charSet) { if (!charSet.converted) { processCharSetImpl(gData, charSet); charSet.converted = true; } } } private static void processCharSetImpl(REGlobalData gData, RECharSet charSet) { int src = charSet.startIndex; int end = src + charSet.strlength; char rangeStart = 0, thisCh; int byteLength; char c; int n; int nDigits; int i; boolean inRange = false; charSet.sense = true; byteLength = (charSet.length / 8) + 1; charSet.bits = new byte[byteLength]; if (src == end) return; if (gData.regexp.source[src] == '^') { charSet.sense = false; ++src; } while (src != end) { nDigits = 2; switch (gData.regexp.source[src]) { case '\\': ++src; c = gData.regexp.source[src++]; switch (c) { case 'b': thisCh = 0x8; break; case 'f': thisCh = 0xC; break; case 'n': thisCh = 0xA; break; case 'r': thisCh = 0xD; break; case 't': thisCh = 0x9; break; case 'v': thisCh = 0xB; break; case 'c': if (((src + 1) < end) && isWord(gData.regexp.source[src + 1])) thisCh = (char)(gData.regexp.source[src++] & 0x1F); else { --src; thisCh = '\\'; } break; case 'u': nDigits += 2; // fall thru case 'x': n = 0; for (i = 0; (i < nDigits) && (src < end); i++) { c = gData.regexp.source[src++]; int digit = toASCIIHexDigit(c); if (digit < 0) { /* back off to accepting the original '\' * as a literal */ src -= (i + 1); n = '\\'; break; } n = (n << 4) | digit; } thisCh = (char)(n); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': /* * This is a non-ECMA extension - decimal escapes (in this * case, octal!) are supposed to be an error inside class * ranges, but supported here for backwards compatibility. * */ n = (c - '0'); c = gData.regexp.source[src]; if ('0' <= c && c <= '7') { src++; n = 8 * n + (c - '0'); c = gData.regexp.source[src]; if ('0' <= c && c <= '7') { src++; i = 8 * n + (c - '0'); if (i <= 0377) n = i; else src--; } } thisCh = (char)(n); break; case 'd': addCharacterRangeToCharSet(charSet, '0', '9'); continue; /* don't need range processing */ case 'D': addCharacterRangeToCharSet(charSet, (char)0, (char)('0' - 1)); addCharacterRangeToCharSet(charSet, (char)('9' + 1), (char)(charSet.length)); continue; case 's': for (i = charSet.length; i >= 0; i--) if (isREWhiteSpace(i)) addCharacterToCharSet(charSet, (char)(i)); continue; case 'S': for (i = charSet.length; i >= 0; i--) if (!isREWhiteSpace(i)) addCharacterToCharSet(charSet, (char)(i)); continue; case 'w': for (i = charSet.length; i >= 0; i--) if (isWord((char)i)) addCharacterToCharSet(charSet, (char)(i)); continue; case 'W': for (i = charSet.length; i >= 0; i--) if (!isWord((char)i)) addCharacterToCharSet(charSet, (char)(i)); continue; default: thisCh = c; break; } break; default: thisCh = gData.regexp.source[src++]; break; } if (inRange) { if ((gData.regexp.flags & JSREG_FOLD) != 0) { addCharacterRangeToCharSet(charSet, upcase(rangeStart), upcase(thisCh)); addCharacterRangeToCharSet(charSet, downcase(rangeStart), downcase(thisCh)); } else { addCharacterRangeToCharSet(charSet, rangeStart, thisCh); } inRange = false; } else { if ((gData.regexp.flags & JSREG_FOLD) != 0) { addCharacterToCharSet(charSet, upcase(thisCh)); addCharacterToCharSet(charSet, downcase(thisCh)); } else { addCharacterToCharSet(charSet, thisCh); } if (src < (end - 1)) { if (gData.regexp.source[src] == '-') { ++src; inRange = true; rangeStart = thisCh; } } } } } /* * Initialize the character set if it this is the first call. * Test the bit - if the ^ flag was specified, non-inclusion is a success */ private static boolean classMatcher(REGlobalData gData, RECharSet charSet, char ch) { if (!charSet.converted) { processCharSet(gData, charSet); } int byteIndex = ch / 8; if (charSet.sense) { if ((charSet.length == 0) || ( (ch > charSet.length) || ((charSet.bits[byteIndex] & (1 << (ch & 0x7))) == 0) )) return false; } else { if (! ((charSet.length == 0) || ( (ch > charSet.length) || ((charSet.bits[byteIndex] & (1 << (ch & 0x7))) == 0) ))) return false; } return true; } private static boolean executeREBytecode(REGlobalData gData, char[] chars, int end) { int pc = 0; byte program[] = gData.regexp.program; int currentContinuation_op; int currentContinuation_pc; boolean result = false; currentContinuation_pc = 0; currentContinuation_op = REOP_END; if (debug) { System.out.println("Input = \"" + new String(chars) + "\", start at " + gData.cp); } int op = program[pc++]; for (;;) { if (debug) { System.out.println("Testing at " + gData.cp + ", op = " + op); } switch (op) { case REOP_EMPTY: result = true; break; case REOP_BOL: if (gData.cp != 0) { if (gData.multiline || ((gData.regexp.flags & JSREG_MULTILINE) != 0)) { if (!isLineTerm(chars[gData.cp - 1])) { result = false; break; } } else { result = false; break; } } result = true; break; case REOP_EOL: if (gData.cp != end) { if (gData.multiline || ((gData.regexp.flags & JSREG_MULTILINE) != 0)) { if (!isLineTerm(chars[gData.cp])) { result = false; break; } } else { result = false; break; } } result = true; break; case REOP_WBDRY: result = ((gData.cp == 0 || !isWord(chars[gData.cp - 1])) ^ !((gData.cp < end) && isWord(chars[gData.cp]))); break; case REOP_WNONBDRY: result = ((gData.cp == 0 || !isWord(chars[gData.cp - 1])) ^ ((gData.cp < end) && isWord(chars[gData.cp]))); break; case REOP_DOT: result = (gData.cp != end && !isLineTerm(chars[gData.cp])); if (result) { gData.cp++; } break; case REOP_DIGIT: result = (gData.cp != end && isDigit(chars[gData.cp])); if (result) { gData.cp++; } break; case REOP_NONDIGIT: result = (gData.cp != end && !isDigit(chars[gData.cp])); if (result) { gData.cp++; } break; case REOP_SPACE: result = (gData.cp != end && isREWhiteSpace(chars[gData.cp])); if (result) { gData.cp++; } break; case REOP_NONSPACE: result = (gData.cp != end && !isREWhiteSpace(chars[gData.cp])); if (result) { gData.cp++; } break; case REOP_ALNUM: result = (gData.cp != end && isWord(chars[gData.cp])); if (result) { gData.cp++; } break; case REOP_NONALNUM: result = (gData.cp != end && !isWord(chars[gData.cp])); if (result) { gData.cp++; } break; case REOP_FLAT: { int offset = getIndex(program, pc); pc += INDEX_LEN; int length = getIndex(program, pc); pc += INDEX_LEN; result = flatNMatcher(gData, offset, length, chars, end); } break; case REOP_FLATi: { int offset = getIndex(program, pc); pc += INDEX_LEN; int length = getIndex(program, pc); pc += INDEX_LEN; result = flatNIMatcher(gData, offset, length, chars, end); } break; case REOP_FLAT1: { char matchCh = (char)(program[pc++] & 0xFF); result = (gData.cp != end && chars[gData.cp] == matchCh); if (result) { gData.cp++; } } break; case REOP_FLAT1i: { char matchCh = (char)(program[pc++] & 0xFF); result = (gData.cp != end && upcase(chars[gData.cp]) == upcase(matchCh)); if (result) { gData.cp++; } } break; case REOP_UCFLAT1: { char matchCh = (char)getIndex(program, pc); pc += INDEX_LEN; result = (gData.cp != end && chars[gData.cp] == matchCh); if (result) { gData.cp++; } } break; case REOP_UCFLAT1i: { char matchCh = (char)getIndex(program, pc); pc += INDEX_LEN; result = (gData.cp != end && upcase(chars[gData.cp]) == upcase(matchCh)); if (result) { gData.cp++; } } break; case REOP_ALT: { int nextpc; byte nextop; pushProgState(gData, 0, 0, null, currentContinuation_pc, currentContinuation_op); nextpc = pc + getOffset(program, pc); nextop = program[nextpc++]; pushBackTrackState(gData, nextop, nextpc); pc += INDEX_LEN; op = program[pc++]; } continue; case REOP_JUMP: { int offset; REProgState state = popProgState(gData); currentContinuation_pc = state.continuation_pc; currentContinuation_op = state.continuation_op; offset = getOffset(program, pc); pc += offset; op = program[pc++]; } continue; case REOP_LPAREN: { int parenIndex = getIndex(program, pc); pc += INDEX_LEN; gData.set_parens(parenIndex, gData.cp, 0); op = program[pc++]; } continue; case REOP_RPAREN: { int cap_index; int parenIndex = getIndex(program, pc); pc += INDEX_LEN; cap_index = gData.parens_index(parenIndex); gData.set_parens(parenIndex, cap_index, gData.cp - cap_index); if (parenIndex > gData.lastParen) gData.lastParen = parenIndex; op = program[pc++]; } continue; case REOP_BACKREF: { int parenIndex = getIndex(program, pc); pc += INDEX_LEN; result = backrefMatcher(gData, parenIndex, chars, end); } break; case REOP_CLASS: { int index = getIndex(program, pc); pc += INDEX_LEN; if (gData.cp != end) { if (classMatcher(gData, gData.regexp.classList[index], chars[gData.cp])) { gData.cp++; result = true; break; } } result = false; } break; case REOP_ASSERT: case REOP_ASSERT_NOT: { byte testOp; pushProgState(gData, 0, 0, gData.backTrackStackTop, currentContinuation_pc, currentContinuation_op); if (op == REOP_ASSERT) { testOp = REOP_ASSERTTEST; } else { testOp = REOP_ASSERTNOTTEST; } pushBackTrackState(gData, testOp, pc + getOffset(program, pc)); pc += INDEX_LEN; op = program[pc++]; } continue; case REOP_ASSERTTEST: case REOP_ASSERTNOTTEST: { REProgState state = popProgState(gData); gData.cp = state.index; gData.backTrackStackTop = state.backTrack; currentContinuation_pc = state.continuation_pc; currentContinuation_op = state.continuation_op; if (result) { if (op == REOP_ASSERTTEST) { result = true; } else { result = false; } } else { if (op == REOP_ASSERTTEST) { // Do nothing } else { result = true; } } } break; case REOP_STAR: case REOP_PLUS: case REOP_OPT: case REOP_QUANT: case REOP_MINIMALSTAR: case REOP_MINIMALPLUS: case REOP_MINIMALOPT: case REOP_MINIMALQUANT: { int min, max; boolean greedy = false; switch (op) { case REOP_STAR: greedy = true; // fallthrough case REOP_MINIMALSTAR: min = 0; max = -1; break; case REOP_PLUS: greedy = true; // fallthrough case REOP_MINIMALPLUS: min = 1; max = -1; break; case REOP_OPT: greedy = true; // fallthrough case REOP_MINIMALOPT: min = 0; max = 1; break; case REOP_QUANT: greedy = true; // fallthrough case REOP_MINIMALQUANT: min = getOffset(program, pc); pc += INDEX_LEN; // See comments in emitREBytecode for " - 1" reason max = getOffset(program, pc) - 1; pc += INDEX_LEN; break; default: throw Kit.codeBug(); } pushProgState(gData, min, max, null, currentContinuation_pc, currentContinuation_op); if (greedy) { currentContinuation_op = REOP_REPEAT; currentContinuation_pc = pc; pushBackTrackState(gData, REOP_REPEAT, pc); /* Step over , & */ pc += 3 * INDEX_LEN; op = program[pc++]; } else { if (min != 0) { currentContinuation_op = REOP_MINIMALREPEAT; currentContinuation_pc = pc; /* & */ pc += 3 * INDEX_LEN; op = program[pc++]; } else { pushBackTrackState(gData, REOP_MINIMALREPEAT, pc); popProgState(gData); pc += 2 * INDEX_LEN; // & pc = pc + getOffset(program, pc); op = program[pc++]; } } } continue; case REOP_ENDCHILD: // Use the current continuation. pc = currentContinuation_pc; op = currentContinuation_op; continue; case REOP_REPEAT: { REProgState state = popProgState(gData); if (!result) { // // There's been a failure, see if we have enough // children. // if (state.min == 0) result = true; currentContinuation_pc = state.continuation_pc; currentContinuation_op = state.continuation_op; pc += 2 * INDEX_LEN; /* & */ pc = pc + getOffset(program, pc); break; } else { if (state.min == 0 && gData.cp == state.index) { // matched an empty string, that'll get us nowhere result = false; currentContinuation_pc = state.continuation_pc; currentContinuation_op = state.continuation_op; pc += 2 * INDEX_LEN; pc = pc + getOffset(program, pc); break; } int new_min = state.min, new_max = state.max; if (new_min != 0) new_min--; if (new_max != -1) new_max--; if (new_max == 0) { result = true; currentContinuation_pc = state.continuation_pc; currentContinuation_op = state.continuation_op; pc += 2 * INDEX_LEN; pc = pc + getOffset(program, pc); break; } pushProgState(gData, new_min, new_max, null, state.continuation_pc, state.continuation_op); currentContinuation_op = REOP_REPEAT; currentContinuation_pc = pc; pushBackTrackState(gData, REOP_REPEAT, pc); int parenCount = getIndex(program, pc); pc += INDEX_LEN; int parenIndex = getIndex(program, pc); pc += 2 * INDEX_LEN; op = program[pc++]; for (int k = 0; k < parenCount; k++) { gData.set_parens(parenIndex + k, -1, 0); } } } continue; case REOP_MINIMALREPEAT: { REProgState state = popProgState(gData); if (!result) { // // Non-greedy failure - try to consume another child. // if (state.max == -1 || state.max > 0) { pushProgState(gData, state.min, state.max, null, state.continuation_pc, state.continuation_op); currentContinuation_op = REOP_MINIMALREPEAT; currentContinuation_pc = pc; int parenCount = getIndex(program, pc); pc += INDEX_LEN; int parenIndex = getIndex(program, pc); pc += 2 * INDEX_LEN; for (int k = 0; k < parenCount; k++) { gData.set_parens(parenIndex + k, -1, 0); } op = program[pc++]; continue; } else { // Don't need to adjust pc since we're going to pop. currentContinuation_pc = state.continuation_pc; currentContinuation_op = state.continuation_op; break; } } else { if (state.min == 0 && gData.cp == state.index) { // Matched an empty string, that'll get us nowhere. result = false; currentContinuation_pc = state.continuation_pc; currentContinuation_op = state.continuation_op; break; } int new_min = state.min, new_max = state.max; if (new_min != 0) new_min--; if (new_max != -1) new_max--; pushProgState(gData, new_min, new_max, null, state.continuation_pc, state.continuation_op); if (new_min != 0) { currentContinuation_op = REOP_MINIMALREPEAT; currentContinuation_pc = pc; int parenCount = getIndex(program, pc); pc += INDEX_LEN; int parenIndex = getIndex(program, pc); pc += 2 * INDEX_LEN; for (int k = 0; k < parenCount; k++) { gData.set_parens(parenIndex + k, -1, 0); } op = program[pc++]; } else { currentContinuation_pc = state.continuation_pc; currentContinuation_op = state.continuation_op; pushBackTrackState(gData, REOP_MINIMALREPEAT, pc); popProgState(gData); pc += 2 * INDEX_LEN; pc = pc + getOffset(program, pc); op = program[pc++]; } continue; } } case REOP_END: return true; default: throw Kit.codeBug(); } /* * If the match failed and there's a backtrack option, take it. * Otherwise this is a complete and utter failure. */ if (!result) { REBackTrackData backTrackData = gData.backTrackStackTop; if (backTrackData != null) { gData.backTrackStackTop = backTrackData.previous; gData.lastParen = backTrackData.lastParen; // XXX: If backTrackData will no longer be used, then // there is no need to clone backTrackData.parens if (backTrackData.parens != null) { gData.parens = backTrackData.parens.clone(); } gData.cp = backTrackData.cp; gData.stateStackTop = backTrackData.stateStackTop; currentContinuation_op = gData.stateStackTop.continuation_op; currentContinuation_pc = gData.stateStackTop.continuation_pc; pc = backTrackData.continuation_pc; op = backTrackData.continuation_op; continue; } else return false; } op = program[pc++]; } } private static boolean matchRegExp(REGlobalData gData, RECompiled re, char[] chars, int start, int end, boolean multiline) { if (re.parenCount != 0) { gData.parens = new long[re.parenCount]; } else { gData.parens = null; } gData.backTrackStackTop = null; gData.stateStackTop = null; gData.multiline = multiline; gData.regexp = re; gData.lastParen = 0; int anchorCh = gData.regexp.anchorCh; // // have to include the position beyond the last character // in order to detect end-of-input/line condition // for (int i = start; i <= end; ++i) { // // If the first node is a literal match, step the index into // the string until that match is made, or fail if it can't be // found at all. // if (anchorCh >= 0) { for (;;) { if (i == end) { return false; } char matchCh = chars[i]; if (matchCh == anchorCh || ((gData.regexp.flags & JSREG_FOLD) != 0 && upcase(matchCh) == upcase((char)anchorCh))) { break; } ++i; } } gData.cp = i; for (int j = 0; j < re.parenCount; j++) { gData.set_parens(j, -1, 0); } boolean result = executeREBytecode(gData, chars, end); gData.backTrackStackTop = null; gData.stateStackTop = null; if (result) { gData.skipped = i - start; return true; } } return false; } /* * indexp is assumed to be an array of length 1 */ Object executeRegExp(Context cx, Scriptable scopeObj, RegExpImpl res, String str, int indexp[], int matchType) { REGlobalData gData = new REGlobalData(); int start = indexp[0]; char[] charArray = str.toCharArray(); int end = charArray.length; if (start > end) start = end; // // Call the recursive matcher to do the real work. // boolean matches = matchRegExp(gData, re, charArray, start, end, res.multiline); if (!matches) { if (matchType != PREFIX) return null; return Undefined.instance; } int index = gData.cp; int i = index; indexp[0] = i; int matchlen = i - (start + gData.skipped); int ep = index; index -= matchlen; Object result; Scriptable obj; if (matchType == TEST) { /* * Testing for a match and updating cx.regExpImpl: don't allocate * an array object, do return true. */ result = Boolean.TRUE; obj = null; } else { /* * The array returned on match has element 0 bound to the matched * string, elements 1 through re.parenCount bound to the paren * matches, an index property telling the length of the left context, * and an input property referring to the input string. */ Scriptable scope = getTopLevelScope(scopeObj); result = ScriptRuntime.newObject(cx, scope, "Array", null); obj = (Scriptable) result; String matchstr = new String(charArray, index, matchlen); obj.put(0, obj, matchstr); } if (re.parenCount == 0) { res.parens = null; res.lastParen = SubString.emptySubString; } else { SubString parsub = null; int num; res.parens = new SubString[re.parenCount]; for (num = 0; num < re.parenCount; num++) { int cap_index = gData.parens_index(num); String parstr; if (cap_index != -1) { int cap_length = gData.parens_length(num); parsub = new SubString(charArray, cap_index, cap_length); res.parens[num] = parsub; if (matchType == TEST) continue; parstr = parsub.toString(); obj.put(num+1, obj, parstr); } else { if (matchType != TEST) obj.put(num+1, obj, Undefined.instance); } } res.lastParen = parsub; } if (! (matchType == TEST)) { /* * Define the index and input properties last for better for/in loop * order (so they come after the elements). */ obj.put("index", obj, new Integer(start + gData.skipped)); obj.put("input", obj, str); } if (res.lastMatch == null) { res.lastMatch = new SubString(); res.leftContext = new SubString(); res.rightContext = new SubString(); } res.lastMatch.charArray = charArray; res.lastMatch.index = index; res.lastMatch.length = matchlen; res.leftContext.charArray = charArray; if (cx.getLanguageVersion() == Context.VERSION_1_2) { /* * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used * in scalar contexts, and unintentionally for the string.match "list" * psuedo-context. On "hi there bye", the following would result: * * Language while(/ /g){print("$`");} s/ /$`/g * perl4.036 "hi", "there" "hihitherehi therebye" * perl5 "hi", "hi there" "hihitherehi therebye" * js1.2 "hi", "there" "hihitheretherebye" * * Insofar as JS1.2 always defined $` as "left context from the last * match" for global regexps, it was more consistent than perl4. */ res.leftContext.index = start; res.leftContext.length = gData.skipped; } else { /* * For JS1.3 and ECMAv2, emulate Perl5 exactly: * * js1.3 "hi", "hi there" "hihitherehi therebye" */ res.leftContext.index = 0; res.leftContext.length = start + gData.skipped; } res.rightContext.charArray = charArray; res.rightContext.index = ep; res.rightContext.length = end - ep; return result; } int getFlags() { return re.flags; } private static void reportWarning(Context cx, String messageId, String arg) { if (cx.hasFeature(Context.FEATURE_STRICT_MODE)) { String msg = ScriptRuntime.getMessage1(messageId, arg); Context.reportWarning(msg); } } private static void reportError(String messageId, String arg) { String msg = ScriptRuntime.getMessage1(messageId, arg); throw ScriptRuntime.constructError("SyntaxError", msg); } // #string_id_map# private static final int Id_lastIndex = 1, Id_source = 2, Id_global = 3, Id_ignoreCase = 4, Id_multiline = 5, MAX_INSTANCE_ID = 5; @Override protected int getMaxInstanceId() { return MAX_INSTANCE_ID; } @Override protected int findInstanceIdInfo(String s) { int id; // #generated# Last update: 2007-05-09 08:16:24 EDT L0: { id = 0; String X = null; int c; int s_length = s.length(); if (s_length==6) { c=s.charAt(0); if (c=='g') { X="global";id=Id_global; } else if (c=='s') { X="source";id=Id_source; } } else if (s_length==9) { c=s.charAt(0); if (c=='l') { X="lastIndex";id=Id_lastIndex; } else if (c=='m') { X="multiline";id=Id_multiline; } } else if (s_length==10) { X="ignoreCase";id=Id_ignoreCase; } if (X!=null && X!=s && !X.equals(s)) id = 0; break L0; } // #/generated# // #/string_id_map# if (id == 0) return super.findInstanceIdInfo(s); int attr; switch (id) { case Id_lastIndex: attr = PERMANENT | DONTENUM; break; case Id_source: case Id_global: case Id_ignoreCase: case Id_multiline: attr = PERMANENT | READONLY | DONTENUM; break; default: throw new IllegalStateException(); } return instanceIdInfo(attr, id); } @Override protected String getInstanceIdName(int id) { switch (id) { case Id_lastIndex: return "lastIndex"; case Id_source: return "source"; case Id_global: return "global"; case Id_ignoreCase: return "ignoreCase"; case Id_multiline: return "multiline"; } return super.getInstanceIdName(id); } @Override protected Object getInstanceIdValue(int id) { switch (id) { case Id_lastIndex: return ScriptRuntime.wrapNumber(lastIndex); case Id_source: return new String(re.source); case Id_global: return ScriptRuntime.wrapBoolean((re.flags & JSREG_GLOB) != 0); case Id_ignoreCase: return ScriptRuntime.wrapBoolean((re.flags & JSREG_FOLD) != 0); case Id_multiline: return ScriptRuntime.wrapBoolean((re.flags & JSREG_MULTILINE) != 0); } return super.getInstanceIdValue(id); } @Override protected void setInstanceIdValue(int id, Object value) { if (id == Id_lastIndex) { lastIndex = ScriptRuntime.toNumber(value); return; } super.setInstanceIdValue(id, value); } @Override protected void initPrototypeId(int id) { String s; int arity; switch (id) { case Id_compile: arity=1; s="compile"; break; case Id_toString: arity=0; s="toString"; break; case Id_toSource: arity=0; s="toSource"; break; case Id_exec: arity=1; s="exec"; break; case Id_test: arity=1; s="test"; break; case Id_prefix: arity=1; s="prefix"; break; default: throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(REGEXP_TAG, id, s, arity); } @Override public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(REGEXP_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); switch (id) { case Id_compile: return realThis(thisObj, f).compile(cx, scope, args); case Id_toString: case Id_toSource: return realThis(thisObj, f).toString(); case Id_exec: return realThis(thisObj, f).execSub(cx, scope, args, MATCH); case Id_test: { Object x = realThis(thisObj, f).execSub(cx, scope, args, TEST); return Boolean.TRUE.equals(x) ? Boolean.TRUE : Boolean.FALSE; } case Id_prefix: return realThis(thisObj, f).execSub(cx, scope, args, PREFIX); } throw new IllegalArgumentException(String.valueOf(id)); } private static NativeRegExp realThis(Scriptable thisObj, IdFunctionObject f) { if (!(thisObj instanceof NativeRegExp)) throw incompatibleCallError(f); return (NativeRegExp)thisObj; } // #string_id_map# @Override protected int findPrototypeId(String s) { int id; // #generated# Last update: 2007-05-09 08:16:24 EDT L0: { id = 0; String X = null; int c; L: switch (s.length()) { case 4: c=s.charAt(0); if (c=='e') { X="exec";id=Id_exec; } else if (c=='t') { X="test";id=Id_test; } break L; case 6: X="prefix";id=Id_prefix; break L; case 7: X="compile";id=Id_compile; break L; case 8: c=s.charAt(3); if (c=='o') { X="toSource";id=Id_toSource; } else if (c=='t') { X="toString";id=Id_toString; } break L; } if (X!=null && X!=s && !X.equals(s)) id = 0; break L0; } // #/generated# return id; } private static final int Id_compile = 1, Id_toString = 2, Id_toSource = 3, Id_exec = 4, Id_test = 5, Id_prefix = 6, MAX_PROTOTYPE_ID = 6; // #/string_id_map# private RECompiled re; double lastIndex; /* index after last match, for //g iterator */ } // class NativeRegExp class RECompiled implements Serializable { static final long serialVersionUID = -6144956577595844213L; char []source; /* locked source string, sans // */ int parenCount; /* number of parenthesized submatches */ int flags; /* flags */ byte[] program; /* regular expression bytecode */ int classCount; /* count [...] bitmaps */ RECharSet[] classList; /* list of [...] bitmaps */ int anchorCh = -1; /* if >= 0, then re starts with this literal char */ } class RENode { RENode(byte op) { this.op = op; } byte op; /* r.e. op bytecode */ RENode next; /* next in concatenation order */ RENode kid; /* first operand */ RENode kid2; /* second operand */ int num; /* could be a number */ int parenIndex; /* or a parenthesis index */ /* or a range */ int min; int max; int parenCount; boolean greedy; /* or a character class */ int startIndex; int kidlen; /* length of string at kid, in chars */ int bmsize; /* bitmap size, based on max char code */ int index; /* index into class list */ /* or a literal sequence */ char chr; /* of one character */ int length; /* or many (via the index) */ int flatIndex; /* which is -1 if not sourced */ } class CompilerState { CompilerState(Context cx, char[] source, int length, int flags) { this.cx = cx; this.cpbegin = source; this.cp = 0; this.cpend = length; this.flags = flags; this.parenCount = 0; this.classCount = 0; this.progLength = 0; } Context cx; char cpbegin[]; int cpend; int cp; int flags; int parenCount; int parenNesting; int classCount; /* number of [] encountered */ int progLength; /* estimated bytecode length */ RENode result; } class REProgState { REProgState(REProgState previous, int min, int max, int index, REBackTrackData backTrack, int continuation_pc, int continuation_op) { this.previous = previous; this.min = min; this.max = max; this.index = index; this.continuation_op = continuation_op; this.continuation_pc = continuation_pc; this.backTrack = backTrack; } REProgState previous; // previous state in stack int min; /* current quantifier min */ int max; /* current quantifier max */ int index; /* progress in text */ int continuation_op; int continuation_pc; REBackTrackData backTrack; // used by ASSERT_ to recover state } class REBackTrackData { REBackTrackData(REGlobalData gData, int op, int pc) { previous = gData.backTrackStackTop; continuation_op = op; continuation_pc = pc; lastParen = gData.lastParen; if (gData.parens != null) { parens = gData.parens.clone(); } cp = gData.cp; stateStackTop = gData.stateStackTop; } REBackTrackData previous; int continuation_op; /* where to backtrack to */ int continuation_pc; int lastParen; long[] parens; /* parenthesis captures */ int cp; /* char buffer index */ REProgState stateStackTop; /* state of op that backtracked */ } class REGlobalData { boolean multiline; RECompiled regexp; /* the RE in execution */ int lastParen; /* highest paren set so far */ int skipped; /* chars skipped anchoring this r.e. */ int cp; /* char buffer index */ long[] parens; /* parens captures */ REProgState stateStackTop; /* stack of state of current ancestors */ REBackTrackData backTrackStackTop; /* last matched-so-far position */ /** * Get start of parenthesis capture contents, -1 for empty. */ int parens_index(int i) { return (int)(parens[i]); } /** * Get length of parenthesis capture contents. */ int parens_length(int i) { return (int)(parens[i] >>> 32); } void set_parens(int i, int index, int length) { parens[i] = (index & 0xffffffffL) | ((long)length << 32); } } /* * This struct holds a bitmap representation of a class from a regexp. * There's a list of these referenced by the classList field in the NativeRegExp * struct below. The initial state has startIndex set to the offset in the * original regexp source of the beginning of the class contents. The first * use of the class converts the source representation into a bitmap. * */ final class RECharSet implements Serializable { static final long serialVersionUID = 7931787979395898394L; RECharSet(int length, int startIndex, int strlength) { this.length = length; this.startIndex = startIndex; this.strlength = strlength; } int length; int startIndex; int strlength; volatile transient boolean converted; volatile transient boolean sense; volatile transient byte[] bits; } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeJavaTopPackage.java0000644000175000017500000001544711753547210026465 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Frank Mitchell * Mike Shaver * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * This class reflects Java packages into the JavaScript environment. We * lazily reflect classes and subpackages, and use a caching/sharing * system to ensure that members reflected into one JavaPackage appear * in all other references to the same package (as with Packages.java.lang * and java.lang). * * @author Mike Shaver * @see NativeJavaArray * @see NativeJavaObject * @see NativeJavaClass */ public class NativeJavaTopPackage extends NativeJavaPackage implements Function, IdFunctionCall { static final long serialVersionUID = -1455787259477709999L; // we know these are packages so we can skip the class check // note that this is ok even if the package isn't present. private static final String[][] commonPackages = { {"java", "lang", "reflect"}, {"java", "io"}, {"java", "math"}, {"java", "net"}, {"java", "util", "zip"}, {"java", "text", "resources"}, {"java", "applet"}, {"javax", "swing"} }; NativeJavaTopPackage(ClassLoader loader) { super(true, "", loader); } public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { return construct(cx, scope, args); } public Scriptable construct(Context cx, Scriptable scope, Object[] args) { ClassLoader loader = null; if (args.length != 0) { Object arg = args[0]; if (arg instanceof Wrapper) { arg = ((Wrapper)arg).unwrap(); } if (arg instanceof ClassLoader) { loader = (ClassLoader)arg; } } if (loader == null) { Context.reportRuntimeError0("msg.not.classloader"); return null; } return new NativeJavaPackage(true, "", loader); } public static void init(Context cx, Scriptable scope, boolean sealed) { ClassLoader loader = cx.getApplicationClassLoader(); final NativeJavaTopPackage top = new NativeJavaTopPackage(loader); top.setPrototype(getObjectPrototype(scope)); top.setParentScope(scope); for (int i = 0; i != commonPackages.length; i++) { NativeJavaPackage parent = top; for (int j = 0; j != commonPackages[i].length; j++) { parent = parent.forcePackage(commonPackages[i][j], scope); } } // getClass implementation IdFunctionObject getClass = new IdFunctionObject(top, FTAG, Id_getClass, "getClass", 1, scope); // We want to get a real alias, and not a distinct JavaPackage // with the same packageName, so that we share classes and top // that are underneath. String[] topNames = { "java", "javax", "org", "com", "edu", "net" }; NativeJavaPackage[] topPackages = new NativeJavaPackage[topNames.length]; for (int i=0; i < topNames.length; i++) { topPackages[i] = (NativeJavaPackage)top.get(topNames[i], top); } // It's safe to downcast here since initStandardObjects takes // a ScriptableObject. ScriptableObject global = (ScriptableObject) scope; if (sealed) { getClass.sealObject(); } getClass.exportAsScopeProperty(); global.defineProperty("Packages", top, ScriptableObject.DONTENUM); for (int i=0; i < topNames.length; i++) { global.defineProperty(topNames[i], topPackages[i], ScriptableObject.DONTENUM); } } public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (f.hasTag(FTAG)) { if (f.methodId() == Id_getClass) { return js_getClass(cx, scope, args); } } throw f.unknown(); } private Scriptable js_getClass(Context cx, Scriptable scope, Object[] args) { if (args.length > 0 && args[0] instanceof Wrapper) { Scriptable result = this; Class cl = ((Wrapper) args[0]).unwrap().getClass(); // Evaluate the class name by getting successive properties of // the string to find the appropriate NativeJavaClass object String name = cl.getName(); int offset = 0; for (;;) { int index = name.indexOf('.', offset); String propName = index == -1 ? name.substring(offset) : name.substring(offset, index); Object prop = result.get(propName, result); if (!(prop instanceof Scriptable)) break; // fall through to error result = (Scriptable) prop; if (index == -1) return result; offset = index+1; } } throw Context.reportRuntimeError0("msg.not.java.obj"); } private static final Object FTAG = "JavaTopPackage"; private static final int Id_getClass = 1; } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeBoolean.java0000644000175000017500000001314311753547210025213 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * Mike McCabe * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * This class implements the Boolean native object. * See ECMA 15.6. * @author Norris Boyd */ final class NativeBoolean extends IdScriptableObject { static final long serialVersionUID = -3716996899943880933L; private static final Object BOOLEAN_TAG = "Boolean"; static void init(Scriptable scope, boolean sealed) { NativeBoolean obj = new NativeBoolean(false); obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); } private NativeBoolean(boolean b) { booleanValue = b; } @Override public String getClassName() { return "Boolean"; } @Override public Object getDefaultValue(Class typeHint) { // This is actually non-ECMA, but will be proposed // as a change in round 2. if (typeHint == ScriptRuntime.BooleanClass) return ScriptRuntime.wrapBoolean(booleanValue); return super.getDefaultValue(typeHint); } @Override protected void initPrototypeId(int id) { String s; int arity; switch (id) { case Id_constructor: arity=1; s="constructor"; break; case Id_toString: arity=0; s="toString"; break; case Id_toSource: arity=0; s="toSource"; break; case Id_valueOf: arity=0; s="valueOf"; break; default: throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(BOOLEAN_TAG, id, s, arity); } @Override public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(BOOLEAN_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); if (id == Id_constructor) { boolean b; if (args.length == 0) { b = false; } else { b = args[0] instanceof ScriptableObject && ((ScriptableObject) args[0]).avoidObjectDetection() ? true : ScriptRuntime.toBoolean(args[0]); } if (thisObj == null) { // new Boolean(val) creates a new boolean object. return new NativeBoolean(b); } // Boolean(val) converts val to a boolean. return ScriptRuntime.wrapBoolean(b); } // The rest of Boolean.prototype methods require thisObj to be Boolean if (!(thisObj instanceof NativeBoolean)) throw incompatibleCallError(f); boolean value = ((NativeBoolean)thisObj).booleanValue; switch (id) { case Id_toString: return value ? "true" : "false"; case Id_toSource: return value ? "(new Boolean(true))" : "(new Boolean(false))"; case Id_valueOf: return ScriptRuntime.wrapBoolean(value); } throw new IllegalArgumentException(String.valueOf(id)); } // #string_id_map# @Override protected int findPrototypeId(String s) { int id; // #generated# Last update: 2007-05-09 08:15:31 EDT L0: { id = 0; String X = null; int c; int s_length = s.length(); if (s_length==7) { X="valueOf";id=Id_valueOf; } else if (s_length==8) { c=s.charAt(3); if (c=='o') { X="toSource";id=Id_toSource; } else if (c=='t') { X="toString";id=Id_toString; } } else if (s_length==11) { X="constructor";id=Id_constructor; } if (X!=null && X!=s && !X.equals(s)) id = 0; break L0; } // #/generated# return id; } private static final int Id_constructor = 1, Id_toString = 2, Id_toSource = 3, Id_valueOf = 4, MAX_PROTOTYPE_ID = 4; // #/string_id_map# private boolean booleanValue; } yui-compressor-2.4.7/src/org/mozilla/javascript/VMBridge.java0000644000175000017500000001576711753547210024142 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; import java.lang.reflect.Method; import java.lang.reflect.Member; import java.util.Iterator; public abstract class VMBridge { static final VMBridge instance = makeInstance(); private static VMBridge makeInstance() { String[] classNames = { "org.mozilla.javascript.VMBridge_custom", "org.mozilla.javascript.jdk15.VMBridge_jdk15", "org.mozilla.javascript.jdk13.VMBridge_jdk13", "org.mozilla.javascript.jdk11.VMBridge_jdk11", }; for (int i = 0; i != classNames.length; ++i) { String className = classNames[i]; Class cl = Kit.classOrNull(className); if (cl != null) { VMBridge bridge = (VMBridge)Kit.newInstanceOrNull(cl); if (bridge != null) { return bridge; } } } throw new IllegalStateException("Failed to create VMBridge instance"); } /** * Return a helper object to optimize {@link Context} access. *

* The runtime will pass the resulting helper object to the subsequent * calls to {@link #getContext(Object contextHelper)} and * {@link #setContext(Object contextHelper, Context cx)} methods. * In this way the implementation can use the helper to cache * information about current thread to make {@link Context} access faster. */ protected abstract Object getThreadContextHelper(); /** * Get {@link Context} instance associated with the current thread * or null if none. * * @param contextHelper The result of {@link #getThreadContextHelper()} * called from the current thread. */ protected abstract Context getContext(Object contextHelper); /** * Associate {@link Context} instance with the current thread or remove * the current association if cx is null. * * @param contextHelper The result of {@link #getThreadContextHelper()} * called from the current thread. */ protected abstract void setContext(Object contextHelper, Context cx); /** * Return the ClassLoader instance associated with the current thread. */ protected abstract ClassLoader getCurrentThreadClassLoader(); /** * In many JVMSs, public methods in private * classes are not accessible by default (Sun Bug #4071593). * VMBridge instance should try to workaround that via, for example, * calling method.setAccessible(true) when it is available. * The implementation is responsible to catch all possible exceptions * like SecurityException if the workaround is not available. * * @return true if it was possible to make method accessible * or false otherwise. */ protected abstract boolean tryToMakeAccessible(Object accessibleObject); /** * Create helper object to create later proxies implementing the specified * interfaces later. Under JDK 1.3 the implementation can look like: *

     * return java.lang.reflect.Proxy.getProxyClass(..., interfaces).
     *     getConstructor(new Class[] {
     *         java.lang.reflect.InvocationHandler.class });
     * 
* * @param interfaces Array with one or more interface class objects. */ protected Object getInterfaceProxyHelper(ContextFactory cf, Class[] interfaces) { throw Context.reportRuntimeError( "VMBridge.getInterfaceProxyHelper is not supported"); } /** * Create proxy object for {@link InterfaceAdapter}. The proxy should call * {@link InterfaceAdapter#invoke(ContextFactory cf, * Object target, * Scriptable topScope, * Method method, * Object[] args)} * as implementation of interface methods associated with * proxyHelper. * * @param proxyHelper The result of the previous call to * {@link #getInterfaceProxyHelper(ContextFactory, Class[])}. */ protected Object newInterfaceProxy(Object proxyHelper, ContextFactory cf, InterfaceAdapter adapter, Object target, Scriptable topScope) { throw Context.reportRuntimeError( "VMBridge.newInterfaceProxy is not supported"); } /** * Returns whether or not a given member (method or constructor) * has variable arguments. * Variable argument methods have only been supported in Java since * JDK 1.5. */ protected abstract boolean isVarArgs(Member member); /** * If "obj" is a java.util.Iterator or a java.lang.Iterable, return a * wrapping as a JavaScript Iterator. Otherwise, return null. * This method is in VMBridge since Iterable is a JDK 1.5 addition. */ public Iterator getJavaIterator(Context cx, Scriptable scope, Object obj) { if (obj instanceof Wrapper) { Object unwrapped = ((Wrapper) obj).unwrap(); Iterator iterator = null; if (unwrapped instanceof Iterator) iterator = (Iterator) unwrapped; return iterator; } return null; } } yui-compressor-2.4.7/src/org/mozilla/javascript/ContinuationPending.java0000644000175000017500000000754011753547210026450 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * Exception thrown by * {@link org.mozilla.javascript.Context#executeScriptWithContinuations(Script, Scriptable)} * and {@link org.mozilla.javascript.Context#callFunctionWithContinuations(Callable, Scriptable, Object[])} * when execution encounters a continuation captured by * {@link org.mozilla.javascript.Context#captureContinuation()}. * Exception will contain the captured state needed to restart the continuation * with {@link org.mozilla.javascript.Context#resumeContinuation(Object, Scriptable, Object)}. * @author Norris Boyd */ public class ContinuationPending extends RuntimeException { private static final long serialVersionUID = 4956008116771118856L; private NativeContinuation continuationState; private Object applicationState; /** * Construct a ContinuationPending exception. Internal call only; * users of the API should get continuations created on their behalf by * calling {@link org.mozilla.javascript.Context#executeScriptWithContinuations(Script, Scriptable)} * and {@link org.mozilla.javascript.Context#callFunctionWithContinuations(Callable, Scriptable, Object[])} * @param continuationState Internal Continuation object */ ContinuationPending(NativeContinuation continuationState) { this.continuationState = continuationState; } /** * Get continuation object. The only * use for this object is to be passed to * {@link org.mozilla.javascript.Context#resumeContinuation(Object, Scriptable, Object)}. * @return continuation object */ public Object getContinuation() { return continuationState; } /** * @return internal continuation state */ NativeContinuation getContinuationState() { return continuationState; } /** * Store an arbitrary object that applications can use to associate * their state with the continuation. * @param applicationState arbitrary application state */ public void setApplicationState(Object applicationState) { this.applicationState = applicationState; } /** * @return arbitrary application state */ public Object getApplicationState() { return applicationState; } } yui-compressor-2.4.7/src/org/mozilla/javascript/RegExpProxy.java0000644000175000017500000000514411753547210024723 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Roger Lawrence * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * A proxy for the regexp package, so that the regexp package can be * loaded optionally. * * @author Norris Boyd */ public interface RegExpProxy { // Types of regexp actions public static final int RA_MATCH = 1; public static final int RA_REPLACE = 2; public static final int RA_SEARCH = 3; public boolean isRegExp(Scriptable obj); public Object compileRegExp(Context cx, String source, String flags); public Scriptable wrapRegExp(Context cx, Scriptable scope, Object compiled); public Object action(Context cx, Scriptable scope, Scriptable thisObj, Object[] args, int actionType); public int find_split(Context cx, Scriptable scope, String target, String separator, Scriptable re, int[] ip, int[] matchlen, boolean[] matched, String[][] parensp); } yui-compressor-2.4.7/src/org/mozilla/javascript/Synchronizer.java0000644000175000017500000000562711753547210025172 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Delegator.java, released * Sep 27, 2000. * * The Initial Developer of the Original Code is * Matthias Radestock. . * Portions created by the Initial Developer are Copyright (C) 2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * This class provides support for implementing Java-style synchronized * methods in Javascript. * * Synchronized functions are created from ordinary Javascript * functions by the Synchronizer constructor, e.g. * new Packages.org.mozilla.javascript.Synchronizer(fun). * The resulting object is a function that establishes an exclusive * lock on the this object of its invocation. * * The Rhino shell provides a short-cut for the creation of * synchronized methods: sync(fun) has the same effect as * calling the above constructor. * * @see org.mozilla.javascript.Delegator * @author Matthias Radestock */ public class Synchronizer extends Delegator { /** * Create a new synchronized function from an existing one. * * @param obj the existing function */ public Synchronizer(Scriptable obj) { super(obj); } /** * @see org.mozilla.javascript.Function#call */ @Override public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { synchronized(thisObj instanceof Wrapper ? ((Wrapper)thisObj).unwrap() : thisObj) { return ((Function)obj).call(cx,scope,thisObj,args); } } } yui-compressor-2.4.7/src/org/mozilla/javascript/InterpreterData.java0000644000175000017500000001140311753547210025557 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Bob Jervis * Roger Lawrence * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.Serializable; import org.mozilla.javascript.debug.DebuggableScript; final class InterpreterData implements Serializable, DebuggableScript { static final long serialVersionUID = 5067677351589230234L; static final int INITIAL_MAX_ICODE_LENGTH = 1024; static final int INITIAL_STRINGTABLE_SIZE = 64; static final int INITIAL_NUMBERTABLE_SIZE = 64; InterpreterData(int languageVersion, String sourceFile, String encodedSource) { this.languageVersion = languageVersion; this.itsSourceFile = sourceFile; this.encodedSource = encodedSource; init(); } InterpreterData(InterpreterData parent) { this.parentData = parent; this.languageVersion = parent.languageVersion; this.itsSourceFile = parent.itsSourceFile; this.encodedSource = parent.encodedSource; init(); } private void init() { itsICode = new byte[INITIAL_MAX_ICODE_LENGTH]; itsStringTable = new String[INITIAL_STRINGTABLE_SIZE]; } String itsName; String itsSourceFile; boolean itsNeedsActivation; int itsFunctionType; String[] itsStringTable; double[] itsDoubleTable; InterpreterData[] itsNestedFunctions; Object[] itsRegExpLiterals; byte[] itsICode; int[] itsExceptionTable; int itsMaxVars; int itsMaxLocals; int itsMaxStack; int itsMaxFrameArray; // see comments in NativeFuncion for definition of argNames and argCount String[] argNames; boolean[] argIsConst; int argCount; int itsMaxCalleeArgs; String encodedSource; int encodedSourceStart; int encodedSourceEnd; int languageVersion; boolean useDynamicScope; boolean topLevel; Object[] literalIds; UintMap longJumps; int firstLinePC = -1; // PC for the first LINE icode InterpreterData parentData; boolean evalScriptFlag; // true if script corresponds to eval() code public boolean isTopLevel() { return topLevel; } public boolean isFunction() { return itsFunctionType != 0; } public String getFunctionName() { return itsName; } public int getParamCount() { return argCount; } public int getParamAndVarCount() { return argNames.length; } public String getParamOrVarName(int index) { return argNames[index]; } public boolean getParamOrVarConst(int index) { return argIsConst[index]; } public String getSourceName() { return itsSourceFile; } public boolean isGeneratedScript() { return ScriptRuntime.isGeneratedScript(itsSourceFile); } public int[] getLineNumbers() { return Interpreter.getLineNumbers(this); } public int getFunctionCount() { return (itsNestedFunctions == null) ? 0 : itsNestedFunctions.length; } public DebuggableScript getFunction(int index) { return itsNestedFunctions[index]; } public DebuggableScript getParent() { return parentData; } } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeJavaPackage.java0000644000175000017500000001607411753547210025777 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Frank Mitchell * Mike Shaver * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.util.HashSet; import java.util.Set; /** * This class reflects Java packages into the JavaScript environment. We * lazily reflect classes and subpackages, and use a caching/sharing * system to ensure that members reflected into one JavaPackage appear * in all other references to the same package (as with Packages.java.lang * and java.lang). * * @author Mike Shaver * @see NativeJavaArray * @see NativeJavaObject * @see NativeJavaClass */ public class NativeJavaPackage extends ScriptableObject { static final long serialVersionUID = 7445054382212031523L; NativeJavaPackage(boolean internalUsage, String packageName, ClassLoader classLoader) { this.packageName = packageName; this.classLoader = classLoader; } /** * @deprecated NativeJavaPackage is an internal class, do not use * it directly. */ public NativeJavaPackage(String packageName, ClassLoader classLoader) { this(false, packageName, classLoader); } /** * @deprecated NativeJavaPackage is an internal class, do not use * it directly. */ public NativeJavaPackage(String packageName) { this(false, packageName, Context.getCurrentContext().getApplicationClassLoader()); } @Override public String getClassName() { return "JavaPackage"; } @Override public boolean has(String id, Scriptable start) { return true; } @Override public boolean has(int index, Scriptable start) { return false; } @Override public void put(String id, Scriptable start, Object value) { // Can't add properties to Java packages. Sorry. } @Override public void put(int index, Scriptable start, Object value) { throw Context.reportRuntimeError0("msg.pkg.int"); } @Override public Object get(String id, Scriptable start) { return getPkgProperty(id, start, true); } @Override public Object get(int index, Scriptable start) { return NOT_FOUND; } // set up a name which is known to be a package so we don't // need to look for a class by that name NativeJavaPackage forcePackage(String name, Scriptable scope) { Object cached = super.get(name, this); if (cached != null && cached instanceof NativeJavaPackage) { return (NativeJavaPackage) cached; } else { String newPackage = packageName.length() == 0 ? name : packageName + "." + name; NativeJavaPackage pkg = new NativeJavaPackage(true, newPackage, classLoader); ScriptRuntime.setObjectProtoAndParent(pkg, scope); super.put(name, this, pkg); return pkg; } } synchronized Object getPkgProperty(String name, Scriptable start, boolean createPkg) { Object cached = super.get(name, start); if (cached != NOT_FOUND) return cached; if (negativeCache != null && negativeCache.contains(name)) { // Performance optimization: see bug 421071 return null; } String className = (packageName.length() == 0) ? name : packageName + '.' + name; Context cx = Context.getContext(); ClassShutter shutter = cx.getClassShutter(); Scriptable newValue = null; if (shutter == null || shutter.visibleToScripts(className)) { Class cl = null; if (classLoader != null) { cl = Kit.classOrNull(classLoader, className); } else { cl = Kit.classOrNull(className); } if (cl != null) { newValue = new NativeJavaClass(getTopLevelScope(this), cl); newValue.setPrototype(getPrototype()); } } if (newValue == null) { if (createPkg) { NativeJavaPackage pkg; pkg = new NativeJavaPackage(true, className, classLoader); ScriptRuntime.setObjectProtoAndParent(pkg, getParentScope()); newValue = pkg; } else { // add to negative cache if (negativeCache == null) negativeCache = new HashSet(); negativeCache.add(name); } } if (newValue != null) { // Make it available for fast lookup and sharing of // lazily-reflected constructors and static members. super.put(name, start, newValue); } return newValue; } @Override public Object getDefaultValue(Class ignored) { return toString(); } @Override public String toString() { return "[JavaPackage " + packageName + "]"; } @Override public boolean equals(Object obj) { if(obj instanceof NativeJavaPackage) { NativeJavaPackage njp = (NativeJavaPackage)obj; return packageName.equals(njp.packageName) && classLoader == njp.classLoader; } return false; } @Override public int hashCode() { return packageName.hashCode() ^ (classLoader == null ? 0 : classLoader.hashCode()); } private String packageName; private ClassLoader classLoader; private Set negativeCache = null; } yui-compressor-2.4.7/src/org/mozilla/javascript/Context.java0000644000175000017500000027551111753547210024122 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Bob Jervis * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.CharArrayWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.Reader; import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; import java.util.Locale; import org.mozilla.javascript.debug.DebuggableScript; import org.mozilla.javascript.debug.Debugger; import org.mozilla.javascript.xml.XMLLib; /** * This class represents the runtime context of an executing script. * * Before executing a script, an instance of Context must be created * and associated with the thread that will be executing the script. * The Context will be used to store information about the executing * of the script such as the call stack. Contexts are associated with * the current thread using the {@link #call(ContextAction)} * or {@link #enter()} methods.

* * Different forms of script execution are supported. Scripts may be * evaluated from the source directly, or first compiled and then later * executed. Interactive execution is also supported.

* * Some aspects of script execution, such as type conversions and * object creation, may be accessed directly through methods of * Context. * * @see Scriptable * @author Norris Boyd * @author Brendan Eich */ public class Context { /** * Language versions. * * All integral values are reserved for future version numbers. */ /** * The unknown version. */ public static final int VERSION_UNKNOWN = -1; /** * The default version. */ public static final int VERSION_DEFAULT = 0; /** * JavaScript 1.0 */ public static final int VERSION_1_0 = 100; /** * JavaScript 1.1 */ public static final int VERSION_1_1 = 110; /** * JavaScript 1.2 */ public static final int VERSION_1_2 = 120; /** * JavaScript 1.3 */ public static final int VERSION_1_3 = 130; /** * JavaScript 1.4 */ public static final int VERSION_1_4 = 140; /** * JavaScript 1.5 */ public static final int VERSION_1_5 = 150; /** * JavaScript 1.6 */ public static final int VERSION_1_6 = 160; /** * JavaScript 1.7 */ public static final int VERSION_1_7 = 170; /** * Controls behaviour of Date.prototype.getYear(). * If hasFeature(FEATURE_NON_ECMA_GET_YEAR) returns true, * Date.prototype.getYear subtructs 1900 only if 1900 <= date < 2000. * The default behavior of {@link #hasFeature(int)} is always to subtruct * 1900 as rquired by ECMAScript B.2.4. */ public static final int FEATURE_NON_ECMA_GET_YEAR = 1; /** * Control if member expression as function name extension is available. * If hasFeature(FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME) returns * true, allow function memberExpression(args) { body } to be * syntax sugar for memberExpression = function(args) { body }, * when memberExpression is not a simple identifier. * See ECMAScript-262, section 11.2 for definition of memberExpression. * By default {@link #hasFeature(int)} returns false. */ public static final int FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME = 2; /** * Control if reserved keywords are treated as identifiers. * If hasFeature(RESERVED_KEYWORD_AS_IDENTIFIER) returns true, * treat future reserved keyword (see Ecma-262, section 7.5.3) as ordinary * identifiers but warn about this usage. * * By default {@link #hasFeature(int)} returns false. */ public static final int FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER = 3; /** * Control if toString() should returns the same result * as toSource() when applied to objects and arrays. * If hasFeature(FEATURE_TO_STRING_AS_SOURCE) returns true, * calling toString() on JS objects gives the same result as * calling toSource(). That is it returns JS source with code * to create an object with all enumeratable fields of the original object * instead of printing [object result of * {@link Scriptable#getClassName()}]. *

* By default {@link #hasFeature(int)} returns true only if * the current JS version is set to {@link #VERSION_1_2}. */ public static final int FEATURE_TO_STRING_AS_SOURCE = 4; /** * Control if properties __proto__ and __parent__ * are treated specially. * If hasFeature(FEATURE_PARENT_PROTO_PROPERTIES) returns true, * treat __parent__ and __proto__ as special properties. *

* The properties allow to query and set scope and prototype chains for the * objects. The special meaning of the properties is available * only when they are used as the right hand side of the dot operator. * For example, while x.__proto__ = y changes the prototype * chain of the object x to point to y, * x["__proto__"] = y simply assigns a new value to the property * __proto__ in x even when the feature is on. * * By default {@link #hasFeature(int)} returns true. */ public static final int FEATURE_PARENT_PROTO_PROPERTIES = 5; /** * @deprecated In previous releases, this name was given to * FEATURE_PARENT_PROTO_PROPERTIES. */ public static final int FEATURE_PARENT_PROTO_PROPRTIES = 5; /** * Control if support for E4X(ECMAScript for XML) extension is available. * If hasFeature(FEATURE_E4X) returns true, the XML syntax is available. *

* By default {@link #hasFeature(int)} returns true if * the current JS version is set to {@link #VERSION_DEFAULT} * or is at least {@link #VERSION_1_6}. * @since 1.6 Release 1 */ public static final int FEATURE_E4X = 6; /** * Control if dynamic scope should be used for name access. * If hasFeature(FEATURE_DYNAMIC_SCOPE) returns true, then the name lookup * during name resolution will use the top scope of the script or function * which is at the top of JS execution stack instead of the top scope of the * script or function from the current stack frame if the top scope of * the top stack frame contains the top scope of the current stack frame * on its prototype chain. *

* This is useful to define shared scope containing functions that can * be called from scripts and functions using private scopes. *

* By default {@link #hasFeature(int)} returns false. * @since 1.6 Release 1 */ public static final int FEATURE_DYNAMIC_SCOPE = 7; /** * Control if strict variable mode is enabled. * When the feature is on Rhino reports runtime errors if assignment * to a global variable that does not exist is executed. When the feature * is off such assignments create a new variable in the global scope as * required by ECMA 262. *

* By default {@link #hasFeature(int)} returns false. * @since 1.6 Release 1 */ public static final int FEATURE_STRICT_VARS = 8; /** * Control if strict eval mode is enabled. * When the feature is on Rhino reports runtime errors if non-string * argument is passed to the eval function. When the feature is off * eval simply return non-string argument as is without performing any * evaluation as required by ECMA 262. *

* By default {@link #hasFeature(int)} returns false. * @since 1.6 Release 1 */ public static final int FEATURE_STRICT_EVAL = 9; /** * When the feature is on Rhino will add a "fileName" and "lineNumber" * properties to Error objects automatically. When the feature is off, you * have to explicitly pass them as the second and third argument to the * Error constructor. Note that neither behavior is fully ECMA 262 * compliant (as 262 doesn't specify a three-arg constructor), but keeping * the feature off results in Error objects that don't have * additional non-ECMA properties when constructed using the ECMA-defined * single-arg constructor and is thus desirable if a stricter ECMA * compliance is desired, specifically adherence to the point 15.11.5. of * the standard. *

* By default {@link #hasFeature(int)} returns false. * @since 1.6 Release 6 */ public static final int FEATURE_LOCATION_INFORMATION_IN_ERROR = 10; /** * Controls whether JS 1.5 'strict mode' is enabled. * When the feature is on, Rhino reports more than a dozen different * warnings. When the feature is off, these warnings are not generated. * FEATURE_STRICT_MODE implies FEATURE_STRICT_VARS and FEATURE_STRICT_EVAL. *

* By default {@link #hasFeature(int)} returns false. * @since 1.6 Release 6 */ public static final int FEATURE_STRICT_MODE = 11; /** * Controls whether a warning should be treated as an error. * @since 1.6 Release 6 */ public static final int FEATURE_WARNING_AS_ERROR = 12; /** * Enables enhanced access to Java. * Specifically, controls whether private and protected members can be * accessed, and whether scripts can catch all Java exceptions. *

* Note that this feature should only be enabled for trusted scripts. *

* By default {@link #hasFeature(int)} returns false. * @since 1.7 Release 1 */ public static final int FEATURE_ENHANCED_JAVA_ACCESS = 13; public static final String languageVersionProperty = "language version"; public static final String errorReporterProperty = "error reporter"; /** * Convenient value to use as zero-length array of objects. */ public static final Object[] emptyArgs = ScriptRuntime.emptyArgs; /** * Creates a new Context. The context will be associated with the {@link * ContextFactory#getGlobal() global context factory}. * * Note that the Context must be associated with a thread before * it can be used to execute a script. * @deprecated this constructor is deprecated because it creates a * dependency on a static singleton context factory. Use * {@link ContextFactory#enter()} or * {@link ContextFactory#call(ContextAction)} instead. If you subclass * this class, consider using {@link #Context(ContextFactory)} constructor * instead in the subclasses' constructors. */ public Context() { this(ContextFactory.getGlobal()); } /** * Creates a new context. Provided as a preferred super constructor for * subclasses in place of the deprecated default public constructor. * @param factory the context factory associated with this context (most * likely, the one that created the context). Can not be null. The context * features are inherited from the factory, and the context will also * otherwise use its factory's services. * @throws IllegalArgumentException if factory parameter is null. */ protected Context(ContextFactory factory) { if(factory == null) { throw new IllegalArgumentException("factory == null"); } this.factory = factory; setLanguageVersion(VERSION_DEFAULT); optimizationLevel = codegenClass != null ? 0 : -1; maximumInterpreterStackDepth = Integer.MAX_VALUE; } /** * Get the current Context. * * The current Context is per-thread; this method looks up * the Context associated with the current thread.

* * @return the Context associated with the current thread, or * null if no context is associated with the current * thread. * @see ContextFactory#enterContext() * @see ContextFactory#call(ContextAction) */ public static Context getCurrentContext() { Object helper = VMBridge.instance.getThreadContextHelper(); return VMBridge.instance.getContext(helper); } /** * Same as calling {@link ContextFactory#enterContext()} on the global * ContextFactory instance. * @return a Context associated with the current thread * @see #getCurrentContext() * @see #exit() * @see #call(ContextAction) */ public static Context enter() { return enter(null); } /** * Get a Context associated with the current thread, using * the given Context if need be. *

* The same as enter() except that cx * is associated with the current thread and returned if * the current thread has no associated context and cx * is not associated with any other thread. * @param cx a Context to associate with the thread if possible * @return a Context associated with the current thread * @deprecated use {@link ContextFactory#enterContext(Context)} instead as * this method relies on usage of a static singleton "global" ContextFactory. * @see ContextFactory#enterContext(Context) * @see ContextFactory#call(ContextAction) */ public static Context enter(Context cx) { return enter(cx, ContextFactory.getGlobal()); } static final Context enter(Context cx, ContextFactory factory) { Object helper = VMBridge.instance.getThreadContextHelper(); Context old = VMBridge.instance.getContext(helper); if (old != null) { cx = old; } else { if (cx == null) { cx = factory.makeContext(); if (cx.enterCount != 0) { throw new IllegalStateException("factory.makeContext() returned Context instance already associated with some thread"); } factory.onContextCreated(cx); if (factory.isSealed() && !cx.isSealed()) { cx.seal(null); } } else { if (cx.enterCount != 0) { throw new IllegalStateException("can not use Context instance already associated with some thread"); } } VMBridge.instance.setContext(helper, cx); } ++cx.enterCount; return cx; } /** * Exit a block of code requiring a Context. * * Calling exit() will remove the association between * the current thread and a Context if the prior call to * {@link ContextFactory#enterContext()} on this thread newly associated a * Context with this thread. Once the current thread no longer has an * associated Context, it cannot be used to execute JavaScript until it is * again associated with a Context. * @see ContextFactory#enterContext() */ public static void exit() { Object helper = VMBridge.instance.getThreadContextHelper(); Context cx = VMBridge.instance.getContext(helper); if (cx == null) { throw new IllegalStateException( "Calling Context.exit without previous Context.enter"); } if (cx.enterCount < 1) Kit.codeBug(); if (--cx.enterCount == 0) { VMBridge.instance.setContext(helper, null); cx.factory.onContextReleased(cx); } } /** * Call {@link ContextAction#run(Context cx)} * using the Context instance associated with the current thread. * If no Context is associated with the thread, then * ContextFactory.getGlobal().makeContext() will be called to * construct new Context instance. The instance will be temporary * associated with the thread during call to * {@link ContextAction#run(Context)}. * @deprecated use {@link ContextFactory#call(ContextAction)} instead as * this method relies on usage of a static singleton "global" * ContextFactory. * @return The result of {@link ContextAction#run(Context)}. */ public static Object call(ContextAction action) { return call(ContextFactory.getGlobal(), action); } /** * Call {@link * Callable#call(Context cx, Scriptable scope, Scriptable thisObj, * Object[] args)} * using the Context instance associated with the current thread. * If no Context is associated with the thread, then * {@link ContextFactory#makeContext()} will be called to construct * new Context instance. The instance will be temporary associated * with the thread during call to {@link ContextAction#run(Context)}. *

* It is allowed but not advisable to use null for factory * argument in which case the global static singleton ContextFactory * instance will be used to create new context instances. * @see ContextFactory#call(ContextAction) */ public static Object call(ContextFactory factory, final Callable callable, final Scriptable scope, final Scriptable thisObj, final Object[] args) { if(factory == null) { factory = ContextFactory.getGlobal(); } return call(factory, new ContextAction() { public Object run(Context cx) { return callable.call(cx, scope, thisObj, args); } }); } /** * The method implements {@link ContextFactory#call(ContextAction)} logic. */ static Object call(ContextFactory factory, ContextAction action) { Context cx = enter(null, factory); try { return action.run(cx); } finally { exit(); } } /** * @deprecated * @see ContextFactory#addListener(ContextFactory.Listener) * @see ContextFactory#getGlobal() */ public static void addContextListener(ContextListener listener) { // Special workaround for the debugger String DBG = "org.mozilla.javascript.tools.debugger.Main"; if (DBG.equals(listener.getClass().getName())) { Class cl = listener.getClass(); Class factoryClass = Kit.classOrNull( "org.mozilla.javascript.ContextFactory"); Class[] sig = { factoryClass }; Object[] args = { ContextFactory.getGlobal() }; try { Method m = cl.getMethod("attachTo", sig); m.invoke(listener, args); } catch (Exception ex) { RuntimeException rex = new RuntimeException(); Kit.initCause(rex, ex); throw rex; } return; } ContextFactory.getGlobal().addListener(listener); } /** * @deprecated * @see ContextFactory#removeListener(ContextFactory.Listener) * @see ContextFactory#getGlobal() */ public static void removeContextListener(ContextListener listener) { ContextFactory.getGlobal().addListener(listener); } /** * Return {@link ContextFactory} instance used to create this Context. */ public final ContextFactory getFactory() { return factory; } /** * Checks if this is a sealed Context. A sealed Context instance does not * allow to modify any of its properties and will throw an exception * on any such attempt. * @see #seal(Object sealKey) */ public final boolean isSealed() { return sealed; } /** * Seal this Context object so any attempt to modify any of its properties * including calling {@link #enter()} and {@link #exit()} methods will * throw an exception. *

* If sealKey is not null, calling * {@link #unseal(Object sealKey)} with the same key unseals * the object. If sealKey is null, unsealing is no longer possible. * * @see #isSealed() * @see #unseal(Object) */ public final void seal(Object sealKey) { if (sealed) onSealedMutation(); sealed = true; this.sealKey = sealKey; } /** * Unseal previously sealed Context object. * The sealKey argument should not be null and should match * sealKey suplied with the last call to * {@link #seal(Object)} or an exception will be thrown. * * @see #isSealed() * @see #seal(Object sealKey) */ public final void unseal(Object sealKey) { if (sealKey == null) throw new IllegalArgumentException(); if (this.sealKey != sealKey) throw new IllegalArgumentException(); if (!sealed) throw new IllegalStateException(); sealed = false; this.sealKey = null; } static void onSealedMutation() { throw new IllegalStateException(); } /** * Get the current language version. *

* The language version number affects JavaScript semantics as detailed * in the overview documentation. * * @return an integer that is one of VERSION_1_0, VERSION_1_1, etc. */ public final int getLanguageVersion() { return version; } /** * Set the language version. * *

* Setting the language version will affect functions and scripts compiled * subsequently. See the overview documentation for version-specific * behavior. * * @param version the version as specified by VERSION_1_0, VERSION_1_1, etc. */ public void setLanguageVersion(int version) { if (sealed) onSealedMutation(); checkLanguageVersion(version); Object listeners = propertyListeners; if (listeners != null && version != this.version) { firePropertyChangeImpl(listeners, languageVersionProperty, new Integer(this.version), new Integer(version)); } this.version = version; } public static boolean isValidLanguageVersion(int version) { switch (version) { case VERSION_DEFAULT: case VERSION_1_0: case VERSION_1_1: case VERSION_1_2: case VERSION_1_3: case VERSION_1_4: case VERSION_1_5: case VERSION_1_6: case VERSION_1_7: return true; } return false; } public static void checkLanguageVersion(int version) { if (isValidLanguageVersion(version)) { return; } throw new IllegalArgumentException("Bad language version: "+version); } /** * Get the implementation version. * *

* The implementation version is of the form *

     *    "name langVer release relNum date"
     * 
* where name is the name of the product, langVer is * the language version, relNum is the release number, and * date is the release date for that specific * release in the form "yyyy mm dd". * * @return a string that encodes the product, language version, release * number, and date. */ public final String getImplementationVersion() { // XXX Probably it would be better to embed this directly into source // with special build preprocessing but that would require some ant // tweaking and then replacing token in resource files was simpler if (implementationVersion == null) { implementationVersion = ScriptRuntime.getMessage0("implementation.version"); } return implementationVersion; } /** * Get the current error reporter. * * @see org.mozilla.javascript.ErrorReporter */ public final ErrorReporter getErrorReporter() { if (errorReporter == null) { return DefaultErrorReporter.instance; } return errorReporter; } /** * Change the current error reporter. * * @return the previous error reporter * @see org.mozilla.javascript.ErrorReporter */ public final ErrorReporter setErrorReporter(ErrorReporter reporter) { if (sealed) onSealedMutation(); if (reporter == null) throw new IllegalArgumentException(); ErrorReporter old = getErrorReporter(); if (reporter == old) { return old; } Object listeners = propertyListeners; if (listeners != null) { firePropertyChangeImpl(listeners, errorReporterProperty, old, reporter); } this.errorReporter = reporter; return old; } /** * Get the current locale. Returns the default locale if none has * been set. * * @see java.util.Locale */ public final Locale getLocale() { if (locale == null) locale = Locale.getDefault(); return locale; } /** * Set the current locale. * * @see java.util.Locale */ public final Locale setLocale(Locale loc) { if (sealed) onSealedMutation(); Locale result = locale; locale = loc; return result; } /** * Register an object to receive notifications when a bound property * has changed * @see java.beans.PropertyChangeEvent * @see #removePropertyChangeListener(java.beans.PropertyChangeListener) * @param l the listener */ public final void addPropertyChangeListener(PropertyChangeListener l) { if (sealed) onSealedMutation(); propertyListeners = Kit.addListener(propertyListeners, l); } /** * Remove an object from the list of objects registered to receive * notification of changes to a bounded property * @see java.beans.PropertyChangeEvent * @see #addPropertyChangeListener(java.beans.PropertyChangeListener) * @param l the listener */ public final void removePropertyChangeListener(PropertyChangeListener l) { if (sealed) onSealedMutation(); propertyListeners = Kit.removeListener(propertyListeners, l); } /** * Notify any registered listeners that a bounded property has changed * @see #addPropertyChangeListener(java.beans.PropertyChangeListener) * @see #removePropertyChangeListener(java.beans.PropertyChangeListener) * @see java.beans.PropertyChangeListener * @see java.beans.PropertyChangeEvent * @param property the bound property * @param oldValue the old value * @param newValue the new value */ final void firePropertyChange(String property, Object oldValue, Object newValue) { Object listeners = propertyListeners; if (listeners != null) { firePropertyChangeImpl(listeners, property, oldValue, newValue); } } private void firePropertyChangeImpl(Object listeners, String property, Object oldValue, Object newValue) { for (int i = 0; ; ++i) { Object l = Kit.getListener(listeners, i); if (l == null) break; if (l instanceof PropertyChangeListener) { PropertyChangeListener pcl = (PropertyChangeListener)l; pcl.propertyChange(new PropertyChangeEvent( this, property, oldValue, newValue)); } } } /** * Report a warning using the error reporter for the current thread. * * @param message the warning message to report * @param sourceName a string describing the source, such as a filename * @param lineno the starting line number * @param lineSource the text of the line (may be null) * @param lineOffset the offset into lineSource where problem was detected * @see org.mozilla.javascript.ErrorReporter */ public static void reportWarning(String message, String sourceName, int lineno, String lineSource, int lineOffset) { Context cx = Context.getContext(); if (cx.hasFeature(FEATURE_WARNING_AS_ERROR)) reportError(message, sourceName, lineno, lineSource, lineOffset); else cx.getErrorReporter().warning(message, sourceName, lineno, lineSource, lineOffset); } /** * Report a warning using the error reporter for the current thread. * * @param message the warning message to report * @see org.mozilla.javascript.ErrorReporter */ public static void reportWarning(String message) { int[] linep = { 0 }; String filename = getSourcePositionFromStack(linep); Context.reportWarning(message, filename, linep[0], null, 0); } public static void reportWarning(String message, Throwable t) { int[] linep = { 0 }; String filename = getSourcePositionFromStack(linep); Writer sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); pw.println(message); t.printStackTrace(pw); pw.flush(); Context.reportWarning(sw.toString(), filename, linep[0], null, 0); } /** * Report an error using the error reporter for the current thread. * * @param message the error message to report * @param sourceName a string describing the source, such as a filename * @param lineno the starting line number * @param lineSource the text of the line (may be null) * @param lineOffset the offset into lineSource where problem was detected * @see org.mozilla.javascript.ErrorReporter */ public static void reportError(String message, String sourceName, int lineno, String lineSource, int lineOffset) { Context cx = getCurrentContext(); if (cx != null) { cx.getErrorReporter().error(message, sourceName, lineno, lineSource, lineOffset); } else { throw new EvaluatorException(message, sourceName, lineno, lineSource, lineOffset); } } /** * Report an error using the error reporter for the current thread. * * @param message the error message to report * @see org.mozilla.javascript.ErrorReporter */ public static void reportError(String message) { int[] linep = { 0 }; String filename = getSourcePositionFromStack(linep); Context.reportError(message, filename, linep[0], null, 0); } /** * Report a runtime error using the error reporter for the current thread. * * @param message the error message to report * @param sourceName a string describing the source, such as a filename * @param lineno the starting line number * @param lineSource the text of the line (may be null) * @param lineOffset the offset into lineSource where problem was detected * @return a runtime exception that will be thrown to terminate the * execution of the script * @see org.mozilla.javascript.ErrorReporter */ public static EvaluatorException reportRuntimeError(String message, String sourceName, int lineno, String lineSource, int lineOffset) { Context cx = getCurrentContext(); if (cx != null) { return cx.getErrorReporter(). runtimeError(message, sourceName, lineno, lineSource, lineOffset); } else { throw new EvaluatorException(message, sourceName, lineno, lineSource, lineOffset); } } static EvaluatorException reportRuntimeError0(String messageId) { String msg = ScriptRuntime.getMessage0(messageId); return reportRuntimeError(msg); } static EvaluatorException reportRuntimeError1(String messageId, Object arg1) { String msg = ScriptRuntime.getMessage1(messageId, arg1); return reportRuntimeError(msg); } static EvaluatorException reportRuntimeError2(String messageId, Object arg1, Object arg2) { String msg = ScriptRuntime.getMessage2(messageId, arg1, arg2); return reportRuntimeError(msg); } static EvaluatorException reportRuntimeError3(String messageId, Object arg1, Object arg2, Object arg3) { String msg = ScriptRuntime.getMessage3(messageId, arg1, arg2, arg3); return reportRuntimeError(msg); } static EvaluatorException reportRuntimeError4(String messageId, Object arg1, Object arg2, Object arg3, Object arg4) { String msg = ScriptRuntime.getMessage4(messageId, arg1, arg2, arg3, arg4); return reportRuntimeError(msg); } /** * Report a runtime error using the error reporter for the current thread. * * @param message the error message to report * @see org.mozilla.javascript.ErrorReporter */ public static EvaluatorException reportRuntimeError(String message) { int[] linep = { 0 }; String filename = getSourcePositionFromStack(linep); return Context.reportRuntimeError(message, filename, linep[0], null, 0); } /** * Initialize the standard objects. * * Creates instances of the standard objects and their constructors * (Object, String, Number, Date, etc.), setting up 'scope' to act * as a global object as in ECMA 15.1.

* * This method must be called to initialize a scope before scripts * can be evaluated in that scope.

* * This method does not affect the Context it is called upon. * * @return the initialized scope */ public final ScriptableObject initStandardObjects() { return initStandardObjects(null, false); } /** * Initialize the standard objects. * * Creates instances of the standard objects and their constructors * (Object, String, Number, Date, etc.), setting up 'scope' to act * as a global object as in ECMA 15.1.

* * This method must be called to initialize a scope before scripts * can be evaluated in that scope.

* * This method does not affect the Context it is called upon. * * @param scope the scope to initialize, or null, in which case a new * object will be created to serve as the scope * @return the initialized scope. The method returns the value of the scope * argument if it is not null or newly allocated scope object which * is an instance {@link ScriptableObject}. */ public final Scriptable initStandardObjects(ScriptableObject scope) { return initStandardObjects(scope, false); } /** * Initialize the standard objects. * * Creates instances of the standard objects and their constructors * (Object, String, Number, Date, etc.), setting up 'scope' to act * as a global object as in ECMA 15.1.

* * This method must be called to initialize a scope before scripts * can be evaluated in that scope.

* * This method does not affect the Context it is called upon.

* * This form of the method also allows for creating "sealed" standard * objects. An object that is sealed cannot have properties added, changed, * or removed. This is useful to create a "superglobal" that can be shared * among several top-level objects. Note that sealing is not allowed in * the current ECMA/ISO language specification, but is likely for * the next version. * * @param scope the scope to initialize, or null, in which case a new * object will be created to serve as the scope * @param sealed whether or not to create sealed standard objects that * cannot be modified. * @return the initialized scope. The method returns the value of the scope * argument if it is not null or newly allocated scope object. * @since 1.4R3 */ public ScriptableObject initStandardObjects(ScriptableObject scope, boolean sealed) { return ScriptRuntime.initStandardObjects(this, scope, sealed); } /** * Get the singleton object that represents the JavaScript Undefined value. */ public static Object getUndefinedValue() { return Undefined.instance; } /** * Evaluate a JavaScript source string. * * The provided source name and line number are used for error messages * and for producing debug information. * * @param scope the scope to execute in * @param source the JavaScript source * @param sourceName a string describing the source, such as a filename * @param lineno the starting line number * @param securityDomain an arbitrary object that specifies security * information about the origin or owner of the script. For * implementations that don't care about security, this value * may be null. * @return the result of evaluating the string * @see org.mozilla.javascript.SecurityController */ public final Object evaluateString(Scriptable scope, String source, String sourceName, int lineno, Object securityDomain) { Script script = compileString(source, sourceName, lineno, securityDomain); if (script != null) { return script.exec(this, scope); } else { return null; } } /** * Evaluate a reader as JavaScript source. * * All characters of the reader are consumed. * * @param scope the scope to execute in * @param in the Reader to get JavaScript source from * @param sourceName a string describing the source, such as a filename * @param lineno the starting line number * @param securityDomain an arbitrary object that specifies security * information about the origin or owner of the script. For * implementations that don't care about security, this value * may be null. * @return the result of evaluating the source * * @exception IOException if an IOException was generated by the Reader */ public final Object evaluateReader(Scriptable scope, Reader in, String sourceName, int lineno, Object securityDomain) throws IOException { Script script = compileReader(scope, in, sourceName, lineno, securityDomain); if (script != null) { return script.exec(this, scope); } else { return null; } } /** * Execute script that may pause execution by capturing a continuation. * Caller must be prepared to catch a ContinuationPending exception * and resume execution by calling * {@link #resumeContinuation(Object, Scriptable, Object)}. * @param script The script to execute. Script must have been compiled * with interpreted mode (optimization level -1) * @param scope The scope to execute the script against * @throws ContinuationPending if the script calls a function that results * in a call to {@link #captureContinuation()} * @since 1.7 Release 2 */ public Object executeScriptWithContinuations(Script script, Scriptable scope) throws ContinuationPending { if (!(script instanceof InterpretedFunction) || !((InterpretedFunction)script).isScript()) { // Can only be applied to scripts throw new IllegalArgumentException("Script argument was not" + " a script or was not created by interpreted mode "); } return callFunctionWithContinuations((InterpretedFunction) script, scope, ScriptRuntime.emptyArgs); } /** * Call function that may pause execution by capturing a continuation. * Caller must be prepared to catch a ContinuationPending exception * and resume execution by calling * {@link #resumeContinuation(Object, Scriptable, Object)}. * @param function The function to call. The function must have been * compiled with interpreted mode (optimization level -1) * @param scope The scope to execute the script against * @param args The arguments for the function * @throws ContinuationPending if the script calls a function that results * in a call to {@link #captureContinuation()} * @since 1.7 Release 2 */ public Object callFunctionWithContinuations(Callable function, Scriptable scope, Object[] args) throws ContinuationPending { if (!(function instanceof InterpretedFunction)) { // Can only be applied to scripts throw new IllegalArgumentException("Function argument was not" + " created by interpreted mode "); } if (ScriptRuntime.hasTopCall(this)) { throw new IllegalStateException("Cannot have any pending top " + "calls when executing a script with continuations"); } // Annotate so we can check later to ensure no java code in // intervening frames isContinuationsTopCall = true; return ScriptRuntime.doTopCall(function, this, scope, scope, args); } /** * Capture a continuation from the current execution. The execution must * have been started via a call to * {@link #executeScriptWithContinuations(Script, Scriptable)} or * {@link #callFunctionWithContinuations(Callable, Scriptable, Object[])}. * This implies that the code calling * this method must have been called as a function from the * JavaScript script. Also, there cannot be any non-JavaScript code * between the JavaScript frames (e.g., a call to eval()). The * ContinuationPending exception returned must be thrown. * @return A ContinuationPending exception that must be thrown * @since 1.7 Release 2 */ public ContinuationPending captureContinuation() { return new ContinuationPending( Interpreter.captureContinuation(this)); } /** * Restarts execution of the JavaScript suspended at the call * to {@link #captureContinuation()}. Execution of the code will resume * with the functionResult as the result of the call that captured the * continuation. * Execution of the script will either conclude normally and the * result returned, another continuation will be captured and * thrown, or the script will terminate abnormally and throw an exception. * @param continuation The value returned by * {@link ContinuationPending#getContinuation()} * @param functionResult This value will appear to the code being resumed * as the result of the function that captured the continuation * @throws ContinuationPending if another continuation is captured before * the code terminates * @since 1.7 Release 2 */ public Object resumeContinuation(Object continuation, Scriptable scope, Object functionResult) throws ContinuationPending { Object[] args = { functionResult }; return Interpreter.restartContinuation( (org.mozilla.javascript.NativeContinuation) continuation, this, scope, args); } /** * Check whether a string is ready to be compiled. *

* stringIsCompilableUnit is intended to support interactive compilation of * JavaScript. If compiling the string would result in an error * that might be fixed by appending more source, this method * returns false. In every other case, it returns true. *

* Interactive shells may accumulate source lines, using this * method after each new line is appended to check whether the * statement being entered is complete. * * @param source the source buffer to check * @return whether the source is ready for compilation * @since 1.4 Release 2 */ public final boolean stringIsCompilableUnit(String source) { boolean errorseen = false; CompilerEnvirons compilerEnv = new CompilerEnvirons(); compilerEnv.initFromContext(this); // no source name or source text manager, because we're just // going to throw away the result. compilerEnv.setGeneratingSource(false); Parser p = new Parser(compilerEnv, DefaultErrorReporter.instance); try { p.parse(source, null, 1); } catch (EvaluatorException ee) { errorseen = true; } // Return false only if an error occurred as a result of reading past // the end of the file, i.e. if the source could be fixed by // appending more source. if (errorseen && p.eof()) return false; else return true; } /** * @deprecated * @see #compileReader(Reader in, String sourceName, int lineno, * Object securityDomain) */ public final Script compileReader(Scriptable scope, Reader in, String sourceName, int lineno, Object securityDomain) throws IOException { return compileReader(in, sourceName, lineno, securityDomain); } /** * Compiles the source in the given reader. *

* Returns a script that may later be executed. * Will consume all the source in the reader. * * @param in the input reader * @param sourceName a string describing the source, such as a filename * @param lineno the starting line number for reporting errors * @param securityDomain an arbitrary object that specifies security * information about the origin or owner of the script. For * implementations that don't care about security, this value * may be null. * @return a script that may later be executed * @exception IOException if an IOException was generated by the Reader * @see org.mozilla.javascript.Script */ public final Script compileReader(Reader in, String sourceName, int lineno, Object securityDomain) throws IOException { if (lineno < 0) { // For compatibility IllegalArgumentException can not be thrown here lineno = 0; } return (Script) compileImpl(null, in, null, sourceName, lineno, securityDomain, false, null, null); } /** * Compiles the source in the given string. *

* Returns a script that may later be executed. * * @param source the source string * @param sourceName a string describing the source, such as a filename * @param lineno the starting line number for reporting errors * @param securityDomain an arbitrary object that specifies security * information about the origin or owner of the script. For * implementations that don't care about security, this value * may be null. * @return a script that may later be executed * @see org.mozilla.javascript.Script */ public final Script compileString(String source, String sourceName, int lineno, Object securityDomain) { if (lineno < 0) { // For compatibility IllegalArgumentException can not be thrown here lineno = 0; } return compileString(source, null, null, sourceName, lineno, securityDomain); } final Script compileString(String source, Evaluator compiler, ErrorReporter compilationErrorReporter, String sourceName, int lineno, Object securityDomain) { try { return (Script) compileImpl(null, null, source, sourceName, lineno, securityDomain, false, compiler, compilationErrorReporter); } catch (IOException ex) { // Should not happen when dealing with source as string throw new RuntimeException(); } } /** * Compile a JavaScript function. *

* The function source must be a function definition as defined by * ECMA (e.g., "function f(a) { return a; }"). * * @param scope the scope to compile relative to * @param source the function definition source * @param sourceName a string describing the source, such as a filename * @param lineno the starting line number * @param securityDomain an arbitrary object that specifies security * information about the origin or owner of the script. For * implementations that don't care about security, this value * may be null. * @return a Function that may later be called * @see org.mozilla.javascript.Function */ public final Function compileFunction(Scriptable scope, String source, String sourceName, int lineno, Object securityDomain) { return compileFunction(scope, source, null, null, sourceName, lineno, securityDomain); } final Function compileFunction(Scriptable scope, String source, Evaluator compiler, ErrorReporter compilationErrorReporter, String sourceName, int lineno, Object securityDomain) { try { return (Function) compileImpl(scope, null, source, sourceName, lineno, securityDomain, true, compiler, compilationErrorReporter); } catch (IOException ioe) { // Should never happen because we just made the reader // from a String throw new RuntimeException(); } } /** * Decompile the script. *

* The canonical source of the script is returned. * * @param script the script to decompile * @param indent the number of spaces to indent the result * @return a string representing the script source */ public final String decompileScript(Script script, int indent) { NativeFunction scriptImpl = (NativeFunction) script; return scriptImpl.decompile(indent, 0); } /** * Decompile a JavaScript Function. *

* Decompiles a previously compiled JavaScript function object to * canonical source. *

* Returns function body of '[native code]' if no decompilation * information is available. * * @param fun the JavaScript function to decompile * @param indent the number of spaces to indent the result * @return a string representing the function source */ public final String decompileFunction(Function fun, int indent) { if (fun instanceof BaseFunction) return ((BaseFunction)fun).decompile(indent, 0); else return "function " + fun.getClassName() + "() {\n\t[native code]\n}\n"; } /** * Decompile the body of a JavaScript Function. *

* Decompiles the body a previously compiled JavaScript Function * object to canonical source, omitting the function header and * trailing brace. * * Returns '[native code]' if no decompilation information is available. * * @param fun the JavaScript function to decompile * @param indent the number of spaces to indent the result * @return a string representing the function body source. */ public final String decompileFunctionBody(Function fun, int indent) { if (fun instanceof BaseFunction) { BaseFunction bf = (BaseFunction)fun; return bf.decompile(indent, Decompiler.ONLY_BODY_FLAG); } // ALERT: not sure what the right response here is. return "[native code]\n"; } /** * Create a new JavaScript object. * * Equivalent to evaluating "new Object()". * @param scope the scope to search for the constructor and to evaluate * against * @return the new object */ public final Scriptable newObject(Scriptable scope) { return newObject(scope, "Object", ScriptRuntime.emptyArgs); } /** * Create a new JavaScript object by executing the named constructor. * * The call newObject(scope, "Foo") is equivalent to * evaluating "new Foo()". * * @param scope the scope to search for the constructor and to evaluate against * @param constructorName the name of the constructor to call * @return the new object */ public final Scriptable newObject(Scriptable scope, String constructorName) { return newObject(scope, constructorName, ScriptRuntime.emptyArgs); } /** * Creates a new JavaScript object by executing the named constructor. * * Searches scope for the named constructor, calls it with * the given arguments, and returns the result.

* * The code *

     * Object[] args = { "a", "b" };
     * newObject(scope, "Foo", args)
* is equivalent to evaluating "new Foo('a', 'b')", assuming that the Foo * constructor has been defined in scope. * * @param scope The scope to search for the constructor and to evaluate * against * @param constructorName the name of the constructor to call * @param args the array of arguments for the constructor * @return the new object */ public final Scriptable newObject(Scriptable scope, String constructorName, Object[] args) { scope = ScriptableObject.getTopLevelScope(scope); Function ctor = ScriptRuntime.getExistingCtor(this, scope, constructorName); if (args == null) { args = ScriptRuntime.emptyArgs; } return ctor.construct(this, scope, args); } /** * Create an array with a specified initial length. *

* @param scope the scope to create the object in * @param length the initial length (JavaScript arrays may have * additional properties added dynamically). * @return the new array object */ public final Scriptable newArray(Scriptable scope, int length) { NativeArray result = new NativeArray(length); ScriptRuntime.setObjectProtoAndParent(result, scope); return result; } /** * Create an array with a set of initial elements. * * @param scope the scope to create the object in. * @param elements the initial elements. Each object in this array * must be an acceptable JavaScript type and type * of array should be exactly Object[], not * SomeObjectSubclass[]. * @return the new array object. */ public final Scriptable newArray(Scriptable scope, Object[] elements) { if (elements.getClass().getComponentType() != ScriptRuntime.ObjectClass) throw new IllegalArgumentException(); NativeArray result = new NativeArray(elements); ScriptRuntime.setObjectProtoAndParent(result, scope); return result; } /** * Get the elements of a JavaScript array. *

* If the object defines a length property convertible to double number, * then the number is converted Uint32 value as defined in Ecma 9.6 * and Java array of that size is allocated. * The array is initialized with the values obtained by * calling get() on object for each value of i in [0,length-1]. If * there is not a defined value for a property the Undefined value * is used to initialize the corresponding element in the array. The * Java array is then returned. * If the object doesn't define a length property or it is not a number, * empty array is returned. * @param object the JavaScript array or array-like object * @return a Java array of objects * @since 1.4 release 2 */ public final Object[] getElements(Scriptable object) { return ScriptRuntime.getArrayElements(object); } /** * Convert the value to a JavaScript boolean value. *

* See ECMA 9.2. * * @param value a JavaScript value * @return the corresponding boolean value converted using * the ECMA rules */ public static boolean toBoolean(Object value) { return ScriptRuntime.toBoolean(value); } /** * Convert the value to a JavaScript Number value. *

* Returns a Java double for the JavaScript Number. *

* See ECMA 9.3. * * @param value a JavaScript value * @return the corresponding double value converted using * the ECMA rules */ public static double toNumber(Object value) { return ScriptRuntime.toNumber(value); } /** * Convert the value to a JavaScript String value. *

* See ECMA 9.8. *

* @param value a JavaScript value * @return the corresponding String value converted using * the ECMA rules */ public static String toString(Object value) { return ScriptRuntime.toString(value); } /** * Convert the value to an JavaScript object value. *

* Note that a scope must be provided to look up the constructors * for Number, Boolean, and String. *

* See ECMA 9.9. *

* Additionally, arbitrary Java objects and classes will be * wrapped in a Scriptable object with its Java fields and methods * reflected as JavaScript properties of the object. * * @param value any Java object * @param scope global scope containing constructors for Number, * Boolean, and String * @return new JavaScript object */ public static Scriptable toObject(Object value, Scriptable scope) { return ScriptRuntime.toObject(scope, value); } /** * @deprecated * @see #toObject(Object, Scriptable) */ public static Scriptable toObject(Object value, Scriptable scope, Class staticType) { return ScriptRuntime.toObject(scope, value); } /** * Convenient method to convert java value to its closest representation * in JavaScript. *

* If value is an instance of String, Number, Boolean, Function or * Scriptable, it is returned as it and will be treated as the corresponding * JavaScript type of string, number, boolean, function and object. *

* Note that for Number instances during any arithmetic operation in * JavaScript the engine will always use the result of * Number.doubleValue() resulting in a precision loss if * the number can not fit into double. *

* If value is an instance of Character, it will be converted to string of * length 1 and its JavaScript type will be string. *

* The rest of values will be wrapped as LiveConnect objects * by calling {@link WrapFactory#wrap(Context cx, Scriptable scope, * Object obj, Class staticType)} as in: *

     *    Context cx = Context.getCurrentContext();
     *    return cx.getWrapFactory().wrap(cx, scope, value, null);
     * 
* * @param value any Java object * @param scope top scope object * @return value suitable to pass to any API that takes JavaScript values. */ public static Object javaToJS(Object value, Scriptable scope) { if (value instanceof String || value instanceof Number || value instanceof Boolean || value instanceof Scriptable) { return value; } else if (value instanceof Character) { return String.valueOf(((Character)value).charValue()); } else { Context cx = Context.getContext(); return cx.getWrapFactory().wrap(cx, scope, value, null); } } /** * Convert a JavaScript value into the desired type. * Uses the semantics defined with LiveConnect3 and throws an * Illegal argument exception if the conversion cannot be performed. * @param value the JavaScript value to convert * @param desiredType the Java type to convert to. Primitive Java * types are represented using the TYPE fields in the corresponding * wrapper class in java.lang. * @return the converted value * @throws EvaluatorException if the conversion cannot be performed */ public static Object jsToJava(Object value, Class desiredType) throws EvaluatorException { return NativeJavaObject.coerceTypeImpl(desiredType, value); } /** * @deprecated * @see #jsToJava(Object, Class) * @throws IllegalArgumentException if the conversion cannot be performed. * Note that {@link #jsToJava(Object, Class)} throws * {@link EvaluatorException} instead. */ public static Object toType(Object value, Class desiredType) throws IllegalArgumentException { try { return jsToJava(value, desiredType); } catch (EvaluatorException ex) { IllegalArgumentException ex2 = new IllegalArgumentException(ex.getMessage()); Kit.initCause(ex2, ex); throw ex2; } } /** * Rethrow the exception wrapping it as the script runtime exception. * Unless the exception is instance of {@link EcmaError} or * {@link EvaluatorException} it will be wrapped as * {@link WrappedException}, a subclass of {@link EvaluatorException}. * The resulting exception object always contains * source name and line number of script that triggered exception. *

* This method always throws an exception, its return value is provided * only for convenience to allow a usage like: *

     * throw Context.throwAsScriptRuntimeEx(ex);
     * 
* to indicate that code after the method is unreachable. * @throws EvaluatorException * @throws EcmaError */ public static RuntimeException throwAsScriptRuntimeEx(Throwable e) { while ((e instanceof InvocationTargetException)) { e = ((InvocationTargetException) e).getTargetException(); } // special handling of Error so scripts would not catch them if (e instanceof Error) { Context cx = getContext(); if (cx == null || !cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)) { throw (Error)e; } } if (e instanceof RhinoException) { throw (RhinoException)e; } throw new WrappedException(e); } /** * Tell whether debug information is being generated. * @since 1.3 */ public final boolean isGeneratingDebug() { return generatingDebug; } /** * Specify whether or not debug information should be generated. *

* Setting the generation of debug information on will set the * optimization level to zero. * @since 1.3 */ public final void setGeneratingDebug(boolean generatingDebug) { if (sealed) onSealedMutation(); generatingDebugChanged = true; if (generatingDebug && getOptimizationLevel() > 0) setOptimizationLevel(0); this.generatingDebug = generatingDebug; } /** * Tell whether source information is being generated. * @since 1.3 */ public final boolean isGeneratingSource() { return generatingSource; } /** * Specify whether or not source information should be generated. *

* Without source information, evaluating the "toString" method * on JavaScript functions produces only "[native code]" for * the body of the function. * Note that code generated without source is not fully ECMA * conformant. * @since 1.3 */ public final void setGeneratingSource(boolean generatingSource) { if (sealed) onSealedMutation(); this.generatingSource = generatingSource; } /** * Get the current optimization level. *

* The optimization level is expressed as an integer between -1 and * 9. * @since 1.3 * */ public final int getOptimizationLevel() { return optimizationLevel; } /** * Set the current optimization level. *

* The optimization level is expected to be an integer between -1 and * 9. Any negative values will be interpreted as -1, and any values * greater than 9 will be interpreted as 9. * An optimization level of -1 indicates that interpretive mode will * always be used. Levels 0 through 9 indicate that class files may * be generated. Higher optimization levels trade off compile time * performance for runtime performance. * The optimizer level can't be set greater than -1 if the optimizer * package doesn't exist at run time. * @param optimizationLevel an integer indicating the level of * optimization to perform * @since 1.3 * */ public final void setOptimizationLevel(int optimizationLevel) { if (sealed) onSealedMutation(); if (optimizationLevel == -2) { // To be compatible with Cocoon fork optimizationLevel = -1; } checkOptimizationLevel(optimizationLevel); if (codegenClass == null) optimizationLevel = -1; this.optimizationLevel = optimizationLevel; } public static boolean isValidOptimizationLevel(int optimizationLevel) { return -1 <= optimizationLevel && optimizationLevel <= 9; } public static void checkOptimizationLevel(int optimizationLevel) { if (isValidOptimizationLevel(optimizationLevel)) { return; } throw new IllegalArgumentException( "Optimization level outside [-1..9]: "+optimizationLevel); } /** * Returns the maximum stack depth (in terms of number of call frames) * allowed in a single invocation of interpreter. If the set depth would be * exceeded, the interpreter will throw an EvaluatorException in the script. * Defaults to Integer.MAX_VALUE. The setting only has effect for * interpreted functions (those compiled with optimization level set to -1). * As the interpreter doesn't use the Java stack but rather manages its own * stack in the heap memory, a runaway recursion in interpreted code would * eventually consume all available memory and cause OutOfMemoryError * instead of a StackOverflowError limited to only a single thread. This * setting helps prevent such situations. * * @return The current maximum interpreter stack depth. */ public final int getMaximumInterpreterStackDepth() { return maximumInterpreterStackDepth; } /** * Sets the maximum stack depth (in terms of number of call frames) * allowed in a single invocation of interpreter. If the set depth would be * exceeded, the interpreter will throw an EvaluatorException in the script. * Defaults to Integer.MAX_VALUE. The setting only has effect for * interpreted functions (those compiled with optimization level set to -1). * As the interpreter doesn't use the Java stack but rather manages its own * stack in the heap memory, a runaway recursion in interpreted code would * eventually consume all available memory and cause OutOfMemoryError * instead of a StackOverflowError limited to only a single thread. This * setting helps prevent such situations. * * @param max the new maximum interpreter stack depth * @throws IllegalStateException if this context's optimization level is not * -1 * @throws IllegalArgumentException if the new depth is not at least 1 */ public final void setMaximumInterpreterStackDepth(int max) { if(sealed) onSealedMutation(); if(optimizationLevel != -1) { throw new IllegalStateException("Cannot set maximumInterpreterStackDepth when optimizationLevel != -1"); } if(max < 1) { throw new IllegalArgumentException("Cannot set maximumInterpreterStackDepth to less than 1"); } maximumInterpreterStackDepth = max; } /** * Set the security controller for this context. *

SecurityController may only be set if it is currently null * and {@link SecurityController#hasGlobal()} is false. * Otherwise a SecurityException is thrown. * @param controller a SecurityController object * @throws SecurityException if there is already a SecurityController * object for this Context or globally installed. * @see SecurityController#initGlobal(SecurityController controller) * @see SecurityController#hasGlobal() */ public final void setSecurityController(SecurityController controller) { if (sealed) onSealedMutation(); if (controller == null) throw new IllegalArgumentException(); if (securityController != null) { throw new SecurityException("Can not overwrite existing SecurityController object"); } if (SecurityController.hasGlobal()) { throw new SecurityException("Can not overwrite existing global SecurityController object"); } securityController = controller; } /** * Set the LiveConnect access filter for this context. *

{@link ClassShutter} may only be set if it is currently null. * Otherwise a SecurityException is thrown. * @param shutter a ClassShutter object * @throws SecurityException if there is already a ClassShutter * object for this Context */ public final void setClassShutter(ClassShutter shutter) { if (sealed) onSealedMutation(); if (shutter == null) throw new IllegalArgumentException(); if (classShutter != null) { throw new SecurityException("Cannot overwrite existing " + "ClassShutter object"); } classShutter = shutter; } final ClassShutter getClassShutter() { return classShutter; } /** * Get a value corresponding to a key. *

* Since the Context is associated with a thread it can be * used to maintain values that can be later retrieved using * the current thread. *

* Note that the values are maintained with the Context, so * if the Context is disassociated from the thread the values * cannot be retrieved. Also, if private data is to be maintained * in this manner the key should be a java.lang.Object * whose reference is not divulged to untrusted code. * @param key the key used to lookup the value * @return a value previously stored using putThreadLocal. */ public final Object getThreadLocal(Object key) { if (threadLocalMap == null) return null; return threadLocalMap.get(key); } /** * Put a value that can later be retrieved using a given key. *

* @param key the key used to index the value * @param value the value to save */ public synchronized final void putThreadLocal(Object key, Object value) { if (sealed) onSealedMutation(); if (threadLocalMap == null) threadLocalMap = new HashMap(); threadLocalMap.put(key, value); } /** * Remove values from thread-local storage. * @param key the key for the entry to remove. * @since 1.5 release 2 */ public final void removeThreadLocal(Object key) { if (sealed) onSealedMutation(); if (threadLocalMap == null) return; threadLocalMap.remove(key); } /** * @deprecated * @see #FEATURE_DYNAMIC_SCOPE * @see #hasFeature(int) */ public final boolean hasCompileFunctionsWithDynamicScope() { return compileFunctionsWithDynamicScopeFlag; } /** * @deprecated * @see #FEATURE_DYNAMIC_SCOPE * @see #hasFeature(int) */ public final void setCompileFunctionsWithDynamicScope(boolean flag) { if (sealed) onSealedMutation(); compileFunctionsWithDynamicScopeFlag = flag; } /** * @deprecated * @see ClassCache#get(Scriptable) * @see ClassCache#setCachingEnabled(boolean) */ public static void setCachingEnabled(boolean cachingEnabled) { } /** * Set a WrapFactory for this Context. *

* The WrapFactory allows custom object wrapping behavior for * Java object manipulated with JavaScript. * @see WrapFactory * @since 1.5 Release 4 */ public final void setWrapFactory(WrapFactory wrapFactory) { if (sealed) onSealedMutation(); if (wrapFactory == null) throw new IllegalArgumentException(); this.wrapFactory = wrapFactory; } /** * Return the current WrapFactory, or null if none is defined. * @see WrapFactory * @since 1.5 Release 4 */ public final WrapFactory getWrapFactory() { if (wrapFactory == null) { wrapFactory = new WrapFactory(); } return wrapFactory; } /** * Return the current debugger. * @return the debugger, or null if none is attached. */ public final Debugger getDebugger() { return debugger; } /** * Return the debugger context data associated with current context. * @return the debugger data, or null if debugger is not attached */ public final Object getDebuggerContextData() { return debuggerData; } /** * Set the associated debugger. * @param debugger the debugger to be used on callbacks from * the engine. * @param contextData arbitrary object that debugger can use to store * per Context data. */ public final void setDebugger(Debugger debugger, Object contextData) { if (sealed) onSealedMutation(); this.debugger = debugger; debuggerData = contextData; } /** * Return DebuggableScript instance if any associated with the script. * If callable supports DebuggableScript implementation, the method * returns it. Otherwise null is returned. */ public static DebuggableScript getDebuggableView(Script script) { if (script instanceof NativeFunction) { return ((NativeFunction)script).getDebuggableView(); } return null; } /** * Controls certain aspects of script semantics. * Should be overwritten to alter default behavior. *

* The default implementation calls * {@link ContextFactory#hasFeature(Context cx, int featureIndex)} * that allows to customize Context behavior without introducing * Context subclasses. {@link ContextFactory} documentation gives * an example of hasFeature implementation. * * @param featureIndex feature index to check * @return true if the featureIndex feature is turned on * @see #FEATURE_NON_ECMA_GET_YEAR * @see #FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME * @see #FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER * @see #FEATURE_TO_STRING_AS_SOURCE * @see #FEATURE_PARENT_PROTO_PROPRTIES * @see #FEATURE_E4X * @see #FEATURE_DYNAMIC_SCOPE * @see #FEATURE_STRICT_VARS * @see #FEATURE_STRICT_EVAL * @see #FEATURE_LOCATION_INFORMATION_IN_ERROR * @see #FEATURE_STRICT_MODE * @see #FEATURE_WARNING_AS_ERROR * @see #FEATURE_ENHANCED_JAVA_ACCESS */ public boolean hasFeature(int featureIndex) { ContextFactory f = getFactory(); return f.hasFeature(this, featureIndex); } /** Returns an object which specifies an E4X implementation to use within this Context. Note that the XMLLib.Factory interface should be considered experimental. The default implementation uses the implementation provided by this Context's {@link ContextFactory}. @return An XMLLib.Factory. Should not return null if {@link #FEATURE_E4X} is enabled. See {@link #hasFeature}. */ public XMLLib.Factory getE4xImplementationFactory() { return getFactory().getE4xImplementationFactory(); } /** * Get threshold of executed instructions counter that triggers call to * observeInstructionCount(). * When the threshold is zero, instruction counting is disabled, * otherwise each time the run-time executes at least the threshold value * of script instructions, observeInstructionCount() will * be called. */ public final int getInstructionObserverThreshold() { return instructionThreshold; } /** * Set threshold of executed instructions counter that triggers call to * observeInstructionCount(). * When the threshold is zero, instruction counting is disabled, * otherwise each time the run-time executes at least the threshold value * of script instructions, observeInstructionCount() will * be called.

* Note that the meaning of "instruction" is not guaranteed to be * consistent between compiled and interpretive modes: executing a given * script or function in the different modes will result in different * instruction counts against the threshold. * {@link #setGenerateObserverCount} is called with true if * threshold is greater than zero, false otherwise. * @param threshold The instruction threshold */ public final void setInstructionObserverThreshold(int threshold) { if (sealed) onSealedMutation(); if (threshold < 0) throw new IllegalArgumentException(); instructionThreshold = threshold; setGenerateObserverCount(threshold > 0); } /** * Turn on or off generation of code with callbacks to * track the count of executed instructions. * Currently only affects JVM byte code generation: this slows down the * generated code, but code generated without the callbacks will not * be counted toward instruction thresholds. Rhino's interpretive * mode does instruction counting without inserting callbacks, so * there is no requirement to compile code differently. * @param generateObserverCount if true, generated code will contain * calls to accumulate an estimate of the instructions executed. */ public void setGenerateObserverCount(boolean generateObserverCount) { this.generateObserverCount = generateObserverCount; } /** * Allow application to monitor counter of executed script instructions * in Context subclasses. * Run-time calls this when instruction counting is enabled and the counter * reaches limit set by setInstructionObserverThreshold(). * The method is useful to observe long running scripts and if necessary * to terminate them. *

* The default implementation calls * {@link ContextFactory#observeInstructionCount(Context cx, * int instructionCount)} * that allows to customize Context behavior without introducing * Context subclasses. * * @param instructionCount amount of script instruction executed since * last call to observeInstructionCount * @throws Error to terminate the script * @see #setOptimizationLevel(int) */ protected void observeInstructionCount(int instructionCount) { ContextFactory f = getFactory(); f.observeInstructionCount(this, instructionCount); } /** * Create class loader for generated classes. * The method calls {@link ContextFactory#createClassLoader(ClassLoader)} * using the result of {@link #getFactory()}. */ public GeneratedClassLoader createClassLoader(ClassLoader parent) { ContextFactory f = getFactory(); return f.createClassLoader(parent); } public final ClassLoader getApplicationClassLoader() { if (applicationClassLoader == null) { ContextFactory f = getFactory(); ClassLoader loader = f.getApplicationClassLoader(); if (loader == null) { ClassLoader threadLoader = VMBridge.instance.getCurrentThreadClassLoader(); if (threadLoader != null && Kit.testIfCanLoadRhinoClasses(threadLoader)) { // Thread.getContextClassLoader is not cached since // its caching prevents it from GC which may lead to // a memory leak and hides updates to // Thread.getContextClassLoader return threadLoader; } // Thread.getContextClassLoader can not load Rhino classes, // try to use the loader of ContextFactory or Context // subclasses. Class fClass = f.getClass(); if (fClass != ScriptRuntime.ContextFactoryClass) { loader = fClass.getClassLoader(); } else { loader = getClass().getClassLoader(); } } applicationClassLoader = loader; } return applicationClassLoader; } public final void setApplicationClassLoader(ClassLoader loader) { if (sealed) onSealedMutation(); if (loader == null) { // restore default behaviour applicationClassLoader = null; return; } if (!Kit.testIfCanLoadRhinoClasses(loader)) { throw new IllegalArgumentException( "Loader can not resolve Rhino classes"); } applicationClassLoader = loader; } /********** end of API **********/ /** * Internal method that reports an error for missing calls to * enter(). */ static Context getContext() { Context cx = getCurrentContext(); if (cx == null) { throw new RuntimeException( "No Context associated with current Thread"); } return cx; } private Object compileImpl(Scriptable scope, Reader sourceReader, String sourceString, String sourceName, int lineno, Object securityDomain, boolean returnFunction, Evaluator compiler, ErrorReporter compilationErrorReporter) throws IOException { if(sourceName == null) { sourceName = "unnamed script"; } if (securityDomain != null && getSecurityController() == null) { throw new IllegalArgumentException( "securityDomain should be null if setSecurityController() was never called"); } // One of sourceReader or sourceString has to be null if (!(sourceReader == null ^ sourceString == null)) Kit.codeBug(); // scope should be given if and only if compiling function if (!(scope == null ^ returnFunction)) Kit.codeBug(); CompilerEnvirons compilerEnv = new CompilerEnvirons(); compilerEnv.initFromContext(this); if (compilationErrorReporter == null) { compilationErrorReporter = compilerEnv.getErrorReporter(); } if (debugger != null) { if (sourceReader != null) { sourceString = Kit.readReader(sourceReader); sourceReader = null; } } Parser p = new Parser(compilerEnv, compilationErrorReporter); if (returnFunction) { p.calledByCompileFunction = true; } ScriptOrFnNode tree; if (sourceString != null) { tree = p.parse(sourceString, sourceName, lineno); } else { tree = p.parse(sourceReader, sourceName, lineno); } if (returnFunction) { if (!(tree.getFunctionCount() == 1 && tree.getFirstChild() != null && tree.getFirstChild().getType() == Token.FUNCTION)) { // XXX: the check just look for the first child // and allows for more nodes after it for compatibility // with sources like function() {};;; throw new IllegalArgumentException( "compileFunction only accepts source with single JS function: "+sourceString); } } if (compiler == null) { compiler = createCompiler(); } String encodedSource = p.getEncodedSource(); Object bytecode = compiler.compile(compilerEnv, tree, encodedSource, returnFunction); if (debugger != null) { if (sourceString == null) Kit.codeBug(); if (bytecode instanceof DebuggableScript) { DebuggableScript dscript = (DebuggableScript)bytecode; notifyDebugger_r(this, dscript, sourceString); } else { throw new RuntimeException("NOT SUPPORTED"); } } Object result; if (returnFunction) { result = compiler.createFunctionObject(this, scope, bytecode, securityDomain); } else { result = compiler.createScriptObject(bytecode, securityDomain); } return result; } private static void notifyDebugger_r(Context cx, DebuggableScript dscript, String debugSource) { cx.debugger.handleCompilationDone(cx, dscript, debugSource); for (int i = 0; i != dscript.getFunctionCount(); ++i) { notifyDebugger_r(cx, dscript.getFunction(i), debugSource); } } private static Class codegenClass = Kit.classOrNull( "org.mozilla.javascript.optimizer.Codegen"); private static Class interpreterClass = Kit.classOrNull( "org.mozilla.javascript.Interpreter"); private Evaluator createCompiler() { Evaluator result = null; if (optimizationLevel >= 0 && codegenClass != null) { result = (Evaluator)Kit.newInstanceOrNull(codegenClass); } if (result == null) { result = createInterpreter(); } return result; } static Evaluator createInterpreter() { return (Evaluator)Kit.newInstanceOrNull(interpreterClass); } static String getSourcePositionFromStack(int[] linep) { Context cx = getCurrentContext(); if (cx == null) return null; if (cx.lastInterpreterFrame != null) { Evaluator evaluator = createInterpreter(); if (evaluator != null) return evaluator.getSourcePositionFromStack(cx, linep); } /** * A bit of a hack, but the only way to get filename and line * number from an enclosing frame. */ CharArrayWriter writer = new CharArrayWriter(); RuntimeException re = new RuntimeException(); re.printStackTrace(new PrintWriter(writer)); String s = writer.toString(); int open = -1; int close = -1; int colon = -1; for (int i=0; i < s.length(); i++) { char c = s.charAt(i); if (c == ':') colon = i; else if (c == '(') open = i; else if (c == ')') close = i; else if (c == '\n' && open != -1 && close != -1 && colon != -1 && open < colon && colon < close) { String fileStr = s.substring(open + 1, colon); if (!fileStr.endsWith(".java")) { String lineStr = s.substring(colon + 1, close); try { linep[0] = Integer.parseInt(lineStr); if (linep[0] < 0) { linep[0] = 0; } return fileStr; } catch (NumberFormatException e) { // fall through } } open = close = colon = -1; } } return null; } RegExpProxy getRegExpProxy() { if (regExpProxy == null) { Class cl = Kit.classOrNull( "org.mozilla.javascript.regexp.RegExpImpl"); if (cl != null) { regExpProxy = (RegExpProxy)Kit.newInstanceOrNull(cl); } } return regExpProxy; } final boolean isVersionECMA1() { return version == VERSION_DEFAULT || version >= VERSION_1_3; } // The method must NOT be public or protected SecurityController getSecurityController() { SecurityController global = SecurityController.global(); if (global != null) { return global; } return securityController; } public final boolean isGeneratingDebugChanged() { return generatingDebugChanged; } /** * Add a name to the list of names forcing the creation of real * activation objects for functions. * * @param name the name of the object to add to the list */ public void addActivationName(String name) { if (sealed) onSealedMutation(); if (activationNames == null) activationNames = new HashSet(); activationNames.add(name); } /** * Check whether the name is in the list of names of objects * forcing the creation of activation objects. * * @param name the name of the object to test * * @return true if an function activation object is needed. */ public final boolean isActivationNeeded(String name) { return activationNames != null && activationNames.contains(name); } /** * Remove a name from the list of names forcing the creation of real * activation objects for functions. * * @param name the name of the object to remove from the list */ public void removeActivationName(String name) { if (sealed) onSealedMutation(); if (activationNames != null) activationNames.remove(name); } private static String implementationVersion; private final ContextFactory factory; private boolean sealed; private Object sealKey; Scriptable topCallScope; boolean isContinuationsTopCall; NativeCall currentActivationCall; XMLLib cachedXMLLib; // for Objects, Arrays to tag themselves as being printed out, // so they don't print themselves out recursively. // Use ObjToIntMap instead of java.util.HashSet for JDK 1.1 compatibility ObjToIntMap iterating; Object interpreterSecurityDomain; int version; private SecurityController securityController; private ClassShutter classShutter; private ErrorReporter errorReporter; RegExpProxy regExpProxy; private Locale locale; private boolean generatingDebug; private boolean generatingDebugChanged; private boolean generatingSource=true; boolean compileFunctionsWithDynamicScopeFlag; boolean useDynamicScope; private int optimizationLevel; private int maximumInterpreterStackDepth; private WrapFactory wrapFactory; Debugger debugger; private Object debuggerData; private int enterCount; private Object propertyListeners; private Map threadLocalMap; private ClassLoader applicationClassLoader; /** * This is the list of names of objects forcing the creation of * function activation records. */ Set activationNames; // For the interpreter to store the last frame for error reports etc. Object lastInterpreterFrame; // For the interpreter to store information about previous invocations // interpreter invocations ObjArray previousInterpreterInvocations; // For instruction counting (interpreter only) int instructionCount; int instructionThreshold; // It can be used to return the second index-like result from function int scratchIndex; // It can be used to return the second uint32 result from function long scratchUint32; // It can be used to return the second Scriptable result from function Scriptable scratchScriptable; // Generate an observer count on compiled code public boolean generateObserverCount = false; } yui-compressor-2.4.7/src/org/mozilla/javascript/ScriptRuntime.java0000644000175000017500000041403311753547210025300 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Patrick Beard * Norris Boyd * Igor Bukanov * Mike Harm * Ethan Hugg * Bob Jervis * Roger Lawrence * Terry Lucas * Frank Mitchell * Milen Nankov * Hannes Wallnoefer * Andrew Wason * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.Serializable; import java.lang.reflect.*; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; import org.mozilla.javascript.xml.XMLObject; import org.mozilla.javascript.xml.XMLLib; /** * This is the class that implements the runtime. * * @author Norris Boyd */ public class ScriptRuntime { /** * No instances should be created. */ protected ScriptRuntime() { } static class NoSuchMethodShim implements Callable { String methodName; Callable noSuchMethodMethod; NoSuchMethodShim(Callable noSuchMethodMethod, String methodName) { this.noSuchMethodMethod = noSuchMethodMethod; this.methodName = methodName; } /** * Perform the call. * * @param cx the current Context for this thread * @param scope the scope to use to resolve properties. * @param thisObj the JavaScript this object * @param args the array of arguments * @return the result of the call */ public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { Object[] nestedArgs = new Object[2]; nestedArgs[0] = methodName; nestedArgs[1] = newArrayLiteral(args, null, cx, scope); return noSuchMethodMethod.call(cx, scope, thisObj, nestedArgs); } } /* * There's such a huge space (and some time) waste for the Foo.class * syntax: the compiler sticks in a test of a static field in the * enclosing class for null and the code for creating the class value. * It has to do this since the reference has to get pushed off until * execution time (i.e. can't force an early load), but for the * 'standard' classes - especially those in java.lang, we can trust * that they won't cause problems by being loaded early. */ public final static Class BooleanClass = Kit.classOrNull("java.lang.Boolean"), ByteClass = Kit.classOrNull("java.lang.Byte"), CharacterClass = Kit.classOrNull("java.lang.Character"), ClassClass = Kit.classOrNull("java.lang.Class"), DoubleClass = Kit.classOrNull("java.lang.Double"), FloatClass = Kit.classOrNull("java.lang.Float"), IntegerClass = Kit.classOrNull("java.lang.Integer"), LongClass = Kit.classOrNull("java.lang.Long"), NumberClass = Kit.classOrNull("java.lang.Number"), ObjectClass = Kit.classOrNull("java.lang.Object"), ShortClass = Kit.classOrNull("java.lang.Short"), StringClass = Kit.classOrNull("java.lang.String"), DateClass = Kit.classOrNull("java.util.Date"); public final static Class ContextClass = Kit.classOrNull("org.mozilla.javascript.Context"), ContextFactoryClass = Kit.classOrNull("org.mozilla.javascript.ContextFactory"), FunctionClass = Kit.classOrNull("org.mozilla.javascript.Function"), ScriptableObjectClass = Kit.classOrNull("org.mozilla.javascript.ScriptableObject"); public static final Class ScriptableClass = Scriptable.class; private static final String[] lazilyNames = { "RegExp", "org.mozilla.javascript.regexp.NativeRegExp", "Packages", "org.mozilla.javascript.NativeJavaTopPackage", "java", "org.mozilla.javascript.NativeJavaTopPackage", "javax", "org.mozilla.javascript.NativeJavaTopPackage", "org", "org.mozilla.javascript.NativeJavaTopPackage", "com", "org.mozilla.javascript.NativeJavaTopPackage", "edu", "org.mozilla.javascript.NativeJavaTopPackage", "net", "org.mozilla.javascript.NativeJavaTopPackage", "getClass", "org.mozilla.javascript.NativeJavaTopPackage", "JavaAdapter", "org.mozilla.javascript.JavaAdapter", "JavaImporter", "org.mozilla.javascript.ImporterTopLevel", "Continuation", "org.mozilla.javascript.NativeContinuation", // TODO Grotesque hack using literal string (xml) just to minimize // changes for now "XML", "(xml)", "XMLList", "(xml)", "Namespace", "(xml)", "QName", "(xml)", }; private static final Object LIBRARY_SCOPE_KEY = "LIBRARY_SCOPE"; public static boolean isRhinoRuntimeType(Class cl) { if (cl.isPrimitive()) { return (cl != Character.TYPE); } else { return (cl == StringClass || cl == BooleanClass || NumberClass.isAssignableFrom(cl) || ScriptableClass.isAssignableFrom(cl)); } } public static ScriptableObject initStandardObjects(Context cx, ScriptableObject scope, boolean sealed) { if (scope == null) { scope = new NativeObject(); } scope.associateValue(LIBRARY_SCOPE_KEY, scope); (new ClassCache()).associate(scope); BaseFunction.init(scope, sealed); NativeObject.init(scope, sealed); Scriptable objectProto = ScriptableObject.getObjectPrototype(scope); // Function.prototype.__proto__ should be Object.prototype Scriptable functionProto = ScriptableObject.getFunctionPrototype(scope); functionProto.setPrototype(objectProto); // Set the prototype of the object passed in if need be if (scope.getPrototype() == null) scope.setPrototype(objectProto); // must precede NativeGlobal since it's needed therein NativeError.init(scope, sealed); NativeGlobal.init(cx, scope, sealed); NativeArray.init(scope, sealed); if (cx.getOptimizationLevel() > 0) { // When optimizing, attempt to fulfill all requests for new Array(N) // with a higher threshold before switching to a sparse // representation NativeArray.setMaximumInitialCapacity(200000); } NativeString.init(scope, sealed); NativeBoolean.init(scope, sealed); NativeNumber.init(scope, sealed); NativeDate.init(scope, sealed); NativeMath.init(scope, sealed); NativeWith.init(scope, sealed); NativeCall.init(scope, sealed); NativeScript.init(scope, sealed); NativeIterator.init(scope, sealed); // Also initializes NativeGenerator boolean withXml = cx.hasFeature(Context.FEATURE_E4X) && cx.getE4xImplementationFactory() != null; for (int i = 0; i != lazilyNames.length; i += 2) { String topProperty = lazilyNames[i]; String className = lazilyNames[i + 1]; if (!withXml && className.equals("(xml)")) { continue; } else if (withXml && className.equals("(xml)")) { className = cx.getE4xImplementationFactory(). getImplementationClassName(); } new LazilyLoadedCtor(scope, topProperty, className, sealed); } return scope; } public static ScriptableObject getLibraryScopeOrNull(Scriptable scope) { ScriptableObject libScope; libScope = (ScriptableObject)ScriptableObject. getTopScopeValue(scope, LIBRARY_SCOPE_KEY); return libScope; } // It is public so NativeRegExp can access it. public static boolean isJSLineTerminator(int c) { // Optimization for faster check for eol character: // they do not have 0xDFD0 bits set if ((c & 0xDFD0) != 0) { return false; } return c == '\n' || c == '\r' || c == 0x2028 || c == 0x2029; } public static Boolean wrapBoolean(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } public static Integer wrapInt(int i) { return new Integer(i); } public static Number wrapNumber(double x) { if (x != x) { return ScriptRuntime.NaNobj; } return new Double(x); } /** * Convert the value to a boolean. * * See ECMA 9.2. */ public static boolean toBoolean(Object val) { for (;;) { if (val instanceof Boolean) return ((Boolean) val).booleanValue(); if (val == null || val == Undefined.instance) return false; if (val instanceof String) return ((String) val).length() != 0; if (val instanceof Number) { double d = ((Number) val).doubleValue(); return (d == d && d != 0.0); } if (val instanceof Scriptable) { if (val instanceof ScriptableObject && ((ScriptableObject) val).avoidObjectDetection()) { return false; } if (Context.getContext().isVersionECMA1()) { // pure ECMA return true; } // ECMA extension val = ((Scriptable) val).getDefaultValue(BooleanClass); if (val instanceof Scriptable) throw errorWithClassName("msg.primitive.expected", val); continue; } warnAboutNonJSObject(val); return true; } } /** * Convert the value to a number. * * See ECMA 9.3. */ public static double toNumber(Object val) { for (;;) { if (val instanceof Number) return ((Number) val).doubleValue(); if (val == null) return +0.0; if (val == Undefined.instance) return NaN; if (val instanceof String) return toNumber((String) val); if (val instanceof Boolean) return ((Boolean) val).booleanValue() ? 1 : +0.0; if (val instanceof Scriptable) { val = ((Scriptable) val).getDefaultValue(NumberClass); if (val instanceof Scriptable) throw errorWithClassName("msg.primitive.expected", val); continue; } warnAboutNonJSObject(val); return NaN; } } public static double toNumber(Object[] args, int index) { return (index < args.length) ? toNumber(args[index]) : NaN; } // Can not use Double.NaN defined as 0.0d / 0.0 as under the Microsoft VM, // versions 2.01 and 3.0P1, that causes some uses (returns at least) of // Double.NaN to be converted to 1.0. // So we use ScriptRuntime.NaN instead of Double.NaN. public static final double NaN = Double.longBitsToDouble(0x7ff8000000000000L); // A similar problem exists for negative zero. public static final double negativeZero = Double.longBitsToDouble(0x8000000000000000L); public static final Double NaNobj = new Double(NaN); /* * Helper function for toNumber, parseInt, and TokenStream.getToken. */ static double stringToNumber(String s, int start, int radix) { char digitMax = '9'; char lowerCaseBound = 'a'; char upperCaseBound = 'A'; int len = s.length(); if (radix < 10) { digitMax = (char) ('0' + radix - 1); } if (radix > 10) { lowerCaseBound = (char) ('a' + radix - 10); upperCaseBound = (char) ('A' + radix - 10); } int end; double sum = 0.0; for (end=start; end < len; end++) { char c = s.charAt(end); int newDigit; if ('0' <= c && c <= digitMax) newDigit = c - '0'; else if ('a' <= c && c < lowerCaseBound) newDigit = c - 'a' + 10; else if ('A' <= c && c < upperCaseBound) newDigit = c - 'A' + 10; else break; sum = sum*radix + newDigit; } if (start == end) { return NaN; } if (sum >= 9007199254740992.0) { if (radix == 10) { /* If we're accumulating a decimal number and the number * is >= 2^53, then the result from the repeated multiply-add * above may be inaccurate. Call Java to get the correct * answer. */ try { return Double.valueOf(s.substring(start, end)).doubleValue(); } catch (NumberFormatException nfe) { return NaN; } } else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32) { /* The number may also be inaccurate for one of these bases. * This happens if the addition in value*radix + digit causes * a round-down to an even least significant mantissa bit * when the first dropped bit is a one. If any of the * following digits in the number (which haven't been added * in yet) are nonzero then the correct action would have * been to round up instead of down. An example of this * occurs when reading the number 0x1000000000000081, which * rounds to 0x1000000000000000 instead of 0x1000000000000100. */ int bitShiftInChar = 1; int digit = 0; final int SKIP_LEADING_ZEROS = 0; final int FIRST_EXACT_53_BITS = 1; final int AFTER_BIT_53 = 2; final int ZEROS_AFTER_54 = 3; final int MIXED_AFTER_54 = 4; int state = SKIP_LEADING_ZEROS; int exactBitsLimit = 53; double factor = 0.0; boolean bit53 = false; // bit54 is the 54th bit (the first dropped from the mantissa) boolean bit54 = false; for (;;) { if (bitShiftInChar == 1) { if (start == end) break; digit = s.charAt(start++); if ('0' <= digit && digit <= '9') digit -= '0'; else if ('a' <= digit && digit <= 'z') digit -= 'a' - 10; else digit -= 'A' - 10; bitShiftInChar = radix; } bitShiftInChar >>= 1; boolean bit = (digit & bitShiftInChar) != 0; switch (state) { case SKIP_LEADING_ZEROS: if (bit) { --exactBitsLimit; sum = 1.0; state = FIRST_EXACT_53_BITS; } break; case FIRST_EXACT_53_BITS: sum *= 2.0; if (bit) sum += 1.0; --exactBitsLimit; if (exactBitsLimit == 0) { bit53 = bit; state = AFTER_BIT_53; } break; case AFTER_BIT_53: bit54 = bit; factor = 2.0; state = ZEROS_AFTER_54; break; case ZEROS_AFTER_54: if (bit) { state = MIXED_AFTER_54; } // fallthrough case MIXED_AFTER_54: factor *= 2; break; } } switch (state) { case SKIP_LEADING_ZEROS: sum = 0.0; break; case FIRST_EXACT_53_BITS: case AFTER_BIT_53: // do nothing break; case ZEROS_AFTER_54: // x1.1 -> x1 + 1 (round up) // x0.1 -> x0 (round down) if (bit54 & bit53) sum += 1.0; sum *= factor; break; case MIXED_AFTER_54: // x.100...1.. -> x + 1 (round up) // x.0anything -> x (round down) if (bit54) sum += 1.0; sum *= factor; break; } } /* We don't worry about inaccurate numbers for any other base. */ } return sum; } /** * ToNumber applied to the String type * * See ECMA 9.3.1 */ public static double toNumber(String s) { int len = s.length(); int start = 0; char startChar; for (;;) { if (start == len) { // Empty or contains only whitespace return +0.0; } startChar = s.charAt(start); if (!Character.isWhitespace(startChar)) break; start++; } if (startChar == '0') { if (start + 2 < len) { int c1 = s.charAt(start + 1); if (c1 == 'x' || c1 == 'X') { // A hexadecimal number return stringToNumber(s, start + 2, 16); } } } else if (startChar == '+' || startChar == '-') { if (start + 3 < len && s.charAt(start + 1) == '0') { int c2 = s.charAt(start + 2); if (c2 == 'x' || c2 == 'X') { // A hexadecimal number with sign double val = stringToNumber(s, start + 3, 16); return startChar == '-' ? -val : val; } } } int end = len - 1; char endChar; while (Character.isWhitespace(endChar = s.charAt(end))) end--; if (endChar == 'y') { // check for "Infinity" if (startChar == '+' || startChar == '-') start++; if (start + 7 == end && s.regionMatches(start, "Infinity", 0, 8)) return startChar == '-' ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; return NaN; } // A non-hexadecimal, non-infinity number: // just try a normal floating point conversion String sub = s.substring(start, end+1); if (MSJVM_BUG_WORKAROUNDS) { // The MS JVM will accept non-conformant strings // rather than throwing a NumberFormatException // as it should. for (int i=sub.length()-1; i >= 0; i--) { char c = sub.charAt(i); if (('0' <= c && c <= '9') || c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-') continue; return NaN; } } try { return Double.valueOf(sub).doubleValue(); } catch (NumberFormatException ex) { return NaN; } } /** * Helper function for builtin objects that use the varargs form. * ECMA function formal arguments are undefined if not supplied; * this function pads the argument array out to the expected * length, if necessary. */ public static Object[] padArguments(Object[] args, int count) { if (count < args.length) return args; int i; Object[] result = new Object[count]; for (i = 0; i < args.length; i++) { result[i] = args[i]; } for (; i < count; i++) { result[i] = Undefined.instance; } return result; } /* Work around Microsoft Java VM bugs. */ private final static boolean MSJVM_BUG_WORKAROUNDS = true; public static String escapeString(String s) { return escapeString(s, '"'); } /** * For escaping strings printed by object and array literals; not quite * the same as 'escape.' */ public static String escapeString(String s, char escapeQuote) { if (!(escapeQuote == '"' || escapeQuote == '\'')) Kit.codeBug(); StringBuffer sb = null; for(int i = 0, L = s.length(); i != L; ++i) { int c = s.charAt(i); if (' ' <= c && c <= '~' && c != escapeQuote && c != '\\') { // an ordinary print character (like C isprint()) and not " // or \ . if (sb != null) { sb.append((char)c); } continue; } if (sb == null) { sb = new StringBuffer(L + 3); sb.append(s); sb.setLength(i); } int escape = -1; switch (c) { case '\b': escape = 'b'; break; case '\f': escape = 'f'; break; case '\n': escape = 'n'; break; case '\r': escape = 'r'; break; case '\t': escape = 't'; break; case 0xb: escape = 'v'; break; // Java lacks \v. case ' ': escape = ' '; break; case '\\': escape = '\\'; break; } if (escape >= 0) { // an \escaped sort of character sb.append('\\'); sb.append((char)escape); } else if (c == escapeQuote) { sb.append('\\'); sb.append(escapeQuote); } else { int hexSize; if (c < 256) { // 2-digit hex sb.append("\\x"); hexSize = 2; } else { // Unicode. sb.append("\\u"); hexSize = 4; } // append hexadecimal form of c left-padded with 0 for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) { int digit = 0xf & (c >> shift); int hc = (digit < 10) ? '0' + digit : 'a' - 10 + digit; sb.append((char)hc); } } } return (sb == null) ? s : sb.toString(); } static boolean isValidIdentifierName(String s) { int L = s.length(); if (L == 0) return false; if (!Character.isJavaIdentifierStart(s.charAt(0))) return false; for (int i = 1; i != L; ++i) { if (!Character.isJavaIdentifierPart(s.charAt(i))) return false; } return !TokenStream.isKeyword(s); } /** * Convert the value to a string. * * See ECMA 9.8. */ public static String toString(Object val) { for (;;) { if (val == null) { return "null"; } if (val == Undefined.instance) { return "undefined"; } if (val instanceof String) { return (String)val; } if (val instanceof Number) { // XXX should we just teach NativeNumber.stringValue() // about Numbers? return numberToString(((Number)val).doubleValue(), 10); } if (val instanceof Scriptable) { val = ((Scriptable) val).getDefaultValue(StringClass); if (val instanceof Scriptable) { throw errorWithClassName("msg.primitive.expected", val); } continue; } return val.toString(); } } static String defaultObjectToString(Scriptable obj) { return "[object " + obj.getClassName() + ']'; } public static String toString(Object[] args, int index) { return (index < args.length) ? toString(args[index]) : "undefined"; } /** * Optimized version of toString(Object) for numbers. */ public static String toString(double val) { return numberToString(val, 10); } public static String numberToString(double d, int base) { if (d != d) return "NaN"; if (d == Double.POSITIVE_INFINITY) return "Infinity"; if (d == Double.NEGATIVE_INFINITY) return "-Infinity"; if (d == 0.0) return "0"; if ((base < 2) || (base > 36)) { throw Context.reportRuntimeError1( "msg.bad.radix", Integer.toString(base)); } if (base != 10) { return DToA.JS_dtobasestr(base, d); } else { StringBuffer result = new StringBuffer(); DToA.JS_dtostr(result, DToA.DTOSTR_STANDARD, 0, d); return result.toString(); } } static String uneval(Context cx, Scriptable scope, Object value) { if (value == null) { return "null"; } if (value == Undefined.instance) { return "undefined"; } if (value instanceof String) { String escaped = escapeString((String)value); StringBuffer sb = new StringBuffer(escaped.length() + 2); sb.append('\"'); sb.append(escaped); sb.append('\"'); return sb.toString(); } if (value instanceof Number) { double d = ((Number)value).doubleValue(); if (d == 0 && 1 / d < 0) { return "-0"; } return toString(d); } if (value instanceof Boolean) { return toString(value); } if (value instanceof Scriptable) { Scriptable obj = (Scriptable)value; // Wrapped Java objects won't have "toSource" and will report // errors for get()s of nonexistent name, so use has() first if (ScriptableObject.hasProperty(obj, "toSource")) { Object v = ScriptableObject.getProperty(obj, "toSource"); if (v instanceof Function) { Function f = (Function)v; return toString(f.call(cx, scope, obj, emptyArgs)); } } return toString(value); } warnAboutNonJSObject(value); return value.toString(); } static String defaultObjectToSource(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { boolean toplevel, iterating; if (cx.iterating == null) { toplevel = true; iterating = false; cx.iterating = new ObjToIntMap(31); } else { toplevel = false; iterating = cx.iterating.has(thisObj); } StringBuffer result = new StringBuffer(128); if (toplevel) { result.append("("); } result.append('{'); // Make sure cx.iterating is set to null when done // so we don't leak memory try { if (!iterating) { cx.iterating.intern(thisObj); // stop recursion. Object[] ids = thisObj.getIds(); for (int i=0; i < ids.length; i++) { Object id = ids[i]; Object value; if (id instanceof Integer) { int intId = ((Integer)id).intValue(); value = thisObj.get(intId, thisObj); if (value == Scriptable.NOT_FOUND) continue; // a property has been removed if (i > 0) result.append(", "); result.append(intId); } else { String strId = (String)id; value = thisObj.get(strId, thisObj); if (value == Scriptable.NOT_FOUND) continue; // a property has been removed if (i > 0) result.append(", "); if (ScriptRuntime.isValidIdentifierName(strId)) { result.append(strId); } else { result.append('\''); result.append( ScriptRuntime.escapeString(strId, '\'')); result.append('\''); } } result.append(':'); result.append(ScriptRuntime.uneval(cx, scope, value)); } } } finally { if (toplevel) { cx.iterating = null; } } result.append('}'); if (toplevel) { result.append(')'); } return result.toString(); } public static Scriptable toObject(Scriptable scope, Object val) { if (val instanceof Scriptable) { return (Scriptable)val; } return toObject(Context.getContext(), scope, val); } /** * Warning: this doesn't allow to resolve primitive prototype properly when many top scopes are involved */ public static Scriptable toObjectOrNull(Context cx, Object obj) { if (obj instanceof Scriptable) { return (Scriptable)obj; } else if (obj != null && obj != Undefined.instance) { return toObject(cx, getTopCallScope(cx), obj); } return null; } /** * @param scope the scope that should be used to resolve primitive prototype */ public static Scriptable toObjectOrNull(Context cx, Object obj, final Scriptable scope) { if (obj instanceof Scriptable) { return (Scriptable)obj; } else if (obj != null && obj != Undefined.instance) { return toObject(cx, scope, obj); } return null; } /** * @deprecated Use {@link #toObject(Scriptable, Object)} instead. */ public static Scriptable toObject(Scriptable scope, Object val, Class staticClass) { if (val instanceof Scriptable) { return (Scriptable)val; } return toObject(Context.getContext(), scope, val); } /** * Convert the value to an object. * * See ECMA 9.9. */ public static Scriptable toObject(Context cx, Scriptable scope, Object val) { if (val instanceof Scriptable) { return (Scriptable) val; } if (val == null) { throw typeError0("msg.null.to.object"); } if (val == Undefined.instance) { throw typeError0("msg.undef.to.object"); } String className = val instanceof String ? "String" : val instanceof Number ? "Number" : val instanceof Boolean ? "Boolean" : null; if (className != null) { Object[] args = { val }; scope = ScriptableObject.getTopLevelScope(scope); return newObject(cx, scope, className, args); } // Extension: Wrap as a LiveConnect object. Object wrapped = cx.getWrapFactory().wrap(cx, scope, val, null); if (wrapped instanceof Scriptable) return (Scriptable) wrapped; throw errorWithClassName("msg.invalid.type", val); } /** * @deprecated Use {@link #toObject(Context, Scriptable, Object)} instead. */ public static Scriptable toObject(Context cx, Scriptable scope, Object val, Class staticClass) { return toObject(cx, scope, val); } /** * @deprecated The method is only present for compatibility. */ public static Object call(Context cx, Object fun, Object thisArg, Object[] args, Scriptable scope) { if (!(fun instanceof Function)) { throw notFunctionError(toString(fun)); } Function function = (Function)fun; Scriptable thisObj = toObjectOrNull(cx, thisArg); if (thisObj == null) { throw undefCallError(thisObj, "function"); } return function.call(cx, scope, thisObj, args); } public static Scriptable newObject(Context cx, Scriptable scope, String constructorName, Object[] args) { scope = ScriptableObject.getTopLevelScope(scope); Function ctor = getExistingCtor(cx, scope, constructorName); if (args == null) { args = ScriptRuntime.emptyArgs; } return ctor.construct(cx, scope, args); } /** * * See ECMA 9.4. */ public static double toInteger(Object val) { return toInteger(toNumber(val)); } // convenience method public static double toInteger(double d) { // if it's NaN if (d != d) return +0.0; if (d == 0.0 || d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY) return d; if (d > 0.0) return Math.floor(d); else return Math.ceil(d); } public static double toInteger(Object[] args, int index) { return (index < args.length) ? toInteger(args[index]) : +0.0; } /** * * See ECMA 9.5. */ public static int toInt32(Object val) { // short circuit for common integer values if (val instanceof Integer) return ((Integer)val).intValue(); return toInt32(toNumber(val)); } public static int toInt32(Object[] args, int index) { return (index < args.length) ? toInt32(args[index]) : 0; } public static int toInt32(double d) { int id = (int)d; if (id == d) { // This covers -0.0 as well return id; } if (d != d || d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY) { return 0; } d = (d >= 0) ? Math.floor(d) : Math.ceil(d); double two32 = 4294967296.0; d = Math.IEEEremainder(d, two32); // (double)(long)d == d should hold here long l = (long)d; // returning (int)d does not work as d can be outside int range // but the result must always be 32 lower bits of l return (int)l; } /** * See ECMA 9.6. * @return long value representing 32 bits unsigned integer */ public static long toUint32(double d) { long l = (long)d; if (l == d) { // This covers -0.0 as well return l & 0xffffffffL; } if (d != d || d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY) { return 0; } d = (d >= 0) ? Math.floor(d) : Math.ceil(d); // 0x100000000 gives me a numeric overflow... double two32 = 4294967296.0; l = (long)Math.IEEEremainder(d, two32); return l & 0xffffffffL; } public static long toUint32(Object val) { return toUint32(toNumber(val)); } /** * * See ECMA 9.7. */ public static char toUint16(Object val) { double d = toNumber(val); int i = (int)d; if (i == d) { return (char)i; } if (d != d || d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY) { return 0; } d = (d >= 0) ? Math.floor(d) : Math.ceil(d); int int16 = 0x10000; i = (int)Math.IEEEremainder(d, int16); return (char)i; } // XXX: this is until setDefaultNamespace will learn how to store NS // properly and separates namespace form Scriptable.get etc. private static final String DEFAULT_NS_TAG = "__default_namespace__"; public static Object setDefaultNamespace(Object namespace, Context cx) { Scriptable scope = cx.currentActivationCall; if (scope == null) { scope = getTopCallScope(cx); } XMLLib xmlLib = currentXMLLib(cx); Object ns = xmlLib.toDefaultXmlNamespace(cx, namespace); // XXX : this should be in separated namesapce from Scriptable.get/put if (!scope.has(DEFAULT_NS_TAG, scope)) { // XXX: this is racy of cause ScriptableObject.defineProperty(scope, DEFAULT_NS_TAG, ns, ScriptableObject.PERMANENT | ScriptableObject.DONTENUM); } else { scope.put(DEFAULT_NS_TAG, scope, ns); } return Undefined.instance; } public static Object searchDefaultNamespace(Context cx) { Scriptable scope = cx.currentActivationCall; if (scope == null) { scope = getTopCallScope(cx); } Object nsObject; for (;;) { Scriptable parent = scope.getParentScope(); if (parent == null) { nsObject = ScriptableObject.getProperty(scope, DEFAULT_NS_TAG); if (nsObject == Scriptable.NOT_FOUND) { return null; } break; } nsObject = scope.get(DEFAULT_NS_TAG, scope); if (nsObject != Scriptable.NOT_FOUND) { break; } scope = parent; } return nsObject; } public static Object getTopLevelProp(Scriptable scope, String id) { scope = ScriptableObject.getTopLevelScope(scope); return ScriptableObject.getProperty(scope, id); } static Function getExistingCtor(Context cx, Scriptable scope, String constructorName) { Object ctorVal = ScriptableObject.getProperty(scope, constructorName); if (ctorVal instanceof Function) { return (Function)ctorVal; } if (ctorVal == Scriptable.NOT_FOUND) { throw Context.reportRuntimeError1( "msg.ctor.not.found", constructorName); } else { throw Context.reportRuntimeError1( "msg.not.ctor", constructorName); } } /** * Return -1L if str is not an index or the index value as lower 32 * bits of the result. */ private static long indexFromString(String str) { // The length of the decimal string representation of // Integer.MAX_VALUE, 2147483647 final int MAX_VALUE_LENGTH = 10; int len = str.length(); if (len > 0) { int i = 0; boolean negate = false; int c = str.charAt(0); if (c == '-') { if (len > 1) { c = str.charAt(1); i = 1; negate = true; } } c -= '0'; if (0 <= c && c <= 9 && len <= (negate ? MAX_VALUE_LENGTH + 1 : MAX_VALUE_LENGTH)) { // Use negative numbers to accumulate index to handle // Integer.MIN_VALUE that is greater by 1 in absolute value // then Integer.MAX_VALUE int index = -c; int oldIndex = 0; i++; if (index != 0) { // Note that 00, 01, 000 etc. are not indexes while (i != len && 0 <= (c = str.charAt(i) - '0') && c <= 9) { oldIndex = index; index = 10 * index - c; i++; } } // Make sure all characters were consumed and that it couldn't // have overflowed. if (i == len && (oldIndex > (Integer.MIN_VALUE / 10) || (oldIndex == (Integer.MIN_VALUE / 10) && c <= (negate ? -(Integer.MIN_VALUE % 10) : (Integer.MAX_VALUE % 10))))) { return 0xFFFFFFFFL & (negate ? index : -index); } } } return -1L; } /** * If str is a decimal presentation of Uint32 value, return it as long. * Othewise return -1L; */ public static long testUint32String(String str) { // The length of the decimal string representation of // UINT32_MAX_VALUE, 4294967296 final int MAX_VALUE_LENGTH = 10; int len = str.length(); if (1 <= len && len <= MAX_VALUE_LENGTH) { int c = str.charAt(0); c -= '0'; if (c == 0) { // Note that 00,01 etc. are not valid Uint32 presentations return (len == 1) ? 0L : -1L; } if (1 <= c && c <= 9) { long v = c; for (int i = 1; i != len; ++i) { c = str.charAt(i) - '0'; if (!(0 <= c && c <= 9)) { return -1; } v = 10 * v + c; } // Check for overflow if ((v >>> 32) == 0) { return v; } } } return -1; } /** * If s represents index, then return index value wrapped as Integer * and othewise return s. */ static Object getIndexObject(String s) { long indexTest = indexFromString(s); if (indexTest >= 0) { return new Integer((int)indexTest); } return s; } /** * If d is exact int value, return its value wrapped as Integer * and othewise return d converted to String. */ static Object getIndexObject(double d) { int i = (int)d; if (i == d) { return new Integer(i); } return toString(d); } /** * If toString(id) is a decimal presentation of int32 value, then id * is index. In this case return null and make the index available * as ScriptRuntime.lastIndexResult(cx). Otherwise return toString(id). */ static String toStringIdOrIndex(Context cx, Object id) { if (id instanceof Number) { double d = ((Number)id).doubleValue(); int index = (int)d; if (index == d) { storeIndexResult(cx, index); return null; } return toString(id); } else { String s; if (id instanceof String) { s = (String)id; } else { s = toString(id); } long indexTest = indexFromString(s); if (indexTest >= 0) { storeIndexResult(cx, (int)indexTest); return null; } return s; } } /** * Call obj.[[Get]](id) */ public static Object getObjectElem(Object obj, Object elem, Context cx) { return getObjectElem(obj, elem, cx, getTopCallScope(cx)); } /** * Call obj.[[Get]](id) */ public static Object getObjectElem(Object obj, Object elem, Context cx, final Scriptable scope) { Scriptable sobj = toObjectOrNull(cx, obj, scope); if (sobj == null) { throw undefReadError(obj, elem); } return getObjectElem(sobj, elem, cx); } public static Object getObjectElem(Scriptable obj, Object elem, Context cx) { if (obj instanceof XMLObject) { XMLObject xmlObject = (XMLObject)obj; return xmlObject.ecmaGet(cx, elem); } Object result; String s = toStringIdOrIndex(cx, elem); if (s == null) { int index = lastIndexResult(cx); result = ScriptableObject.getProperty(obj, index); } else { result = ScriptableObject.getProperty(obj, s); } if (result == Scriptable.NOT_FOUND) { result = Undefined.instance; } return result; } /** * Version of getObjectElem when elem is a valid JS identifier name. */ public static Object getObjectProp(Object obj, String property, Context cx) { Scriptable sobj = toObjectOrNull(cx, obj); if (sobj == null) { throw undefReadError(obj, property); } return getObjectProp(sobj, property, cx); } /** * @param scope the scope that should be used to resolve primitive prototype */ public static Object getObjectProp(Object obj, String property, Context cx, final Scriptable scope) { Scriptable sobj = toObjectOrNull(cx, obj, scope); if (sobj == null) { throw undefReadError(obj, property); } return getObjectProp(sobj, property, cx); } public static Object getObjectProp(Scriptable obj, String property, Context cx) { if (obj instanceof XMLObject) { // TODO: Change XMLObject to just use Scriptable interface // to avoid paying cost of instanceof check on *every property // lookup* ! XMLObject xmlObject = (XMLObject)obj; return xmlObject.ecmaGet(cx, property); } Object result = ScriptableObject.getProperty(obj, property); if (result == Scriptable.NOT_FOUND) { if (cx.hasFeature(Context.FEATURE_STRICT_MODE)) { Context.reportWarning(ScriptRuntime.getMessage1( "msg.ref.undefined.prop", property)); } result = Undefined.instance; } return result; } public static Object getObjectPropNoWarn(Object obj, String property, Context cx) { Scriptable sobj = toObjectOrNull(cx, obj); if (sobj == null) { throw undefReadError(obj, property); } if (obj instanceof XMLObject) { // TODO: fix as mentioned in note in method above getObjectProp(sobj, property, cx); } Object result = ScriptableObject.getProperty(sobj, property); if (result == Scriptable.NOT_FOUND) { return Undefined.instance; } return result; } /* * A cheaper and less general version of the above for well-known argument * types. */ public static Object getObjectIndex(Object obj, double dblIndex, Context cx) { Scriptable sobj = toObjectOrNull(cx, obj); if (sobj == null) { throw undefReadError(obj, toString(dblIndex)); } int index = (int)dblIndex; if (index == dblIndex) { return getObjectIndex(sobj, index, cx); } else { String s = toString(dblIndex); return getObjectProp(sobj, s, cx); } } public static Object getObjectIndex(Scriptable obj, int index, Context cx) { if (obj instanceof XMLObject) { XMLObject xmlObject = (XMLObject)obj; return xmlObject.ecmaGet(cx, new Integer(index)); } Object result = ScriptableObject.getProperty(obj, index); if (result == Scriptable.NOT_FOUND) { result = Undefined.instance; } return result; } /* * Call obj.[[Put]](id, value) */ public static Object setObjectElem(Object obj, Object elem, Object value, Context cx) { Scriptable sobj = toObjectOrNull(cx, obj); if (sobj == null) { throw undefWriteError(obj, elem, value); } return setObjectElem(sobj, elem, value, cx); } public static Object setObjectElem(Scriptable obj, Object elem, Object value, Context cx) { if (obj instanceof XMLObject) { XMLObject xmlObject = (XMLObject)obj; xmlObject.ecmaPut(cx, elem, value); return value; } String s = toStringIdOrIndex(cx, elem); if (s == null) { int index = lastIndexResult(cx); ScriptableObject.putProperty(obj, index, value); } else { ScriptableObject.putProperty(obj, s, value); } return value; } /** * Version of setObjectElem when elem is a valid JS identifier name. */ public static Object setObjectProp(Object obj, String property, Object value, Context cx) { Scriptable sobj = toObjectOrNull(cx, obj); if (sobj == null) { throw undefWriteError(obj, property, value); } return setObjectProp(sobj, property, value, cx); } public static Object setObjectProp(Scriptable obj, String property, Object value, Context cx) { if (obj instanceof XMLObject) { XMLObject xmlObject = (XMLObject)obj; xmlObject.ecmaPut(cx, property, value); } else { ScriptableObject.putProperty(obj, property, value); } return value; } /* * A cheaper and less general version of the above for well-known argument * types. */ public static Object setObjectIndex(Object obj, double dblIndex, Object value, Context cx) { Scriptable sobj = toObjectOrNull(cx, obj); if (sobj == null) { throw undefWriteError(obj, String.valueOf(dblIndex), value); } int index = (int)dblIndex; if (index == dblIndex) { return setObjectIndex(sobj, index, value, cx); } else { String s = toString(dblIndex); return setObjectProp(sobj, s, value, cx); } } public static Object setObjectIndex(Scriptable obj, int index, Object value, Context cx) { if (obj instanceof XMLObject) { XMLObject xmlObject = (XMLObject)obj; xmlObject.ecmaPut(cx, new Integer(index), value); } else { ScriptableObject.putProperty(obj, index, value); } return value; } public static boolean deleteObjectElem(Scriptable target, Object elem, Context cx) { boolean result; if (target instanceof XMLObject) { XMLObject xmlObject = (XMLObject)target; result = xmlObject.ecmaDelete(cx, elem); } else { String s = toStringIdOrIndex(cx, elem); if (s == null) { int index = lastIndexResult(cx); result = ScriptableObject.deleteProperty(target, index); } else { result = ScriptableObject.deleteProperty(target, s); } } return result; } public static boolean hasObjectElem(Scriptable target, Object elem, Context cx) { boolean result; if (target instanceof XMLObject) { XMLObject xmlObject = (XMLObject)target; result = xmlObject.ecmaHas(cx, elem); } else { String s = toStringIdOrIndex(cx, elem); if (s == null) { int index = lastIndexResult(cx); result = ScriptableObject.hasProperty(target, index); } else { result = ScriptableObject.hasProperty(target, s); } } return result; } public static Object refGet(Ref ref, Context cx) { return ref.get(cx); } public static Object refSet(Ref ref, Object value, Context cx) { return ref.set(cx, value); } public static Object refDel(Ref ref, Context cx) { return wrapBoolean(ref.delete(cx)); } static boolean isSpecialProperty(String s) { return s.equals("__proto__") || s.equals("__parent__"); } public static Ref specialRef(Object obj, String specialProperty, Context cx) { return SpecialRef.createSpecial(cx, obj, specialProperty); } /** * The delete operator * * See ECMA 11.4.1 * * In ECMA 0.19, the description of the delete operator (11.4.1) * assumes that the [[Delete]] method returns a value. However, * the definition of the [[Delete]] operator (8.6.2.5) does not * define a return value. Here we assume that the [[Delete]] * method doesn't return a value. */ public static Object delete(Object obj, Object id, Context cx) { Scriptable sobj = toObjectOrNull(cx, obj); if (sobj == null) { String idStr = (id == null) ? "null" : id.toString(); throw typeError2("msg.undef.prop.delete", toString(obj), idStr); } boolean result = deleteObjectElem(sobj, id, cx); return wrapBoolean(result); } /** * Looks up a name in the scope chain and returns its value. */ public static Object name(Context cx, Scriptable scope, String name) { Scriptable parent = scope.getParentScope(); if (parent == null) { Object result = topScopeName(cx, scope, name); if (result == Scriptable.NOT_FOUND) { throw notFoundError(scope, name); } return result; } return nameOrFunction(cx, scope, parent, name, false); } private static Object nameOrFunction(Context cx, Scriptable scope, Scriptable parentScope, String name, boolean asFunctionCall) { Object result; Scriptable thisObj = scope; // It is used only if asFunctionCall==true. XMLObject firstXMLObject = null; for (;;) { if (scope instanceof NativeWith) { Scriptable withObj = scope.getPrototype(); if (withObj instanceof XMLObject) { XMLObject xmlObj = (XMLObject)withObj; if (xmlObj.ecmaHas(cx, name)) { // function this should be the target object of with thisObj = xmlObj; result = xmlObj.ecmaGet(cx, name); break; } if (firstXMLObject == null) { firstXMLObject = xmlObj; } } else { result = ScriptableObject.getProperty(withObj, name); if (result != Scriptable.NOT_FOUND) { // function this should be the target object of with thisObj = withObj; break; } } } else if (scope instanceof NativeCall) { // NativeCall does not prototype chain and Scriptable.get // can be called directly. result = scope.get(name, scope); if (result != Scriptable.NOT_FOUND) { if (asFunctionCall) { // ECMA 262 requires that this for nested funtions // should be top scope thisObj = ScriptableObject. getTopLevelScope(parentScope); } break; } } else { // Can happen if Rhino embedding decided that nested // scopes are useful for what ever reasons. result = ScriptableObject.getProperty(scope, name); if (result != Scriptable.NOT_FOUND) { thisObj = scope; break; } } scope = parentScope; parentScope = parentScope.getParentScope(); if (parentScope == null) { result = topScopeName(cx, scope, name); if (result == Scriptable.NOT_FOUND) { if (firstXMLObject == null || asFunctionCall) { throw notFoundError(scope, name); } // The name was not found, but we did find an XML // object in the scope chain and we are looking for name, // not function. The result should be an empty XMLList // in name context. result = firstXMLObject.ecmaGet(cx, name); } // For top scope thisObj for functions is always scope itself. thisObj = scope; break; } } if (asFunctionCall) { if (!(result instanceof Callable)) { throw notFunctionError(result, name); } storeScriptable(cx, thisObj); } return result; } private static Object topScopeName(Context cx, Scriptable scope, String name) { if (cx.useDynamicScope) { scope = checkDynamicScope(cx.topCallScope, scope); } return ScriptableObject.getProperty(scope, name); } /** * Returns the object in the scope chain that has a given property. * * The order of evaluation of an assignment expression involves * evaluating the lhs to a reference, evaluating the rhs, and then * modifying the reference with the rhs value. This method is used * to 'bind' the given name to an object containing that property * so that the side effects of evaluating the rhs do not affect * which property is modified. * Typically used in conjunction with setName. * * See ECMA 10.1.4 */ public static Scriptable bind(Context cx, Scriptable scope, String id) { Scriptable firstXMLObject = null; Scriptable parent = scope.getParentScope(); childScopesChecks: if (parent != null) { // Check for possibly nested "with" scopes first while (scope instanceof NativeWith) { Scriptable withObj = scope.getPrototype(); if (withObj instanceof XMLObject) { XMLObject xmlObject = (XMLObject)withObj; if (xmlObject.ecmaHas(cx, id)) { return xmlObject; } if (firstXMLObject == null) { firstXMLObject = xmlObject; } } else { if (ScriptableObject.hasProperty(withObj, id)) { return withObj; } } scope = parent; parent = parent.getParentScope(); if (parent == null) { break childScopesChecks; } } for (;;) { if (ScriptableObject.hasProperty(scope, id)) { return scope; } scope = parent; parent = parent.getParentScope(); if (parent == null) { break childScopesChecks; } } } // scope here is top scope if (cx.useDynamicScope) { scope = checkDynamicScope(cx.topCallScope, scope); } if (ScriptableObject.hasProperty(scope, id)) { return scope; } // Nothing was found, but since XML objects always bind // return one if found return firstXMLObject; } public static Object setName(Scriptable bound, Object value, Context cx, Scriptable scope, String id) { if (bound != null) { if (bound instanceof XMLObject) { XMLObject xmlObject = (XMLObject)bound; xmlObject.ecmaPut(cx, id, value); } else { ScriptableObject.putProperty(bound, id, value); } } else { // "newname = 7;", where 'newname' has not yet // been defined, creates a new property in the // top scope unless strict mode is specified. if (cx.hasFeature(Context.FEATURE_STRICT_MODE) || cx.hasFeature(Context.FEATURE_STRICT_VARS)) { Context.reportWarning( ScriptRuntime.getMessage1("msg.assn.create.strict", id)); } // Find the top scope by walking up the scope chain. bound = ScriptableObject.getTopLevelScope(scope); if (cx.useDynamicScope) { bound = checkDynamicScope(cx.topCallScope, bound); } bound.put(id, bound, value); } return value; } public static Object setConst(Scriptable bound, Object value, Context cx, String id) { if (bound instanceof XMLObject) { XMLObject xmlObject = (XMLObject)bound; xmlObject.ecmaPut(cx, id, value); } else { ScriptableObject.putConstProperty(bound, id, value); } return value; } /** * This is the enumeration needed by the for..in statement. * * See ECMA 12.6.3. * * IdEnumeration maintains a ObjToIntMap to make sure a given * id is enumerated only once across multiple objects in a * prototype chain. * * XXX - ECMA delete doesn't hide properties in the prototype, * but js/ref does. This means that the js/ref for..in can * avoid maintaining a hash table and instead perform lookups * to see if a given property has already been enumerated. * */ private static class IdEnumeration implements Serializable { private static final long serialVersionUID = 1L; Scriptable obj; Object[] ids; int index; ObjToIntMap used; Object currentId; int enumType; /* one of ENUM_INIT_KEYS, ENUM_INIT_VALUES, ENUM_INIT_ARRAY */ // if true, integer ids will be returned as numbers rather than strings boolean enumNumbers; Scriptable iterator; } public static Scriptable toIterator(Context cx, Scriptable scope, Scriptable obj, boolean keyOnly) { if (ScriptableObject.hasProperty(obj, NativeIterator.ITERATOR_PROPERTY_NAME)) { Object v = ScriptableObject.getProperty(obj, NativeIterator.ITERATOR_PROPERTY_NAME); if (!(v instanceof Callable)) { throw typeError0("msg.invalid.iterator"); } Callable f = (Callable) v; Object[] args = new Object[] { keyOnly ? Boolean.TRUE : Boolean.FALSE }; v = f.call(cx, scope, obj, args); if (!(v instanceof Scriptable)) { throw typeError0("msg.iterator.primitive"); } return (Scriptable) v; } return null; } // for backwards compatibility with generated class files public static Object enumInit(Object value, Context cx, boolean enumValues) { return enumInit(value, cx, enumValues ? ENUMERATE_VALUES : ENUMERATE_KEYS); } public static final int ENUMERATE_KEYS = 0; public static final int ENUMERATE_VALUES = 1; public static final int ENUMERATE_ARRAY = 2; public static final int ENUMERATE_KEYS_NO_ITERATOR = 3; public static final int ENUMERATE_VALUES_NO_ITERATOR = 4; public static final int ENUMERATE_ARRAY_NO_ITERATOR = 5; public static Object enumInit(Object value, Context cx, int enumType) { IdEnumeration x = new IdEnumeration(); x.obj = toObjectOrNull(cx, value); if (x.obj == null) { // null or undefined do not cause errors but rather lead to empty // "for in" loop return x; } x.enumType = enumType; x.iterator = null; if (enumType != ENUMERATE_KEYS_NO_ITERATOR && enumType != ENUMERATE_VALUES_NO_ITERATOR && enumType != ENUMERATE_ARRAY_NO_ITERATOR) { x.iterator = toIterator(cx, x.obj.getParentScope(), x.obj, true); } if (x.iterator == null) { // enumInit should read all initial ids before returning // or "for (a.i in a)" would wrongly enumerate i in a as well enumChangeObject(x); } return x; } public static void setEnumNumbers(Object enumObj, boolean enumNumbers) { ((IdEnumeration)enumObj).enumNumbers = enumNumbers; } public static Boolean enumNext(Object enumObj) { IdEnumeration x = (IdEnumeration)enumObj; if (x.iterator != null) { Object v = ScriptableObject.getProperty(x.iterator, "next"); if (!(v instanceof Callable)) return Boolean.FALSE; Callable f = (Callable) v; Context cx = Context.getContext(); try { x.currentId = f.call(cx, x.iterator.getParentScope(), x.iterator, emptyArgs); return Boolean.TRUE; } catch (JavaScriptException e) { if (e.getValue() instanceof NativeIterator.StopIteration) { return Boolean.FALSE; } throw e; } } for (;;) { if (x.obj == null) { return Boolean.FALSE; } if (x.index == x.ids.length) { x.obj = x.obj.getPrototype(); enumChangeObject(x); continue; } Object id = x.ids[x.index++]; if (x.used != null && x.used.has(id)) { continue; } if (id instanceof String) { String strId = (String)id; if (!x.obj.has(strId, x.obj)) continue; // must have been deleted x.currentId = strId; } else { int intId = ((Number)id).intValue(); if (!x.obj.has(intId, x.obj)) continue; // must have been deleted x.currentId = x.enumNumbers ? (Object) (new Integer(intId)) : String.valueOf(intId); } return Boolean.TRUE; } } public static Object enumId(Object enumObj, Context cx) { IdEnumeration x = (IdEnumeration)enumObj; if (x.iterator != null) { return x.currentId; } switch (x.enumType) { case ENUMERATE_KEYS: case ENUMERATE_KEYS_NO_ITERATOR: return x.currentId; case ENUMERATE_VALUES: case ENUMERATE_VALUES_NO_ITERATOR: return enumValue(enumObj, cx); case ENUMERATE_ARRAY: case ENUMERATE_ARRAY_NO_ITERATOR: Object[] elements = { x.currentId, enumValue(enumObj, cx) }; return cx.newArray(x.obj, elements); default: throw Kit.codeBug(); } } public static Object enumValue(Object enumObj, Context cx) { IdEnumeration x = (IdEnumeration)enumObj; Object result; String s = toStringIdOrIndex(cx, x.currentId); if (s == null) { int index = lastIndexResult(cx); result = x.obj.get(index, x.obj); } else { result = x.obj.get(s, x.obj); } return result; } private static void enumChangeObject(IdEnumeration x) { Object[] ids = null; while (x.obj != null) { ids = x.obj.getIds(); if (ids.length != 0) { break; } x.obj = x.obj.getPrototype(); } if (x.obj != null && x.ids != null) { Object[] previous = x.ids; int L = previous.length; if (x.used == null) { x.used = new ObjToIntMap(L); } for (int i = 0; i != L; ++i) { x.used.intern(previous[i]); } } x.ids = ids; x.index = 0; } /** * Prepare for calling name(...): return function corresponding to * name and make current top scope available * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj. * The caller must call ScriptRuntime.lastStoredScriptable() immediately * after calling this method. */ public static Callable getNameFunctionAndThis(String name, Context cx, Scriptable scope) { Scriptable parent = scope.getParentScope(); if (parent == null) { Object result = topScopeName(cx, scope, name); if (!(result instanceof Callable)) { if (result == Scriptable.NOT_FOUND) { throw notFoundError(scope, name); } else { throw notFunctionError(result, name); } } // Top scope is not NativeWith or NativeCall => thisObj == scope Scriptable thisObj = scope; storeScriptable(cx, thisObj); return (Callable)result; } // name will call storeScriptable(cx, thisObj); return (Callable)nameOrFunction(cx, scope, parent, name, true); } /** * Prepare for calling obj[id](...): return function corresponding to * obj[id] and make obj properly converted to Scriptable available * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj. * The caller must call ScriptRuntime.lastStoredScriptable() immediately * after calling this method. */ public static Callable getElemFunctionAndThis(Object obj, Object elem, Context cx) { String s = toStringIdOrIndex(cx, elem); if (s != null) { return getPropFunctionAndThis(obj, s, cx); } int index = lastIndexResult(cx); Scriptable thisObj = toObjectOrNull(cx, obj); if (thisObj == null) { throw undefCallError(obj, String.valueOf(index)); } Object value; for (;;) { // Ignore XML lookup as required by ECMA 357, 11.2.2.1 value = ScriptableObject.getProperty(thisObj, index); if (value != Scriptable.NOT_FOUND) { break; } if (!(thisObj instanceof XMLObject)) { break; } XMLObject xmlObject = (XMLObject)thisObj; Scriptable extra = xmlObject.getExtraMethodSource(cx); if (extra == null) { break; } thisObj = extra; } if (!(value instanceof Callable)) { throw notFunctionError(value, elem); } storeScriptable(cx, thisObj); return (Callable)value; } /** * Prepare for calling obj.property(...): return function corresponding to * obj.property and make obj properly converted to Scriptable available * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj. * The caller must call ScriptRuntime.lastStoredScriptable() immediately * after calling this method. * Warning: this doesn't allow to resolve primitive prototype properly when * many top scopes are involved. */ public static Callable getPropFunctionAndThis(Object obj, String property, Context cx) { Scriptable thisObj = toObjectOrNull(cx, obj); return getPropFunctionAndThisHelper(obj, property, cx, thisObj); } /** * Prepare for calling obj.property(...): return function corresponding to * obj.property and make obj properly converted to Scriptable available * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj. * The caller must call ScriptRuntime.lastStoredScriptable() immediately * after calling this method. */ public static Callable getPropFunctionAndThis(Object obj, String property, Context cx, final Scriptable scope) { Scriptable thisObj = toObjectOrNull(cx, obj, scope); return getPropFunctionAndThisHelper(obj, property, cx, thisObj); } private static Callable getPropFunctionAndThisHelper(Object obj, String property, Context cx, Scriptable thisObj) { if (thisObj == null) { throw undefCallError(obj, property); } Object value; for (;;) { // Ignore XML lookup as required by ECMA 357, 11.2.2.1 value = ScriptableObject.getProperty(thisObj, property); if (value != Scriptable.NOT_FOUND) { break; } if (!(thisObj instanceof XMLObject)) { break; } XMLObject xmlObject = (XMLObject)thisObj; Scriptable extra = xmlObject.getExtraMethodSource(cx); if (extra == null) { break; } thisObj = extra; } if (!(value instanceof Callable)) { Object noSuchMethod = ScriptableObject.getProperty(thisObj, "__noSuchMethod__"); if (noSuchMethod instanceof Callable) value = new NoSuchMethodShim((Callable)noSuchMethod, property); else throw notFunctionError(thisObj, value, property); } storeScriptable(cx, thisObj); return (Callable)value; } /** * Prepare for calling (...): return function corresponding to * and make parent scope of the function available * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj. * The caller must call ScriptRuntime.lastStoredScriptable() immediately * after calling this method. */ public static Callable getValueFunctionAndThis(Object value, Context cx) { if (!(value instanceof Callable)) { throw notFunctionError(value); } Callable f = (Callable)value; Scriptable thisObj = null; if (f instanceof Scriptable) { thisObj = ((Scriptable)f).getParentScope(); } if (thisObj == null) { if (cx.topCallScope == null) throw new IllegalStateException(); thisObj = cx.topCallScope; } if (thisObj.getParentScope() != null) { if (thisObj instanceof NativeWith) { // functions defined inside with should have with target // as their thisObj } else if (thisObj instanceof NativeCall) { // nested functions should have top scope as their thisObj thisObj = ScriptableObject.getTopLevelScope(thisObj); } } storeScriptable(cx, thisObj); return f; } /** * Perform function call in reference context. Should always * return value that can be passed to * {@link #refGet(Ref, Context)} or {@link #refSet(Ref, Object, Context)} * arbitrary number of times. * The args array reference should not be stored in any object that is * can be GC-reachable after this method returns. If this is necessary, * store args.clone(), not args array itself. */ public static Ref callRef(Callable function, Scriptable thisObj, Object[] args, Context cx) { if (function instanceof RefCallable) { RefCallable rfunction = (RefCallable)function; Ref ref = rfunction.refCall(cx, thisObj, args); if (ref == null) { throw new IllegalStateException(rfunction.getClass().getName()+".refCall() returned null"); } return ref; } // No runtime support for now String msg = getMessage1("msg.no.ref.from.function", toString(function)); throw constructError("ReferenceError", msg); } /** * Operator new. * * See ECMA 11.2.2 */ public static Scriptable newObject(Object fun, Context cx, Scriptable scope, Object[] args) { if (!(fun instanceof Function)) { throw notFunctionError(fun); } Function function = (Function)fun; return function.construct(cx, scope, args); } public static Object callSpecial(Context cx, Callable fun, Scriptable thisObj, Object[] args, Scriptable scope, Scriptable callerThis, int callType, String filename, int lineNumber) { if (callType == Node.SPECIALCALL_EVAL) { if (NativeGlobal.isEvalFunction(fun)) { return evalSpecial(cx, scope, callerThis, args, filename, lineNumber); } } else if (callType == Node.SPECIALCALL_WITH) { if (NativeWith.isWithFunction(fun)) { throw Context.reportRuntimeError1("msg.only.from.new", "With"); } } else { throw Kit.codeBug(); } return fun.call(cx, scope, thisObj, args); } public static Object newSpecial(Context cx, Object fun, Object[] args, Scriptable scope, int callType) { if (callType == Node.SPECIALCALL_EVAL) { if (NativeGlobal.isEvalFunction(fun)) { throw typeError1("msg.not.ctor", "eval"); } } else if (callType == Node.SPECIALCALL_WITH) { if (NativeWith.isWithFunction(fun)) { return NativeWith.newWithSpecial(cx, scope, args); } } else { throw Kit.codeBug(); } return newObject(fun, cx, scope, args); } /** * Function.prototype.apply and Function.prototype.call * * See Ecma 15.3.4.[34] */ public static Object applyOrCall(boolean isApply, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { int L = args.length; Callable function = getCallable(thisObj); Scriptable callThis = null; if (L != 0) { callThis = toObjectOrNull(cx, args[0]); } if (callThis == null) { // This covers the case of args[0] == (null|undefined) as well. callThis = getTopCallScope(cx); } Object[] callArgs; if (isApply) { // Follow Ecma 15.3.4.3 callArgs = L <= 1 ? ScriptRuntime.emptyArgs : getApplyArguments(cx, args[1]); } else { // Follow Ecma 15.3.4.4 if (L <= 1) { callArgs = ScriptRuntime.emptyArgs; } else { callArgs = new Object[L - 1]; System.arraycopy(args, 1, callArgs, 0, L - 1); } } return function.call(cx, scope, callThis, callArgs); } static Object[] getApplyArguments(Context cx, Object arg1) { if (arg1 == null || arg1 == Undefined.instance) { return ScriptRuntime.emptyArgs; } else if (arg1 instanceof NativeArray || arg1 instanceof Arguments) { return cx.getElements((Scriptable) arg1); } else { throw ScriptRuntime.typeError0("msg.arg.isnt.array"); } } static Callable getCallable(Scriptable thisObj) { Callable function; if (thisObj instanceof Callable) { function = (Callable)thisObj; } else { Object value = thisObj.getDefaultValue(ScriptRuntime.FunctionClass); if (!(value instanceof Callable)) { throw ScriptRuntime.notFunctionError(value, thisObj); } function = (Callable)value; } return function; } /** * The eval function property of the global object. * * See ECMA 15.1.2.1 */ public static Object evalSpecial(Context cx, Scriptable scope, Object thisArg, Object[] args, String filename, int lineNumber) { if (args.length < 1) return Undefined.instance; Object x = args[0]; if (!(x instanceof String)) { if (cx.hasFeature(Context.FEATURE_STRICT_MODE) || cx.hasFeature(Context.FEATURE_STRICT_EVAL)) { throw Context.reportRuntimeError0("msg.eval.nonstring.strict"); } String message = ScriptRuntime.getMessage0("msg.eval.nonstring"); Context.reportWarning(message); return x; } if (filename == null) { int[] linep = new int[1]; filename = Context.getSourcePositionFromStack(linep); if (filename != null) { lineNumber = linep[0]; } else { filename = ""; } } String sourceName = ScriptRuntime. makeUrlForGeneratedScript(true, filename, lineNumber); ErrorReporter reporter; reporter = DefaultErrorReporter.forEval(cx.getErrorReporter()); Evaluator evaluator = Context.createInterpreter(); if (evaluator == null) { throw new JavaScriptException("Interpreter not present", filename, lineNumber); } // Compile with explicit interpreter instance to force interpreter // mode. Script script = cx.compileString((String)x, evaluator, reporter, sourceName, 1, null); evaluator.setEvalScriptFlag(script); Callable c = (Callable)script; return c.call(cx, scope, (Scriptable)thisArg, ScriptRuntime.emptyArgs); } /** * The typeof operator */ public static String typeof(Object value) { if (value == null) return "object"; if (value == Undefined.instance) return "undefined"; if (value instanceof Scriptable) { if (value instanceof ScriptableObject && ((ScriptableObject)value).avoidObjectDetection()) { return "undefined"; } if (value instanceof XMLObject) return "xml"; return (value instanceof Callable) ? "function" : "object"; } if (value instanceof String) return "string"; if (value instanceof Number) return "number"; if (value instanceof Boolean) return "boolean"; throw errorWithClassName("msg.invalid.type", value); } /** * The typeof operator that correctly handles the undefined case */ public static String typeofName(Scriptable scope, String id) { Context cx = Context.getContext(); Scriptable val = bind(cx, scope, id); if (val == null) return "undefined"; return typeof(getObjectProp(val, id, cx)); } // neg: // implement the '-' operator inline in the caller // as "-toNumber(val)" // not: // implement the '!' operator inline in the caller // as "!toBoolean(val)" // bitnot: // implement the '~' operator inline in the caller // as "~toInt32(val)" public static Object add(Object val1, Object val2, Context cx) { if(val1 instanceof Number && val2 instanceof Number) { return wrapNumber(((Number)val1).doubleValue() + ((Number)val2).doubleValue()); } if (val1 instanceof XMLObject) { Object test = ((XMLObject)val1).addValues(cx, true, val2); if (test != Scriptable.NOT_FOUND) { return test; } } if (val2 instanceof XMLObject) { Object test = ((XMLObject)val2).addValues(cx, false, val1); if (test != Scriptable.NOT_FOUND) { return test; } } if (val1 instanceof Scriptable) val1 = ((Scriptable) val1).getDefaultValue(null); if (val2 instanceof Scriptable) val2 = ((Scriptable) val2).getDefaultValue(null); if (!(val1 instanceof String) && !(val2 instanceof String)) if ((val1 instanceof Number) && (val2 instanceof Number)) return wrapNumber(((Number)val1).doubleValue() + ((Number)val2).doubleValue()); else return wrapNumber(toNumber(val1) + toNumber(val2)); return toString(val1).concat(toString(val2)); } public static String add(String val1, Object val2) { return val1.concat(toString(val2)); } public static String add(Object val1, String val2) { return toString(val1).concat(val2); } /** * @deprecated The method is only present for compatibility. */ public static Object nameIncrDecr(Scriptable scopeChain, String id, int incrDecrMask) { return nameIncrDecr(scopeChain, id, Context.getContext(), incrDecrMask); } public static Object nameIncrDecr(Scriptable scopeChain, String id, Context cx, int incrDecrMask) { Scriptable target; Object value; search: { do { if (cx.useDynamicScope && scopeChain.getParentScope() == null) { scopeChain = checkDynamicScope(cx.topCallScope, scopeChain); } target = scopeChain; do { value = target.get(id, scopeChain); if (value != Scriptable.NOT_FOUND) { break search; } target = target.getPrototype(); } while (target != null); scopeChain = scopeChain.getParentScope(); } while (scopeChain != null); throw notFoundError(scopeChain, id); } return doScriptableIncrDecr(target, id, scopeChain, value, incrDecrMask); } public static Object propIncrDecr(Object obj, String id, Context cx, int incrDecrMask) { Scriptable start = toObjectOrNull(cx, obj); if (start == null) { throw undefReadError(obj, id); } Scriptable target = start; Object value; search: { do { value = target.get(id, start); if (value != Scriptable.NOT_FOUND) { break search; } target = target.getPrototype(); } while (target != null); start.put(id, start, NaNobj); return NaNobj; } return doScriptableIncrDecr(target, id, start, value, incrDecrMask); } private static Object doScriptableIncrDecr(Scriptable target, String id, Scriptable protoChainStart, Object value, int incrDecrMask) { boolean post = ((incrDecrMask & Node.POST_FLAG) != 0); double number; if (value instanceof Number) { number = ((Number)value).doubleValue(); } else { number = toNumber(value); if (post) { // convert result to number value = wrapNumber(number); } } if ((incrDecrMask & Node.DECR_FLAG) == 0) { ++number; } else { --number; } Number result = wrapNumber(number); target.put(id, protoChainStart, result); if (post) { return value; } else { return result; } } public static Object elemIncrDecr(Object obj, Object index, Context cx, int incrDecrMask) { Object value = getObjectElem(obj, index, cx); boolean post = ((incrDecrMask & Node.POST_FLAG) != 0); double number; if (value instanceof Number) { number = ((Number)value).doubleValue(); } else { number = toNumber(value); if (post) { // convert result to number value = wrapNumber(number); } } if ((incrDecrMask & Node.DECR_FLAG) == 0) { ++number; } else { --number; } Number result = wrapNumber(number); setObjectElem(obj, index, result, cx); if (post) { return value; } else { return result; } } public static Object refIncrDecr(Ref ref, Context cx, int incrDecrMask) { Object value = ref.get(cx); boolean post = ((incrDecrMask & Node.POST_FLAG) != 0); double number; if (value instanceof Number) { number = ((Number)value).doubleValue(); } else { number = toNumber(value); if (post) { // convert result to number value = wrapNumber(number); } } if ((incrDecrMask & Node.DECR_FLAG) == 0) { ++number; } else { --number; } Number result = wrapNumber(number); ref.set(cx, result); if (post) { return value; } else { return result; } } private static Object toPrimitive(Object val) { if (!(val instanceof Scriptable)) { return val; } Scriptable s = (Scriptable)val; Object result = s.getDefaultValue(null); if (result instanceof Scriptable) throw typeError0("msg.bad.default.value"); return result; } /** * Equality * * See ECMA 11.9 */ public static boolean eq(Object x, Object y) { if (x == null || x == Undefined.instance) { if (y == null || y == Undefined.instance) { return true; } if (y instanceof ScriptableObject) { Object test = ((ScriptableObject)y).equivalentValues(x); if (test != Scriptable.NOT_FOUND) { return ((Boolean)test).booleanValue(); } } return false; } else if (x instanceof Number) { return eqNumber(((Number)x).doubleValue(), y); } else if (x instanceof String) { return eqString((String)x, y); } else if (x instanceof Boolean) { boolean b = ((Boolean)x).booleanValue(); if (y instanceof Boolean) { return b == ((Boolean)y).booleanValue(); } if (y instanceof ScriptableObject) { Object test = ((ScriptableObject)y).equivalentValues(x); if (test != Scriptable.NOT_FOUND) { return ((Boolean)test).booleanValue(); } } return eqNumber(b ? 1.0 : 0.0, y); } else if (x instanceof Scriptable) { if (y instanceof Scriptable) { if (x == y) { return true; } if (x instanceof ScriptableObject) { Object test = ((ScriptableObject)x).equivalentValues(y); if (test != Scriptable.NOT_FOUND) { return ((Boolean)test).booleanValue(); } } if (y instanceof ScriptableObject) { Object test = ((ScriptableObject)y).equivalentValues(x); if (test != Scriptable.NOT_FOUND) { return ((Boolean)test).booleanValue(); } } if (x instanceof Wrapper && y instanceof Wrapper) { // See bug 413838. Effectively an extension to ECMA for // the LiveConnect case. Object unwrappedX = ((Wrapper)x).unwrap(); Object unwrappedY = ((Wrapper)y).unwrap(); return unwrappedX == unwrappedY || (isPrimitive(unwrappedX) && isPrimitive(unwrappedY) && eq(unwrappedX, unwrappedY)); } return false; } else if (y instanceof Boolean) { if (x instanceof ScriptableObject) { Object test = ((ScriptableObject)x).equivalentValues(y); if (test != Scriptable.NOT_FOUND) { return ((Boolean)test).booleanValue(); } } double d = ((Boolean)y).booleanValue() ? 1.0 : 0.0; return eqNumber(d, x); } else if (y instanceof Number) { return eqNumber(((Number)y).doubleValue(), x); } else if (y instanceof String) { return eqString((String)y, x); } // covers the case when y == Undefined.instance as well return false; } else { warnAboutNonJSObject(x); return x == y; } } private static boolean isPrimitive(Object obj) { return (obj instanceof Number) || (obj instanceof String) || (obj instanceof Boolean); } static boolean eqNumber(double x, Object y) { for (;;) { if (y == null || y == Undefined.instance) { return false; } else if (y instanceof Number) { return x == ((Number)y).doubleValue(); } else if (y instanceof String) { return x == toNumber(y); } else if (y instanceof Boolean) { return x == (((Boolean)y).booleanValue() ? 1.0 : +0.0); } else if (y instanceof Scriptable) { if (y instanceof ScriptableObject) { Object xval = wrapNumber(x); Object test = ((ScriptableObject)y).equivalentValues(xval); if (test != Scriptable.NOT_FOUND) { return ((Boolean)test).booleanValue(); } } y = toPrimitive(y); } else { warnAboutNonJSObject(y); return false; } } } private static boolean eqString(String x, Object y) { for (;;) { if (y == null || y == Undefined.instance) { return false; } else if (y instanceof String) { return x.equals(y); } else if (y instanceof Number) { return toNumber(x) == ((Number)y).doubleValue(); } else if (y instanceof Boolean) { return toNumber(x) == (((Boolean)y).booleanValue() ? 1.0 : 0.0); } else if (y instanceof Scriptable) { if (y instanceof ScriptableObject) { Object test = ((ScriptableObject)y).equivalentValues(x); if (test != Scriptable.NOT_FOUND) { return ((Boolean)test).booleanValue(); } } y = toPrimitive(y); continue; } else { warnAboutNonJSObject(y); return false; } } } public static boolean shallowEq(Object x, Object y) { if (x == y) { if (!(x instanceof Number)) { return true; } // NaN check double d = ((Number)x).doubleValue(); return d == d; } if (x == null || x == Undefined.instance) { return false; } else if (x instanceof Number) { if (y instanceof Number) { return ((Number)x).doubleValue() == ((Number)y).doubleValue(); } } else if (x instanceof String) { if (y instanceof String) { return x.equals(y); } } else if (x instanceof Boolean) { if (y instanceof Boolean) { return x.equals(y); } } else if (x instanceof Scriptable) { if (x instanceof Wrapper && y instanceof Wrapper) { return ((Wrapper)x).unwrap() == ((Wrapper)y).unwrap(); } } else { warnAboutNonJSObject(x); return x == y; } return false; } /** * The instanceof operator. * * @return a instanceof b */ public static boolean instanceOf(Object a, Object b, Context cx) { // Check RHS is an object if (! (b instanceof Scriptable)) { throw typeError0("msg.instanceof.not.object"); } // for primitive values on LHS, return false // XXX we may want to change this so that // 5 instanceof Number == true if (! (a instanceof Scriptable)) return false; return ((Scriptable)b).hasInstance((Scriptable)a); } /** * Delegates to * * @return true iff rhs appears in lhs' proto chain */ public static boolean jsDelegatesTo(Scriptable lhs, Scriptable rhs) { Scriptable proto = lhs.getPrototype(); while (proto != null) { if (proto.equals(rhs)) return true; proto = proto.getPrototype(); } return false; } /** * The in operator. * * This is a new JS 1.3 language feature. The in operator mirrors * the operation of the for .. in construct, and tests whether the * rhs has the property given by the lhs. It is different from the * for .. in construct in that: *
- it doesn't perform ToObject on the right hand side *
- it returns true for DontEnum properties. * @param a the left hand operand * @param b the right hand operand * * @return true if property name or element number a is a property of b */ public static boolean in(Object a, Object b, Context cx) { if (!(b instanceof Scriptable)) { throw typeError0("msg.instanceof.not.object"); } return hasObjectElem((Scriptable)b, a, cx); } public static boolean cmp_LT(Object val1, Object val2) { double d1, d2; if (val1 instanceof Number && val2 instanceof Number) { d1 = ((Number)val1).doubleValue(); d2 = ((Number)val2).doubleValue(); } else { if (val1 instanceof Scriptable) val1 = ((Scriptable) val1).getDefaultValue(NumberClass); if (val2 instanceof Scriptable) val2 = ((Scriptable) val2).getDefaultValue(NumberClass); if (val1 instanceof String && val2 instanceof String) { return ((String)val1).compareTo((String)val2) < 0; } d1 = toNumber(val1); d2 = toNumber(val2); } return d1 < d2; } public static boolean cmp_LE(Object val1, Object val2) { double d1, d2; if (val1 instanceof Number && val2 instanceof Number) { d1 = ((Number)val1).doubleValue(); d2 = ((Number)val2).doubleValue(); } else { if (val1 instanceof Scriptable) val1 = ((Scriptable) val1).getDefaultValue(NumberClass); if (val2 instanceof Scriptable) val2 = ((Scriptable) val2).getDefaultValue(NumberClass); if (val1 instanceof String && val2 instanceof String) { return ((String)val1).compareTo((String)val2) <= 0; } d1 = toNumber(val1); d2 = toNumber(val2); } return d1 <= d2; } // ------------------ // Statements // ------------------ public static ScriptableObject getGlobal(Context cx) { final String GLOBAL_CLASS = "org.mozilla.javascript.tools.shell.Global"; Class globalClass = Kit.classOrNull(GLOBAL_CLASS); if (globalClass != null) { try { Class[] parm = { ScriptRuntime.ContextClass }; Constructor globalClassCtor = globalClass.getConstructor(parm); Object[] arg = { cx }; return (ScriptableObject) globalClassCtor.newInstance(arg); } catch (Exception e) { // fall through... } } return new ImporterTopLevel(cx); } public static boolean hasTopCall(Context cx) { return (cx.topCallScope != null); } public static Scriptable getTopCallScope(Context cx) { Scriptable scope = cx.topCallScope; if (scope == null) { throw new IllegalStateException(); } return scope; } public static Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (scope == null) throw new IllegalArgumentException(); if (cx.topCallScope != null) throw new IllegalStateException(); Object result; cx.topCallScope = ScriptableObject.getTopLevelScope(scope); cx.useDynamicScope = cx.hasFeature(Context.FEATURE_DYNAMIC_SCOPE); ContextFactory f = cx.getFactory(); try { result = f.doTopCall(callable, cx, scope, thisObj, args); } finally { cx.topCallScope = null; // Cleanup cached references cx.cachedXMLLib = null; if (cx.currentActivationCall != null) { // Function should always call exitActivationFunction // if it creates activation record throw new IllegalStateException(); } } return result; } /** * Return possibleDynamicScope if staticTopScope * is present on its prototype chain and return staticTopScope * otherwise. * Should only be called when staticTopScope is top scope. */ static Scriptable checkDynamicScope(Scriptable possibleDynamicScope, Scriptable staticTopScope) { // Return cx.topCallScope if scope if (possibleDynamicScope == staticTopScope) { return possibleDynamicScope; } Scriptable proto = possibleDynamicScope; for (;;) { proto = proto.getPrototype(); if (proto == staticTopScope) { return possibleDynamicScope; } if (proto == null) { return staticTopScope; } } } public static void addInstructionCount(Context cx, int instructionsToAdd) { cx.instructionCount += instructionsToAdd; if (cx.instructionCount > cx.instructionThreshold) { cx.observeInstructionCount(cx.instructionCount); cx.instructionCount = 0; } } public static void initScript(NativeFunction funObj, Scriptable thisObj, Context cx, Scriptable scope, boolean evalScript) { if (cx.topCallScope == null) throw new IllegalStateException(); int varCount = funObj.getParamAndVarCount(); if (varCount != 0) { Scriptable varScope = scope; // Never define any variables from var statements inside with // object. See bug 38590. while (varScope instanceof NativeWith) { varScope = varScope.getParentScope(); } for (int i = varCount; i-- != 0;) { String name = funObj.getParamOrVarName(i); boolean isConst = funObj.getParamOrVarConst(i); // Don't overwrite existing def if already defined in object // or prototypes of object. if (!ScriptableObject.hasProperty(scope, name)) { if (!evalScript) { // Global var definitions are supposed to be DONTDELETE if (isConst) ScriptableObject.defineConstProperty(varScope, name); else ScriptableObject.defineProperty( varScope, name, Undefined.instance, ScriptableObject.PERMANENT); } else { varScope.put(name, varScope, Undefined.instance); } } else { ScriptableObject.redefineProperty(scope, name, isConst); } } } } public static Scriptable createFunctionActivation(NativeFunction funObj, Scriptable scope, Object[] args) { return new NativeCall(funObj, scope, args); } public static void enterActivationFunction(Context cx, Scriptable scope) { if (cx.topCallScope == null) throw new IllegalStateException(); NativeCall call = (NativeCall)scope; call.parentActivationCall = cx.currentActivationCall; cx.currentActivationCall = call; } public static void exitActivationFunction(Context cx) { NativeCall call = cx.currentActivationCall; cx.currentActivationCall = call.parentActivationCall; call.parentActivationCall = null; } static NativeCall findFunctionActivation(Context cx, Function f) { NativeCall call = cx.currentActivationCall; while (call != null) { if (call.function == f) return call; call = call.parentActivationCall; } return null; } public static Scriptable newCatchScope(Throwable t, Scriptable lastCatchScope, String exceptionName, Context cx, Scriptable scope) { Object obj; boolean cacheObj; getObj: if (t instanceof JavaScriptException) { cacheObj = false; obj = ((JavaScriptException)t).getValue(); } else { cacheObj = true; // Create wrapper object unless it was associated with // the previous scope object if (lastCatchScope != null) { NativeObject last = (NativeObject)lastCatchScope; obj = last.getAssociatedValue(t); if (obj == null) Kit.codeBug(); break getObj; } RhinoException re; String errorName; String errorMsg; Throwable javaException = null; if (t instanceof EcmaError) { EcmaError ee = (EcmaError)t; re = ee; errorName = ee.getName(); errorMsg = ee.getErrorMessage(); } else if (t instanceof WrappedException) { WrappedException we = (WrappedException)t; re = we; javaException = we.getWrappedException(); errorName = "JavaException"; errorMsg = javaException.getClass().getName() +": "+javaException.getMessage(); } else if (t instanceof EvaluatorException) { // Pure evaluator exception, nor WrappedException instance EvaluatorException ee = (EvaluatorException)t; re = ee; errorName = "InternalError"; errorMsg = ee.getMessage(); } else if (cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)) { // With FEATURE_ENHANCED_JAVA_ACCESS, scripts can catch // all exception types re = new WrappedException(t); errorName = "JavaException"; errorMsg = t.toString(); } else { // Script can catch only instances of JavaScriptException, // EcmaError and EvaluatorException throw Kit.codeBug(); } String sourceUri = re.sourceName(); if (sourceUri == null) { sourceUri = ""; } int line = re.lineNumber(); Object args[]; if (line > 0) { args = new Object[] { errorMsg, sourceUri, new Integer(line) }; } else { args = new Object[] { errorMsg, sourceUri }; } Scriptable errorObject = cx.newObject(scope, errorName, args); ScriptableObject.putProperty(errorObject, "name", errorName); if (javaException != null && isVisible(cx, javaException)) { Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException, null); ScriptableObject.defineProperty( errorObject, "javaException", wrap, ScriptableObject.PERMANENT | ScriptableObject.READONLY); } if (isVisible(cx, re)) { Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null); ScriptableObject.defineProperty( errorObject, "rhinoException", wrap, ScriptableObject.PERMANENT | ScriptableObject.READONLY); } obj = errorObject; } NativeObject catchScopeObject = new NativeObject(); // See ECMA 12.4 catchScopeObject.defineProperty( exceptionName, obj, ScriptableObject.PERMANENT); if (isVisible(cx, t)) { // Add special Rhino object __exception__ defined in the catch // scope that can be used to retrieve the Java exception associated // with the JavaScript exception (to get stack trace info, etc.) catchScopeObject.defineProperty( "__exception__", Context.javaToJS(t, scope), ScriptableObject.PERMANENT|ScriptableObject.DONTENUM); } if (cacheObj) { catchScopeObject.associateValue(t, obj); } return catchScopeObject; } private static boolean isVisible(Context cx, Object obj) { ClassShutter shutter = cx.getClassShutter(); return shutter == null || shutter.visibleToScripts(obj.getClass().getName()); } public static Scriptable enterWith(Object obj, Context cx, Scriptable scope) { Scriptable sobj = toObjectOrNull(cx, obj); if (sobj == null) { throw typeError1("msg.undef.with", toString(obj)); } if (sobj instanceof XMLObject) { XMLObject xmlObject = (XMLObject)sobj; return xmlObject.enterWith(scope); } return new NativeWith(scope, sobj); } public static Scriptable leaveWith(Scriptable scope) { NativeWith nw = (NativeWith)scope; return nw.getParentScope(); } public static Scriptable enterDotQuery(Object value, Scriptable scope) { if (!(value instanceof XMLObject)) { throw notXmlError(value); } XMLObject object = (XMLObject)value; return object.enterDotQuery(scope); } public static Object updateDotQuery(boolean value, Scriptable scope) { // Return null to continue looping NativeWith nw = (NativeWith)scope; return nw.updateDotQuery(value); } public static Scriptable leaveDotQuery(Scriptable scope) { NativeWith nw = (NativeWith)scope; return nw.getParentScope(); } public static void setFunctionProtoAndParent(BaseFunction fn, Scriptable scope) { fn.setParentScope(scope); fn.setPrototype(ScriptableObject.getFunctionPrototype(scope)); } public static void setObjectProtoAndParent(ScriptableObject object, Scriptable scope) { // Compared with function it always sets the scope to top scope scope = ScriptableObject.getTopLevelScope(scope); object.setParentScope(scope); Scriptable proto = ScriptableObject.getClassPrototype(scope, object.getClassName()); object.setPrototype(proto); } public static void initFunction(Context cx, Scriptable scope, NativeFunction function, int type, boolean fromEvalCode) { if (type == FunctionNode.FUNCTION_STATEMENT) { String name = function.getFunctionName(); if (name != null && name.length() != 0) { if (!fromEvalCode) { // ECMA specifies that functions defined in global and // function scope outside eval should have DONTDELETE set. ScriptableObject.defineProperty (scope, name, function, ScriptableObject.PERMANENT); } else { scope.put(name, scope, function); } } } else if (type == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) { String name = function.getFunctionName(); if (name != null && name.length() != 0) { // Always put function expression statements into initial // activation object ignoring the with statement to follow // SpiderMonkey while (scope instanceof NativeWith) { scope = scope.getParentScope(); } scope.put(name, scope, function); } } else { throw Kit.codeBug(); } } public static Scriptable newArrayLiteral(Object[] objects, int[] skipIndices, Context cx, Scriptable scope) { final int SKIP_DENSITY = 2; int count = objects.length; int skipCount = 0; if (skipIndices != null) { skipCount = skipIndices.length; } int length = count + skipCount; if (length > 1 && skipCount * SKIP_DENSITY < length) { // If not too sparse, create whole array for constructor Object[] sparse; if (skipCount == 0) { sparse = objects; } else { sparse = new Object[length]; int skip = 0; for (int i = 0, j = 0; i != length; ++i) { if (skip != skipCount && skipIndices[skip] == i) { sparse[i] = Scriptable.NOT_FOUND; ++skip; continue; } sparse[i] = objects[j]; ++j; } } return cx.newObject(scope, "Array", sparse); } Scriptable arrayObj = cx.newObject(scope, "Array", ScriptRuntime.emptyArgs); int skip = 0; for (int i = 0, j = 0; i != length; ++i) { if (skip != skipCount && skipIndices[skip] == i) { ++skip; continue; } ScriptableObject.putProperty(arrayObj, i, objects[j]); ++j; } return arrayObj; } /** * This method is here for backward compat with existing compiled code. It * is called when an object literal is compiled. The next instance will be * the version called from new code. * @deprecated This method only present for compatibility. */ public static Scriptable newObjectLiteral(Object[] propertyIds, Object[] propertyValues, Context cx, Scriptable scope) { // This will initialize to all zeros, exactly what we need for old-style // getterSetters values (no getters or setters in the list) int [] getterSetters = new int[propertyIds.length]; return newObjectLiteral(propertyIds, propertyValues, getterSetters, cx, scope); } public static Scriptable newObjectLiteral(Object[] propertyIds, Object[] propertyValues, int [] getterSetters, Context cx, Scriptable scope) { Scriptable object = cx.newObject(scope); for (int i = 0, end = propertyIds.length; i != end; ++i) { Object id = propertyIds[i]; int getterSetter = getterSetters[i]; Object value = propertyValues[i]; if (id instanceof String) { if (getterSetter == 0) ScriptableObject.putProperty(object, (String)id, value); else { Callable fun; String definer; if (getterSetter < 0) // < 0 means get foo() ... definer = "__defineGetter__"; else definer = "__defineSetter__"; fun = getPropFunctionAndThis(object, definer, cx); // Must consume the last scriptable object in cx lastStoredScriptable(cx); Object[] outArgs = new Object[2]; outArgs[0] = id; outArgs[1] = value; fun.call(cx, scope, object, outArgs); } } else { int index = ((Integer)id).intValue(); ScriptableObject.putProperty(object, index, value); } } return object; } public static boolean isArrayObject(Object obj) { return obj instanceof NativeArray || obj instanceof Arguments; } public static Object[] getArrayElements(Scriptable object) { Context cx = Context.getContext(); long longLen = NativeArray.getLengthProperty(cx, object); if (longLen > Integer.MAX_VALUE) { // arrays beyond MAX_INT is not in Java in any case throw new IllegalArgumentException(); } int len = (int) longLen; if (len == 0) { return ScriptRuntime.emptyArgs; } else { Object[] result = new Object[len]; for (int i=0; i < len; i++) { Object elem = ScriptableObject.getProperty(object, i); result[i] = (elem == Scriptable.NOT_FOUND) ? Undefined.instance : elem; } return result; } } static void checkDeprecated(Context cx, String name) { int version = cx.getLanguageVersion(); if (version >= Context.VERSION_1_4 || version == Context.VERSION_DEFAULT) { String msg = getMessage1("msg.deprec.ctor", name); if (version == Context.VERSION_DEFAULT) Context.reportWarning(msg); else throw Context.reportRuntimeError(msg); } } public static String getMessage0(String messageId) { return getMessage(messageId, null); } public static String getMessage1(String messageId, Object arg1) { Object[] arguments = {arg1}; return getMessage(messageId, arguments); } public static String getMessage2( String messageId, Object arg1, Object arg2) { Object[] arguments = {arg1, arg2}; return getMessage(messageId, arguments); } public static String getMessage3( String messageId, Object arg1, Object arg2, Object arg3) { Object[] arguments = {arg1, arg2, arg3}; return getMessage(messageId, arguments); } public static String getMessage4( String messageId, Object arg1, Object arg2, Object arg3, Object arg4) { Object[] arguments = {arg1, arg2, arg3, arg4}; return getMessage(messageId, arguments); } /** * This is an interface defining a message provider. Create your * own implementation to override the default error message provider. * * @author Mike Harm */ public interface MessageProvider { /** * Returns a textual message identified by the given messageId, * parameterized by the given arguments. * * @param messageId the identifier of the message * @param arguments the arguments to fill into the message */ String getMessage(String messageId, Object[] arguments); } public static MessageProvider messageProvider = new DefaultMessageProvider(); public static String getMessage(String messageId, Object[] arguments) { return messageProvider.getMessage(messageId, arguments); } /* OPT there's a noticable delay for the first error! Maybe it'd * make sense to use a ListResourceBundle instead of a properties * file to avoid (synchronized) text parsing. */ private static class DefaultMessageProvider implements MessageProvider { public String getMessage(String messageId, Object[] arguments) { final String defaultResource = "org.mozilla.javascript.resources.Messages"; Context cx = Context.getCurrentContext(); Locale locale = cx != null ? cx.getLocale() : Locale.getDefault(); // ResourceBundle does caching. ResourceBundle rb = ResourceBundle.getBundle(defaultResource, locale); String formatString; try { formatString = rb.getString(messageId); } catch (java.util.MissingResourceException mre) { throw new RuntimeException ("no message resource found for message property "+ messageId); } /* * It's OK to format the string, even if 'arguments' is null; * we need to format it anyway, to make double ''s collapse to * single 's. */ MessageFormat formatter = new MessageFormat(formatString); return formatter.format(arguments); } } public static EcmaError constructError(String error, String message) { int[] linep = new int[1]; String filename = Context.getSourcePositionFromStack(linep); return constructError(error, message, filename, linep[0], null, 0); } public static EcmaError constructError(String error, String message, int lineNumberDelta) { int[] linep = new int[1]; String filename = Context.getSourcePositionFromStack(linep); if (linep[0] != 0) { linep[0] += lineNumberDelta; } return constructError(error, message, filename, linep[0], null, 0); } public static EcmaError constructError(String error, String message, String sourceName, int lineNumber, String lineSource, int columnNumber) { return new EcmaError(error, message, sourceName, lineNumber, lineSource, columnNumber); } public static EcmaError typeError(String message) { return constructError("TypeError", message); } public static EcmaError typeError0(String messageId) { String msg = getMessage0(messageId); return typeError(msg); } public static EcmaError typeError1(String messageId, String arg1) { String msg = getMessage1(messageId, arg1); return typeError(msg); } public static EcmaError typeError2(String messageId, String arg1, String arg2) { String msg = getMessage2(messageId, arg1, arg2); return typeError(msg); } public static EcmaError typeError3(String messageId, String arg1, String arg2, String arg3) { String msg = getMessage3(messageId, arg1, arg2, arg3); return typeError(msg); } public static RuntimeException undefReadError(Object object, Object id) { String idStr = (id == null) ? "null" : id.toString(); return typeError2("msg.undef.prop.read", toString(object), idStr); } public static RuntimeException undefCallError(Object object, Object id) { String idStr = (id == null) ? "null" : id.toString(); return typeError2("msg.undef.method.call", toString(object), idStr); } public static RuntimeException undefWriteError(Object object, Object id, Object value) { String idStr = (id == null) ? "null" : id.toString(); String valueStr = (value instanceof Scriptable) ? value.toString() : toString(value); return typeError3("msg.undef.prop.write", toString(object), idStr, valueStr); } public static RuntimeException notFoundError(Scriptable object, String property) { // XXX: use object to improve the error message String msg = getMessage1("msg.is.not.defined", property); throw constructError("ReferenceError", msg); } public static RuntimeException notFunctionError(Object value) { return notFunctionError(value, value); } public static RuntimeException notFunctionError(Object value, Object messageHelper) { // Use value for better error reporting String msg = (messageHelper == null) ? "null" : messageHelper.toString(); if (value == Scriptable.NOT_FOUND) { return typeError1("msg.function.not.found", msg); } return typeError2("msg.isnt.function", msg, typeof(value)); } public static RuntimeException notFunctionError(Object obj, Object value, String propertyName) { // Use obj and value for better error reporting String objString = toString(obj); if (value == Scriptable.NOT_FOUND) { return typeError2("msg.function.not.found.in", propertyName, objString); } return typeError3("msg.isnt.function.in", propertyName, objString, typeof(value)); } private static RuntimeException notXmlError(Object value) { throw typeError1("msg.isnt.xml.object", toString(value)); } private static void warnAboutNonJSObject(Object nonJSObject) { String message = "RHINO USAGE WARNING: Missed Context.javaToJS() conversion:\n" +"Rhino runtime detected object "+nonJSObject+" of class "+nonJSObject.getClass().getName()+" where it expected String, Number, Boolean or Scriptable instance. Please check your code for missing Context.javaToJS() call."; Context.reportWarning(message); // Just to be sure that it would be noticed System.err.println(message); } public static RegExpProxy getRegExpProxy(Context cx) { return cx.getRegExpProxy(); } public static void setRegExpProxy(Context cx, RegExpProxy proxy) { if (proxy == null) throw new IllegalArgumentException(); cx.regExpProxy = proxy; } public static RegExpProxy checkRegExpProxy(Context cx) { RegExpProxy result = getRegExpProxy(cx); if (result == null) { throw Context.reportRuntimeError0("msg.no.regexp"); } return result; } private static XMLLib currentXMLLib(Context cx) { // Scripts should be running to access this if (cx.topCallScope == null) throw new IllegalStateException(); XMLLib xmlLib = cx.cachedXMLLib; if (xmlLib == null) { xmlLib = XMLLib.extractFromScope(cx.topCallScope); if (xmlLib == null) throw new IllegalStateException(); cx.cachedXMLLib = xmlLib; } return xmlLib; } /** * Escapes the reserved characters in a value of an attribute * * @param value Unescaped text * @return The escaped text */ public static String escapeAttributeValue(Object value, Context cx) { XMLLib xmlLib = currentXMLLib(cx); return xmlLib.escapeAttributeValue(value); } /** * Escapes the reserved characters in a value of a text node * * @param value Unescaped text * @return The escaped text */ public static String escapeTextValue(Object value, Context cx) { XMLLib xmlLib = currentXMLLib(cx); return xmlLib.escapeTextValue(value); } public static Ref memberRef(Object obj, Object elem, Context cx, int memberTypeFlags) { if (!(obj instanceof XMLObject)) { throw notXmlError(obj); } XMLObject xmlObject = (XMLObject)obj; return xmlObject.memberRef(cx, elem, memberTypeFlags); } public static Ref memberRef(Object obj, Object namespace, Object elem, Context cx, int memberTypeFlags) { if (!(obj instanceof XMLObject)) { throw notXmlError(obj); } XMLObject xmlObject = (XMLObject)obj; return xmlObject.memberRef(cx, namespace, elem, memberTypeFlags); } public static Ref nameRef(Object name, Context cx, Scriptable scope, int memberTypeFlags) { XMLLib xmlLib = currentXMLLib(cx); return xmlLib.nameRef(cx, name, scope, memberTypeFlags); } public static Ref nameRef(Object namespace, Object name, Context cx, Scriptable scope, int memberTypeFlags) { XMLLib xmlLib = currentXMLLib(cx); return xmlLib.nameRef(cx, namespace, name, scope, memberTypeFlags); } private static void storeIndexResult(Context cx, int index) { cx.scratchIndex = index; } static int lastIndexResult(Context cx) { return cx.scratchIndex; } public static void storeUint32Result(Context cx, long value) { if ((value >>> 32) != 0) throw new IllegalArgumentException(); cx.scratchUint32 = value; } public static long lastUint32Result(Context cx) { long value = cx.scratchUint32; if ((value >>> 32) != 0) throw new IllegalStateException(); return value; } private static void storeScriptable(Context cx, Scriptable value) { // The previously stored scratchScriptable should be consumed if (cx.scratchScriptable != null) throw new IllegalStateException(); cx.scratchScriptable = value; } public static Scriptable lastStoredScriptable(Context cx) { Scriptable result = cx.scratchScriptable; cx.scratchScriptable = null; return result; } static String makeUrlForGeneratedScript (boolean isEval, String masterScriptUrl, int masterScriptLine) { if (isEval) { return masterScriptUrl+'#'+masterScriptLine+"(eval)"; } else { return masterScriptUrl+'#'+masterScriptLine+"(Function)"; } } static boolean isGeneratedScript(String sourceUrl) { // ALERT: this may clash with a valid URL containing (eval) or // (Function) return sourceUrl.indexOf("(eval)") >= 0 || sourceUrl.indexOf("(Function)") >= 0; } private static RuntimeException errorWithClassName(String msg, Object val) { return Context.reportRuntimeError1(msg, val.getClass().getName()); } public static final Object[] emptyArgs = new Object[0]; public static final String[] emptyStrings = new String[0]; } yui-compressor-2.4.7/src/org/mozilla/javascript/DToA.java0000644000175000017500000013354211753547210023262 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Waldemar Horwat * Roger Lawrence * Attila Szegedi * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ /**************************************************************** * * The author of this software is David M. Gay. * * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. * * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. * ***************************************************************/ package org.mozilla.javascript; import java.math.BigInteger; class DToA { /* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce, * which occurs when printing -5e-324 in binary. We could compute a better estimate of the size of * the output string and malloc fewer bytes depending on d and base, but why bother? */ private static final int DTOBASESTR_BUFFER_SIZE = 1078; private static char BASEDIGIT(int digit) { return (char)((digit >= 10) ? 'a' - 10 + digit : '0' + digit); } static final int DTOSTR_STANDARD = 0, /* Either fixed or exponential format; round-trip */ DTOSTR_STANDARD_EXPONENTIAL = 1, /* Always exponential format; round-trip */ DTOSTR_FIXED = 2, /* Round to digits after the decimal point; exponential if number is large */ DTOSTR_EXPONENTIAL = 3, /* Always exponential format; significant digits */ DTOSTR_PRECISION = 4; /* Either fixed or exponential format; significant digits */ private static final int Frac_mask = 0xfffff; private static final int Exp_shift = 20; private static final int Exp_msk1 = 0x100000; private static final long Frac_maskL = 0xfffffffffffffL; private static final int Exp_shiftL = 52; private static final long Exp_msk1L = 0x10000000000000L; private static final int Bias = 1023; private static final int P = 53; private static final int Exp_shift1 = 20; private static final int Exp_mask = 0x7ff00000; private static final int Exp_mask_shifted = 0x7ff; private static final int Bndry_mask = 0xfffff; private static final int Log2P = 1; private static final int Sign_bit = 0x80000000; private static final int Exp_11 = 0x3ff00000; private static final int Ten_pmax = 22; private static final int Quick_max = 14; private static final int Bletch = 0x10; private static final int Frac_mask1 = 0xfffff; private static final int Int_max = 14; private static final int n_bigtens = 5; private static final double tens[] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 }; private static final double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; private static int lo0bits(int y) { int k; int x = y; if ((x & 7) != 0) { if ((x & 1) != 0) return 0; if ((x & 2) != 0) { return 1; } return 2; } k = 0; if ((x & 0xffff) == 0) { k = 16; x >>>= 16; } if ((x & 0xff) == 0) { k += 8; x >>>= 8; } if ((x & 0xf) == 0) { k += 4; x >>>= 4; } if ((x & 0x3) == 0) { k += 2; x >>>= 2; } if ((x & 1) == 0) { k++; x >>>= 1; if ((x & 1) == 0) return 32; } return k; } /* Return the number (0 through 32) of most significant zero bits in x. */ private static int hi0bits(int x) { int k = 0; if ((x & 0xffff0000) == 0) { k = 16; x <<= 16; } if ((x & 0xff000000) == 0) { k += 8; x <<= 8; } if ((x & 0xf0000000) == 0) { k += 4; x <<= 4; } if ((x & 0xc0000000) == 0) { k += 2; x <<= 2; } if ((x & 0x80000000) == 0) { k++; if ((x & 0x40000000) == 0) return 32; } return k; } private static void stuffBits(byte bits[], int offset, int val) { bits[offset] = (byte)(val >> 24); bits[offset + 1] = (byte)(val >> 16); bits[offset + 2] = (byte)(val >> 8); bits[offset + 3] = (byte)(val); } /* Convert d into the form b*2^e, where b is an odd integer. b is the returned * Bigint and e is the returned binary exponent. Return the number of significant * bits in b in bits. d must be finite and nonzero. */ private static BigInteger d2b(double d, int[] e, int[] bits) { byte dbl_bits[]; int i, k, y, z, de; long dBits = Double.doubleToLongBits(d); int d0 = (int)(dBits >>> 32); int d1 = (int)(dBits); z = d0 & Frac_mask; d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ if ((de = (d0 >>> Exp_shift)) != 0) z |= Exp_msk1; if ((y = d1) != 0) { dbl_bits = new byte[8]; k = lo0bits(y); y >>>= k; if (k != 0) { stuffBits(dbl_bits, 4, y | z << (32 - k)); z >>= k; } else stuffBits(dbl_bits, 4, y); stuffBits(dbl_bits, 0, z); i = (z != 0) ? 2 : 1; } else { // JS_ASSERT(z); dbl_bits = new byte[4]; k = lo0bits(z); z >>>= k; stuffBits(dbl_bits, 0, z); k += 32; i = 1; } if (de != 0) { e[0] = de - Bias - (P-1) + k; bits[0] = P - k; } else { e[0] = de - Bias - (P-1) + 1 + k; bits[0] = 32*i - hi0bits(z); } return new BigInteger(dbl_bits); } static String JS_dtobasestr(int base, double d) { if (!(2 <= base && base <= 36)) throw new IllegalArgumentException("Bad base: "+base); /* Check for Infinity and NaN */ if (Double.isNaN(d)) { return "NaN"; } else if (Double.isInfinite(d)) { return (d > 0.0) ? "Infinity" : "-Infinity"; } else if (d == 0) { // ALERT: should it distinguish -0.0 from +0.0 ? return "0"; } boolean negative; if (d >= 0.0) { negative = false; } else { negative = true; d = -d; } /* Get the integer part of d including '-' sign. */ String intDigits; double dfloor = Math.floor(d); long lfloor = (long)dfloor; if (lfloor == dfloor) { // int part fits long intDigits = Long.toString((negative) ? -lfloor : lfloor, base); } else { // BigInteger should be used long floorBits = Double.doubleToLongBits(dfloor); int exp = (int)(floorBits >> Exp_shiftL) & Exp_mask_shifted; long mantissa; if (exp == 0) { mantissa = (floorBits & Frac_maskL) << 1; } else { mantissa = (floorBits & Frac_maskL) | Exp_msk1L; } if (negative) { mantissa = -mantissa; } exp -= 1075; BigInteger x = BigInteger.valueOf(mantissa); if (exp > 0) { x = x.shiftLeft(exp); } else if (exp < 0) { x = x.shiftRight(-exp); } intDigits = x.toString(base); } if (d == dfloor) { // No fraction part return intDigits; } else { /* We have a fraction. */ char[] buffer; /* The output string */ int p; /* index to current position in the buffer */ int digit; double df; /* The fractional part of d */ BigInteger b; buffer = new char[DTOBASESTR_BUFFER_SIZE]; p = 0; df = d - dfloor; long dBits = Double.doubleToLongBits(d); int word0 = (int)(dBits >> 32); int word1 = (int)(dBits); int[] e = new int[1]; int[] bbits = new int[1]; b = d2b(df, e, bbits); // JS_ASSERT(e < 0); /* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */ int s2 = -(word0 >>> Exp_shift1 & Exp_mask >> Exp_shift1); if (s2 == 0) s2 = -1; s2 += Bias + P; /* 1/2^s2 = (nextDouble(d) - d)/2 */ // JS_ASSERT(-s2 < e); BigInteger mlo = BigInteger.valueOf(1); BigInteger mhi = mlo; if ((word1 == 0) && ((word0 & Bndry_mask) == 0) && ((word0 & (Exp_mask & Exp_mask << 1)) != 0)) { /* The special case. Here we want to be within a quarter of the last input significant digit instead of one half of it when the output string's value is less than d. */ s2 += Log2P; mhi = BigInteger.valueOf(1< df = b/2^s2 > 0; * (d - prevDouble(d))/2 = mlo/2^s2; * (nextDouble(d) - d)/2 = mhi/2^s2. */ BigInteger bigBase = BigInteger.valueOf(base); boolean done = false; do { b = b.multiply(bigBase); BigInteger[] divResult = b.divideAndRemainder(s); b = divResult[1]; digit = (char)(divResult[0].intValue()); if (mlo == mhi) mlo = mhi = mlo.multiply(bigBase); else { mlo = mlo.multiply(bigBase); mhi = mhi.multiply(bigBase); } /* Do we yet have the shortest string that will round to d? */ int j = b.compareTo(mlo); /* j is b/2^s2 compared with mlo/2^s2. */ BigInteger delta = s.subtract(mhi); int j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta); /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */ if (j1 == 0 && ((word1 & 1) == 0)) { if (j > 0) digit++; done = true; } else if (j < 0 || (j == 0 && ((word1 & 1) == 0))) { if (j1 > 0) { /* Either dig or dig+1 would work here as the least significant digit. Use whichever would produce an output value closer to d. */ b = b.shiftLeft(1); j1 = b.compareTo(s); if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output * such as 3.5 in base 3. */ digit++; } done = true; } else if (j1 > 0) { digit++; done = true; } // JS_ASSERT(digit < (uint32)base); buffer[p++] = BASEDIGIT(digit); } while (!done); StringBuffer sb = new StringBuffer(intDigits.length() + 1 + p); sb.append(intDigits); sb.append('.'); sb.append(buffer, 0, p); return sb.toString(); } } /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. * * Inspired by "How to Print Floating-Point Numbers Accurately" by * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. * * Modifications: * 1. Rather than iterating, we use a simple numeric overestimate * to determine k = floor(log10(d)). We scale relevant * quantities using O(log2(k)) rather than O(k) multiplications. * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't * try to generate digits strictly left to right. Instead, we * compute with fewer bits and propagate the carry if necessary * when rounding the final digit up. This is often faster. * 3. Under the assumption that input will be rounded nearest, * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. * That is, we allow equality in stopping tests when the * round-nearest rule will give the same floating-point value * as would satisfaction of the stopping test with strict * inequality. * 4. We remove common factors of powers of 2 from relevant * quantities. * 5. When converting floating-point integers less than 1e16, * we use floating-point arithmetic rather than resorting * to multiple-precision integers. * 6. When asked to produce fewer than 15 digits, we first try * to get by with floating-point arithmetic; we resort to * multiple-precision integer arithmetic only if we cannot * guarantee that the floating-point calculation has given * the correctly rounded result. For k requested digits and * "uniformly" distributed input, the probability is * something like 10^(k-15) that we must resort to the Long * calculation. */ static int word0(double d) { long dBits = Double.doubleToLongBits(d); return (int)(dBits >> 32); } static double setWord0(double d, int i) { long dBits = Double.doubleToLongBits(d); dBits = ((long)i << 32) | (dBits & 0x0FFFFFFFFL); return Double.longBitsToDouble(dBits); } static int word1(double d) { long dBits = Double.doubleToLongBits(d); return (int)(dBits); } /* Return b * 5^k. k must be nonnegative. */ // XXXX the C version built a cache of these static BigInteger pow5mult(BigInteger b, int k) { return b.multiply(BigInteger.valueOf(5).pow(k)); } static boolean roundOff(StringBuffer buf) { int i = buf.length(); while (i != 0) { --i; char c = buf.charAt(i); if (c != '9') { buf.setCharAt(i, (char)(c + 1)); buf.setLength(i + 1); return false; } } buf.setLength(0); return true; } /* Always emits at least one digit. */ /* If biasUp is set, then rounding in modes 2 and 3 will round away from zero * when the number is exactly halfway between two representable values. For example, * rounding 2.5 to zero digits after the decimal point will return 3 and not 2. * 2.49 will still round to 2, and 2.51 will still round to 3. */ /* bufsize should be at least 20 for modes 0 and 1. For the other modes, * bufsize should be two greater than the maximum number of output characters expected. */ static int JS_dtoa(double d, int mode, boolean biasUp, int ndigits, boolean[] sign, StringBuffer buf) { /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; trailing zeros are suppressed from the returned string. If not null, *rve is set to point to the end of the return value. If d is +-Infinity or NaN, then *decpt is set to 9999. mode: 0 ==> shortest string that yields d when read in and rounded to nearest. 1 ==> like 0, but with Steele & White stopping rule; e.g. with IEEE P754 arithmetic , mode 0 gives 1e23 whereas mode 1 gives 9.999999999999999e22. 2 ==> max(1,ndigits) significant digits. This gives a return value similar to that of ecvt, except that trailing zeros are suppressed. 3 ==> through ndigits past the decimal point. This gives a return value similar to that from fcvt, except that trailing zeros are suppressed, and ndigits can be negative. 4-9 should give the same return values as 2-3, i.e., 4 <= mode <= 9 ==> same return as mode 2 + (mode & 1). These modes are mainly for debugging; often they run slower but sometimes faster than modes 2-3. 4,5,8,9 ==> left-to-right digit generation. 6-9 ==> don't try fast floating-point estimate (if applicable). Values of mode other than 0-9 are treated as mode 0. Sufficient space is allocated to the return value to hold the suppressed trailing zeros. */ int b2, b5, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0, m2, m5, s2, s5; char dig; long L; long x; BigInteger b, b1, delta, mlo, mhi, S; int[] be = new int[1]; int[] bbits = new int[1]; double d2, ds, eps; boolean spec_case, denorm, k_check, try_quick, leftright; if ((word0(d) & Sign_bit) != 0) { /* set sign for everything, including 0's and NaNs */ sign[0] = true; // word0(d) &= ~Sign_bit; /* clear sign bit */ d = setWord0(d, word0(d) & ~Sign_bit); } else sign[0] = false; if ((word0(d) & Exp_mask) == Exp_mask) { /* Infinity or NaN */ buf.append(((word1(d) == 0) && ((word0(d) & Frac_mask) == 0)) ? "Infinity" : "NaN"); return 9999; } if (d == 0) { // no_digits: buf.setLength(0); buf.append('0'); /* copy "0" to buffer */ return 1; } b = d2b(d, be, bbits); if ((i = (word0(d) >>> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { d2 = setWord0(d, (word0(d) & Frac_mask1) | Exp_11); /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) * * This suggests computing an approximation k to log10(d) by * * k = (i - Bias)*0.301029995663981 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); * * We want k to be too large rather than too small. * The error in the first-order Taylor series approximation * is in our favor, so we just round up the constant enough * to compensate for any error in the multiplication of * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, * adding 1e-13 to the constant term more than suffices. * Hence we adjust the constant term to 0.1760912590558. * (We could get a more accurate k by invoking log10, * but this is probably not worthwhile.) */ i -= Bias; denorm = false; } else { /* d is denormalized */ i = bbits[0] + be[0] + (Bias + (P-1) - 1); x = (i > 32) ? word0(d) << (64 - i) | word1(d) >>> (i - 32) : word1(d) << (32 - i); // d2 = x; // word0(d2) -= 31*Exp_msk1; /* adjust exponent */ d2 = setWord0(x, word0(x) - 31*Exp_msk1); i -= (Bias + (P-1) - 1) + 1; denorm = true; } /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; k = (int)ds; if (ds < 0.0 && ds != k) k--; /* want k = floor(ds) */ k_check = true; if (k >= 0 && k <= Ten_pmax) { if (d < tens[k]) k--; k_check = false; } /* At this point floor(log10(d)) <= k <= floor(log10(d))+1. If k_check is zero, we're guaranteed that k = floor(log10(d)). */ j = bbits[0] - i - 1; /* At this point d = b/2^j, where b is an odd integer. */ if (j >= 0) { b2 = 0; s2 = j; } else { b2 = -j; s2 = 0; } if (k >= 0) { b5 = 0; s5 = k; s2 += k; } else { b2 -= k; b5 = -k; s5 = 0; } /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer, b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */ if (mode < 0 || mode > 9) mode = 0; try_quick = true; if (mode > 5) { mode -= 4; try_quick = false; } leftright = true; ilim = ilim1 = 0; switch(mode) { case 0: case 1: ilim = ilim1 = -1; i = 18; ndigits = 0; break; case 2: leftright = false; /* no break */ case 4: if (ndigits <= 0) ndigits = 1; ilim = ilim1 = i = ndigits; break; case 3: leftright = false; /* no break */ case 5: i = ndigits + k + 1; ilim = i; ilim1 = i - 1; if (i <= 0) i = 1; } /* ilim is the maximum number of significant digits we want, based on k and ndigits. */ /* ilim1 is the maximum number of significant digits we want, based on k and ndigits, when it turns out that k was computed too high by one. */ boolean fast_failed = false; if (ilim >= 0 && ilim <= Quick_max && try_quick) { /* Try to get by with floating-point arithmetic. */ i = 0; d2 = d; k0 = k; ilim0 = ilim; ieps = 2; /* conservative */ /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */ if (k > 0) { ds = tens[k&0xf]; j = k >> 4; if ((j & Bletch) != 0) { /* prevent overflows */ j &= Bletch - 1; d /= bigtens[n_bigtens-1]; ieps++; } for(; (j != 0); j >>= 1, i++) if ((j & 1) != 0) { ieps++; ds *= bigtens[i]; } d /= ds; } else if ((j1 = -k) != 0) { d *= tens[j1 & 0xf]; for(j = j1 >> 4; (j != 0); j >>= 1, i++) if ((j & 1) != 0) { ieps++; d *= bigtens[i]; } } /* Check that k was computed correctly. */ if (k_check && d < 1.0 && ilim > 0) { if (ilim1 <= 0) fast_failed = true; else { ilim = ilim1; k--; d *= 10.; ieps++; } } /* eps bounds the cumulative error. */ // eps = ieps*d + 7.0; // word0(eps) -= (P-1)*Exp_msk1; eps = ieps*d + 7.0; eps = setWord0(eps, word0(eps) - (P-1)*Exp_msk1); if (ilim == 0) { S = mhi = null; d -= 5.0; if (d > eps) { buf.append('1'); k++; return k + 1; } if (d < -eps) { buf.setLength(0); buf.append('0'); /* copy "0" to buffer */ return 1; } fast_failed = true; } if (!fast_failed) { fast_failed = true; if (leftright) { /* Use Steele & White method of only * generating digits needed. */ eps = 0.5/tens[ilim-1] - eps; for(i = 0;;) { L = (long)d; d -= L; buf.append((char)('0' + L)); if (d < eps) { return k + 1; } if (1.0 - d < eps) { // goto bump_up; char lastCh; while (true) { lastCh = buf.charAt(buf.length() - 1); buf.setLength(buf.length() - 1); if (lastCh != '9') break; if (buf.length() == 0) { k++; lastCh = '0'; break; } } buf.append((char)(lastCh + 1)); return k + 1; } if (++i >= ilim) break; eps *= 10.0; d *= 10.0; } } else { /* Generate ilim digits, then fix them up. */ eps *= tens[ilim-1]; for(i = 1;; i++, d *= 10.0) { L = (long)d; d -= L; buf.append((char)('0' + L)); if (i == ilim) { if (d > 0.5 + eps) { // goto bump_up; char lastCh; while (true) { lastCh = buf.charAt(buf.length() - 1); buf.setLength(buf.length() - 1); if (lastCh != '9') break; if (buf.length() == 0) { k++; lastCh = '0'; break; } } buf.append((char)(lastCh + 1)); return k + 1; } else if (d < 0.5 - eps) { stripTrailingZeroes(buf); // while(*--s == '0') ; // s++; return k + 1; } break; } } } } if (fast_failed) { buf.setLength(0); d = d2; k = k0; ilim = ilim0; } } /* Do we have a "small" integer? */ if (be[0] >= 0 && k <= Int_max) { /* Yes. */ ds = tens[k]; if (ndigits < 0 && ilim <= 0) { S = mhi = null; if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds)) { buf.setLength(0); buf.append('0'); /* copy "0" to buffer */ return 1; } buf.append('1'); k++; return k + 1; } for(i = 1;; i++) { L = (long) (d / ds); d -= L*ds; buf.append((char)('0' + L)); if (i == ilim) { d += d; if ((d > ds) || (d == ds && (((L & 1) != 0) || biasUp))) { // bump_up: // while(*--s == '9') // if (s == buf) { // k++; // *s = '0'; // break; // } // ++*s++; char lastCh; while (true) { lastCh = buf.charAt(buf.length() - 1); buf.setLength(buf.length() - 1); if (lastCh != '9') break; if (buf.length() == 0) { k++; lastCh = '0'; break; } } buf.append((char)(lastCh + 1)); } break; } d *= 10.0; if (d == 0) break; } return k + 1; } m2 = b2; m5 = b5; mhi = mlo = null; if (leftright) { if (mode < 2) { i = (denorm) ? be[0] + (Bias + (P-1) - 1 + 1) : 1 + P - bbits[0]; /* i is 1 plus the number of trailing zero bits in d's significand. Thus, (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */ } else { j = ilim - 1; if (m5 >= j) m5 -= j; else { s5 += j -= m5; b5 += j; m5 = 0; } if ((i = ilim) < 0) { m2 -= i; i = 0; } /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */ } b2 += i; s2 += i; mhi = BigInteger.valueOf(1); /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or input (when mode < 2) significant digit, divided by 10^k. */ } /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in b2, m2, and s2 without changing the equalities. */ if (m2 > 0 && s2 > 0) { i = (m2 < s2) ? m2 : s2; b2 -= i; m2 -= i; s2 -= i; } /* Fold b5 into b and m5 into mhi. */ if (b5 > 0) { if (leftright) { if (m5 > 0) { mhi = pow5mult(mhi, m5); b1 = mhi.multiply(b); b = b1; } if ((j = b5 - m5) != 0) b = pow5mult(b, j); } else b = pow5mult(b, b5); } /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */ S = BigInteger.valueOf(1); if (s5 > 0) S = pow5mult(S, s5); /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */ /* Check for special case that d is a normalized power of 2. */ spec_case = false; if (mode < 2) { if ( (word1(d) == 0) && ((word0(d) & Bndry_mask) == 0) && ((word0(d) & (Exp_mask & Exp_mask << 1)) != 0) ) { /* The special case. Here we want to be within a quarter of the last input significant digit instead of one half of it when the decimal output string's value is less than d. */ b2 += Log2P; s2 += Log2P; spec_case = true; } } /* Arrange for convenient computation of quotients: * shift left if necessary so divisor has 4 leading 0 bits. * * Perhaps we should just compute leading 28 bits of S once * and for all and pass them and a shift to quorem, so it * can do shifts and ors to compute the numerator for q. */ byte [] S_bytes = S.toByteArray(); int S_hiWord = 0; for (int idx = 0; idx < 4; idx++) { S_hiWord = (S_hiWord << 8); if (idx < S_bytes.length) S_hiWord |= (S_bytes[idx] & 0xFF); } if ((i = (((s5 != 0) ? 32 - hi0bits(S_hiWord) : 1) + s2) & 0x1f) != 0) i = 32 - i; /* i is the number of leading zero bits in the most significant word of S*2^s2. */ if (i > 4) { i -= 4; b2 += i; m2 += i; s2 += i; } else if (i < 4) { i += 28; b2 += i; m2 += i; s2 += i; } /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */ if (b2 > 0) b = b.shiftLeft(b2); if (s2 > 0) S = S.shiftLeft(s2); /* Now we have d/10^k = b/S and (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */ if (k_check) { if (b.compareTo(S) < 0) { k--; b = b.multiply(BigInteger.valueOf(10)); /* we botched the k estimate */ if (leftright) mhi = mhi.multiply(BigInteger.valueOf(10)); ilim = ilim1; } } /* At this point 1 <= d/10^k = b/S < 10. */ if (ilim <= 0 && mode > 2) { /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode. Output either zero or the minimum nonzero output depending on which is closer to d. */ if ((ilim < 0 ) || ((i = b.compareTo(S = S.multiply(BigInteger.valueOf(5)))) < 0) || ((i == 0 && !biasUp))) { /* Always emit at least one digit. If the number appears to be zero using the current mode, then emit one '0' digit and set decpt to 1. */ /*no_digits: k = -1 - ndigits; goto ret; */ buf.setLength(0); buf.append('0'); /* copy "0" to buffer */ return 1; // goto no_digits; } // one_digit: buf.append('1'); k++; return k + 1; } if (leftright) { if (m2 > 0) mhi = mhi.shiftLeft(m2); /* Compute mlo -- check for special case * that d is a normalized power of 2. */ mlo = mhi; if (spec_case) { mhi = mlo; mhi = mhi.shiftLeft(Log2P); } /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */ /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */ for(i = 1;;i++) { BigInteger[] divResult = b.divideAndRemainder(S); b = divResult[1]; dig = (char)(divResult[0].intValue() + '0'); /* Do we yet have the shortest decimal string * that will round to d? */ j = b.compareTo(mlo); /* j is b/S compared with mlo/S. */ delta = S.subtract(mhi); j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta); /* j1 is b/S compared with 1 - mhi/S. */ if ((j1 == 0) && (mode == 0) && ((word1(d) & 1) == 0)) { if (dig == '9') { buf.append('9'); if (roundOff(buf)) { k++; buf.append('1'); } return k + 1; // goto round_9_up; } if (j > 0) dig++; buf.append(dig); return k + 1; } if ((j < 0) || ((j == 0) && (mode == 0) && ((word1(d) & 1) == 0) )) { if (j1 > 0) { /* Either dig or dig+1 would work here as the least significant decimal digit. Use whichever would produce a decimal value closer to d. */ b = b.shiftLeft(1); j1 = b.compareTo(S); if (((j1 > 0) || (j1 == 0 && (((dig & 1) == 1) || biasUp))) && (dig++ == '9')) { buf.append('9'); if (roundOff(buf)) { k++; buf.append('1'); } return k + 1; // goto round_9_up; } } buf.append(dig); return k + 1; } if (j1 > 0) { if (dig == '9') { /* possible if i == 1 */ // round_9_up: // *s++ = '9'; // goto roundoff; buf.append('9'); if (roundOff(buf)) { k++; buf.append('1'); } return k + 1; } buf.append((char)(dig + 1)); return k + 1; } buf.append(dig); if (i == ilim) break; b = b.multiply(BigInteger.valueOf(10)); if (mlo == mhi) mlo = mhi = mhi.multiply(BigInteger.valueOf(10)); else { mlo = mlo.multiply(BigInteger.valueOf(10)); mhi = mhi.multiply(BigInteger.valueOf(10)); } } } else for(i = 1;; i++) { // (char)(dig = quorem(b,S) + '0'); BigInteger[] divResult = b.divideAndRemainder(S); b = divResult[1]; dig = (char)(divResult[0].intValue() + '0'); buf.append(dig); if (i >= ilim) break; b = b.multiply(BigInteger.valueOf(10)); } /* Round off last digit */ b = b.shiftLeft(1); j = b.compareTo(S); if ((j > 0) || (j == 0 && (((dig & 1) == 1) || biasUp))) { // roundoff: // while(*--s == '9') // if (s == buf) { // k++; // *s++ = '1'; // goto ret; // } // ++*s++; if (roundOff(buf)) { k++; buf.append('1'); return k + 1; } } else { stripTrailingZeroes(buf); // while(*--s == '0') ; // s++; } // ret: // Bfree(S); // if (mhi) { // if (mlo && mlo != mhi) // Bfree(mlo); // Bfree(mhi); // } // ret1: // Bfree(b); // JS_ASSERT(s < buf + bufsize); return k + 1; } private static void stripTrailingZeroes(StringBuffer buf) { // while(*--s == '0') ; // s++; int bl = buf.length(); while(bl-->0 && buf.charAt(bl) == '0') { // empty } buf.setLength(bl + 1); } /* Mapping of JSDToStrMode -> JS_dtoa mode */ private static final int dtoaModes[] = { 0, /* DTOSTR_STANDARD */ 0, /* DTOSTR_STANDARD_EXPONENTIAL, */ 3, /* DTOSTR_FIXED, */ 2, /* DTOSTR_EXPONENTIAL, */ 2}; /* DTOSTR_PRECISION */ static void JS_dtostr(StringBuffer buffer, int mode, int precision, double d) { int decPt; /* Position of decimal point relative to first digit returned by JS_dtoa */ boolean[] sign = new boolean[1]; /* true if the sign bit was set in d */ int nDigits; /* Number of significand digits returned by JS_dtoa */ // JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE : // DTOSTR_VARIABLE_BUFFER_SIZE(precision))); if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21)) mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */ decPt = JS_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, sign, buffer); nDigits = buffer.length(); /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */ if (decPt != 9999) { boolean exponentialNotation = false; int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */ int p; switch (mode) { case DTOSTR_STANDARD: if (decPt < -5 || decPt > 21) exponentialNotation = true; else minNDigits = decPt; break; case DTOSTR_FIXED: if (precision >= 0) minNDigits = decPt + precision; else minNDigits = decPt; break; case DTOSTR_EXPONENTIAL: // JS_ASSERT(precision > 0); minNDigits = precision; /* Fall through */ case DTOSTR_STANDARD_EXPONENTIAL: exponentialNotation = true; break; case DTOSTR_PRECISION: // JS_ASSERT(precision > 0); minNDigits = precision; if (decPt < -5 || decPt > precision) exponentialNotation = true; break; } /* If the number has fewer than minNDigits, pad it with zeros at the end */ if (nDigits < minNDigits) { p = minNDigits; nDigits = minNDigits; do { buffer.append('0'); } while (buffer.length() != p); } if (exponentialNotation) { /* Insert a decimal point if more than one significand digit */ if (nDigits != 1) { buffer.insert(1, '.'); } buffer.append('e'); if ((decPt - 1) >= 0) buffer.append('+'); buffer.append(decPt - 1); // JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1); } else if (decPt != nDigits) { /* Some kind of a fraction in fixed notation */ // JS_ASSERT(decPt <= nDigits); if (decPt > 0) { /* dd...dd . dd...dd */ buffer.insert(decPt, '.'); } else { /* 0 . 00...00dd...dd */ for (int i = 0; i < 1 - decPt; i++) buffer.insert(0, '0'); buffer.insert(1, '.'); } } } /* If negative and neither -0.0 nor NaN, output a leading '-'. */ if (sign[0] && !(word0(d) == Sign_bit && word1(d) == 0) && !((word0(d) & Exp_mask) == Exp_mask && ((word1(d) != 0) || ((word0(d) & Frac_mask) != 0)))) { buffer.insert(0, '-'); } } } yui-compressor-2.4.7/src/org/mozilla/javascript/UniqueTag.java0000644000175000017500000000732611753547210024375 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.Serializable; /** * Class instances represent serializable tags to mark special Object values. *

* Compatibility note: under jdk 1.1 use * org.mozilla.javascript.serialize.ScriptableInputStream to read serialized * instances of UniqueTag as under this JDK version the default * ObjectInputStream would not restore them correctly as it lacks support * for readResolve method */ public final class UniqueTag implements Serializable { static final long serialVersionUID = -4320556826714577259L; private static final int ID_NOT_FOUND = 1; private static final int ID_NULL_VALUE = 2; private static final int ID_DOUBLE_MARK = 3; /** * Tag to mark non-existing values. */ public static final UniqueTag NOT_FOUND = new UniqueTag(ID_NOT_FOUND); /** * Tag to distinguish between uninitialized and null values. */ public static final UniqueTag NULL_VALUE = new UniqueTag(ID_NULL_VALUE); /** * Tag to indicate that a object represents "double" with the real value * stored somewhere else. */ public static final UniqueTag DOUBLE_MARK = new UniqueTag(ID_DOUBLE_MARK); private final int tagId; private UniqueTag(int tagId) { this.tagId = tagId; } public Object readResolve() { switch (tagId) { case ID_NOT_FOUND: return NOT_FOUND; case ID_NULL_VALUE: return NULL_VALUE; case ID_DOUBLE_MARK: return DOUBLE_MARK; } throw new IllegalStateException(String.valueOf(tagId)); } // Overridden for better debug printouts @Override public String toString() { String name; switch (tagId) { case ID_NOT_FOUND: name = "NOT_FOUND"; break; case ID_NULL_VALUE: name = "NULL_VALUE"; break; case ID_DOUBLE_MARK: name = "DOUBLE_MARK"; break; default: throw Kit.codeBug(); } return super.toString()+": "+name; } } yui-compressor-2.4.7/src/org/mozilla/javascript/JavaAdapter.java0000644000175000017500000012610611753547210024653 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Patrick Beard * Norris Boyd * Igor Bukanov * Mike McCabe * Matthias Radestock * Andi Vajda * Andrew Wason * Kemal Bayram * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import org.mozilla.classfile.*; import java.lang.reflect.*; import java.io.*; import java.security.*; import java.util.*; public final class JavaAdapter implements IdFunctionCall { /** * Provides a key with which to distinguish previously generated * adapter classes stored in a hash table. */ static class JavaAdapterSignature { Class superClass; Class[] interfaces; ObjToIntMap names; JavaAdapterSignature(Class superClass, Class[] interfaces, ObjToIntMap names) { this.superClass = superClass; this.interfaces = interfaces; this.names = names; } @Override public boolean equals(Object obj) { if (!(obj instanceof JavaAdapterSignature)) return false; JavaAdapterSignature sig = (JavaAdapterSignature) obj; if (superClass != sig.superClass) return false; if (interfaces != sig.interfaces) { if (interfaces.length != sig.interfaces.length) return false; for (int i=0; i < interfaces.length; i++) if (interfaces[i] != sig.interfaces[i]) return false; } if (names.size() != sig.names.size()) return false; ObjToIntMap.Iterator iter = new ObjToIntMap.Iterator(names); for (iter.start(); !iter.done(); iter.next()) { String name = (String)iter.getKey(); int arity = iter.getValue(); if (arity != names.get(name, arity + 1)) return false; } return true; } @Override public int hashCode() { return superClass.hashCode() | (0x9e3779b9 * (names.size() | (interfaces.length << 16))); } } public static void init(Context cx, Scriptable scope, boolean sealed) { JavaAdapter obj = new JavaAdapter(); IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_JavaAdapter, "JavaAdapter", 1, scope); ctor.markAsConstructor(null); if (sealed) { ctor.sealObject(); } ctor.exportAsScopeProperty(); } public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (f.hasTag(FTAG)) { if (f.methodId() == Id_JavaAdapter) { return js_createAdapter(cx, scope, args); } } throw f.unknown(); } public static Object convertResult(Object result, Class c) { if (result == Undefined.instance && (c != ScriptRuntime.ObjectClass && c != ScriptRuntime.StringClass)) { // Avoid an error for an undefined value; return null instead. return null; } return Context.jsToJava(result, c); } public static Scriptable createAdapterWrapper(Scriptable obj, Object adapter) { Scriptable scope = ScriptableObject.getTopLevelScope(obj); NativeJavaObject res = new NativeJavaObject(scope, adapter, null, true); res.setPrototype(obj); return res; } public static Object getAdapterSelf(Class adapterClass, Object adapter) throws NoSuchFieldException, IllegalAccessException { Field self = adapterClass.getDeclaredField("self"); return self.get(adapter); } static Object js_createAdapter(Context cx, Scriptable scope, Object[] args) { int N = args.length; if (N == 0) { throw ScriptRuntime.typeError0("msg.adapter.zero.args"); } Class superClass = null; Class[] intfs = new Class[N - 1]; int interfaceCount = 0; for (int i = 0; i != N - 1; ++i) { Object arg = args[i]; if (!(arg instanceof NativeJavaClass)) { throw ScriptRuntime.typeError2("msg.not.java.class.arg", String.valueOf(i), ScriptRuntime.toString(arg)); } Class c = ((NativeJavaClass) arg).getClassObject(); if (!c.isInterface()) { if (superClass != null) { throw ScriptRuntime.typeError2("msg.only.one.super", superClass.getName(), c.getName()); } superClass = c; } else { intfs[interfaceCount++] = c; } } if (superClass == null) superClass = ScriptRuntime.ObjectClass; Class[] interfaces = new Class[interfaceCount]; System.arraycopy(intfs, 0, interfaces, 0, interfaceCount); Scriptable obj = ScriptRuntime.toObject(cx, scope, args[N - 1]); Class adapterClass = getAdapterClass(scope, superClass, interfaces, obj); Class[] ctorParms = { ScriptRuntime.ContextFactoryClass, ScriptRuntime.ScriptableClass }; Object[] ctorArgs = { cx.getFactory(), obj }; try { Object adapter = adapterClass.getConstructor(ctorParms). newInstance(ctorArgs); return getAdapterSelf(adapterClass, adapter); } catch (Exception ex) { throw Context.throwAsScriptRuntimeEx(ex); } } // Needed by NativeJavaObject serializer public static void writeAdapterObject(Object javaObject, ObjectOutputStream out) throws IOException { Class cl = javaObject.getClass(); out.writeObject(cl.getSuperclass().getName()); Class[] interfaces = cl.getInterfaces(); String[] interfaceNames = new String[interfaces.length]; for (int i=0; i < interfaces.length; i++) interfaceNames[i] = interfaces[i].getName(); out.writeObject(interfaceNames); try { Object delegee = cl.getField("delegee").get(javaObject); out.writeObject(delegee); return; } catch (IllegalAccessException e) { } catch (NoSuchFieldException e) { } throw new IOException(); } // Needed by NativeJavaObject de-serializer public static Object readAdapterObject(Scriptable self, ObjectInputStream in) throws IOException, ClassNotFoundException { ContextFactory factory; Context cx = Context.getCurrentContext(); if (cx != null) { factory = cx.getFactory(); } else { factory = null; } Class superClass = Class.forName((String)in.readObject()); String[] interfaceNames = (String[])in.readObject(); Class[] interfaces = new Class[interfaceNames.length]; for (int i=0; i < interfaceNames.length; i++) interfaces[i] = Class.forName(interfaceNames[i]); Scriptable delegee = (Scriptable)in.readObject(); Class adapterClass = getAdapterClass(self, superClass, interfaces, delegee); Class[] ctorParms = { ScriptRuntime.ContextFactoryClass, ScriptRuntime.ScriptableClass, ScriptRuntime.ScriptableClass }; Object[] ctorArgs = { factory, delegee, self }; try { return adapterClass.getConstructor(ctorParms).newInstance(ctorArgs); } catch(InstantiationException e) { } catch(IllegalAccessException e) { } catch(InvocationTargetException e) { } catch(NoSuchMethodException e) { } throw new ClassNotFoundException("adapter"); } private static ObjToIntMap getObjectFunctionNames(Scriptable obj) { Object[] ids = ScriptableObject.getPropertyIds(obj); ObjToIntMap map = new ObjToIntMap(ids.length); for (int i = 0; i != ids.length; ++i) { if (!(ids[i] instanceof String)) continue; String id = (String) ids[i]; Object value = ScriptableObject.getProperty(obj, id); if (value instanceof Function) { Function f = (Function)value; int length = ScriptRuntime.toInt32( ScriptableObject.getProperty(f, "length")); if (length < 0) { length = 0; } map.put(id, length); } } return map; } private static Class getAdapterClass(Scriptable scope, Class superClass, Class[] interfaces, Scriptable obj) { ClassCache cache = ClassCache.get(scope); Map> generated = cache.getInterfaceAdapterCacheMap(); ObjToIntMap names = getObjectFunctionNames(obj); JavaAdapterSignature sig; sig = new JavaAdapterSignature(superClass, interfaces, names); Class adapterClass = generated.get(sig); if (adapterClass == null) { String adapterName = "adapter" + cache.newClassSerialNumber(); byte[] code = createAdapterCode(names, adapterName, superClass, interfaces, null); adapterClass = loadAdapterClass(adapterName, code); if (cache.isCachingEnabled()) { generated.put(sig, adapterClass); } } return adapterClass; } public static byte[] createAdapterCode(ObjToIntMap functionNames, String adapterName, Class superClass, Class[] interfaces, String scriptClassName) { ClassFileWriter cfw = new ClassFileWriter(adapterName, superClass.getName(), ""); cfw.addField("factory", "Lorg/mozilla/javascript/ContextFactory;", (short) (ClassFileWriter.ACC_PUBLIC | ClassFileWriter.ACC_FINAL)); cfw.addField("delegee", "Lorg/mozilla/javascript/Scriptable;", (short) (ClassFileWriter.ACC_PUBLIC | ClassFileWriter.ACC_FINAL)); cfw.addField("self", "Lorg/mozilla/javascript/Scriptable;", (short) (ClassFileWriter.ACC_PUBLIC | ClassFileWriter.ACC_FINAL)); int interfacesCount = interfaces == null ? 0 : interfaces.length; for (int i=0; i < interfacesCount; i++) { if (interfaces[i] != null) cfw.addInterface(interfaces[i].getName()); } String superName = superClass.getName().replace('.', '/'); generateCtor(cfw, adapterName, superName); generateSerialCtor(cfw, adapterName, superName); if (scriptClassName != null) generateEmptyCtor(cfw, adapterName, superName, scriptClassName); ObjToIntMap generatedOverrides = new ObjToIntMap(); ObjToIntMap generatedMethods = new ObjToIntMap(); // generate methods to satisfy all specified interfaces. for (int i = 0; i < interfacesCount; i++) { Method[] methods = interfaces[i].getMethods(); for (int j = 0; j < methods.length; j++) { Method method = methods[j]; int mods = method.getModifiers(); if (Modifier.isStatic(mods) || Modifier.isFinal(mods)) { continue; } String methodName = method.getName(); Class[] argTypes = method.getParameterTypes(); if (!functionNames.has(methodName)) { try { superClass.getMethod(methodName, argTypes); // The class we're extending implements this method and // the JavaScript object doesn't have an override. See // bug 61226. continue; } catch (NoSuchMethodException e) { // Not implemented by superclass; fall through } } // make sure to generate only one instance of a particular // method/signature. String methodSignature = getMethodSignature(method, argTypes); String methodKey = methodName + methodSignature; if (! generatedOverrides.has(methodKey)) { generateMethod(cfw, adapterName, methodName, argTypes, method.getReturnType()); generatedOverrides.put(methodKey, 0); generatedMethods.put(methodName, 0); } } } // Now, go through the superclass's methods, checking for abstract // methods or additional methods to override. // generate any additional overrides that the object might contain. Method[] methods = getOverridableMethods(superClass); for (int j = 0; j < methods.length; j++) { Method method = methods[j]; int mods = method.getModifiers(); // if a method is marked abstract, must implement it or the // resulting class won't be instantiable. otherwise, if the object // has a property of the same name, then an override is intended. boolean isAbstractMethod = Modifier.isAbstract(mods); String methodName = method.getName(); if (isAbstractMethod || functionNames.has(methodName)) { // make sure to generate only one instance of a particular // method/signature. Class[] argTypes = method.getParameterTypes(); String methodSignature = getMethodSignature(method, argTypes); String methodKey = methodName + methodSignature; if (! generatedOverrides.has(methodKey)) { generateMethod(cfw, adapterName, methodName, argTypes, method.getReturnType()); generatedOverrides.put(methodKey, 0); generatedMethods.put(methodName, 0); // if a method was overridden, generate a "super$method" // which lets the delegate call the superclass' version. if (!isAbstractMethod) { generateSuper(cfw, adapterName, superName, methodName, methodSignature, argTypes, method.getReturnType()); } } } } // Generate Java methods for remaining properties that are not // overrides. ObjToIntMap.Iterator iter = new ObjToIntMap.Iterator(functionNames); for (iter.start(); !iter.done(); iter.next()) { String functionName = (String)iter.getKey(); if (generatedMethods.has(functionName)) continue; int length = iter.getValue(); Class[] parms = new Class[length]; for (int k=0; k < length; k++) parms[k] = ScriptRuntime.ObjectClass; generateMethod(cfw, adapterName, functionName, parms, ScriptRuntime.ObjectClass); } return cfw.toByteArray(); } static Method[] getOverridableMethods(Class c) { ArrayList list = new ArrayList(); HashSet skip = new HashSet(); while (c != null) { appendOverridableMethods(c, list, skip); for (Class intf: c.getInterfaces()) appendOverridableMethods(intf, list, skip); c = c.getSuperclass(); } return list.toArray(new Method[list.size()]); } private static void appendOverridableMethods(Class c, ArrayList list, HashSet skip) { Method[] methods = c.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { String methodKey = methods[i].getName() + getMethodSignature(methods[i], methods[i].getParameterTypes()); if (skip.contains(methodKey)) continue; // skip this method int mods = methods[i].getModifiers(); if (Modifier.isStatic(mods)) continue; if (Modifier.isFinal(mods)) { // Make sure we don't add a final method to the list // of overridable methods. skip.add(methodKey); continue; } if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) { list.add(methods[i]); skip.add(methodKey); } } } static Class loadAdapterClass(String className, byte[] classBytes) { Object staticDomain; Class domainClass = SecurityController.getStaticSecurityDomainClass(); if(domainClass == CodeSource.class || domainClass == ProtectionDomain.class) { ProtectionDomain protectionDomain = JavaAdapter.class.getProtectionDomain(); if(domainClass == CodeSource.class) { staticDomain = protectionDomain == null ? null : protectionDomain.getCodeSource(); } else { staticDomain = protectionDomain; } } else { staticDomain = null; } GeneratedClassLoader loader = SecurityController.createLoader(null, staticDomain); Class result = loader.defineClass(className, classBytes); loader.linkClass(result); return result; } public static Function getFunction(Scriptable obj, String functionName) { Object x = ScriptableObject.getProperty(obj, functionName); if (x == Scriptable.NOT_FOUND) { // This method used to swallow the exception from calling // an undefined method. People have come to depend on this // somewhat dubious behavior. It allows people to avoid // implementing listener methods that they don't care about, // for instance. return null; } if (!(x instanceof Function)) throw ScriptRuntime.notFunctionError(x, functionName); return (Function)x; } /** * Utility method which dynamically binds a Context to the current thread, * if none already exists. */ public static Object callMethod(ContextFactory factory, final Scriptable thisObj, final Function f, final Object[] args, final long argsToWrap) { if (f == null) { // See comments in getFunction return Undefined.instance; } if (factory == null) { factory = ContextFactory.getGlobal(); } final Scriptable scope = f.getParentScope(); if (argsToWrap == 0) { return Context.call(factory, f, scope, thisObj, args); } Context cx = Context.getCurrentContext(); if (cx != null) { return doCall(cx, scope, thisObj, f, args, argsToWrap); } else { return factory.call(new ContextAction() { public Object run(Context cx) { return doCall(cx, scope, thisObj, f, args, argsToWrap); } }); } } private static Object doCall(Context cx, Scriptable scope, Scriptable thisObj, Function f, Object[] args, long argsToWrap) { // Wrap the rest of objects for (int i = 0; i != args.length; ++i) { if (0 != (argsToWrap & (1 << i))) { Object arg = args[i]; if (!(arg instanceof Scriptable)) { args[i] = cx.getWrapFactory().wrap(cx, scope, arg, null); } } } return f.call(cx, scope, thisObj, args); } public static Scriptable runScript(final Script script) { return (Scriptable)ContextFactory.getGlobal().call( new ContextAction() { public Object run(Context cx) { ScriptableObject global = ScriptRuntime.getGlobal(cx); script.exec(cx, global); return global; } }); } private static void generateCtor(ClassFileWriter cfw, String adapterName, String superName) { cfw.startMethod("", "(Lorg/mozilla/javascript/ContextFactory;" +"Lorg/mozilla/javascript/Scriptable;)V", ClassFileWriter.ACC_PUBLIC); // Invoke base class constructor cfw.add(ByteCode.ALOAD_0); // this cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "", "()V"); // Save parameter in instance variable "factory" cfw.add(ByteCode.ALOAD_0); // this cfw.add(ByteCode.ALOAD_1); // first arg: ContextFactory instance cfw.add(ByteCode.PUTFIELD, adapterName, "factory", "Lorg/mozilla/javascript/ContextFactory;"); // Save parameter in instance variable "delegee" cfw.add(ByteCode.ALOAD_0); // this cfw.add(ByteCode.ALOAD_2); // second arg: Scriptable delegee cfw.add(ByteCode.PUTFIELD, adapterName, "delegee", "Lorg/mozilla/javascript/Scriptable;"); cfw.add(ByteCode.ALOAD_0); // this for the following PUTFIELD for self // create a wrapper object to be used as "this" in method calls cfw.add(ByteCode.ALOAD_2); // the Scriptable delegee cfw.add(ByteCode.ALOAD_0); // this cfw.addInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/JavaAdapter", "createAdapterWrapper", "(Lorg/mozilla/javascript/Scriptable;" +"Ljava/lang/Object;" +")Lorg/mozilla/javascript/Scriptable;"); cfw.add(ByteCode.PUTFIELD, adapterName, "self", "Lorg/mozilla/javascript/Scriptable;"); cfw.add(ByteCode.RETURN); cfw.stopMethod((short)3); // 3: this + factory + delegee } private static void generateSerialCtor(ClassFileWriter cfw, String adapterName, String superName) { cfw.startMethod("", "(Lorg/mozilla/javascript/ContextFactory;" +"Lorg/mozilla/javascript/Scriptable;" +"Lorg/mozilla/javascript/Scriptable;" +")V", ClassFileWriter.ACC_PUBLIC); // Invoke base class constructor cfw.add(ByteCode.ALOAD_0); // this cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "", "()V"); // Save parameter in instance variable "factory" cfw.add(ByteCode.ALOAD_0); // this cfw.add(ByteCode.ALOAD_1); // first arg: ContextFactory instance cfw.add(ByteCode.PUTFIELD, adapterName, "factory", "Lorg/mozilla/javascript/ContextFactory;"); // Save parameter in instance variable "delegee" cfw.add(ByteCode.ALOAD_0); // this cfw.add(ByteCode.ALOAD_2); // second arg: Scriptable delegee cfw.add(ByteCode.PUTFIELD, adapterName, "delegee", "Lorg/mozilla/javascript/Scriptable;"); // save self cfw.add(ByteCode.ALOAD_0); // this cfw.add(ByteCode.ALOAD_3); // second arg: Scriptable self cfw.add(ByteCode.PUTFIELD, adapterName, "self", "Lorg/mozilla/javascript/Scriptable;"); cfw.add(ByteCode.RETURN); cfw.stopMethod((short)4); // 4: this + factory + delegee + self } private static void generateEmptyCtor(ClassFileWriter cfw, String adapterName, String superName, String scriptClassName) { cfw.startMethod("", "()V", ClassFileWriter.ACC_PUBLIC); // Invoke base class constructor cfw.add(ByteCode.ALOAD_0); // this cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "", "()V"); // Set factory to null to use current global when necessary cfw.add(ByteCode.ALOAD_0); cfw.add(ByteCode.ACONST_NULL); cfw.add(ByteCode.PUTFIELD, adapterName, "factory", "Lorg/mozilla/javascript/ContextFactory;"); // Load script class cfw.add(ByteCode.NEW, scriptClassName); cfw.add(ByteCode.DUP); cfw.addInvoke(ByteCode.INVOKESPECIAL, scriptClassName, "", "()V"); // Run script and save resulting scope cfw.addInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/JavaAdapter", "runScript", "(Lorg/mozilla/javascript/Script;" +")Lorg/mozilla/javascript/Scriptable;"); cfw.add(ByteCode.ASTORE_1); // Save the Scriptable in instance variable "delegee" cfw.add(ByteCode.ALOAD_0); // this cfw.add(ByteCode.ALOAD_1); // the Scriptable cfw.add(ByteCode.PUTFIELD, adapterName, "delegee", "Lorg/mozilla/javascript/Scriptable;"); cfw.add(ByteCode.ALOAD_0); // this for the following PUTFIELD for self // create a wrapper object to be used as "this" in method calls cfw.add(ByteCode.ALOAD_1); // the Scriptable cfw.add(ByteCode.ALOAD_0); // this cfw.addInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/JavaAdapter", "createAdapterWrapper", "(Lorg/mozilla/javascript/Scriptable;" +"Ljava/lang/Object;" +")Lorg/mozilla/javascript/Scriptable;"); cfw.add(ByteCode.PUTFIELD, adapterName, "self", "Lorg/mozilla/javascript/Scriptable;"); cfw.add(ByteCode.RETURN); cfw.stopMethod((short)2); // this + delegee } /** * Generates code to wrap Java arguments into Object[]. * Non-primitive Java types are left as-is pending conversion * in the helper method. Leaves the array object on the top of the stack. */ static void generatePushWrappedArgs(ClassFileWriter cfw, Class[] argTypes, int arrayLength) { // push arguments cfw.addPush(arrayLength); cfw.add(ByteCode.ANEWARRAY, "java/lang/Object"); int paramOffset = 1; for (int i = 0; i != argTypes.length; ++i) { cfw.add(ByteCode.DUP); // duplicate array reference cfw.addPush(i); paramOffset += generateWrapArg(cfw, paramOffset, argTypes[i]); cfw.add(ByteCode.AASTORE); } } /** * Generates code to wrap Java argument into Object. * Non-primitive Java types are left unconverted pending conversion * in the helper method. Leaves the wrapper object on the top of the stack. */ private static int generateWrapArg(ClassFileWriter cfw, int paramOffset, Class argType) { int size = 1; if (!argType.isPrimitive()) { cfw.add(ByteCode.ALOAD, paramOffset); } else if (argType == Boolean.TYPE) { // wrap boolean values with java.lang.Boolean. cfw.add(ByteCode.NEW, "java/lang/Boolean"); cfw.add(ByteCode.DUP); cfw.add(ByteCode.ILOAD, paramOffset); cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Boolean", "", "(Z)V"); } else if (argType == Character.TYPE) { // Create a string of length 1 using the character parameter. cfw.add(ByteCode.ILOAD, paramOffset); cfw.addInvoke(ByteCode.INVOKESTATIC, "java/lang/String", "valueOf", "(C)Ljava/lang/String;"); } else { // convert all numeric values to java.lang.Double. cfw.add(ByteCode.NEW, "java/lang/Double"); cfw.add(ByteCode.DUP); String typeName = argType.getName(); switch (typeName.charAt(0)) { case 'b': case 's': case 'i': // load an int value, convert to double. cfw.add(ByteCode.ILOAD, paramOffset); cfw.add(ByteCode.I2D); break; case 'l': // load a long, convert to double. cfw.add(ByteCode.LLOAD, paramOffset); cfw.add(ByteCode.L2D); size = 2; break; case 'f': // load a float, convert to double. cfw.add(ByteCode.FLOAD, paramOffset); cfw.add(ByteCode.F2D); break; case 'd': cfw.add(ByteCode.DLOAD, paramOffset); size = 2; break; } cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Double", "", "(D)V"); } return size; } /** * Generates code to convert a wrapped value type to a primitive type. * Handles unwrapping java.lang.Boolean, and java.lang.Number types. * Generates the appropriate RETURN bytecode. */ static void generateReturnResult(ClassFileWriter cfw, Class retType, boolean callConvertResult) { // wrap boolean values with java.lang.Boolean, convert all other // primitive values to java.lang.Double. if (retType == Void.TYPE) { cfw.add(ByteCode.POP); cfw.add(ByteCode.RETURN); } else if (retType == Boolean.TYPE) { cfw.addInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/Context", "toBoolean", "(Ljava/lang/Object;)Z"); cfw.add(ByteCode.IRETURN); } else if (retType == Character.TYPE) { // characters are represented as strings in JavaScript. // return the first character. // first convert the value to a string if possible. cfw.addInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/Context", "toString", "(Ljava/lang/Object;)Ljava/lang/String;"); cfw.add(ByteCode.ICONST_0); cfw.addInvoke(ByteCode.INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C"); cfw.add(ByteCode.IRETURN); } else if (retType.isPrimitive()) { cfw.addInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/Context", "toNumber", "(Ljava/lang/Object;)D"); String typeName = retType.getName(); switch (typeName.charAt(0)) { case 'b': case 's': case 'i': cfw.add(ByteCode.D2I); cfw.add(ByteCode.IRETURN); break; case 'l': cfw.add(ByteCode.D2L); cfw.add(ByteCode.LRETURN); break; case 'f': cfw.add(ByteCode.D2F); cfw.add(ByteCode.FRETURN); break; case 'd': cfw.add(ByteCode.DRETURN); break; default: throw new RuntimeException("Unexpected return type " + retType.toString()); } } else { String retTypeStr = retType.getName(); if (callConvertResult) { cfw.addLoadConstant(retTypeStr); cfw.addInvoke(ByteCode.INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); cfw.addInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/JavaAdapter", "convertResult", "(Ljava/lang/Object;" +"Ljava/lang/Class;" +")Ljava/lang/Object;"); } // Now cast to return type cfw.add(ByteCode.CHECKCAST, retTypeStr); cfw.add(ByteCode.ARETURN); } } private static void generateMethod(ClassFileWriter cfw, String genName, String methodName, Class[] parms, Class returnType) { StringBuffer sb = new StringBuffer(); int paramsEnd = appendMethodSignature(parms, returnType, sb); String methodSignature = sb.toString(); cfw.startMethod(methodName, methodSignature, ClassFileWriter.ACC_PUBLIC); // Prepare stack to call method // push factory cfw.add(ByteCode.ALOAD_0); cfw.add(ByteCode.GETFIELD, genName, "factory", "Lorg/mozilla/javascript/ContextFactory;"); // push self cfw.add(ByteCode.ALOAD_0); cfw.add(ByteCode.GETFIELD, genName, "self", "Lorg/mozilla/javascript/Scriptable;"); // push function cfw.add(ByteCode.ALOAD_0); cfw.add(ByteCode.GETFIELD, genName, "delegee", "Lorg/mozilla/javascript/Scriptable;"); cfw.addPush(methodName); cfw.addInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/JavaAdapter", "getFunction", "(Lorg/mozilla/javascript/Scriptable;" +"Ljava/lang/String;" +")Lorg/mozilla/javascript/Function;"); // push arguments generatePushWrappedArgs(cfw, parms, parms.length); // push bits to indicate which parameters should be wrapped if (parms.length > 64) { // If it will be an issue, then passing a static boolean array // can be an option, but for now using simple bitmask throw Context.reportRuntimeError0( "JavaAdapter can not subclass methods with more then" +" 64 arguments."); } long convertionMask = 0; for (int i = 0; i != parms.length; ++i) { if (!parms[i].isPrimitive()) { convertionMask |= (1 << i); } } cfw.addPush(convertionMask); // go through utility method, which creates a Context to run the // method in. cfw.addInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/JavaAdapter", "callMethod", "(Lorg/mozilla/javascript/ContextFactory;" +"Lorg/mozilla/javascript/Scriptable;" +"Lorg/mozilla/javascript/Function;" +"[Ljava/lang/Object;" +"J" +")Ljava/lang/Object;"); generateReturnResult(cfw, returnType, true); cfw.stopMethod((short)paramsEnd); } /** * Generates code to push typed parameters onto the operand stack * prior to a direct Java method call. */ private static int generatePushParam(ClassFileWriter cfw, int paramOffset, Class paramType) { if (!paramType.isPrimitive()) { cfw.addALoad(paramOffset); return 1; } String typeName = paramType.getName(); switch (typeName.charAt(0)) { case 'z': case 'b': case 'c': case 's': case 'i': // load an int value, convert to double. cfw.addILoad(paramOffset); return 1; case 'l': // load a long, convert to double. cfw.addLLoad(paramOffset); return 2; case 'f': // load a float, convert to double. cfw.addFLoad(paramOffset); return 1; case 'd': cfw.addDLoad(paramOffset); return 2; } throw Kit.codeBug(); } /** * Generates code to return a Java type, after calling a Java method * that returns the same type. * Generates the appropriate RETURN bytecode. */ private static void generatePopResult(ClassFileWriter cfw, Class retType) { if (retType.isPrimitive()) { String typeName = retType.getName(); switch (typeName.charAt(0)) { case 'b': case 'c': case 's': case 'i': case 'z': cfw.add(ByteCode.IRETURN); break; case 'l': cfw.add(ByteCode.LRETURN); break; case 'f': cfw.add(ByteCode.FRETURN); break; case 'd': cfw.add(ByteCode.DRETURN); break; } } else { cfw.add(ByteCode.ARETURN); } } /** * Generates a method called "super$methodName()" which can be called * from JavaScript that is equivalent to calling "super.methodName()" * from Java. Eventually, this may be supported directly in JavaScript. */ private static void generateSuper(ClassFileWriter cfw, String genName, String superName, String methodName, String methodSignature, Class[] parms, Class returnType) { cfw.startMethod("super$" + methodName, methodSignature, ClassFileWriter.ACC_PUBLIC); // push "this" cfw.add(ByteCode.ALOAD, 0); // push the rest of the parameters. int paramOffset = 1; for (int i = 0; i < parms.length; i++) { paramOffset += generatePushParam(cfw, paramOffset, parms[i]); } // call the superclass implementation of the method. cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, methodName, methodSignature); // now, handle the return type appropriately. Class retType = returnType; if (!retType.equals(Void.TYPE)) { generatePopResult(cfw, retType); } else { cfw.add(ByteCode.RETURN); } cfw.stopMethod((short)(paramOffset + 1)); } /** * Returns a fully qualified method name concatenated with its signature. */ private static String getMethodSignature(Method method, Class[] argTypes) { StringBuffer sb = new StringBuffer(); appendMethodSignature(argTypes, method.getReturnType(), sb); return sb.toString(); } static int appendMethodSignature(Class[] argTypes, Class returnType, StringBuffer sb) { sb.append('('); int firstLocal = 1 + argTypes.length; // includes this. for (int i = 0; i < argTypes.length; i++) { Class type = argTypes[i]; appendTypeString(sb, type); if (type == Long.TYPE || type == Double.TYPE) { // adjust for duble slot ++firstLocal; } } sb.append(')'); appendTypeString(sb, returnType); return firstLocal; } private static StringBuffer appendTypeString(StringBuffer sb, Class type) { while (type.isArray()) { sb.append('['); type = type.getComponentType(); } if (type.isPrimitive()) { char typeLetter; if (type == Boolean.TYPE) { typeLetter = 'Z'; } else if (type == Long.TYPE) { typeLetter = 'J'; } else { String typeName = type.getName(); typeLetter = Character.toUpperCase(typeName.charAt(0)); } sb.append(typeLetter); } else { sb.append('L'); sb.append(type.getName().replace('.', '/')); sb.append(';'); } return sb; } static int[] getArgsToConvert(Class[] argTypes) { int count = 0; for (int i = 0; i != argTypes.length; ++i) { if (!argTypes[i].isPrimitive()) ++count; } if (count == 0) return null; int[] array = new int[count]; count = 0; for (int i = 0; i != argTypes.length; ++i) { if (!argTypes[i].isPrimitive()) array[count++] = i; } return array; } private static final Object FTAG = "JavaAdapter"; private static final int Id_JavaAdapter = 1; } yui-compressor-2.4.7/src/org/mozilla/javascript/Undefined.java0000644000175000017500000000400611753547210024364 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.Serializable; /** * This class implements the Undefined value in JavaScript. */ public class Undefined implements Serializable { static final long serialVersionUID = 9195680630202616767L; public static final Object instance = new Undefined(); private Undefined() { } public Object readResolve() { return instance; } } yui-compressor-2.4.7/src/org/mozilla/javascript/InterpretedFunction.java0000644000175000017500000001647011753547210026466 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * Bob Jervis * Roger Lawrence * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import org.mozilla.javascript.debug.DebuggableScript; final class InterpretedFunction extends NativeFunction implements Script { static final long serialVersionUID = 541475680333911468L; InterpreterData idata; SecurityController securityController; Object securityDomain; Scriptable[] functionRegExps; private InterpretedFunction(InterpreterData idata, Object staticSecurityDomain) { this.idata = idata; // Always get Context from the current thread to // avoid security breaches via passing mangled Context instances // with bogus SecurityController Context cx = Context.getContext(); SecurityController sc = cx.getSecurityController(); Object dynamicDomain; if (sc != null) { dynamicDomain = sc.getDynamicSecurityDomain(staticSecurityDomain); } else { if (staticSecurityDomain != null) { throw new IllegalArgumentException(); } dynamicDomain = null; } this.securityController = sc; this.securityDomain = dynamicDomain; } private InterpretedFunction(InterpretedFunction parent, int index) { this.idata = parent.idata.itsNestedFunctions[index]; this.securityController = parent.securityController; this.securityDomain = parent.securityDomain; } /** * Create script from compiled bytecode. */ static InterpretedFunction createScript(InterpreterData idata, Object staticSecurityDomain) { InterpretedFunction f; f = new InterpretedFunction(idata, staticSecurityDomain); return f; } /** * Create function compiled from Function(...) constructor. */ static InterpretedFunction createFunction(Context cx,Scriptable scope, InterpreterData idata, Object staticSecurityDomain) { InterpretedFunction f; f = new InterpretedFunction(idata, staticSecurityDomain); f.initInterpretedFunction(cx, scope); return f; } /** * Create function embedded in script or another function. */ static InterpretedFunction createFunction(Context cx, Scriptable scope, InterpretedFunction parent, int index) { InterpretedFunction f = new InterpretedFunction(parent, index); f.initInterpretedFunction(cx, scope); return f; } Scriptable[] createRegExpWraps(Context cx, Scriptable scope) { if (idata.itsRegExpLiterals == null) Kit.codeBug(); RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx); int N = idata.itsRegExpLiterals.length; Scriptable[] array = new Scriptable[N]; for (int i = 0; i != N; ++i) { array[i] = rep.wrapRegExp(cx, scope, idata.itsRegExpLiterals[i]); } return array; } private void initInterpretedFunction(Context cx, Scriptable scope) { initScriptFunction(cx, scope); if (idata.itsRegExpLiterals != null) { functionRegExps = createRegExpWraps(cx, scope); } } @Override public String getFunctionName() { return (idata.itsName == null) ? "" : idata.itsName; } /** * Calls the function. * @param cx the current context * @param scope the scope used for the call * @param thisObj the value of "this" * @param args function arguments. Must not be null. You can use * {@link ScriptRuntime#emptyArgs} to pass empty arguments. * @return the result of the function call. */ @Override public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!ScriptRuntime.hasTopCall(cx)) { return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args); } return Interpreter.interpret(this, cx, scope, thisObj, args); } public Object exec(Context cx, Scriptable scope) { if (!isScript()) { // Can only be applied to scripts throw new IllegalStateException(); } if (!ScriptRuntime.hasTopCall(cx)) { // It will go through "call" path. but they are equivalent return ScriptRuntime.doTopCall( this, cx, scope, scope, ScriptRuntime.emptyArgs); } return Interpreter.interpret( this, cx, scope, scope, ScriptRuntime.emptyArgs); } public boolean isScript() { return idata.itsFunctionType == 0; } @Override public String getEncodedSource() { return Interpreter.getEncodedSource(idata); } @Override public DebuggableScript getDebuggableView() { return idata; } @Override public Object resumeGenerator(Context cx, Scriptable scope, int operation, Object state, Object value) { return Interpreter.resumeGenerator(cx, scope, operation, state, value); } @Override protected int getLanguageVersion() { return idata.languageVersion; } @Override protected int getParamCount() { return idata.argCount; } @Override protected int getParamAndVarCount() { return idata.argNames.length; } @Override protected String getParamOrVarName(int index) { return idata.argNames[index]; } @Override protected boolean getParamOrVarConst(int index) { return idata.argIsConst[index]; } } yui-compressor-2.4.7/src/org/mozilla/javascript/ContextAction.java0000644000175000017500000000420211753547210025243 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov, igor@fastmail.fm * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * Interface to represent arbitrary action that requires to have Context * object associated with the current thread for its execution. */ public interface ContextAction { /** * Execute action using the supplied Context instance. * When Rhino runtime calls the method, cx will be associated * with the current thread as active context. * * @see ContextFactory#call(ContextAction) */ public Object run(Context cx); } yui-compressor-2.4.7/src/org/mozilla/javascript/RefCallable.java0000644000175000017500000000451711753547210024626 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov, igor@mir2.org * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * Object that can allows assignments to the result of function calls. */ public interface RefCallable extends Callable { /** * Perform function call in reference context. * The args array reference should not be stored in any object that is * can be GC-reachable after this method returns. If this is necessary, * for example, to implement {@link Ref} methods, then store args.clone(), * not args array itself. * * @param cx the current Context for this thread * @param thisObj the JavaScript this object * @param args the array of arguments */ public Ref refCall(Context cx, Scriptable thisObj, Object[] args); } yui-compressor-2.4.7/src/org/mozilla/javascript/ImporterTopLevel.java0000644000175000017500000002515711753547210025751 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * Matthias Radestock * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * Class ImporterTopLevel * * This class defines a ScriptableObject that can be instantiated * as a top-level ("global") object to provide functionality similar * to Java's "import" statement. *

* This class can be used to create a top-level scope using the following code: *

 *  Scriptable scope = new ImporterTopLevel(cx);
 * 
* Then JavaScript code will have access to the following methods: *
    *
  • importClass - will "import" a class by making its unqualified name * available as a property of the top-level scope *
  • importPackage - will "import" all the classes of the package by * searching for unqualified names as classes qualified * by the given package. *
* The following code from the shell illustrates this use: *
 * js> importClass(java.io.File)
 * js> f = new File('help.txt')
 * help.txt
 * js> importPackage(java.util)
 * js> v = new Vector()
 * []
 *
 * @author Norris Boyd
 */
public class ImporterTopLevel extends IdScriptableObject
{
    static final long serialVersionUID = -9095380847465315412L;

    private static final Object IMPORTER_TAG = "Importer";

    public ImporterTopLevel() { }

    public ImporterTopLevel(Context cx) {
        this(cx, false);
    }

    public ImporterTopLevel(Context cx, boolean sealed)
    {
        initStandardObjects(cx, sealed);
    }

    @Override
    public String getClassName()
    {
        return (topScopeFlag) ? "global" : "JavaImporter";
    }

    public static void init(Context cx, Scriptable scope, boolean sealed)
    {
        ImporterTopLevel obj = new ImporterTopLevel();
        obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
    }

    public void initStandardObjects(Context cx, boolean sealed)
    {
        // Assume that Context.initStandardObjects initialize JavaImporter
        // property lazily so the above init call is not yet called
        cx.initStandardObjects(this, sealed);
        topScopeFlag = true;
        // If seal is true then exportAsJSClass(cx, seal) would seal
        // this obj. Since this is scope as well, it would not allow
        // to add variables.
        IdFunctionObject ctor = exportAsJSClass(MAX_PROTOTYPE_ID, this, false);
        if (sealed) {
            ctor.sealObject();
        }
        // delete "constructor" defined by exportAsJSClass so "constructor"
        // name would refer to Object.constructor
        // and not to JavaImporter.prototype.constructor.
        delete("constructor");
    }

    @Override
    public boolean has(String name, Scriptable start) {
        return super.has(name, start)
               || getPackageProperty(name, start) != NOT_FOUND;
    }

    @Override
    public Object get(String name, Scriptable start) {
        Object result = super.get(name, start);
        if (result != NOT_FOUND)
            return result;
        result = getPackageProperty(name, start);
        return result;
    }

    private Object getPackageProperty(String name, Scriptable start) {
        Object result = NOT_FOUND;
        Object[] elements;
        synchronized (importedPackages) {
            elements = importedPackages.toArray();
        }
        for (int i=0; i < elements.length; i++) {
            NativeJavaPackage p = (NativeJavaPackage) elements[i];
            Object v = p.getPkgProperty(name, start, false);
            if (v != null && !(v instanceof NativeJavaPackage)) {
                if (result == NOT_FOUND) {
                    result = v;
                } else {
                    throw Context.reportRuntimeError2(
                        "msg.ambig.import", result.toString(), v.toString());
                }
            }
        }
        return result;
    }

    /**
     * @deprecated Kept only for compatibility.
     */
    public void importPackage(Context cx, Scriptable thisObj, Object[] args,
                              Function funObj)
    {
        js_importPackage(args);
    }

    private Object js_construct(Scriptable scope, Object[] args)
    {
        ImporterTopLevel result = new ImporterTopLevel();
        for (int i = 0; i != args.length; ++i) {
            Object arg = args[i];
            if (arg instanceof NativeJavaClass) {
                result.importClass((NativeJavaClass)arg);
            } else if (arg instanceof NativeJavaPackage) {
                result.importPackage((NativeJavaPackage)arg);
            } else {
                throw Context.reportRuntimeError1(
                    "msg.not.class.not.pkg", Context.toString(arg));
            }
        }
        // set explicitly prototype and scope
        // as otherwise in top scope mode BaseFunction.construct
        // would keep them set to null. It also allow to use
        // JavaImporter without new and still get properly
        // initialized object.
        result.setParentScope(scope);
        result.setPrototype(this);
        return result;
    }

    private Object js_importClass(Object[] args)
    {
        for (int i = 0; i != args.length; i++) {
            Object arg = args[i];
            if (!(arg instanceof NativeJavaClass)) {
                throw Context.reportRuntimeError1(
                    "msg.not.class", Context.toString(arg));
            }
            importClass((NativeJavaClass)arg);
        }
        return Undefined.instance;
    }

    private Object js_importPackage(Object[] args)
    {
        for (int i = 0; i != args.length; i++) {
            Object arg = args[i];
            if (!(arg instanceof NativeJavaPackage)) {
                throw Context.reportRuntimeError1(
                    "msg.not.pkg", Context.toString(arg));
            }
            importPackage((NativeJavaPackage)arg);
        }
        return Undefined.instance;
    }

    private void importPackage(NativeJavaPackage pkg)
    {
        if(pkg == null) {
            return;
        }
        synchronized (importedPackages) {
            for (int j = 0; j != importedPackages.size(); j++) {
                if (pkg.equals(importedPackages.get(j))) {
                    return;
                }
            }
            importedPackages.add(pkg);
        }
    }

    private void importClass(NativeJavaClass cl)
    {
        String s = cl.getClassObject().getName();
        String n = s.substring(s.lastIndexOf('.')+1);
        Object val = get(n, this);
        if (val != NOT_FOUND && val != cl) {
            throw Context.reportRuntimeError1("msg.prop.defined", n);
        }
        //defineProperty(n, cl, DONTENUM);
        put(n, this, cl);
    }

    @Override
    protected void initPrototypeId(int id)
    {
        String s;
        int arity;
        switch (id) {
          case Id_constructor:   arity=0; s="constructor";   break;
          case Id_importClass:   arity=1; s="importClass";   break;
          case Id_importPackage: arity=1; s="importPackage"; break;
          default: throw new IllegalArgumentException(String.valueOf(id));
        }
        initPrototypeMethod(IMPORTER_TAG, id, s, arity);
    }

    @Override
    public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
                             Scriptable thisObj, Object[] args)
    {
        if (!f.hasTag(IMPORTER_TAG)) {
            return super.execIdCall(f, cx, scope, thisObj, args);
        }
        int id = f.methodId();
        switch (id) {
          case Id_constructor:
            return js_construct(scope, args);

          case Id_importClass:
            return realThis(thisObj, f).js_importClass(args);

          case Id_importPackage:
            return realThis(thisObj, f).js_importPackage(args);
        }
        throw new IllegalArgumentException(String.valueOf(id));
    }

    private ImporterTopLevel realThis(Scriptable thisObj, IdFunctionObject f)
    {
        if (topScopeFlag) {
            // when used as top scope importPackage and importClass are global
            // function that ignore thisObj
            return this;
        }
        if (!(thisObj instanceof ImporterTopLevel))
            throw incompatibleCallError(f);
        return (ImporterTopLevel)thisObj;
    }

// #string_id_map#

    @Override
    protected int findPrototypeId(String s)
    {
        int id;
// #generated# Last update: 2007-05-09 08:15:24 EDT
        L0: { id = 0; String X = null; int c;
            int s_length = s.length();
            if (s_length==11) {
                c=s.charAt(0);
                if (c=='c') { X="constructor";id=Id_constructor; }
                else if (c=='i') { X="importClass";id=Id_importClass; }
            }
            else if (s_length==13) { X="importPackage";id=Id_importPackage; }
            if (X!=null && X!=s && !X.equals(s)) id = 0;
            break L0;
        }
// #/generated#
        return id;
    }

    private static final int
        Id_constructor          = 1,
        Id_importClass          = 2,
        Id_importPackage        = 3,
        MAX_PROTOTYPE_ID        = 3;

// #/string_id_map#

    private ObjArray importedPackages = new ObjArray();
    private boolean topScopeFlag;
}
yui-compressor-2.4.7/src/org/mozilla/javascript/IdScriptableObject.java0000644000175000017500000006044611753547210026171 0ustar  drazzibdrazzib/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
 *
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0
 *
 * 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 Rhino code, released
 * May 6, 1999.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1997-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Igor Bukanov
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License Version 2 or later (the "GPL"), in which
 * case the provisions of the GPL are applicable instead of those above. If
 * you wish to allow use of your version of this file only under the terms of
 * the GPL and not to allow others to use your version of this file under the
 * MPL, indicate your decision by deleting the provisions above and replacing
 * them with the notice and other provisions required by the GPL. If you do
 * not delete the provisions above, a recipient may use your version of this
 * file under either the MPL or the GPL.
 *
 * ***** END LICENSE BLOCK ***** */

package org.mozilla.javascript;

import java.io.*;

/**
Base class for native object implementation that uses IdFunctionObject to export its methods to script via .prototype object.

Any descendant should implement at least the following methods:
    findInstanceIdInfo
    getInstanceIdName
    execIdCall
    methodArity

To define non-function properties, the descendant should override
    getInstanceIdValue
    setInstanceIdValue
to get/set property value and provide its default attributes.


To customize initializition of constructor and protype objects, descendant
may override scopeInit or fillConstructorProperties methods.

*/
public abstract class IdScriptableObject extends ScriptableObject
    implements IdFunctionCall
{
    private transient volatile PrototypeValues prototypeValues;

    private static final class PrototypeValues implements Serializable
    {
        static final long serialVersionUID = 3038645279153854371L;

        private static final int VALUE_SLOT = 0;
        private static final int NAME_SLOT = 1;
        private static final int SLOT_SPAN = 2;

        private IdScriptableObject obj;
        private int maxId;
        private volatile Object[] valueArray;
        private volatile short[] attributeArray;
        private volatile int lastFoundId = 1;

        // The following helps to avoid creation of valueArray during runtime
        // initialization for common case of "constructor" property
        int constructorId;
        private IdFunctionObject constructor;
        private short constructorAttrs;

        PrototypeValues(IdScriptableObject obj, int maxId)
        {
            if (obj == null) throw new IllegalArgumentException();
            if (maxId < 1) throw new IllegalArgumentException();
            this.obj = obj;
            this.maxId = maxId;
        }

        final int getMaxId()
        {
            return maxId;
        }

        final void initValue(int id, String name, Object value, int attributes)
        {
            if (!(1 <= id && id <= maxId))
                throw new IllegalArgumentException();
            if (name == null)
                throw new IllegalArgumentException();
            if (value == NOT_FOUND)
                throw new IllegalArgumentException();
            ScriptableObject.checkValidAttributes(attributes);
            if (obj.findPrototypeId(name) != id)
                throw new IllegalArgumentException(name);

            if (id == constructorId) {
                if (!(value instanceof IdFunctionObject)) {
                    throw new IllegalArgumentException("consructor should be initialized with IdFunctionObject");
                }
                constructor = (IdFunctionObject)value;
                constructorAttrs = (short)attributes;
                return;
            }

            initSlot(id, name, value, attributes);
        }

        private void initSlot(int id, String name, Object value,
                              int attributes)
        {
            Object[] array = valueArray;
            if (array == null)
                throw new IllegalStateException();

            if (value == null) {
                value = UniqueTag.NULL_VALUE;
            }
            int index = (id - 1) * SLOT_SPAN;
            synchronized (this) {
                Object value2 = array[index + VALUE_SLOT];
                if (value2 == null) {
                    array[index + VALUE_SLOT] = value;
                    array[index + NAME_SLOT] = name;
                    attributeArray[id - 1] = (short)attributes;
                } else {
                    if (!name.equals(array[index + NAME_SLOT]))
                         throw new IllegalStateException();
                }
            }
        }

        final IdFunctionObject createPrecachedConstructor()
        {
            if (constructorId != 0) throw new IllegalStateException();
            constructorId = obj.findPrototypeId("constructor");
            if (constructorId == 0) {
                throw new IllegalStateException(
                    "No id for constructor property");
            }
            obj.initPrototypeId(constructorId);
            if (constructor == null) {
                throw new IllegalStateException(
                    obj.getClass().getName()+".initPrototypeId() did not "
                    +"initialize id="+constructorId);
            }
            constructor.initFunction(obj.getClassName(),
                                     ScriptableObject.getTopLevelScope(obj));
            constructor.markAsConstructor(obj);
            return constructor;
        }

        final int findId(String name)
        {
            Object[] array = valueArray;
            if (array == null) {
                return obj.findPrototypeId(name);
            }
            int id = lastFoundId;
            if (name == array[(id - 1) * SLOT_SPAN + NAME_SLOT]) {
                return id;
            }
            id = obj.findPrototypeId(name);
            if (id != 0) {
                int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
                // Make cache to work!
                array[nameSlot] = name;
                lastFoundId = id;
            }
            return id;
        }

        final boolean has(int id)
        {
            Object[] array = valueArray;
            if (array == null) {
                // Not yet initialized, assume all exists
                return true;
            }
            int valueSlot = (id  - 1) * SLOT_SPAN + VALUE_SLOT;
            Object value = array[valueSlot];
            if (value == null) {
                // The particular entry has not been yet initialized
                return true;
            }
            return value != NOT_FOUND;
        }

        final Object get(int id)
        {
            Object value = ensureId(id);
            if (value == UniqueTag.NULL_VALUE) {
                value = null;
            }
            return value;
        }

        final void set(int id, Scriptable start, Object value)
        {
            if (value == NOT_FOUND) throw new IllegalArgumentException();
            ensureId(id);
            int attr = attributeArray[id - 1];
            if ((attr & READONLY) == 0) {
                if (start == obj) {
                    if (value == null) {
                        value = UniqueTag.NULL_VALUE;
                    }
                    int valueSlot = (id  - 1) * SLOT_SPAN + VALUE_SLOT;
                    synchronized (this) {
                        valueArray[valueSlot] = value;
                    }
                }
                else {
                    int nameSlot = (id  - 1) * SLOT_SPAN + NAME_SLOT;
                    String name = (String)valueArray[nameSlot];
                    start.put(name, start, value);
                }
            }
        }

        final void delete(int id)
        {
            ensureId(id);
            int attr = attributeArray[id - 1];
            if ((attr & PERMANENT) == 0) {
                int valueSlot = (id  - 1) * SLOT_SPAN + VALUE_SLOT;
                synchronized (this) {
                    valueArray[valueSlot] = NOT_FOUND;
                    attributeArray[id - 1] = EMPTY;
                }
            }
        }

        final int getAttributes(int id)
        {
            ensureId(id);
            return attributeArray[id - 1];
        }

        final void setAttributes(int id, int attributes)
        {
            ScriptableObject.checkValidAttributes(attributes);
            ensureId(id);
            synchronized (this) {
                attributeArray[id - 1] = (short)attributes;
            }
        }

        final Object[] getNames(boolean getAll, Object[] extraEntries)
        {
            Object[] names = null;
            int count = 0;
            for (int id = 1; id <= maxId; ++id) {
                Object value = ensureId(id);
                if (getAll || (attributeArray[id - 1] & DONTENUM) == 0) {
                    if (value != NOT_FOUND) {
                        int nameSlot = (id  - 1) * SLOT_SPAN + NAME_SLOT;
                        String name = (String)valueArray[nameSlot];
                        if (names == null) {
                            names = new Object[maxId];
                        }
                        names[count++] = name;
                    }
                }
            }
            if (count == 0) {
                return extraEntries;
            } else if (extraEntries == null || extraEntries.length == 0) {
                if (count != names.length) {
                    Object[] tmp = new Object[count];
                    System.arraycopy(names, 0, tmp, 0, count);
                    names = tmp;
                }
                return names;
            } else {
                int extra = extraEntries.length;
                Object[] tmp = new Object[extra + count];
                System.arraycopy(extraEntries, 0, tmp, 0, extra);
                System.arraycopy(names, 0, tmp, extra, count);
                return tmp;
            }
        }

        private Object ensureId(int id)
        {
            Object[] array = valueArray;
            if (array == null) {
                synchronized (this) {
                    array = valueArray;
                    if (array == null) {
                        array = new Object[maxId * SLOT_SPAN];
                        valueArray = array;
                        attributeArray = new short[maxId];
                    }
                }
            }
            int valueSlot = (id  - 1) * SLOT_SPAN + VALUE_SLOT;
            Object value = array[valueSlot];
            if (value == null) {
                if (id == constructorId) {
                    initSlot(constructorId, "constructor",
                             constructor, constructorAttrs);
                    constructor = null; // no need to refer it any longer
                } else {
                    obj.initPrototypeId(id);
                }
                value = array[valueSlot];
                if (value == null) {
                    throw new IllegalStateException(
                        obj.getClass().getName()+".initPrototypeId(int id) "
                        +"did not initialize id="+id);
                }
            }
            return value;
        }
    }

    public IdScriptableObject()
    {
    }

    public IdScriptableObject(Scriptable scope, Scriptable prototype)
    {
        super(scope, prototype);
    }

    protected final Object defaultGet(String name)
    {
        return super.get(name, this);
    }

    protected final void defaultPut(String name, Object value)
    {
        super.put(name, this, value);
    }

    @Override
    public boolean has(String name, Scriptable start)
    {
        int info = findInstanceIdInfo(name);
        if (info != 0) {
            int attr = (info >>> 16);
            if ((attr & PERMANENT) != 0) {
                return true;
            }
            int id = (info & 0xFFFF);
            return NOT_FOUND != getInstanceIdValue(id);
        }
        if (prototypeValues != null) {
            int id = prototypeValues.findId(name);
            if (id != 0) {
                return prototypeValues.has(id);
            }
        }
        return super.has(name, start);
    }

    @Override
    public Object get(String name, Scriptable start)
    {
        int info = findInstanceIdInfo(name);
        if (info != 0) {
            int id = (info & 0xFFFF);
            return getInstanceIdValue(id);
        }
        if (prototypeValues != null) {
            int id = prototypeValues.findId(name);
            if (id != 0) {
                return prototypeValues.get(id);
            }
        }
        return super.get(name, start);
    }

    @Override
    public void put(String name, Scriptable start, Object value)
    {
        int info = findInstanceIdInfo(name);
        if (info != 0) {
            if (start == this && isSealed()) {
                throw Context.reportRuntimeError1("msg.modify.sealed",
                                                  name);
            }
            int attr = (info >>> 16);
            if ((attr & READONLY) == 0) {
                if (start == this) {
                    int id = (info & 0xFFFF);
                    setInstanceIdValue(id, value);
                }
                else {
                    start.put(name, start, value);
                }
            }
            return;
        }
        if (prototypeValues != null) {
            int id = prototypeValues.findId(name);
            if (id != 0) {
                if (start == this && isSealed()) {
                    throw Context.reportRuntimeError1("msg.modify.sealed",
                                                      name);
                }
                prototypeValues.set(id, start, value);
                return;
            }
        }
        super.put(name, start, value);
    }

    @Override
    public void delete(String name)
    {
        int info = findInstanceIdInfo(name);
        if (info != 0) {
            // Let the super class to throw exceptions for sealed objects
            if (!isSealed()) {
                int attr = (info >>> 16);
                if ((attr & PERMANENT) == 0) {
                    int id = (info & 0xFFFF);
                    setInstanceIdValue(id, NOT_FOUND);
                }
                return;
            }
        }
        if (prototypeValues != null) {
            int id = prototypeValues.findId(name);
            if (id != 0) {
                if (!isSealed()) {
                    prototypeValues.delete(id);
                }
                return;
            }
        }
        super.delete(name);
    }

    @Override
    public int getAttributes(String name)
    {
        int info = findInstanceIdInfo(name);
        if (info != 0) {
            int attr = (info >>> 16);
            return attr;
        }
        if (prototypeValues != null) {
            int id = prototypeValues.findId(name);
            if (id != 0) {
                return prototypeValues.getAttributes(id);
            }
        }
        return super.getAttributes(name);
    }

    @Override
    public void setAttributes(String name, int attributes)
    {
        ScriptableObject.checkValidAttributes(attributes);
        int info = findInstanceIdInfo(name);
        if (info != 0) {
            int currentAttributes = (info >>> 16);
            if (attributes != currentAttributes) {
                throw new RuntimeException(
                    "Change of attributes for this id is not supported");
            }
            return;
        }
        if (prototypeValues != null) {
            int id = prototypeValues.findId(name);
            if (id != 0) {
                prototypeValues.setAttributes(id, attributes);
                return;
            }
        }
        super.setAttributes(name, attributes);
    }

    @Override
    Object[] getIds(boolean getAll)
    {
        Object[] result = super.getIds(getAll);

        if (prototypeValues != null) {
            result = prototypeValues.getNames(getAll, result);
        }

        int maxInstanceId = getMaxInstanceId();
        if (maxInstanceId != 0) {
            Object[] ids = null;
            int count = 0;

            for (int id = maxInstanceId; id != 0; --id) {
                String name = getInstanceIdName(id);
                int info = findInstanceIdInfo(name);
                if (info != 0) {
                    int attr = (info >>> 16);
                    if ((attr & PERMANENT) == 0) {
                        if (NOT_FOUND == getInstanceIdValue(id)) {
                            continue;
                        }
                    }
                    if (getAll || (attr & DONTENUM) == 0) {
                        if (count == 0) {
                            // Need extra room for no more then [1..id] names
                            ids = new Object[id];
                        }
                        ids[count++] = name;
                    }
                }
            }
            if (count != 0) {
                if (result.length == 0 && ids.length == count) {
                    result = ids;
                }
                else {
                    Object[] tmp = new Object[result.length + count];
                    System.arraycopy(result, 0, tmp, 0, result.length);
                    System.arraycopy(ids, 0, tmp, result.length, count);
                    result = tmp;
                }
            }
        }
        return result;
    }

    /**
     * Get maximum id findInstanceIdInfo can generate.
     */
    protected int getMaxInstanceId()
    {
        return 0;
    }

    protected static int instanceIdInfo(int attributes, int id)
    {
        return (attributes << 16) | id;
    }

    /**
     * Map name to id of instance property.
     * Should return 0 if not found or the result of
     * {@link #instanceIdInfo(int, int)}.
     */
    protected int findInstanceIdInfo(String name)
    {
        return 0;
    }

    /** Map id back to property name it defines.
     */
    protected String getInstanceIdName(int id)
    {
        throw new IllegalArgumentException(String.valueOf(id));
    }

    /** Get id value.
     ** If id value is constant, descendant can call cacheIdValue to store
     ** value in the permanent cache.
     ** Default implementation creates IdFunctionObject instance for given id
     ** and cache its value
     */
    protected Object getInstanceIdValue(int id)
    {
        throw new IllegalStateException(String.valueOf(id));
    }

    /**
     * Set or delete id value. If value == NOT_FOUND , the implementation
     * should make sure that the following getInstanceIdValue return NOT_FOUND.
     */
    protected void setInstanceIdValue(int id, Object value)
    {
        throw new IllegalStateException(String.valueOf(id));
    }

    /** 'thisObj' will be null if invoked as constructor, in which case
     ** instance of Scriptable should be returned. */
    public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
                             Scriptable thisObj, Object[] args)
    {
        throw f.unknown();
    }

    public final IdFunctionObject exportAsJSClass(int maxPrototypeId,
                                                  Scriptable scope,
                                                  boolean sealed)
    {
        // Set scope and prototype unless this is top level scope itself
        if (scope != this && scope != null) {
            setParentScope(scope);
            setPrototype(getObjectPrototype(scope));
        }

        activatePrototypeMap(maxPrototypeId);
        IdFunctionObject ctor = prototypeValues.createPrecachedConstructor();
        if (sealed) {
            sealObject();
        }
        fillConstructorProperties(ctor);
        if (sealed) {
            ctor.sealObject();
        }
        ctor.exportAsScopeProperty();
        return ctor;
    }

    public final boolean hasPrototypeMap()
    {
        return prototypeValues != null;
    }

    public final void activatePrototypeMap(int maxPrototypeId)
    {
        PrototypeValues values = new PrototypeValues(this, maxPrototypeId);
        synchronized (this) {
            if (prototypeValues != null)
                throw new IllegalStateException();
            prototypeValues = values;
        }
    }

    public final void initPrototypeMethod(Object tag, int id, String name,
                                          int arity)
    {
        Scriptable scope = ScriptableObject.getTopLevelScope(this);
        IdFunctionObject f = newIdFunction(tag, id, name, arity, scope);
        prototypeValues.initValue(id, name, f, DONTENUM);
    }

    public final void initPrototypeConstructor(IdFunctionObject f)
    {
        int id = prototypeValues.constructorId;
        if (id == 0)
            throw new IllegalStateException();
        if (f.methodId() != id)
            throw new IllegalArgumentException();
        if (isSealed()) { f.sealObject(); }
        prototypeValues.initValue(id, "constructor", f, DONTENUM);
    }

    public final void initPrototypeValue(int id, String name, Object value,
                                         int attributes)
    {
        prototypeValues.initValue(id, name, value, attributes);
    }

    protected void initPrototypeId(int id)
    {
        throw new IllegalStateException(String.valueOf(id));
    }

    protected int findPrototypeId(String name)
    {
        throw new IllegalStateException(name);
    }

    protected void fillConstructorProperties(IdFunctionObject ctor)
    {
    }

    protected void addIdFunctionProperty(Scriptable obj, Object tag, int id,
                                         String name, int arity)
    {
        Scriptable scope = ScriptableObject.getTopLevelScope(obj);
        IdFunctionObject f = newIdFunction(tag, id, name, arity, scope);
        f.addAsProperty(obj);
    }

    /**
     * Utility method to construct type error to indicate incompatible call
     * when converting script thisObj to a particular type is not possible.
     * Possible usage would be to have a private function like realThis:
     * 
     *  private static NativeSomething realThis(Scriptable thisObj,
     *                                          IdFunctionObject f)
     *  {
     *      if (!(thisObj instanceof NativeSomething))
     *          throw incompatibleCallError(f);
     *      return (NativeSomething)thisObj;
     * }
     * 
* Note that although such function can be implemented universally via * java.lang.Class.isInstance(), it would be much more slower. * @param f function that is attempting to convert 'this' * object. * @return Scriptable object suitable for a check by the instanceof * operator. * @throws RuntimeException if no more instanceof target can be found */ protected static EcmaError incompatibleCallError(IdFunctionObject f) { throw ScriptRuntime.typeError1("msg.incompat.call", f.getFunctionName()); } private IdFunctionObject newIdFunction(Object tag, int id, String name, int arity, Scriptable scope) { IdFunctionObject f = new IdFunctionObject(this, tag, id, name, arity, scope); if (isSealed()) { f.sealObject(); } return f; } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); int maxPrototypeId = stream.readInt(); if (maxPrototypeId != 0) { activatePrototypeMap(maxPrototypeId); } } private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); int maxPrototypeId = 0; if (prototypeValues != null) { maxPrototypeId = prototypeValues.getMaxId(); } stream.writeInt(maxPrototypeId); } } yui-compressor-2.4.7/src/org/mozilla/javascript/ObjArray.java0000644000175000017500000002613611753547210024204 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.Serializable; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** Implementation of resizable array with focus on minimizing memory usage by storing few initial array elements in object fields. Can also be used as a stack. */ public class ObjArray implements Serializable { static final long serialVersionUID = 4174889037736658296L; public ObjArray() { } public final boolean isSealed() { return sealed; } public final void seal() { sealed = true; } public final boolean isEmpty() { return size == 0; } public final int size() { return size; } public final void setSize(int newSize) { if (newSize < 0) throw new IllegalArgumentException(); if (sealed) throw onSeledMutation(); int N = size; if (newSize < N) { for (int i = newSize; i != N; ++i) { setImpl(i, null); } } else if (newSize > N) { if (newSize > FIELDS_STORE_SIZE) { ensureCapacity(newSize); } } size = newSize; } public final Object get(int index) { if (!(0 <= index && index < size)) throw onInvalidIndex(index, size); return getImpl(index); } public final void set(int index, Object value) { if (!(0 <= index && index < size)) throw onInvalidIndex(index, size); if (sealed) throw onSeledMutation(); setImpl(index, value); } private Object getImpl(int index) { switch (index) { case 0: return f0; case 1: return f1; case 2: return f2; case 3: return f3; case 4: return f4; } return data[index - FIELDS_STORE_SIZE]; } private void setImpl(int index, Object value) { switch (index) { case 0: f0 = value; break; case 1: f1 = value; break; case 2: f2 = value; break; case 3: f3 = value; break; case 4: f4 = value; break; default: data[index - FIELDS_STORE_SIZE] = value; } } public int indexOf(Object obj) { int N = size; for (int i = 0; i != N; ++i) { Object current = getImpl(i); if (current == obj || (current != null && current.equals(obj))) { return i; } } return -1; } public int lastIndexOf(Object obj) { for (int i = size; i != 0;) { --i; Object current = getImpl(i); if (current == obj || (current != null && current.equals(obj))) { return i; } } return -1; } public final Object peek() { int N = size; if (N == 0) throw onEmptyStackTopRead(); return getImpl(N - 1); } public final Object pop() { if (sealed) throw onSeledMutation(); int N = size; --N; Object top; switch (N) { case -1: throw onEmptyStackTopRead(); case 0: top = f0; f0 = null; break; case 1: top = f1; f1 = null; break; case 2: top = f2; f2 = null; break; case 3: top = f3; f3 = null; break; case 4: top = f4; f4 = null; break; default: top = data[N - FIELDS_STORE_SIZE]; data[N - FIELDS_STORE_SIZE] = null; } size = N; return top; } public final void push(Object value) { add(value); } public final void add(Object value) { if (sealed) throw onSeledMutation(); int N = size; if (N >= FIELDS_STORE_SIZE) { ensureCapacity(N + 1); } size = N + 1; setImpl(N, value); } public final void add(int index, Object value) { int N = size; if (!(0 <= index && index <= N)) throw onInvalidIndex(index, N + 1); if (sealed) throw onSeledMutation(); Object tmp; switch (index) { case 0: if (N == 0) { f0 = value; break; } tmp = f0; f0 = value; value = tmp; case 1: if (N == 1) { f1 = value; break; } tmp = f1; f1 = value; value = tmp; case 2: if (N == 2) { f2 = value; break; } tmp = f2; f2 = value; value = tmp; case 3: if (N == 3) { f3 = value; break; } tmp = f3; f3 = value; value = tmp; case 4: if (N == 4) { f4 = value; break; } tmp = f4; f4 = value; value = tmp; index = FIELDS_STORE_SIZE; default: ensureCapacity(N + 1); if (index != N) { System.arraycopy(data, index - FIELDS_STORE_SIZE, data, index - FIELDS_STORE_SIZE + 1, N - index); } data[index - FIELDS_STORE_SIZE] = value; } size = N + 1; } public final void remove(int index) { int N = size; if (!(0 <= index && index < N)) throw onInvalidIndex(index, N); if (sealed) throw onSeledMutation(); --N; switch (index) { case 0: if (N == 0) { f0 = null; break; } f0 = f1; case 1: if (N == 1) { f1 = null; break; } f1 = f2; case 2: if (N == 2) { f2 = null; break; } f2 = f3; case 3: if (N == 3) { f3 = null; break; } f3 = f4; case 4: if (N == 4) { f4 = null; break; } f4 = data[0]; index = FIELDS_STORE_SIZE; default: if (index != N) { System.arraycopy(data, index - FIELDS_STORE_SIZE + 1, data, index - FIELDS_STORE_SIZE, N - index); } data[N - FIELDS_STORE_SIZE] = null; } size = N; } public final void clear() { if (sealed) throw onSeledMutation(); int N = size; for (int i = 0; i != N; ++i) { setImpl(i, null); } size = 0; } public final Object[] toArray() { Object[] array = new Object[size]; toArray(array, 0); return array; } public final void toArray(Object[] array) { toArray(array, 0); } public final void toArray(Object[] array, int offset) { int N = size; switch (N) { default: System.arraycopy(data, 0, array, offset + FIELDS_STORE_SIZE, N - FIELDS_STORE_SIZE); case 5: array[offset + 4] = f4; case 4: array[offset + 3] = f3; case 3: array[offset + 2] = f2; case 2: array[offset + 1] = f1; case 1: array[offset + 0] = f0; case 0: break; } } private void ensureCapacity(int minimalCapacity) { int required = minimalCapacity - FIELDS_STORE_SIZE; if (required <= 0) throw new IllegalArgumentException(); if (data == null) { int alloc = FIELDS_STORE_SIZE * 2; if (alloc < required) { alloc = required; } data = new Object[alloc]; } else { int alloc = data.length; if (alloc < required) { if (alloc <= FIELDS_STORE_SIZE) { alloc = FIELDS_STORE_SIZE * 2; } else { alloc *= 2; } if (alloc < required) { alloc = required; } Object[] tmp = new Object[alloc]; if (size > FIELDS_STORE_SIZE) { System.arraycopy(data, 0, tmp, 0, size - FIELDS_STORE_SIZE); } data = tmp; } } } private static RuntimeException onInvalidIndex(int index, int upperBound) { // \u2209 is "NOT ELEMENT OF" String msg = index+" \u2209 [0, "+upperBound+')'; throw new IndexOutOfBoundsException(msg); } private static RuntimeException onEmptyStackTopRead() { throw new RuntimeException("Empty stack"); } private static RuntimeException onSeledMutation() { throw new IllegalStateException("Attempt to modify sealed array"); } private void writeObject(ObjectOutputStream os) throws IOException { os.defaultWriteObject(); int N = size; for (int i = 0; i != N; ++i) { Object obj = getImpl(i); os.writeObject(obj); } } private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException { is.defaultReadObject(); // It reads size int N = size; if (N > FIELDS_STORE_SIZE) { data = new Object[N - FIELDS_STORE_SIZE]; } for (int i = 0; i != N; ++i) { Object obj = is.readObject(); setImpl(i, obj); } } // Number of data elements private int size; private boolean sealed; private static final int FIELDS_STORE_SIZE = 5; private transient Object f0, f1, f2, f3, f4; private transient Object[] data; } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeJavaMethod.java0000644000175000017500000005423411753547210025664 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Frank Mitchell * Mike Shaver * Ulrike Mueller * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.lang.reflect.*; /** * This class reflects Java methods into the JavaScript environment and * handles overloading of methods. * * @author Mike Shaver * @see NativeJavaArray * @see NativeJavaPackage * @see NativeJavaClass */ public class NativeJavaMethod extends BaseFunction { static final long serialVersionUID = -3440381785576412928L; NativeJavaMethod(MemberBox[] methods) { this.functionName = methods[0].getName(); this.methods = methods; } NativeJavaMethod(MemberBox method, String name) { this.functionName = name; this.methods = new MemberBox[] { method }; } public NativeJavaMethod(Method method, String name) { this(new MemberBox(method), name); } @Override public String getFunctionName() { return functionName; } static String scriptSignature(Object[] values) { StringBuffer sig = new StringBuffer(); for (int i = 0; i != values.length; ++i) { Object value = values[i]; String s; if (value == null) { s = "null"; } else if (value instanceof Boolean) { s = "boolean"; } else if (value instanceof String) { s = "string"; } else if (value instanceof Number) { s = "number"; } else if (value instanceof Scriptable) { if (value instanceof Undefined) { s = "undefined"; } else if (value instanceof Wrapper) { Object wrapped = ((Wrapper)value).unwrap(); s = wrapped.getClass().getName(); } else if (value instanceof Function) { s = "function"; } else { s = "object"; } } else { s = JavaMembers.javaSignature(value.getClass()); } if (i != 0) { sig.append(','); } sig.append(s); } return sig.toString(); } @Override String decompile(int indent, int flags) { StringBuffer sb = new StringBuffer(); boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG)); if (!justbody) { sb.append("function "); sb.append(getFunctionName()); sb.append("() {"); } sb.append("/*\n"); sb.append(toString()); sb.append(justbody ? "*/\n" : "*/}\n"); return sb.toString(); } @Override public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 0, N = methods.length; i != N; ++i) { Method method = methods[i].method(); sb.append(JavaMembers.javaSignature(method.getReturnType())); sb.append(' '); sb.append(method.getName()); sb.append(JavaMembers.liveConnectSignature(methods[i].argTypes)); sb.append('\n'); } return sb.toString(); } @Override public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { // Find a method that matches the types given. if (methods.length == 0) { throw new RuntimeException("No methods defined for call"); } int index = findFunction(cx, methods, args); if (index < 0) { Class c = methods[0].method().getDeclaringClass(); String sig = c.getName() + '.' + getFunctionName() + '(' + scriptSignature(args) + ')'; throw Context.reportRuntimeError1("msg.java.no_such_method", sig); } MemberBox meth = methods[index]; Class[] argTypes = meth.argTypes; if (meth.vararg) { // marshall the explicit parameters Object[] newArgs = new Object[argTypes.length]; for (int i = 0; i < argTypes.length-1; i++) { newArgs[i] = Context.jsToJava(args[i], argTypes[i]); } Object varArgs; // Handle special situation where a single variable parameter // is given and it is a Java or ECMA array or is null. if (args.length == argTypes.length && (args[args.length-1] == null || args[args.length-1] instanceof NativeArray || args[args.length-1] instanceof NativeJavaArray)) { // convert the ECMA array into a native array varArgs = Context.jsToJava(args[args.length-1], argTypes[argTypes.length - 1]); } else { // marshall the variable parameters Class componentType = argTypes[argTypes.length - 1]. getComponentType(); varArgs = Array.newInstance(componentType, args.length - argTypes.length + 1); for (int i = 0; i < Array.getLength(varArgs); i++) { Object value = Context.jsToJava(args[argTypes.length-1 + i], componentType); Array.set(varArgs, i, value); } } // add varargs newArgs[argTypes.length-1] = varArgs; // replace the original args with the new one args = newArgs; } else { // First, we marshall the args. Object[] origArgs = args; for (int i = 0; i < args.length; i++) { Object arg = args[i]; Object coerced = Context.jsToJava(arg, argTypes[i]); if (coerced != arg) { if (origArgs == args) { args = args.clone(); } args[i] = coerced; } } } Object javaObject; if (meth.isStatic()) { javaObject = null; // don't need an object } else { Scriptable o = thisObj; Class c = meth.getDeclaringClass(); for (;;) { if (o == null) { throw Context.reportRuntimeError3( "msg.nonjava.method", getFunctionName(), ScriptRuntime.toString(thisObj), c.getName()); } if (o instanceof Wrapper) { javaObject = ((Wrapper)o).unwrap(); if (c.isInstance(javaObject)) { break; } } o = o.getPrototype(); } } if (debug) { printDebug("Calling ", meth, args); } Object retval = meth.invoke(javaObject, args); Class staticType = meth.method().getReturnType(); if (debug) { Class actualType = (retval == null) ? null : retval.getClass(); System.err.println(" ----- Returned " + retval + " actual = " + actualType + " expect = " + staticType); } Object wrapped = cx.getWrapFactory().wrap(cx, scope, retval, staticType); if (debug) { Class actualType = (wrapped == null) ? null : wrapped.getClass(); System.err.println(" ----- Wrapped as " + wrapped + " class = " + actualType); } if (wrapped == null && staticType == Void.TYPE) { wrapped = Undefined.instance; } return wrapped; } /** * Find the index of the correct function to call given the set of methods * or constructors and the arguments. * If no function can be found to call, return -1. */ static int findFunction(Context cx, MemberBox[] methodsOrCtors, Object[] args) { if (methodsOrCtors.length == 0) { return -1; } else if (methodsOrCtors.length == 1) { MemberBox member = methodsOrCtors[0]; Class[] argTypes = member.argTypes; int alength = argTypes.length; if (member.vararg) { alength--; if ( alength > args.length) { return -1; } } else { if (alength != args.length) { return -1; } } for (int j = 0; j != alength; ++j) { if (!NativeJavaObject.canConvert(args[j], argTypes[j])) { if (debug) printDebug("Rejecting (args can't convert) ", member, args); return -1; } } if (debug) printDebug("Found ", member, args); return 0; } int firstBestFit = -1; int[] extraBestFits = null; int extraBestFitsCount = 0; search: for (int i = 0; i < methodsOrCtors.length; i++) { MemberBox member = methodsOrCtors[i]; Class[] argTypes = member.argTypes; int alength = argTypes.length; if (member.vararg) { alength--; if ( alength > args.length) { continue search; } } else { if (alength != args.length) { continue search; } } for (int j = 0; j < alength; j++) { if (!NativeJavaObject.canConvert(args[j], argTypes[j])) { if (debug) printDebug("Rejecting (args can't convert) ", member, args); continue search; } } if (firstBestFit < 0) { if (debug) printDebug("Found first applicable ", member, args); firstBestFit = i; } else { // Compare with all currently fit methods. // The loop starts from -1 denoting firstBestFit and proceed // until extraBestFitsCount to avoid extraBestFits allocation // in the most common case of no ambiguity int betterCount = 0; // number of times member was prefered over // best fits int worseCount = 0; // number of times best fits were prefered // over member for (int j = -1; j != extraBestFitsCount; ++j) { int bestFitIndex; if (j == -1) { bestFitIndex = firstBestFit; } else { bestFitIndex = extraBestFits[j]; } MemberBox bestFit = methodsOrCtors[bestFitIndex]; if (cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) && (bestFit.member().getModifiers() & Modifier.PUBLIC) != (member.member().getModifiers() & Modifier.PUBLIC)) { // When FEATURE_ENHANCED_JAVA_ACCESS gives us access // to non-public members, continue to prefer public // methods in overloading if ((bestFit.member().getModifiers() & Modifier.PUBLIC) == 0) ++betterCount; else ++worseCount; } else { int preference = preferSignature(args, argTypes, member.vararg, bestFit.argTypes, bestFit.vararg ); if (preference == PREFERENCE_AMBIGUOUS) { break; } else if (preference == PREFERENCE_FIRST_ARG) { ++betterCount; } else if (preference == PREFERENCE_SECOND_ARG) { ++worseCount; } else { if (preference != PREFERENCE_EQUAL) Kit.codeBug(); // This should not happen in theory // but on some JVMs, Class.getMethods will return all // static methods of the class hierarchy, even if // a derived class's parameters match exactly. // We want to call the derived class's method. if (bestFit.isStatic() && bestFit.getDeclaringClass().isAssignableFrom( member.getDeclaringClass())) { // On some JVMs, Class.getMethods will return all // static methods of the class hierarchy, even if // a derived class's parameters match exactly. // We want to call the derived class's method. if (debug) printDebug( "Substituting (overridden static)", member, args); if (j == -1) { firstBestFit = i; } else { extraBestFits[j] = i; } } else { if (debug) printDebug( "Ignoring same signature member ", member, args); } continue search; } } } if (betterCount == 1 + extraBestFitsCount) { // member was prefered over all best fits if (debug) printDebug( "New first applicable ", member, args); firstBestFit = i; extraBestFitsCount = 0; } else if (worseCount == 1 + extraBestFitsCount) { // all best fits were prefered over member, ignore it if (debug) printDebug( "Rejecting (all current bests better) ", member, args); } else { // some ambiguity was present, add member to best fit set if (debug) printDebug( "Added to best fit set ", member, args); if (extraBestFits == null) { // Allocate maximum possible array extraBestFits = new int[methodsOrCtors.length - 1]; } extraBestFits[extraBestFitsCount] = i; ++extraBestFitsCount; } } } if (firstBestFit < 0) { // Nothing was found return -1; } else if (extraBestFitsCount == 0) { // single best fit return firstBestFit; } // report remaining ambiguity StringBuffer buf = new StringBuffer(); for (int j = -1; j != extraBestFitsCount; ++j) { int bestFitIndex; if (j == -1) { bestFitIndex = firstBestFit; } else { bestFitIndex = extraBestFits[j]; } buf.append("\n "); buf.append(methodsOrCtors[bestFitIndex].toJavaDeclaration()); } MemberBox firstFitMember = methodsOrCtors[firstBestFit]; String memberName = firstFitMember.getName(); String memberClass = firstFitMember.getDeclaringClass().getName(); if (methodsOrCtors[0].isMethod()) { throw Context.reportRuntimeError3( "msg.constructor.ambiguous", memberName, scriptSignature(args), buf.toString()); } else { throw Context.reportRuntimeError4( "msg.method.ambiguous", memberClass, memberName, scriptSignature(args), buf.toString()); } } /** Types are equal */ private static final int PREFERENCE_EQUAL = 0; private static final int PREFERENCE_FIRST_ARG = 1; private static final int PREFERENCE_SECOND_ARG = 2; /** No clear "easy" conversion */ private static final int PREFERENCE_AMBIGUOUS = 3; /** * Determine which of two signatures is the closer fit. * Returns one of PREFERENCE_EQUAL, PREFERENCE_FIRST_ARG, * PREFERENCE_SECOND_ARG, or PREFERENCE_AMBIGUOUS. */ private static int preferSignature(Object[] args, Class[] sig1, boolean vararg1, Class[] sig2, boolean vararg2 ) { // TODO: This test is pretty primitive. It basically prefers // a matching no vararg method over a vararg method independent // of the type conversion cost. This can lead to unexpected results. int alength = args.length; if (!vararg1 && vararg2) { // prefer the no vararg signature return PREFERENCE_FIRST_ARG; } else if (vararg1 && !vararg2) { // prefer the no vararg signature return PREFERENCE_SECOND_ARG; } else if (vararg1 && vararg2) { if (sig1.length < sig2.length) { // prefer the signature with more explicit types return PREFERENCE_SECOND_ARG; } else if (sig1.length > sig2.length) { // prefer the signature with more explicit types return PREFERENCE_FIRST_ARG; } else { // Both are varargs and have the same length, so make the // decision with the explicit args. alength = Math.min(args.length, sig1.length-1); } } int totalPreference = 0; for (int j = 0; j < alength; j++) { Class type1 = sig1[j]; Class type2 = sig2[j]; if (type1 == type2) { continue; } Object arg = args[j]; // Determine which of type1, type2 is easier to convert from arg. int rank1 = NativeJavaObject.getConversionWeight(arg, type1); int rank2 = NativeJavaObject.getConversionWeight(arg, type2); int preference; if (rank1 < rank2) { preference = PREFERENCE_FIRST_ARG; } else if (rank1 > rank2) { preference = PREFERENCE_SECOND_ARG; } else { // Equal ranks if (rank1 == NativeJavaObject.CONVERSION_NONTRIVIAL) { if (type1.isAssignableFrom(type2)) { preference = PREFERENCE_SECOND_ARG; } else if (type2.isAssignableFrom(type1)) { preference = PREFERENCE_FIRST_ARG; } else { preference = PREFERENCE_AMBIGUOUS; } } else { preference = PREFERENCE_AMBIGUOUS; } } totalPreference |= preference; if (totalPreference == PREFERENCE_AMBIGUOUS) { break; } } return totalPreference; } private static final boolean debug = false; private static void printDebug(String msg, MemberBox member, Object[] args) { if (debug) { StringBuffer sb = new StringBuffer(); sb.append(" ----- "); sb.append(msg); sb.append(member.getDeclaringClass().getName()); sb.append('.'); if (member.isMethod()) { sb.append(member.getName()); } sb.append(JavaMembers.liveConnectSignature(member.argTypes)); sb.append(" for arguments ("); sb.append(scriptSignature(args)); sb.append(')'); System.out.println(sb); } } MemberBox[] methods; private String functionName; } yui-compressor-2.4.7/src/org/mozilla/javascript/Wrapper.java0000644000175000017500000000400011753547210024075 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * Objects that can wrap other values for reflection in the JS environment * will implement Wrapper. * * Wrapper defines a single method that can be called to unwrap the object. */ public interface Wrapper { /** * Unwrap the object by returning the wrapped value. * * @return a wrapped value */ public Object unwrap(); } yui-compressor-2.4.7/src/org/mozilla/javascript/SecurityUtilities.java0000644000175000017500000000546311753547210026176 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.ProtectionDomain; /** * @author Attila Szegedi */ public class SecurityUtilities { /** * Retrieves a system property within a privileged block. Use it only when * the property is used from within Rhino code and is not passed out of it. * @param name the name of the system property * @return the value of the system property */ public static String getSystemProperty(final String name) { return (String)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return System.getProperty(name); } }); } public static ProtectionDomain getProtectionDomain(final Class clazz) { return (ProtectionDomain)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return clazz.getProtectionDomain(); } }); } } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeIterator.java0000644000175000017500000002277011753547210025433 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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. * * Contributor(s): * Norris Boyd * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.util.Iterator; /** * This class implements iterator objects. See * http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Iterators * * @author Norris Boyd */ public final class NativeIterator extends IdScriptableObject { private static final long serialVersionUID = -4136968203581667681L; private static final Object ITERATOR_TAG = "Iterator"; static void init(ScriptableObject scope, boolean sealed) { // Iterator NativeIterator iterator = new NativeIterator(); iterator.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); // Generator NativeGenerator.init(scope, sealed); // StopIteration NativeObject obj = new StopIteration(); obj.setPrototype(getObjectPrototype(scope)); obj.setParentScope(scope); if (sealed) { obj.sealObject(); } ScriptableObject.defineProperty(scope, STOP_ITERATION, obj, ScriptableObject.DONTENUM); // Use "associateValue" so that generators can continue to // throw StopIteration even if the property of the global // scope is replaced or deleted. scope.associateValue(ITERATOR_TAG, obj); } /** * Only for constructing the prototype object. */ private NativeIterator() { } private NativeIterator(Object objectIterator) { this.objectIterator = objectIterator; } /** * Get the value of the "StopIteration" object. Note that this value * is stored in the top-level scope using "associateValue" so the * value can still be found even if a script overwrites or deletes * the global "StopIteration" property. * @param scope a scope whose parent chain reaches a top-level scope * @return the StopIteration object */ public static Object getStopIterationObject(Scriptable scope) { Scriptable top = ScriptableObject.getTopLevelScope(scope); return ScriptableObject.getTopScopeValue(top, ITERATOR_TAG); } private static final String STOP_ITERATION = "StopIteration"; public static final String ITERATOR_PROPERTY_NAME = "__iterator__"; static class StopIteration extends NativeObject { private static final long serialVersionUID = 2485151085722377663L; @Override public String getClassName() { return STOP_ITERATION; } /* StopIteration has custom instanceof behavior since it * doesn't have a constructor. */ @Override public boolean hasInstance(Scriptable instance) { return instance instanceof StopIteration; } } @Override public String getClassName() { return "Iterator"; } @Override protected void initPrototypeId(int id) { String s; int arity; switch (id) { case Id_constructor: arity=2; s="constructor"; break; case Id_next: arity=0; s="next"; break; case Id___iterator__: arity=1; s=ITERATOR_PROPERTY_NAME; break; default: throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(ITERATOR_TAG, id, s, arity); } @Override public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(ITERATOR_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); if (id == Id_constructor) { return jsConstructor(cx, scope, thisObj, args); } if (!(thisObj instanceof NativeIterator)) throw incompatibleCallError(f); NativeIterator iterator = (NativeIterator) thisObj; switch (id) { case Id_next: return iterator.next(cx, scope); case Id___iterator__: /// XXX: what about argument? SpiderMonkey apparently ignores it return thisObj; default: throw new IllegalArgumentException(String.valueOf(id)); } } /* The JavaScript constructor */ private static Object jsConstructor(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (args.length == 0 || args[0] == null || args[0] == Undefined.instance) { throw ScriptRuntime.typeError1("msg.no.properties", ScriptRuntime.toString(args[0])); } Scriptable obj = ScriptRuntime.toObject(scope, args[0]); boolean keyOnly = args.length > 1 && ScriptRuntime.toBoolean(args[1]); if (thisObj != null) { // Called as a function. Convert to iterator if possible. // For objects that implement java.lang.Iterable or // java.util.Iterator, have JavaScript Iterator call the underlying // iteration methods Iterator iterator = VMBridge.instance.getJavaIterator(cx, scope, obj); if (iterator != null) { scope = ScriptableObject.getTopLevelScope(scope); return cx.getWrapFactory().wrap(cx, scope, new WrappedJavaIterator(iterator, scope), WrappedJavaIterator.class); } // Otherwise, just call the runtime routine Scriptable jsIterator = ScriptRuntime.toIterator(cx, scope, obj, keyOnly); if (jsIterator != null) { return jsIterator; } } // Otherwise, just set up to iterate over the properties of the object. // Do not call __iterator__ method. Object objectIterator = ScriptRuntime.enumInit(obj, cx, keyOnly ? ScriptRuntime.ENUMERATE_KEYS_NO_ITERATOR : ScriptRuntime.ENUMERATE_ARRAY_NO_ITERATOR); ScriptRuntime.setEnumNumbers(objectIterator, true); NativeIterator result = new NativeIterator(objectIterator); result.setPrototype(NativeIterator.getClassPrototype(scope, result.getClassName())); result.setParentScope(scope); return result; } private Object next(Context cx, Scriptable scope) { Boolean b = ScriptRuntime.enumNext(this.objectIterator); if (!b.booleanValue()) { // Out of values. Throw StopIteration. throw new JavaScriptException( NativeIterator.getStopIterationObject(scope), null, 0); } return ScriptRuntime.enumId(this.objectIterator, cx); } static public class WrappedJavaIterator { WrappedJavaIterator(Iterator iterator, Scriptable scope) { this.iterator = iterator; this.scope = scope; } public Object next() { if (!iterator.hasNext()) { // Out of values. Throw StopIteration. throw new JavaScriptException( NativeIterator.getStopIterationObject(scope), null, 0); } return iterator.next(); } public Object __iterator__(boolean b) { return this; } private Iterator iterator; private Scriptable scope; } // #string_id_map# @Override protected int findPrototypeId(String s) { int id; // #generated# Last update: 2007-06-11 09:43:19 EDT L0: { id = 0; String X = null; int s_length = s.length(); if (s_length==4) { X="next";id=Id_next; } else if (s_length==11) { X="constructor";id=Id_constructor; } else if (s_length==12) { X="__iterator__";id=Id___iterator__; } if (X!=null && X!=s && !X.equals(s)) id = 0; break L0; } // #/generated# return id; } private static final int Id_constructor = 1, Id_next = 2, Id___iterator__ = 3, MAX_PROTOTYPE_ID = 3; // #/string_id_map# private Object objectIterator; } yui-compressor-2.4.7/src/org/mozilla/javascript/IdFunctionObject.java0000644000175000017500000001362011753547210025656 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; public class IdFunctionObject extends BaseFunction { static final long serialVersionUID = -5332312783643935019L; public IdFunctionObject(IdFunctionCall idcall, Object tag, int id, int arity) { if (arity < 0) throw new IllegalArgumentException(); this.idcall = idcall; this.tag = tag; this.methodId = id; this.arity = arity; if (arity < 0) throw new IllegalArgumentException(); } public IdFunctionObject(IdFunctionCall idcall, Object tag, int id, String name, int arity, Scriptable scope) { super(scope, null); if (arity < 0) throw new IllegalArgumentException(); if (name == null) throw new IllegalArgumentException(); this.idcall = idcall; this.tag = tag; this.methodId = id; this.arity = arity; this.functionName = name; } public void initFunction(String name, Scriptable scope) { if (name == null) throw new IllegalArgumentException(); if (scope == null) throw new IllegalArgumentException(); this.functionName = name; setParentScope(scope); } public final boolean hasTag(Object tag) { return this.tag == tag; } public final int methodId() { return methodId; } public final void markAsConstructor(Scriptable prototypeProperty) { useCallAsConstructor = true; setImmunePrototypeProperty(prototypeProperty); } public final void addAsProperty(Scriptable target) { ScriptableObject.defineProperty(target, functionName, this, ScriptableObject.DONTENUM); } public void exportAsScopeProperty() { addAsProperty(getParentScope()); } @Override public Scriptable getPrototype() { // Lazy initialization of prototype: for native functions this // may not be called at all Scriptable proto = super.getPrototype(); if (proto == null) { proto = getFunctionPrototype(getParentScope()); setPrototype(proto); } return proto; } @Override public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { return idcall.execIdCall(this, cx, scope, thisObj, args); } @Override public Scriptable createObject(Context cx, Scriptable scope) { if (useCallAsConstructor) { return null; } // Throw error if not explicitly coded to be used as constructor, // to satisfy ECMAScript standard (see bugzilla 202019). // To follow current (2003-05-01) SpiderMonkey behavior, change it to: // return super.createObject(cx, scope); throw ScriptRuntime.typeError1("msg.not.ctor", functionName); } @Override String decompile(int indent, int flags) { StringBuffer sb = new StringBuffer(); boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG)); if (!justbody) { sb.append("function "); sb.append(getFunctionName()); sb.append("() { "); } sb.append("[native code for "); if (idcall instanceof Scriptable) { Scriptable sobj = (Scriptable)idcall; sb.append(sobj.getClassName()); sb.append('.'); } sb.append(getFunctionName()); sb.append(", arity="); sb.append(getArity()); sb.append(justbody ? "]\n" : "] }\n"); return sb.toString(); } @Override public int getArity() { return arity; } @Override public int getLength() { return getArity(); } @Override public String getFunctionName() { return (functionName == null) ? "" : functionName; } public final RuntimeException unknown() { // It is program error to call id-like methods for unknown function return new IllegalArgumentException( "BAD FUNCTION ID="+methodId+" MASTER="+idcall); } private final IdFunctionCall idcall; private final Object tag; private final int methodId; private int arity; private boolean useCallAsConstructor; private String functionName; } yui-compressor-2.4.7/src/org/mozilla/javascript/SecureCaller.java0000644000175000017500000001640611753547210025043 0ustar drazzibdrazzib/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.ref.SoftReference; import java.lang.reflect.UndeclaredThrowableException; import java.net.URL; import java.security.AccessController; import java.security.CodeSource; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.security.SecureClassLoader; import java.util.Map; import java.util.WeakHashMap; /** * @author Attila Szegedi */ public abstract class SecureCaller { private static final byte[] secureCallerImplBytecode = loadBytecode(); // We're storing a CodeSource -> (ClassLoader -> SecureRenderer), since we // need to have one renderer per class loader. We're using weak hash maps // and soft references all the way, since we don't want to interfere with // cleanup of either CodeSource or ClassLoader objects. private static final Map>> callers = new WeakHashMap>>(); public abstract Object call(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args); /** * Call the specified callable using a protection domain belonging to the * specified code source. */ static Object callSecurely(final CodeSource codeSource, Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { final Thread thread = Thread.currentThread(); // Run in doPrivileged as we might be checked for "getClassLoader" // runtime permission final ClassLoader classLoader = (ClassLoader)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return thread.getContextClassLoader(); } }); Map> classLoaderMap; synchronized(callers) { classLoaderMap = callers.get(codeSource); if(classLoaderMap == null) { classLoaderMap = new WeakHashMap>(); callers.put(codeSource, classLoaderMap); } } SecureCaller caller; synchronized(classLoaderMap) { SoftReference ref = classLoaderMap.get(classLoader); if (ref != null) { caller = ref.get(); } else { caller = null; } if (caller == null) { try { // Run in doPrivileged as we'll be checked for // "createClassLoader" runtime permission caller = (SecureCaller)AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws Exception { ClassLoader effectiveClassLoader; Class thisClass = getClass(); if(classLoader.loadClass(thisClass.getName()) != thisClass) { effectiveClassLoader = thisClass.getClassLoader(); } else { effectiveClassLoader = classLoader; } SecureClassLoaderImpl secCl = new SecureClassLoaderImpl(effectiveClassLoader); Class c = secCl.defineAndLinkClass( SecureCaller.class.getName() + "Impl", secureCallerImplBytecode, codeSource); return c.newInstance(); } }); classLoaderMap.put(classLoader, new SoftReference(caller)); } catch(PrivilegedActionException ex) { throw new UndeclaredThrowableException(ex.getCause()); } } } return caller.call(callable, cx, scope, thisObj, args); } private static class SecureClassLoaderImpl extends SecureClassLoader { SecureClassLoaderImpl(ClassLoader parent) { super(parent); } Class defineAndLinkClass(String name, byte[] bytes, CodeSource cs) { Class cl = defineClass(name, bytes, 0, bytes.length, cs); resolveClass(cl); return cl; } } private static byte[] loadBytecode() { return (byte[])AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return loadBytecodePrivileged(); } }); } private static byte[] loadBytecodePrivileged() { URL url = SecureCaller.class.getResource("SecureCallerImpl.clazz"); try { InputStream in = url.openStream(); try { ByteArrayOutputStream bout = new ByteArrayOutputStream(); for(;;) { int r = in.read(); if(r == -1) { return bout.toByteArray(); } bout.write(r); } } finally { in.close(); } } catch(IOException e) { throw new UndeclaredThrowableException(e); } } } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeJavaConstructor.java0000644000175000017500000000552411753547210026767 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Frank Mitchell * Mike Shaver * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * This class reflects a single Java constructor into the JavaScript * environment. It satisfies a request for an overloaded constructor, * as introduced in LiveConnect 3. * All NativeJavaConstructors behave as JSRef `bound' methods, in that they * always construct the same NativeJavaClass regardless of any reparenting * that may occur. * * @author Frank Mitchell * @see NativeJavaMethod * @see NativeJavaPackage * @see NativeJavaClass */ public class NativeJavaConstructor extends BaseFunction { static final long serialVersionUID = -8149253217482668463L; MemberBox ctor; public NativeJavaConstructor(MemberBox ctor) { this.ctor = ctor; } @Override public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { return NativeJavaClass.constructSpecific(cx, scope, args, ctor); } @Override public String getFunctionName() { String sig = JavaMembers.liveConnectSignature(ctor.argTypes); return "".concat(sig); } @Override public String toString() { return "[JavaConstructor " + ctor.getName() + "]"; } } yui-compressor-2.4.7/src/org/mozilla/javascript/resources/0000755000175000017500000000000011753547210023632 5ustar drazzibdrazzibyui-compressor-2.4.7/src/org/mozilla/javascript/resources/Messages.properties0000644000175000017500000004516511753547210027532 0ustar drazzibdrazzib# # Default JavaScript messages file. # # ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0 # # 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 Rhino code, released # May 6, 1999. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1997-1999 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Norris Boyd # Bob Jervis # # Alternatively, the contents of this file may be used under the terms of # the GNU General Public License Version 2 or later (the "GPL"), in which # case the provisions of the GPL are applicable instead of those above. If # you wish to allow use of your version of this file only under the terms of # the GPL and not to allow others to use your version of this file under the # MPL, indicate your decision by deleting the provisions above and replacing # them with the notice and other provisions required by the GPL. If you do # not delete the provisions above, a recipient may use your version of this # file under either the MPL or the GPL. # # ***** END LICENSE BLOCK ***** # This is replaced during jar assembly from property string # and should not be translated implementation.version = @IMPLEMENTATION.VERSION@ # # To add JavaScript error messages for a particular locale, create a # new Messages_[locale].properties file, where [locale] is the Java # string abbreviation for that locale. For example, JavaScript # messages for the Polish locale should be located in # Messages_pl.properties, and messages for the Italian Swiss locale # should be located in Messages_it_CH.properties. Message properties # files should be accessible through the classpath under # org.mozilla.javascript.resources # # See: # java.util.ResourceBundle # java.text.MessageFormat # # SomeJavaClassWhereUsed # Codegen msg.dup.parms =\ Duplicate parameter name "{0}". msg.too.big.jump =\ Program too complex: too big jump offset. msg.too.big.index =\ Program too complex: internal index exceeds 64K limit. msg.while.compiling.fn =\ Encountered code generation error while compiling function "{0}": {1} msg.while.compiling.script =\ Encountered code generation error while compiling script: {0} # Context msg.ctor.not.found =\ Constructor for "{0}" not found. msg.not.ctor =\ "{0}" is not a constructor. # FunctionObject msg.varargs.ctor =\ Method or constructor "{0}" must be static with the signature \ "(Context cx, Object[] args, Function ctorObj, boolean inNewExpr)" \ to define a variable arguments constructor. msg.varargs.fun =\ Method "{0}" must be static with the signature \ "(Context cx, Scriptable thisObj, Object[] args, Function funObj)" \ to define a variable arguments function. msg.incompat.call =\ Method "{0}" called on incompatible object. msg.bad.parms =\ Unsupported parameter type "{0}" in method "{1}". msg.bad.method.return =\ Unsupported return type "{0}" in method "{1}". msg.bad.ctor.return =\ Construction of objects of type "{0}" is not supported. msg.no.overload =\ Method "{0}" occurs multiple times in class "{1}". msg.method.not.found =\ Method "{0}" not found in "{1}". # IRFactory msg.bad.for.in.lhs =\ Invalid left-hand side of for..in loop. msg.mult.index =\ Only one variable allowed in for..in loop. msg.bad.for.in.destruct =\ Left hand side of for..in loop must be an array of length 2 to accept \ key/value pair. msg.cant.convert =\ Can''t convert to type "{0}". msg.bad.assign.left =\ Invalid assignment left-hand side. msg.bad.decr =\ Invalid decrement operand. msg.bad.incr =\ Invalid increment operand. msg.bad.yield =\ yield must be in a function. msg.yield.parenthesized =\ yield expression must be parenthesized. # NativeGlobal msg.cant.call.indirect =\ Function "{0}" must be called directly, and not by way of a \ function of another name. msg.eval.nonstring =\ Calling eval() with anything other than a primitive string value will \ simply return the value. Is this what you intended? msg.eval.nonstring.strict =\ Calling eval() with anything other than a primitive string value is not \ allowed in strict mode. msg.bad.destruct.op =\ Invalid destructuring assignment operator # NativeCall msg.only.from.new =\ "{0}" may only be invoked from a "new" expression. msg.deprec.ctor =\ The "{0}" constructor is deprecated. # NativeFunction msg.no.function.ref.found =\ no source found to decompile function reference {0} msg.arg.isnt.array =\ second argument to Function.prototype.apply must be an array # NativeGlobal msg.bad.esc.mask =\ invalid string escape mask # NativeJavaClass msg.cant.instantiate =\ error instantiating ({0}): class {1} is interface or abstract msg.bad.ctor.sig =\ Found constructor with wrong signature: \ {0} calling {1} with signature {2} msg.not.java.obj =\ Expected argument to getClass() to be a Java object. msg.no.java.ctor =\ Java constructor for "{0}" with arguments "{1}" not found. # NativeJavaMethod msg.method.ambiguous =\ The choice of Java method {0}.{1} matching JavaScript argument types ({2}) is ambiguous; \ candidate methods are: {3} msg.constructor.ambiguous =\ The choice of Java constructor {0} matching JavaScript argument types ({1}) is ambiguous; \ candidate constructors are: {2} # NativeJavaObject msg.conversion.not.allowed =\ Cannot convert {0} to {1} msg.no.empty.interface.conversion =\ Cannot convert {0} to interface {1} with no methods msg.no.function.interface.conversion =\ Cannot convert function {0} to interface since it contains methods with \ different signatures # NativeJavaPackage msg.not.classloader =\ Constructor for "Packages" expects argument of type java.lang.Classloader # NativeRegExp msg.bad.quant =\ Invalid quantifier {0} msg.overlarge.backref =\ Overly large back reference {0} msg.overlarge.min =\ Overly large minimum {0} msg.overlarge.max =\ Overly large maximum {0} msg.zero.quant =\ Zero quantifier {0} msg.max.lt.min =\ Maximum {0} less than minimum msg.unterm.quant =\ Unterminated quantifier {0} msg.unterm.paren =\ Unterminated parenthetical {0} msg.unterm.class =\ Unterminated character class {0} msg.bad.range =\ Invalid range in character class. msg.trail.backslash =\ Trailing \\ in regular expression. msg.re.unmatched.right.paren =\ unmatched ) in regular expression. msg.no.regexp =\ Regular expressions are not available. msg.bad.backref =\ back-reference exceeds number of capturing parentheses. msg.bad.regexp.compile =\ Only one argument may be specified if the first argument to \ RegExp.prototype.compile is a RegExp object. # Parser msg.got.syntax.errors = \ Compilation produced {0} syntax errors. msg.var.redecl =\ TypeError: redeclaration of var {0}. msg.const.redecl =\ TypeError: redeclaration of const {0}. msg.let.redecl =\ TypeError: redeclaration of variable {0}. msg.parm.redecl =\ TypeError: redeclaration of formal parameter {0}. msg.fn.redecl =\ TypeError: redeclaration of function {0}. msg.let.decl.not.in.block =\ SyntaxError: let declaration not directly within block # NodeTransformer msg.dup.label =\ duplicated label msg.undef.label =\ undefined label msg.bad.break =\ unlabelled break must be inside loop or switch msg.continue.outside =\ continue must be inside loop msg.continue.nonloop =\ continue can only use labeles of iteration statements msg.bad.throw.eol =\ Line terminator is not allowed between the throw keyword and throw \ expression. msg.no.paren.parms =\ missing ( before function parameters. msg.no.parm =\ missing formal parameter msg.no.paren.after.parms =\ missing ) after formal parameters msg.no.brace.body =\ missing '{' before function body msg.no.brace.after.body =\ missing } after function body msg.no.paren.cond =\ missing ( before condition msg.no.paren.after.cond =\ missing ) after condition msg.no.semi.stmt =\ missing ; before statement msg.no.name.after.dot =\ missing name after . operator msg.no.name.after.coloncolon =\ missing name after :: operator msg.no.name.after.dotdot =\ missing name after .. operator msg.no.name.after.xmlAttr =\ missing name after .@ msg.no.bracket.index =\ missing ] in index expression msg.no.paren.switch =\ missing ( before switch expression msg.no.paren.after.switch =\ missing ) after switch expression msg.no.brace.switch =\ missing '{' before switch body msg.bad.switch =\ invalid switch statement msg.no.colon.case =\ missing : after case expression msg.double.switch.default =\ double default label in the switch statement msg.no.while.do =\ missing while after do-loop body msg.no.paren.for =\ missing ( after for msg.no.semi.for =\ missing ; after for-loop initializer msg.no.semi.for.cond =\ missing ; after for-loop condition msg.in.after.for.name =\ missing in after for msg.no.paren.for.ctrl =\ missing ) after for-loop control msg.no.paren.with =\ missing ( before with-statement object msg.no.paren.after.with =\ missing ) after with-statement object msg.no.paren.after.let =\ missing ( after let msg.no.paren.let =\ missing ) after variable list msg.no.curly.let =\ missing } after let statement msg.bad.return =\ invalid return msg.no.brace.block =\ missing } in compound statement msg.bad.label =\ invalid label msg.bad.var =\ missing variable name msg.bad.var.init =\ invalid variable initialization msg.no.colon.cond =\ missing : in conditional expression msg.no.paren.arg =\ missing ) after argument list msg.no.bracket.arg =\ missing ] after element list msg.bad.prop =\ invalid property id msg.no.colon.prop =\ missing : after property id msg.no.brace.prop =\ missing } after property list msg.no.paren =\ missing ) in parenthetical msg.reserved.id =\ identifier is a reserved word msg.no.paren.catch =\ missing ( before catch-block condition msg.bad.catchcond =\ invalid catch block condition msg.catch.unreachable =\ any catch clauses following an unqualified catch are unreachable msg.no.brace.try =\ missing '{' before try block msg.no.brace.catchblock =\ missing '{' before catch-block body msg.try.no.catchfinally =\ ''try'' without ''catch'' or ''finally'' msg.no.return.value =\ function {0} does not always return a value msg.anon.no.return.value =\ anonymous function does not always return a value msg.return.inconsistent =\ return statement is inconsistent with previous usage msg.generator.returns =\ TypeError: generator function {0} returns a value msg.anon.generator.returns =\ TypeError: anonymous generator function returns a value msg.syntax =\ syntax error msg.unexpected.eof =\ Unexpected end of file msg.XML.bad.form =\ illegally formed XML syntax msg.XML.not.available =\ XML runtime not available msg.too.deep.parser.recursion =\ Too deep recursion while parsing msg.no.side.effects =\ Code has no side effects msg.extra.trailing.comma =\ Trailing comma is not legal in an ECMA-262 object initializer msg.equal.as.assign =\ Test for equality (==) mistyped as assignment (=)? msg.var.hides.arg =\ Variable {0} hides argument msg.destruct.assign.no.init =\ Missing = in destructuring declaration # ScriptRuntime msg.no.properties =\ {0} has no properties. msg.invalid.iterator =\ Invalid iterator value msg.iterator.primitive =\ __iterator__ returned a primitive value msg.assn.create.strict =\ Assignment to undeclared variable {0} msg.ref.undefined.prop =\ Reference to undefined property "{0}" msg.prop.not.found =\ Property {0} not found. msg.set.prop.no.setter =\ Cannot set property {0} that has only a getter. msg.invalid.type =\ Invalid JavaScript value of type {0} msg.primitive.expected =\ Primitive type expected (had {0} instead) msg.namespace.expected =\ Namespace object expected to left of :: (found {0} instead) msg.null.to.object =\ Cannot convert null to an object. msg.undef.to.object =\ Cannot convert undefined to an object. msg.cyclic.value =\ Cyclic {0} value not allowed. msg.is.not.defined =\ "{0}" is not defined. msg.undef.prop.read =\ Cannot read property "{1}" from {0} msg.undef.prop.write =\ Cannot set property "{1}" of {0} to "{2}" msg.undef.prop.delete =\ Cannot delete property "{1}" of {0} msg.undef.method.call =\ Cannot call method "{1}" of {0} msg.undef.with =\ Cannot apply "with" to {0} msg.isnt.function =\ {0} is not a function, it is {1}. msg.isnt.function.in =\ Cannot call property {0} in object {1}. It is not a function, it is "{2}". msg.function.not.found =\ Cannot find function {0}. msg.function.not.found.in =\ Cannot find function {0} in object {1}. msg.isnt.xml.object =\ {0} is not an xml object. msg.no.ref.to.get =\ {0} is not a reference to read reference value. msg.no.ref.to.set =\ {0} is not a reference to set reference value to {1}. msg.no.ref.from.function =\ Function {0} can not be used as the left-hand side of assignment \ or as an operand of ++ or -- operator. msg.bad.default.value =\ Object''s getDefaultValue() method returned an object. msg.instanceof.not.object = \ Can''t use instanceof on a non-object. msg.instanceof.bad.prototype = \ ''prototype'' property of {0} is not an object. msg.bad.radix = \ illegal radix {0}. # ScriptableObject msg.default.value =\ Cannot find default value for object. msg.zero.arg.ctor =\ Cannot load class "{0}" which has no zero-parameter constructor. duplicate.defineClass.name =\ Invalid method "{0}": name "{1}" is already in use. msg.ctor.multiple.parms =\ Can''t define constructor or class {0} since more than one \ constructor has multiple parameters. msg.extend.scriptable =\ {0} must extend ScriptableObject in order to define property {1}. msg.bad.getter.parms =\ In order to define a property, getter {0} must have zero parameters \ or a single ScriptableObject parameter. msg.obj.getter.parms =\ Expected static or delegated getter {0} to take a ScriptableObject parameter. msg.getter.static =\ Getter and setter must both be static or neither be static. msg.setter.return =\ Setter must have void return type: {0} msg.setter2.parms =\ Two-parameter setter must take a ScriptableObject as its first parameter. msg.setter1.parms =\ Expected single parameter setter for {0} msg.setter2.expected =\ Expected static or delegated setter {0} to take two parameters. msg.setter.parms =\ Expected either one or two parameters for setter. msg.setter.bad.type =\ Unsupported parameter type "{0}" in setter "{1}". msg.add.sealed =\ Cannot add a property to a sealed object: {0}. msg.remove.sealed =\ Cannot remove a property from a sealed object: {0}. msg.modify.sealed =\ Cannot modify a property of a sealed object: {0}. msg.modify.readonly =\ Cannot modify readonly property: {0}. # TokenStream msg.missing.exponent =\ missing exponent msg.caught.nfe =\ number format error msg.unterminated.string.lit =\ unterminated string literal msg.unterminated.comment =\ unterminated comment msg.unterminated.re.lit =\ unterminated regular expression literal msg.invalid.re.flag =\ invalid flag after regular expression msg.no.re.input.for =\ no input for {0} msg.illegal.character =\ illegal character msg.invalid.escape =\ invalid Unicode escape sequence msg.bad.namespace =\ not a valid default namespace statement. \ Syntax is: default xml namespace = EXPRESSION; # TokensStream warnings msg.bad.octal.literal =\ illegal octal literal digit {0}; interpreting it as a decimal digit msg.reserved.keyword =\ illegal usage of future reserved keyword {0}; interpreting it as ordinary identifier # LiveConnect errors msg.java.internal.field.type =\ Internal error: type conversion of {0} to assign to {1} on {2} failed. msg.java.conversion.implicit_method =\ Can''t find converter method "{0}" on class {1}. msg.java.method.assign =\ Java method "{0}" cannot be assigned to. msg.java.internal.private =\ Internal error: attempt to access private/protected field "{0}". msg.java.no_such_method =\ Can''t find method {0}. msg.script.is.not.constructor =\ Script objects are not constructors. msg.nonjava.method =\ Java method "{0}" was invoked with {1} as "this" value that can not be converted to Java type {2}. msg.java.member.not.found =\ Java class "{0}" has no public instance field or method named "{1}". msg.java.array.index.out.of.bounds =\ Array index {0} is out of bounds [0..{1}]. msg.java.array.member.not.found =\ Java arrays have no public instance fields or methods named "{0}". msg.pkg.int =\ Java package names may not be numbers. msg.access.prohibited =\ Access to Java class "{0}" is prohibited. # ImporterTopLevel msg.ambig.import =\ Ambiguous import: "{0}" and and "{1}". msg.not.pkg =\ Function importPackage must be called with a package; had "{0}" instead. msg.not.class =\ Function importClass must be called with a class; had "{0}" instead. msg.not.class.not.pkg =\ "{0}" is neither a class nor a package. msg.prop.defined =\ Cannot import "{0}" since a property by that name is already defined. #JavaAdapter msg.adapter.zero.args =\ JavaAdapter requires at least one argument. msg.not.java.class.arg = \ Argument {0} is not Java class: {1}. #JavaAdapter msg.only.one.super = \ Only one class may be extended by a JavaAdapter. Had {0} and {1}. # Arrays msg.arraylength.bad =\ Inappropriate array length. # Arrays msg.arraylength.too.big =\ Array length {0} exceeds supported capacity limit. # URI msg.bad.uri =\ Malformed URI sequence. # Number msg.bad.precision =\ Precision {0} out of range. # NativeGenerator msg.send.newborn =\ Attempt to send value to newborn generator msg.already.exec.gen =\ Already executing generator msg.StopIteration.invalid =\ StopIteration may not be changed to an arbitrary object. # Interpreter msg.yield.closing =\ Yield from closing generator yui-compressor-2.4.7/src/org/mozilla/javascript/resources/Messages_fr.properties0000644000175000017500000003524511753547210030217 0ustar drazzibdrazzib# # French JavaScript messages file. # # ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0 # # 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 Aviva Inc. code, released # March 5, 2004. # # The Initial Developer of the Original Code is # Aviva Inc. # Portions created by the Initial Developer are Copyright (C) 2004 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Eugene Aresteanu # # Alternatively, the contents of this file may be used under the terms of # the GNU General Public License Version 2 or later (the "GPL"), in which # case the provisions of the GPL are applicable instead of those above. If # you wish to allow use of your version of this file only under the terms of # the GPL and not to allow others to use your version of this file under the # MPL, indicate your decision by deleting the provisions above and replacing # them with the notice and other provisions required by the GPL. If you do # not delete the provisions above, a recipient may use your version of this # file under either the MPL or the GPL. # # ***** END LICENSE BLOCK ***** msg.dup.parms =\ Le nom de param\u00E8tre "{0}" existe d\u00E9j\u00E0. msg.too.big.jump =\ Programme trop complexe : d\u00E9calage de saut trop important msg.too.big.index =\ Programme trop complexe : l''indice interne d\u00E9passe la limite de 64 ko msg.ctor.not.found =\ Le constructeur de "{0}" est introuvable msg.not.ctor =\ {0} n''est pas un constructeur msg.varargs.ctor =\ La m\u00E9thode ou le constructeur "{0}" doit \u00EAtre statique avec la signature "(Context cx, arguments Object[], Function ctorObj, boolean inNewExpr)" pour d\u00E9finir un constructeur d''arguments de variable. msg.varargs.fun =\ La m\u00E9thode "{0}" doit \u00EAtre statique avec la signature "(Context cx, Scriptable thisObj, arguments Object[], Function funObj)" pour d\u00E9finir une fonction d''arguments de variable msg.incompat.call =\ La m\u00E9thode "{0}" a \u00E9t\u00E9 appel\u00E9e dans un objet non compatible msg.bad.parms =\ Les param\u00E8tres de la m\u00E9thode sont incorrects pour "{0}" msg.no.overload =\ La m\u00E9thode "{0}" appara\u00EEt plusieurs fois dans la classe "{1}" msg.method.not.found =\ La m\u00E9thode "{0}" est introuvable dans "{1}" msg.bad.for.in.lhs =\ La partie gauche de la boucle for..in est incorrecte msg.bad.lhs.assign =\ La partie gauche de l''affectation est incorrecte msg.mult.index =\ Une seule variable est autoris\u00E9e dans la boucle for..in msg.cant.convert =\ La conversion en type "{0}" est impossible msg.cant.call.indirect =\ La fonction "{0}" doit \u00EAtre appel\u00E9e directement et non par l''interm\u00E9diaire d''une fonction portant un autre nom msg.eval.nonstring =\ Si vous appelez la fonction eval() avec une valeur qui n''appartient pas \u00E0 une cha\u00EEne primitive, c''est la valeur en question qui est renvoy\u00E9e. \u00E9tait-ce votre intention ? msg.only.from.new =\ {0} ne peut \u00EAtre appel\u00E9e qu''\u00E0 partir d''une "nouvelle" expression. msg.deprec.ctor =\ Le constructeur "{0}" est d\u00E9conseill\u00E9 msg.no.function.ref.found =\ aucune source n''a \u00E9t\u00E9 trouv\u00E9e pour d\u00E9compiler la r\u00E9f\u00E9rence de fonction {0} msg.arg.isnt.array =\ le second argument de la m\u00E9thode Function.prototype.apply doit \u00EAtre un tableau msg.bad.esc.mask =\ le masque d''\u00E9chappement de cha\u00EEne est incorrect msg.cant.instantiate =\ erreur lors de l''instanciation ({0}) : la classe {1} est une classe interface ou abstract msg.bad.ctor.sig =\ Un constructeur avec une signature incorrecte a \u00E9t\u00E9 d\u00E9tect\u00E9 : {0} qui appelle {1} avec la signature {2} msg.not.java.obj =\ L''argument attendu pour la fonction getClass() doit \u00EAtre un objet Java msg.no.java.ctor =\ Le constructeur Java de "{0}" avec les arguments "{1}" est introuvable msg.method.ambiguous =\ Le choix de la m\u00E9thode Java {0}.{1} correspondant aux types d''argument JavaScript ({2}) est ambigu. Les m\u00E9thodes propos\u00E9es sont les suivantes : {3} msg.constructor.ambiguous =\ Le choix du constructeur Java {0} correspondant aux types d''argument JavaScript ({1}) est ambigu. Les constructeurs propos\u00E9s sont les suivants : {2} msg.conversion.not.allowed =\ Impossible de convertir {0} en {1} msg.not.classloader =\ Le constructeur de "Packages" attend un argument de type java.lang.Classloader msg.bad.quant =\ Le quantificateur {0} est incorrect msg.overlarge.max =\ Le maximum {0} est trop important msg.zero.quant =\ Le quantificateur {0} est nul msg.max.lt.min =\ Le maximum {0} est inf\u00E9rieur au minimum msg.unterm.quant =\ Le quantificateur {0} n''a pas de limite msg.unterm.paren =\ Les parenth\u00E8ses {0} n''ont pas de limite msg.unterm.class =\ La classe de caract\u00E8res {0} n''a pas de limite msg.bad.range =\ La classe de caract\u00E8res contient une plage de valeurs incorrecte msg.trail.backslash =\ \\ au d\u00E9but d''une expression r\u00E9guli\u00E8re msg.no.regexp =\ Les expressions r\u00E9guli\u00E8res ne sont pas disponibles msg.bad.backref =\ la r\u00E9f\u00E9rence ant\u00E9rieure d\u00E9passe le nombre de parenth\u00E8ses de capture msg.dup.label =\ Le libell\u00E9 {0} existe d\u00E9j\u00E0 msg.undef.label =\ Le libell\u00E9 {0} n''est pas d\u00E9fini msg.bad.break =\ Le saut non libell\u00E9 doit se trouver dans la boucle ou dans l''aiguillage msg.continue.outside =\ continue doit se trouver dans la boucle msg.continue.nonloop =\ Il n''est possible de continuer que dans l''instruction d''it\u00E9ration libell\u00E9e msg.fn.redecl =\ La fonction "{0}" a \u00E9t\u00E9 de nouveau d\u00E9clar\u00E9e. La d\u00E9finition pr\u00E9c\u00E9dente sera ignor\u00E9e msg.no.paren.parms =\ il manque ''('' avant les param\u00E8tres de la fonction msg.no.parm =\ il manque un param\u00E8tre de forme msg.no.paren.after.parms =\ il manque '')'' apr\u00E8s les param\u00E8tres de forme msg.no.brace.body =\ il manque '{' avant le corps d''une fonction msg.no.brace.after.body =\ il manque ''}'' apr\u00E8s le corps d''une fonction msg.no.paren.cond =\ il manque ''('' avant une condition msg.no.paren.after.cond =\ il manque '')'' apr\u00E8s une condition msg.no.semi.stmt =\ il manque '';'' avant une instruction msg.no.name.after.dot =\ il manque un nom apr\u00E8s un op\u00E9rateur ''.'' msg.no.bracket.index =\ il manque '']'' dans l''expression de l''indice msg.no.paren.switch =\ il manque ''('' avant l''expression d''un aiguillage msg.no.paren.after.switch =\ il manque '')'' apr\u00E8s l''expression d''un aiguillage msg.no.brace.switch =\ il manque '{' avant le corps d''un aiguillage msg.bad.switch =\ l''instruction d''aiguillage est incorrecte msg.no.colon.case =\ il manque '':'' apr\u00E8s l''expression d''un cas msg.no.while.do =\ il manque ''while'' apr\u00E8s le corps d''une boucle do-loop msg.no.paren.for =\ il manque ''('' apr\u00E8s for msg.no.semi.for =\ Il manque '';'' apr\u00E8s l''initialiseur for-loop msg.no.semi.for.cond =\ il manque '';'' apr\u00E8s la condition for-loop msg.no.paren.for.ctrl =\ il manque '')'' apr\u00E8s le contrôle for-loop msg.no.paren.with =\ il manque ''('' avant un objet with-statement msg.no.paren.after.with =\ il manque '')'' apr\u00E8s un objet with-statement msg.bad.return =\ la valeur renvoy\u00E9e est incorrecte msg.no.brace.block =\ il manque ''}'' dans une instruction compos\u00E9e msg.bad.label =\ le libell\u00E9 est incorrect msg.bad.var =\ il manque un nom de variable msg.bad.var.init =\ l''initialisation de la variable est incorrecte msg.no.colon.cond =\ il manque '':'' dans une expression conditionnelle msg.no.paren.arg =\ il manque '')'' apr\u00E8s une liste d''arguments msg.no.bracket.arg =\ il manque '']'' apr\u00E8s une liste d''\u00E9l\u00E9ments msg.bad.prop =\ l''identifiant de propri\u00E9t\u00E9 est incorrect msg.no.colon.prop =\ il manque '':'' apr\u00E8s un identifiant de propri\u00E9t\u00E9 msg.no.brace.prop =\ il manque ''}'' apr\u00E8s une liste de propri\u00E9t\u00E9s msg.no.paren =\ il manque '')'' dans des parenth\u00E8ses msg.reserved.id =\ l''identifiant est un mot r\u00E9serv\u00E9 msg.no.paren.catch =\ il manque ''('' avant une condition catch-block msg.bad.catchcond =\ la condition catch-block est incorrecte msg.catch.unreachable =\ aucune clause catch suivant une interception non qualifi\u00E9e ne peut \u00EAtre atteinte msg.no.brace.catchblock =\ il manque '{' avant le corps catch-block msg.try.no.catchfinally =\ ''try'' a \u00E9t\u00E9 d\u00E9tect\u00E9 sans ''catch'' ni ''finally'' msg.syntax =\ erreur de syntaxe msg.assn.create =\ Une variable va \u00EAtre cr\u00E9\u00E9e en raison de l''affectation \u00E0 un ''{0}'' non d\u00E9fini. Ajoutez une instruction de variable \u00E0 la port\u00E9e sup\u00E9rieure pour que cet avertissement ne soit plus affich\u00E9 msg.prop.not.found =\ La propri\u00E9t\u00E9 est introuvable msg.invalid.type =\ Valeur JavaScript de type {0} incorrecte msg.primitive.expected =\ Un type primitif \u00E9tait attendu (et non {0}) msg.null.to.object =\ Il est impossible de convertir la valeur null en objet msg.undef.to.object =\ Il est impossible de convertir une valeur non d\u00E9finie en objet msg.cyclic.value =\ La valeur cyclique {0} n''est pas autoris\u00E9e msg.is.not.defined =\ "{0}" n''est pas d\u00E9fini msg.isnt.function =\ {0} n''est pas une fonction, est un {1} msg.bad.default.value =\ La m\u00E9thode getDefaultValue() de l''objet a renvoy\u00E9 un objet msg.instanceof.not.object =\ Il est impossible d''utiliser une instance d''un \u00E9l\u00E9ment autre qu''un objet msg.instanceof.bad.prototype =\ La propri\u00E9t\u00E9 ''prototype'' de {0} n''est pas un objet msg.bad.radix =\ la base {0} n''est pas autoris\u00E9e msg.default.value =\ La valeur par d\u00E9faut de l''objet est introuvable msg.zero.arg.ctor =\ Il est impossible de charger la classe "{0}", qui ne poss\u00E8de pas de constructeur de param\u00E8tre z\u00E9ro msg.multiple.ctors =\ Les m\u00E9thodes {0} et {1} ont \u00E9t\u00E9 d\u00E9tect\u00E9es alors qu''il est impossible d''utiliser plusieurs m\u00E9thodes constructor msg.ctor.multiple.parms =\ Il est impossible de d\u00E9finir le constructeur ou la classe {0} car plusieurs constructeurs poss\u00E8dent plusieurs param\u00E8tres msg.extend.scriptable =\ {0} doit \u00E9tendre ScriptableObject afin de d\u00E9finir la propri\u00E9t\u00E9 {1} msg.bad.getter.parms =\ Pour d\u00E9finir une propri\u00E9t\u00E9, la m\u00E9thode d''obtention {0} doit avoir des param\u00E8tres z\u00E9ro ou un seul param\u00E8tre ScriptableObject msg.obj.getter.parms =\ La m\u00E9thode d''obtention statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser un param\u00E8tre ScriptableObject msg.getter.static =\ La m\u00E9thode d''obtention et la m\u00E9thode de d\u00E9finition doivent toutes deux avoir le m\u00EAme \u00E9tat (statique ou non) msg.setter2.parms =\ La m\u00E9thode de d\u00E9finition \u00E0 deux param\u00E8tres doit utiliser un param\u00E8tre ScriptableObject comme premier param\u00E8tre msg.setter1.parms =\ Une m\u00E9thode d''obtention \u00E0 param\u00E8tre unique est attendue pour {0} msg.setter2.expected =\ La m\u00E9thode de d\u00E9finition statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser deux param\u00E8tres msg.setter.parms =\ Un ou deux param\u00E8tres sont attendus pour la m\u00E9thode de d\u00E9finition msg.add.sealed =\ Il est impossible d''ajouter une propri\u00E9t\u00E9 \u00E0 un objet ferm\u00E9 msg.remove.sealed =\ Il est impossible de supprimer une propri\u00E9t\u00E9 d''un objet ferm\u00E9 msg.token.replaces.pushback =\ le jeton de non-obtention {0} remplace le jeton de renvoi {1} msg.missing.exponent =\ il manque un exposant msg.caught.nfe =\ erreur de format de nombre : {0} msg.unterminated.string.lit =\ le litt\u00E9ral de la cha\u00EEne n''a pas de limite msg.unterminated.comment =\ le commentaire n''a pas de limite msg.unterminated.re.lit =\ le litt\u00E9ral de l''expression r\u00E9guli\u00E8re n''a pas de limite msg.invalid.re.flag =\ une expression r\u00E9guli\u00E8re est suivie d''un indicateur incorrect msg.no.re.input.for =\ il n''y a pas d''entr\u00E9e pour {0} msg.illegal.character =\ caract\u00E8re non autoris\u00E9 msg.invalid.escape =\ la s\u00E9quence d''\u00E9chappement Unicode est incorrecte msg.bad.octal.literal =\ le chiffre octal du litt\u00E9ral, {0}, n''est pas autoris\u00E9 et sera interpr\u00E9t\u00E9 comme un chiffre d\u00E9cimal msg.reserved.keyword =\ l''utilisation du futur mot-cl\u00E9 r\u00E9serv\u00E9 {0} n''est pas autoris\u00E9e et celui-ci sera interpr\u00E9t\u00E9 comme un identifiant ordinaire msg.undefined =\ La valeur non d\u00E9finie ne poss\u00E8de pas de propri\u00E9t\u00E9 msg.java.internal.field.type =\ Erreur interne : la conversion de type de {0} afin d''affecter {1} \u00E0 {2} a \u00E9chou\u00E9 msg.java.conversion.implicit_method =\ La m\u00E9thode de conversion "{0}" est introuvable dans la classe {1} sg.java.method.assign =\ La m\u00E9thode Java "{0}" ne peut pas \u00EAtre affect\u00E9e \u00E0 msg.java.internal.private =\ Erreur interne : une tentative d''acc\u00E9der \u00E0 un champ "{0}" priv\u00E9/prot\u00E9g\u00E9 a \u00E9t\u00E9 d\u00E9tect\u00E9e msg.java.no_such_method =\ La m\u00E9thode ''{0}'' est introuvable msg.script.is.not.constructor =\ Les objets Script ne sont pas des constructeurs msg.nonjava.method =\ La m\u00E9thode Java "{0}" a \u00E9t\u00E9 appel\u00E9e avec une valeur ''this'' qui n''est pas un objet Java msg.java.member.not.found =\ La classe Java "{0}" ne poss\u00E8de aucun champ ou aucune m\u00E9thode d''instance publique appel\u00E9 "{1}" msg.java.array.index.out.of.bounds =\ Array index {0} is out of bounds [0..{1}]. msg.pkg.int =\ Les noms de package Java ne peuvent pas \u00EAtre des nombres msg.ambig.import =\ Importation ambigu\u00EB : "{0}" et "{1}" msg.not.pkg =\ La fonction importPackage doit \u00EAtre appel\u00E9e avec un package et non avec "{0}" msg.not.class =\ La fonction importClass doit \u00EAtre appel\u00E9e avec une classe et non avec "{0}" msg.prop.defined =\ Il est impossible d''importer "{0}" car une propri\u00E9t\u00E9 portant le m\u00EAme nom a d\u00E9j\u00E0 \u00E9t\u00E9 d\u00E9finie sg.arraylength.bad =\ La longueur du tableau n''est pas appropri\u00E9e msg.bad.uri =\ La s\u00E9quence URI n''est pas form\u00E9e correctement msg.bad.precision =\ La pr\u00E9cision {0} ne se trouve pas dans la plage de valeurs yui-compressor-2.4.7/src/org/mozilla/javascript/ClassShutter.java0000644000175000017500000000740111753547210025111 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** Embeddings that wish to filter Java classes that are visible to scripts through the LiveConnect, should implement this interface. @see Context#setClassShutter(ClassShutter) @since 1.5 Release 4 @author Norris Boyd */ public interface ClassShutter { /** * Return true iff the Java class with the given name should be exposed * to scripts. *

* An embedding may filter which Java classes are exposed through * LiveConnect to JavaScript scripts. *

* Due to the fact that there is no package reflection in Java, * this method will also be called with package names. There * is no way for Rhino to tell if "Packages.a.b" is a package name * or a class that doesn't exist. What Rhino does is attempt * to load each segment of "Packages.a.b.c": It first attempts to * load class "a", then attempts to load class "a.b", then * finally attempts to load class "a.b.c". On a Rhino installation * without any ClassShutter set, and without any of the * above classes, the expression "Packages.a.b.c" will result in * a [JavaPackage a.b.c] and not an error. *

* With ClassShutter supplied, Rhino will first call * visibleToScripts before attempting to look up the class name. If * visibleToScripts returns false, the class name lookup is not * performed and subsequent Rhino execution assumes the class is * not present. So for "java.lang.System.out.println" the lookup * of "java.lang.System" is skipped and thus Rhino assumes that * "java.lang.System" doesn't exist. So then for "java.lang.System.out", * Rhino attempts to load the class "java.lang.System.out" because * it assumes that "java.lang.System" is a package name. *

* @param fullClassName the full name of the class (including the package * name, with '.' as a delimiter). For example the * standard string class is "java.lang.String" * @return whether or not to reveal this class to scripts */ public boolean visibleToScripts(String fullClassName); } yui-compressor-2.4.7/src/org/mozilla/javascript/Decompiler.java0000644000175000017500000006750411753547210024562 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Mike Ang * Igor Bukanov * Bob Jervis * Mike McCabe * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * The following class save decompilation information about the source. * Source information is returned from the parser as a String * associated with function nodes and with the toplevel script. When * saved in the constant pool of a class, this string will be UTF-8 * encoded, and token values will occupy a single byte. * Source is saved (mostly) as token numbers. The tokens saved pretty * much correspond to the token stream of a 'canonical' representation * of the input program, as directed by the parser. (There were a few * cases where tokens could have been left out where decompiler could * easily reconstruct them, but I left them in for clarity). (I also * looked adding source collection to TokenStream instead, where I * could have limited the changes to a few lines in getToken... but * this wouldn't have saved any space in the resulting source * representation, and would have meant that I'd have to duplicate * parser logic in the decompiler to disambiguate situations where * newlines are important.) The function decompile expands the * tokens back into their string representations, using simple * lookahead to correct spacing and indentation. * * Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens * are stored inline, as a NUMBER token, a character representing the type, and * either 1 or 4 characters representing the bit-encoding of the number. String * types NAME, STRING and OBJECT are currently stored as a token type, * followed by a character giving the length of the string (assumed to * be less than 2^16), followed by the characters of the string * inlined into the source string. Changing this to some reference to * to the string in the compiled class' constant pool would probably * save a lot of space... but would require some method of deriving * the final constant pool entry from information available at parse * time. */ public class Decompiler { /** * Flag to indicate that the decompilation should omit the * function header and trailing brace. */ public static final int ONLY_BODY_FLAG = 1 << 0; /** * Flag to indicate that the decompilation generates toSource result. */ public static final int TO_SOURCE_FLAG = 1 << 1; /** * Decompilation property to specify initial ident value. */ public static final int INITIAL_INDENT_PROP = 1; /** * Decompilation property to specify default identation offset. */ public static final int INDENT_GAP_PROP = 2; /** * Decompilation property to specify identation offset for case labels. */ public static final int CASE_GAP_PROP = 3; // Marker to denote the last RC of function so it can be distinguished from // the last RC of object literals in case of function expressions private static final int FUNCTION_END = Token.LAST_TOKEN + 1; String getEncodedSource() { return sourceToString(0); } int getCurrentOffset() { return sourceTop; } int markFunctionStart(int functionType) { int savedOffset = getCurrentOffset(); addToken(Token.FUNCTION); append((char)functionType); return savedOffset; } int markFunctionEnd(int functionStart) { int offset = getCurrentOffset(); append((char)FUNCTION_END); return offset; } void addToken(int token) { if (!(0 <= token && token <= Token.LAST_TOKEN)) throw new IllegalArgumentException(); append((char)token); } void addEOL(int token) { if (!(0 <= token && token <= Token.LAST_TOKEN)) throw new IllegalArgumentException(); append((char)token); append((char)Token.EOL); } void addName(String str) { addToken(Token.NAME); appendString(str); } void addString(String str) { addToken(Token.STRING); appendString(str); } void addRegexp(String regexp, String flags) { addToken(Token.REGEXP); appendString('/' + regexp + '/' + flags); } void addNumber(double n) { addToken(Token.NUMBER); /* encode the number in the source stream. * Save as NUMBER type (char | char char char char) * where type is * 'D' - double, 'S' - short, 'J' - long. * We need to retain float vs. integer type info to keep the * behavior of liveconnect type-guessing the same after * decompilation. (Liveconnect tries to present 1.0 to Java * as a float/double) * OPT: This is no longer true. We could compress the format. * This may not be the most space-efficient encoding; * the chars created below may take up to 3 bytes in * constant pool UTF-8 encoding, so a Double could take * up to 12 bytes. */ long lbits = (long)n; if (lbits != n) { // if it's floating point, save as a Double bit pattern. // (12/15/97 our scanner only returns Double for f.p.) lbits = Double.doubleToLongBits(n); append('D'); append((char)(lbits >> 48)); append((char)(lbits >> 32)); append((char)(lbits >> 16)); append((char)lbits); } else { // we can ignore negative values, bc they're already prefixed // by NEG if (lbits < 0) Kit.codeBug(); // will it fit in a char? // this gives a short encoding for integer values up to 2^16. if (lbits <= Character.MAX_VALUE) { append('S'); append((char)lbits); } else { // Integral, but won't fit in a char. Store as a long. append('J'); append((char)(lbits >> 48)); append((char)(lbits >> 32)); append((char)(lbits >> 16)); append((char)lbits); } } } private void appendString(String str) { int L = str.length(); int lengthEncodingSize = 1; if (L >= 0x8000) { lengthEncodingSize = 2; } int nextTop = sourceTop + lengthEncodingSize + L; if (nextTop > sourceBuffer.length) { increaseSourceCapacity(nextTop); } if (L >= 0x8000) { // Use 2 chars to encode strings exceeding 32K, were the highest // bit in the first char indicates presence of the next byte sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16)); ++sourceTop; } sourceBuffer[sourceTop] = (char)L; ++sourceTop; str.getChars(0, L, sourceBuffer, sourceTop); sourceTop = nextTop; } private void append(char c) { if (sourceTop == sourceBuffer.length) { increaseSourceCapacity(sourceTop + 1); } sourceBuffer[sourceTop] = c; ++sourceTop; } private void increaseSourceCapacity(int minimalCapacity) { // Call this only when capacity increase is must if (minimalCapacity <= sourceBuffer.length) Kit.codeBug(); int newCapacity = sourceBuffer.length * 2; if (newCapacity < minimalCapacity) { newCapacity = minimalCapacity; } char[] tmp = new char[newCapacity]; System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop); sourceBuffer = tmp; } private String sourceToString(int offset) { if (offset < 0 || sourceTop < offset) Kit.codeBug(); return new String(sourceBuffer, offset, sourceTop - offset); } /** * Decompile the source information associated with this js * function/script back into a string. For the most part, this * just means translating tokens back to their string * representations; there's a little bit of lookahead logic to * decide the proper spacing/indentation. Most of the work in * mapping the original source to the prettyprinted decompiled * version is done by the parser. * * @param source encoded source tree presentation * * @param flags flags to select output format * * @param properties indentation properties * */ public static String decompile(String source, int flags, UintMap properties) { int length = source.length(); if (length == 0) { return ""; } int indent = properties.getInt(INITIAL_INDENT_PROP, 0); if (indent < 0) throw new IllegalArgumentException(); int indentGap = properties.getInt(INDENT_GAP_PROP, 4); if (indentGap < 0) throw new IllegalArgumentException(); int caseGap = properties.getInt(CASE_GAP_PROP, 2); if (caseGap < 0) throw new IllegalArgumentException(); StringBuffer result = new StringBuffer(); boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG)); boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG)); // Spew tokens in source, for debugging. // as TYPE number char if (printSource) { System.err.println("length:" + length); for (int i = 0; i < length; ++i) { // Note that tokenToName will fail unless Context.printTrees // is true. String tokenname = null; if (Token.printNames) { tokenname = Token.name(source.charAt(i)); } if (tokenname == null) { tokenname = "---"; } String pad = tokenname.length() > 7 ? "\t" : "\t\t"; System.err.println (tokenname + pad + (int)source.charAt(i) + "\t'" + ScriptRuntime.escapeString (source.substring(i, i+1)) + "'"); } System.err.println(); } int braceNesting = 0; boolean afterFirstEOL = false; int i = 0; int topFunctionType; if (source.charAt(i) == Token.SCRIPT) { ++i; topFunctionType = -1; } else { topFunctionType = source.charAt(i + 1); } if (!toSource) { // add an initial newline to exactly match js. result.append('\n'); for (int j = 0; j < indent; j++) result.append(' '); } else { if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) { result.append('('); } } while (i < length) { switch(source.charAt(i)) { case Token.GET: case Token.SET: result.append(source.charAt(i) == Token.GET ? "get " : "set "); ++i; i = printSourceString(source, i + 1, false, result); // Now increment one more to get past the FUNCTION token ++i; break; case Token.NAME: case Token.REGEXP: // re-wrapped in '/'s in parser... i = printSourceString(source, i + 1, false, result); continue; case Token.STRING: i = printSourceString(source, i + 1, true, result); continue; case Token.NUMBER: i = printSourceNumber(source, i + 1, result); continue; case Token.TRUE: result.append("true"); break; case Token.FALSE: result.append("false"); break; case Token.NULL: result.append("null"); break; case Token.THIS: result.append("this"); break; case Token.FUNCTION: ++i; // skip function type result.append("function "); break; case FUNCTION_END: // Do nothing break; case Token.COMMA: result.append(", "); break; case Token.LC: ++braceNesting; if (Token.EOL == getNext(source, length, i)) indent += indentGap; result.append('{'); break; case Token.RC: { --braceNesting; /* don't print the closing RC if it closes the * toplevel function and we're called from * decompileFunctionBody. */ if (justFunctionBody && braceNesting == 0) break; result.append('}'); switch (getNext(source, length, i)) { case Token.EOL: case FUNCTION_END: indent -= indentGap; break; case Token.WHILE: case Token.ELSE: indent -= indentGap; result.append(' '); break; } break; } case Token.LP: result.append('('); break; case Token.RP: result.append(')'); if (Token.LC == getNext(source, length, i)) result.append(' '); break; case Token.LB: result.append('['); break; case Token.RB: result.append(']'); break; case Token.EOL: { if (toSource) break; boolean newLine = true; if (!afterFirstEOL) { afterFirstEOL = true; if (justFunctionBody) { /* throw away just added 'function name(...) {' * and restore the original indent */ result.setLength(0); indent -= indentGap; newLine = false; } } if (newLine) { result.append('\n'); } /* add indent if any tokens remain, * less setback if next token is * a label, case or default. */ if (i + 1 < length) { int less = 0; int nextToken = source.charAt(i + 1); if (nextToken == Token.CASE || nextToken == Token.DEFAULT) { less = indentGap - caseGap; } else if (nextToken == Token.RC) { less = indentGap; } /* elaborate check against label... skip past a * following inlined NAME and look for a COLON. */ else if (nextToken == Token.NAME) { int afterName = getSourceStringEnd(source, i + 2); if (source.charAt(afterName) == Token.COLON) less = indentGap; } for (; less < indent; less++) result.append(' '); } break; } case Token.DOT: result.append('.'); break; case Token.NEW: result.append("new "); break; case Token.DELPROP: result.append("delete "); break; case Token.IF: result.append("if "); break; case Token.ELSE: result.append("else "); break; case Token.FOR: result.append("for "); break; case Token.IN: result.append(" in "); break; case Token.WITH: result.append("with "); break; case Token.WHILE: result.append("while "); break; case Token.DO: result.append("do "); break; case Token.TRY: result.append("try "); break; case Token.CATCH: result.append("catch "); break; case Token.FINALLY: result.append("finally "); break; case Token.THROW: result.append("throw "); break; case Token.SWITCH: result.append("switch "); break; case Token.BREAK: result.append("break"); if (Token.NAME == getNext(source, length, i)) result.append(' '); break; case Token.CONTINUE: result.append("continue"); if (Token.NAME == getNext(source, length, i)) result.append(' '); break; case Token.CASE: result.append("case "); break; case Token.DEFAULT: result.append("default"); break; case Token.RETURN: result.append("return"); if (Token.SEMI != getNext(source, length, i)) result.append(' '); break; case Token.VAR: result.append("var "); break; case Token.LET: result.append("let "); break; case Token.SEMI: result.append(';'); if (Token.EOL != getNext(source, length, i)) { // separators in FOR result.append(' '); } break; case Token.ASSIGN: result.append(" = "); break; case Token.ASSIGN_ADD: result.append(" += "); break; case Token.ASSIGN_SUB: result.append(" -= "); break; case Token.ASSIGN_MUL: result.append(" *= "); break; case Token.ASSIGN_DIV: result.append(" /= "); break; case Token.ASSIGN_MOD: result.append(" %= "); break; case Token.ASSIGN_BITOR: result.append(" |= "); break; case Token.ASSIGN_BITXOR: result.append(" ^= "); break; case Token.ASSIGN_BITAND: result.append(" &= "); break; case Token.ASSIGN_LSH: result.append(" <<= "); break; case Token.ASSIGN_RSH: result.append(" >>= "); break; case Token.ASSIGN_URSH: result.append(" >>>= "); break; case Token.HOOK: result.append(" ? "); break; case Token.OBJECTLIT: // pun OBJECTLIT to mean colon in objlit property // initialization. // This needs to be distinct from COLON in the general case // to distinguish from the colon in a ternary... which needs // different spacing. result.append(':'); break; case Token.COLON: if (Token.EOL == getNext(source, length, i)) // it's the end of a label result.append(':'); else // it's the middle part of a ternary result.append(" : "); break; case Token.OR: result.append(" || "); break; case Token.AND: result.append(" && "); break; case Token.BITOR: result.append(" | "); break; case Token.BITXOR: result.append(" ^ "); break; case Token.BITAND: result.append(" & "); break; case Token.SHEQ: result.append(" === "); break; case Token.SHNE: result.append(" !== "); break; case Token.EQ: result.append(" == "); break; case Token.NE: result.append(" != "); break; case Token.LE: result.append(" <= "); break; case Token.LT: result.append(" < "); break; case Token.GE: result.append(" >= "); break; case Token.GT: result.append(" > "); break; case Token.INSTANCEOF: result.append(" instanceof "); break; case Token.LSH: result.append(" << "); break; case Token.RSH: result.append(" >> "); break; case Token.URSH: result.append(" >>> "); break; case Token.TYPEOF: result.append("typeof "); break; case Token.VOID: result.append("void "); break; case Token.CONST: result.append("const "); break; case Token.YIELD: result.append("yield "); break; case Token.NOT: result.append('!'); break; case Token.BITNOT: result.append('~'); break; case Token.POS: result.append('+'); break; case Token.NEG: result.append('-'); break; case Token.INC: result.append("++"); break; case Token.DEC: result.append("--"); break; case Token.ADD: result.append(" + "); break; case Token.SUB: result.append(" - "); break; case Token.MUL: result.append(" * "); break; case Token.DIV: result.append(" / "); break; case Token.MOD: result.append(" % "); break; case Token.COLONCOLON: result.append("::"); break; case Token.DOTDOT: result.append(".."); break; case Token.DOTQUERY: result.append(".("); break; case Token.XMLATTR: result.append('@'); break; default: // If we don't know how to decompile it, raise an exception. throw new RuntimeException("Token: " + Token.name(source.charAt(i))); } ++i; } if (!toSource) { // add that trailing newline if it's an outermost function. if (!justFunctionBody) result.append('\n'); } else { if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) { result.append(')'); } } return result.toString(); } private static int getNext(String source, int length, int i) { return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF; } private static int getSourceStringEnd(String source, int offset) { return printSourceString(source, offset, false, null); } private static int printSourceString(String source, int offset, boolean asQuotedString, StringBuffer sb) { int length = source.charAt(offset); ++offset; if ((0x8000 & length) != 0) { length = ((0x7FFF & length) << 16) | source.charAt(offset); ++offset; } if (sb != null) { String str = source.substring(offset, offset + length); if (!asQuotedString) { sb.append(str); } else { sb.append('"'); sb.append(ScriptRuntime.escapeString(str)); sb.append('"'); } } return offset + length; } private static int printSourceNumber(String source, int offset, StringBuffer sb) { double number = 0.0; char type = source.charAt(offset); ++offset; if (type == 'S') { if (sb != null) { int ival = source.charAt(offset); number = ival; } ++offset; } else if (type == 'J' || type == 'D') { if (sb != null) { long lbits; lbits = (long)source.charAt(offset) << 48; lbits |= (long)source.charAt(offset + 1) << 32; lbits |= (long)source.charAt(offset + 2) << 16; lbits |= source.charAt(offset + 3); if (type == 'J') { number = lbits; } else { number = Double.longBitsToDouble(lbits); } } offset += 4; } else { // Bad source throw new RuntimeException(); } if (sb != null) { sb.append(ScriptRuntime.numberToString(number, 10)); } return offset; } private char[] sourceBuffer = new char[128]; // Per script/function source buffer top: parent source does not include a // nested functions source and uses function index as a reference instead. private int sourceTop; // whether to do a debug print of the source information, when decompiling. private static final boolean printSource = false; } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeCall.java0000644000175000017500000001211411753547210024504 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Bob Jervis * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * This class implements the activation object. * * See ECMA 10.1.6 * * @see org.mozilla.javascript.Arguments * @author Norris Boyd */ public final class NativeCall extends IdScriptableObject { static final long serialVersionUID = -7471457301304454454L; private static final Object CALL_TAG = "Call"; static void init(Scriptable scope, boolean sealed) { NativeCall obj = new NativeCall(); obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); } NativeCall() { } NativeCall(NativeFunction function, Scriptable scope, Object[] args) { this.function = function; setParentScope(scope); // leave prototype null this.originalArgs = (args == null) ? ScriptRuntime.emptyArgs : args; // initialize values of arguments int paramAndVarCount = function.getParamAndVarCount(); int paramCount = function.getParamCount(); if (paramAndVarCount != 0) { for (int i = 0; i < paramCount; ++i) { String name = function.getParamOrVarName(i); Object val = i < args.length ? args[i] : Undefined.instance; defineProperty(name, val, PERMANENT); } } // initialize "arguments" property but only if it was not overridden by // the parameter with the same name if (!super.has("arguments", this)) { defineProperty("arguments", new Arguments(this), PERMANENT); } if (paramAndVarCount != 0) { for (int i = paramCount; i < paramAndVarCount; ++i) { String name = function.getParamOrVarName(i); if (!super.has(name, this)) { if (function.getParamOrVarConst(i)) defineProperty(name, Undefined.instance, CONST); else defineProperty(name, Undefined.instance, PERMANENT); } } } } @Override public String getClassName() { return "Call"; } @Override protected int findPrototypeId(String s) { return s.equals("constructor") ? Id_constructor : 0; } @Override protected void initPrototypeId(int id) { String s; int arity; if (id == Id_constructor) { arity=1; s="constructor"; } else { throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(CALL_TAG, id, s, arity); } @Override public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(CALL_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); if (id == Id_constructor) { if (thisObj != null) { throw Context.reportRuntimeError1("msg.only.from.new", "Call"); } ScriptRuntime.checkDeprecated(cx, "Call"); NativeCall result = new NativeCall(); result.setPrototype(getObjectPrototype(scope)); return result; } throw new IllegalArgumentException(String.valueOf(id)); } private static final int Id_constructor = 1, MAX_PROTOTYPE_ID = 1; NativeFunction function; Object[] originalArgs; transient NativeCall parentActivationCall; } yui-compressor-2.4.7/src/org/mozilla/javascript/JavaScriptException.java0000644000175000017500000000674711753547210026426 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Bojan Cekrlic * Hannes Wallnoefer * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * Java reflection of JavaScript exceptions. * Instances of this class are thrown by the JavaScript 'throw' keyword. * * @author Mike McCabe */ public class JavaScriptException extends RhinoException { static final long serialVersionUID = -7666130513694669293L; /** * @deprecated * Use {@link WrappedException#WrappedException(Throwable)} to report * exceptions in Java code. */ public JavaScriptException(Object value) { this(value, "", 0); } /** * Create a JavaScript exception wrapping the given JavaScript value * * @param value the JavaScript value thrown. */ public JavaScriptException(Object value, String sourceName, int lineNumber) { recordErrorOrigin(sourceName, lineNumber, null, 0); this.value = value; } @Override public String details() { try { return ScriptRuntime.toString(value); } catch (RuntimeException rte) { // ScriptRuntime.toString may throw a RuntimeException if (value == null) { return "null"; } else if (value instanceof Scriptable) { return ScriptRuntime.defaultObjectToString((Scriptable)value); } else { return value.toString(); } } } /** * @return the value wrapped by this exception */ public Object getValue() { return value; } /** * @deprecated Use {@link RhinoException#sourceName()} from the super class. */ public String getSourceName() { return sourceName(); } /** * @deprecated Use {@link RhinoException#lineNumber()} from the super class. */ public int getLineNumber() { return lineNumber(); } private Object value; } yui-compressor-2.4.7/src/org/mozilla/javascript/NodeTransformer.java0000644000175000017500000005554411753547210025610 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * Bob Jervis * Roger Lawrence * Mike McCabe * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.util.ArrayList; import java.util.List; /** * This class transforms a tree to a lower-level representation for codegen. * * @see Node * @author Norris Boyd */ public class NodeTransformer { public NodeTransformer() { } public final void transform(ScriptOrFnNode tree) { transformCompilationUnit(tree); for (int i = 0; i != tree.getFunctionCount(); ++i) { FunctionNode fn = tree.getFunctionNode(i); transform(fn); } } private void transformCompilationUnit(ScriptOrFnNode tree) { loops = new ObjArray(); loopEnds = new ObjArray(); // to save against upchecks if no finally blocks are used. hasFinally = false; // Flatten all only if we are not using scope objects for block scope boolean createScopeObjects = tree.getType() != Token.FUNCTION || ((FunctionNode)tree).requiresActivation(); tree.flattenSymbolTable(!createScopeObjects); //uncomment to print tree before transformation //if (Token.printTrees) System.out.println(tree.toStringTree(tree)); transformCompilationUnit_r(tree, tree, tree, createScopeObjects); } private void transformCompilationUnit_r(final ScriptOrFnNode tree, final Node parent, Node.Scope scope, boolean createScopeObjects) { Node node = null; siblingLoop: for (;;) { Node previous = null; if (node == null) { node = parent.getFirstChild(); } else { previous = node; node = node.getNext(); } if (node == null) { break; } int type = node.getType(); if (createScopeObjects && (type == Token.BLOCK || type == Token.LOOP || type == Token.ARRAYCOMP) && (node instanceof Node.Scope)) { Node.Scope newScope = (Node.Scope) node; if (newScope.symbolTable != null) { // transform to let statement so we get a with statement // created to contain scoped let variables Node let = new Node(type == Token.ARRAYCOMP ? Token.LETEXPR : Token.LET); Node innerLet = new Node(Token.LET); let.addChildToBack(innerLet); for (String name: newScope.symbolTable.keySet()) { innerLet.addChildToBack(Node.newString(Token.NAME, name)); } newScope.symbolTable = null; // so we don't transform again Node oldNode = node; node = replaceCurrent(parent, previous, node, let); type = node.getType(); let.addChildToBack(oldNode); } } switch (type) { case Token.LABEL: case Token.SWITCH: case Token.LOOP: loops.push(node); loopEnds.push(((Node.Jump)node).target); break; case Token.WITH: { loops.push(node); Node leave = node.getNext(); if (leave.getType() != Token.LEAVEWITH) { Kit.codeBug(); } loopEnds.push(leave); break; } case Token.TRY: { Node.Jump jump = (Node.Jump)node; Node finallytarget = jump.getFinally(); if (finallytarget != null) { hasFinally = true; loops.push(node); loopEnds.push(finallytarget); } break; } case Token.TARGET: case Token.LEAVEWITH: if (!loopEnds.isEmpty() && loopEnds.peek() == node) { loopEnds.pop(); loops.pop(); } break; case Token.YIELD: ((FunctionNode)tree).addResumptionPoint(node); break; case Token.RETURN: { boolean isGenerator = tree.getType() == Token.FUNCTION && ((FunctionNode)tree).isGenerator(); if (isGenerator) { node.putIntProp(Node.GENERATOR_END_PROP, 1); } /* If we didn't support try/finally, it wouldn't be * necessary to put LEAVEWITH nodes here... but as * we do need a series of JSR FINALLY nodes before * each RETURN, we need to ensure that each finally * block gets the correct scope... which could mean * that some LEAVEWITH nodes are necessary. */ if (!hasFinally) break; // skip the whole mess. Node unwindBlock = null; for (int i=loops.size()-1; i >= 0; i--) { Node n = (Node) loops.get(i); int elemtype = n.getType(); if (elemtype == Token.TRY || elemtype == Token.WITH) { Node unwind; if (elemtype == Token.TRY) { Node.Jump jsrnode = new Node.Jump(Token.JSR); Node jsrtarget = ((Node.Jump)n).getFinally(); jsrnode.target = jsrtarget; unwind = jsrnode; } else { unwind = new Node(Token.LEAVEWITH); } if (unwindBlock == null) { unwindBlock = new Node(Token.BLOCK, node.getLineno()); } unwindBlock.addChildToBack(unwind); } } if (unwindBlock != null) { Node returnNode = node; Node returnExpr = returnNode.getFirstChild(); node = replaceCurrent(parent, previous, node, unwindBlock); if (returnExpr == null || isGenerator) { unwindBlock.addChildToBack(returnNode); } else { Node store = new Node(Token.EXPR_RESULT, returnExpr); unwindBlock.addChildToFront(store); returnNode = new Node(Token.RETURN_RESULT); unwindBlock.addChildToBack(returnNode); // transform return expression transformCompilationUnit_r(tree, store, scope, createScopeObjects); } // skip transformCompilationUnit_r to avoid infinite loop continue siblingLoop; } break; } case Token.BREAK: case Token.CONTINUE: { Node.Jump jump = (Node.Jump)node; Node.Jump jumpStatement = jump.getJumpStatement(); if (jumpStatement == null) Kit.codeBug(); for (int i = loops.size(); ;) { if (i == 0) { // Parser/IRFactory ensure that break/continue // always has a jump statement associated with it // which should be found throw Kit.codeBug(); } --i; Node n = (Node) loops.get(i); if (n == jumpStatement) { break; } int elemtype = n.getType(); if (elemtype == Token.WITH) { Node leave = new Node(Token.LEAVEWITH); previous = addBeforeCurrent(parent, previous, node, leave); } else if (elemtype == Token.TRY) { Node.Jump tryNode = (Node.Jump)n; Node.Jump jsrFinally = new Node.Jump(Token.JSR); jsrFinally.target = tryNode.getFinally(); previous = addBeforeCurrent(parent, previous, node, jsrFinally); } } if (type == Token.BREAK) { jump.target = jumpStatement.target; } else { jump.target = jumpStatement.getContinue(); } jump.setType(Token.GOTO); break; } case Token.CALL: visitCall(node, tree); break; case Token.NEW: visitNew(node, tree); break; case Token.LETEXPR: case Token.LET: { Node child = node.getFirstChild(); if (child.getType() == Token.LET) { // We have a let statement or expression rather than a // let declaration boolean createWith = tree.getType() != Token.FUNCTION || ((FunctionNode)tree).requiresActivation(); node = visitLet(createWith, parent, previous, node); break; } else { // fall through to process let declaration... } } /* fall through */ case Token.CONST: case Token.VAR: { Node result = new Node(Token.BLOCK); for (Node cursor = node.getFirstChild(); cursor != null;) { // Move cursor to next before createAssignment gets chance // to change n.next Node n = cursor; cursor = cursor.getNext(); if (n.getType() == Token.NAME) { if (!n.hasChildren()) continue; Node init = n.getFirstChild(); n.removeChild(init); n.setType(Token.BINDNAME); n = new Node(type == Token.CONST ? Token.SETCONST : Token.SETNAME, n, init); } else { // May be a destructuring assignment already transformed // to a LETEXPR if (n.getType() != Token.LETEXPR) throw Kit.codeBug(); } Node pop = new Node(Token.EXPR_VOID, n, node.getLineno()); result.addChildToBack(pop); } node = replaceCurrent(parent, previous, node, result); break; } case Token.TYPEOFNAME: { Node.Scope defining = scope.getDefiningScope(node.getString()); if (defining != null) { node.setScope(defining); } } break; case Token.TYPEOF: case Token.IFNE: { /* We want to suppress warnings for undefined property o.p * for the following constructs: typeof o.p, if (o.p), * if (!o.p), if (o.p == undefined), if (undefined == o.p) */ Node child = node.getFirstChild(); if (type == Token.IFNE) { while (child.getType() == Token.NOT) { child = child.getFirstChild(); } if (child.getType() == Token.EQ || child.getType() == Token.NE) { Node first = child.getFirstChild(); Node last = child.getLastChild(); if (first.getType() == Token.NAME && first.getString().equals("undefined")) child = last; else if (last.getType() == Token.NAME && last.getString().equals("undefined")) child = first; } } if (child.getType() == Token.GETPROP) child.setType(Token.GETPROPNOWARN); break; } case Token.NAME: case Token.SETNAME: case Token.SETCONST: case Token.DELPROP: { // Turn name to var for faster access if possible if (createScopeObjects) { break; } Node nameSource; if (type == Token.NAME) { nameSource = node; } else { nameSource = node.getFirstChild(); if (nameSource.getType() != Token.BINDNAME) { if (type == Token.DELPROP) { break; } throw Kit.codeBug(); } } if (nameSource.getScope() != null) { break; // already have a scope set } String name = nameSource.getString(); Node.Scope defining = scope.getDefiningScope(name); if (defining != null) { nameSource.setScope(defining); if (type == Token.NAME) { node.setType(Token.GETVAR); } else if (type == Token.SETNAME) { node.setType(Token.SETVAR); nameSource.setType(Token.STRING); } else if (type == Token.SETCONST) { node.setType(Token.SETCONSTVAR); nameSource.setType(Token.STRING); } else if (type == Token.DELPROP) { // Local variables are by definition permanent Node n = new Node(Token.FALSE); node = replaceCurrent(parent, previous, node, n); } else { throw Kit.codeBug(); } } break; } } transformCompilationUnit_r(tree, node, node instanceof Node.Scope ? (Node.Scope)node : scope, createScopeObjects); } } protected void visitNew(Node node, ScriptOrFnNode tree) { } protected void visitCall(Node node, ScriptOrFnNode tree) { } protected Node visitLet(boolean createWith, Node parent, Node previous, Node scopeNode) { Node vars = scopeNode.getFirstChild(); Node body = vars.getNext(); scopeNode.removeChild(vars); scopeNode.removeChild(body); boolean isExpression = scopeNode.getType() == Token.LETEXPR; Node result; Node newVars; if (createWith) { result = new Node(isExpression ? Token.WITHEXPR : Token.BLOCK); result = replaceCurrent(parent, previous, scopeNode, result); ArrayList list = new ArrayList(); Node objectLiteral = new Node(Token.OBJECTLIT); for (Node v=vars.getFirstChild(); v != null; v = v.getNext()) { Node current = v; if (current.getType() == Token.LETEXPR) { // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {} List destructuringNames = (List) current.getProp(Node.DESTRUCTURING_NAMES); Node c = current.getFirstChild(); if (c.getType() != Token.LET) throw Kit.codeBug(); // Add initialization code to front of body if (isExpression) { body = new Node(Token.COMMA, c.getNext(), body); } else { body = new Node(Token.BLOCK, new Node(Token.EXPR_VOID, c.getNext()), body); } // Update "list" and "objectLiteral" for the variables // defined in the destructuring assignment if (destructuringNames != null) { list.addAll(destructuringNames); for (int i=0; i < destructuringNames.size(); i++) { objectLiteral.addChildToBack( new Node(Token.VOID, Node.newNumber(0.0))); } } current = c.getFirstChild(); // should be a NAME, checked below } if (current.getType() != Token.NAME) throw Kit.codeBug(); list.add(ScriptRuntime.getIndexObject(current.getString())); Node init = current.getFirstChild(); if (init == null) { init = new Node(Token.VOID, Node.newNumber(0.0)); } objectLiteral.addChildToBack(init); } objectLiteral.putProp(Node.OBJECT_IDS_PROP, list.toArray()); newVars = new Node(Token.ENTERWITH, objectLiteral); result.addChildToBack(newVars); result.addChildToBack(new Node(Token.WITH, body)); result.addChildToBack(new Node(Token.LEAVEWITH)); } else { result = new Node(isExpression ? Token.COMMA : Token.BLOCK); result = replaceCurrent(parent, previous, scopeNode, result); newVars = new Node(Token.COMMA); for (Node v=vars.getFirstChild(); v != null; v = v.getNext()) { Node current = v; if (current.getType() == Token.LETEXPR) { // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {} Node c = current.getFirstChild(); if (c.getType() != Token.LET) throw Kit.codeBug(); // Add initialization code to front of body if (isExpression) { body = new Node(Token.COMMA, c.getNext(), body); } else { body = new Node(Token.BLOCK, new Node(Token.EXPR_VOID, c.getNext()), body); } // We're removing the LETEXPR, so move the symbols Node.Scope.joinScopes((Node.Scope)current, (Node.Scope)scopeNode); current = c.getFirstChild(); // should be a NAME, checked below } if (current.getType() != Token.NAME) throw Kit.codeBug(); Node stringNode = Node.newString(current.getString()); stringNode.setScope((Node.Scope)scopeNode); Node init = current.getFirstChild(); if (init == null) { init = new Node(Token.VOID, Node.newNumber(0.0)); } newVars.addChildToBack(new Node(Token.SETVAR, stringNode, init)); } if (isExpression) { result.addChildToBack(newVars); scopeNode.setType(Token.COMMA); result.addChildToBack(scopeNode); scopeNode.addChildToBack(body); } else { result.addChildToBack(new Node(Token.EXPR_VOID, newVars)); scopeNode.setType(Token.BLOCK); result.addChildToBack(scopeNode); scopeNode.addChildrenToBack(body); } } return result; } private static Node addBeforeCurrent(Node parent, Node previous, Node current, Node toAdd) { if (previous == null) { if (!(current == parent.getFirstChild())) Kit.codeBug(); parent.addChildToFront(toAdd); } else { if (!(current == previous.getNext())) Kit.codeBug(); parent.addChildAfter(toAdd, previous); } return toAdd; } private static Node replaceCurrent(Node parent, Node previous, Node current, Node replacement) { if (previous == null) { if (!(current == parent.getFirstChild())) Kit.codeBug(); parent.replaceChild(current, replacement); } else if (previous.next == current) { // Check cachedPrev.next == current is necessary due to possible // tree mutations parent.replaceChildAfter(previous, replacement); } else { parent.replaceChild(current, replacement); } return replacement; } private ObjArray loops; private ObjArray loopEnds; private boolean hasFinally; } yui-compressor-2.4.7/src/org/mozilla/javascript/Ref.java0000644000175000017500000000415111753547210023200 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov, igor@fastmail.fm * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.Serializable; /** * Generic notion of reference object that know how to query/modify the * target objects based on some property/index. */ public abstract class Ref implements Serializable { public boolean has(Context cx) { return true; } public abstract Object get(Context cx); public abstract Object set(Context cx, Object value); public boolean delete(Context cx) { return false; } } yui-compressor-2.4.7/src/org/mozilla/javascript/SpecialRef.java0000644000175000017500000001170411753547210024503 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov, igor@fastmail.fm * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; class SpecialRef extends Ref { static final long serialVersionUID = -7521596632456797847L; private static final int SPECIAL_NONE = 0; private static final int SPECIAL_PROTO = 1; private static final int SPECIAL_PARENT = 2; private Scriptable target; private int type; private String name; private SpecialRef(Scriptable target, int type, String name) { this.target = target; this.type = type; this.name = name; } static Ref createSpecial(Context cx, Object object, String name) { Scriptable target = ScriptRuntime.toObjectOrNull(cx, object); if (target == null) { throw ScriptRuntime.undefReadError(object, name); } int type; if (name.equals("__proto__")) { type = SPECIAL_PROTO; } else if (name.equals("__parent__")) { type = SPECIAL_PARENT; } else { throw new IllegalArgumentException(name); } if (!cx.hasFeature(Context.FEATURE_PARENT_PROTO_PROPERTIES)) { // Clear special after checking for valid name! type = SPECIAL_NONE; } return new SpecialRef(target, type, name); } @Override public Object get(Context cx) { switch (type) { case SPECIAL_NONE: return ScriptRuntime.getObjectProp(target, name, cx); case SPECIAL_PROTO: return target.getPrototype(); case SPECIAL_PARENT: return target.getParentScope(); default: throw Kit.codeBug(); } } @Override public Object set(Context cx, Object value) { switch (type) { case SPECIAL_NONE: return ScriptRuntime.setObjectProp(target, name, value, cx); case SPECIAL_PROTO: case SPECIAL_PARENT: { Scriptable obj = ScriptRuntime.toObjectOrNull(cx, value); if (obj != null) { // Check that obj does not contain on its prototype/scope // chain to prevent cycles Scriptable search = obj; do { if (search == target) { throw Context.reportRuntimeError1( "msg.cyclic.value", name); } if (type == SPECIAL_PROTO) { search = search.getPrototype(); } else { search = search.getParentScope(); } } while (search != null); } if (type == SPECIAL_PROTO) { target.setPrototype(obj); } else { target.setParentScope(obj); } return obj; } default: throw Kit.codeBug(); } } @Override public boolean has(Context cx) { if (type == SPECIAL_NONE) { return ScriptRuntime.hasObjectElem(target, name, cx); } return true; } @Override public boolean delete(Context cx) { if (type == SPECIAL_NONE) { return ScriptRuntime.deleteObjectElem(target, name, cx); } return false; } } yui-compressor-2.4.7/src/org/mozilla/javascript/FunctionNode.java0000644000175000017500000000754511753547210025071 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Roger Lawrence * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.util.ArrayList; import java.util.HashMap; public class FunctionNode extends ScriptOrFnNode { public FunctionNode(String name) { super(Token.FUNCTION); functionName = name; } public String getFunctionName() { return functionName; } public boolean requiresActivation() { return itsNeedsActivation; } public boolean getIgnoreDynamicScope() { return itsIgnoreDynamicScope; } public boolean isGenerator() { return itsIsGenerator; } public void addResumptionPoint(Node target) { if (generatorResumePoints == null) generatorResumePoints = new ArrayList(); generatorResumePoints.add(target); } public ArrayList getResumptionPoints() { return generatorResumePoints; } public HashMap getLiveLocals() { return liveLocals; } public void addLiveLocals(Node node, int[] locals) { if (liveLocals == null) liveLocals = new HashMap(); liveLocals.put(node, locals); } /** * There are three types of functions that can be defined. The first * is a function statement. This is a function appearing as a top-level * statement (i.e., not nested inside some other statement) in either a * script or a function. * * The second is a function expression, which is a function appearing in * an expression except for the third type, which is... * * The third type is a function expression where the expression is the * top-level expression in an expression statement. * * The three types of functions have different treatment and must be * distinguished. */ public static final int FUNCTION_STATEMENT = 1; public static final int FUNCTION_EXPRESSION = 2; public static final int FUNCTION_EXPRESSION_STATEMENT = 3; public int getFunctionType() { return itsFunctionType; } String functionName; int itsFunctionType; boolean itsNeedsActivation; boolean itsIgnoreDynamicScope; boolean itsIsGenerator; ArrayList generatorResumePoints; HashMap liveLocals; } yui-compressor-2.4.7/src/org/mozilla/javascript/Callable.java0000644000175000017500000000437411753547210024172 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov, igor@fastmail.fm * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * Generic notion of callable object that can execute some script-related code * upon request with specified values for script scope and this objects. */ public interface Callable { /** * Perform the call. * * @param cx the current Context for this thread * @param scope the scope to use to resolve properties. * @param thisObj the JavaScript this object * @param args the array of arguments * @return the result of the call */ public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args); } yui-compressor-2.4.7/src/org/mozilla/javascript/Delegator.java0000644000175000017500000002001311753547210024365 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Delegator.java, released * Sep 27, 2000. * * The Initial Developer of the Original Code is * Matthias Radestock. . * Portions created by the Initial Developer are Copyright (C) 2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * This is a helper class for implementing wrappers around Scriptable * objects. It implements the Function interface and delegates all * invocations to a delegee Scriptable object. The normal use of this * class involves creating a sub-class and overriding one or more of * the methods. * * A useful application is the implementation of interceptors, * pre/post conditions, debugging. * * @see Function * @see Scriptable * @author Matthias Radestock */ public class Delegator implements Function { protected Scriptable obj = null; /** * Create a Delegator prototype. * * This constructor should only be used for creating prototype * objects of Delegator. * * @see org.mozilla.javascript.Delegator#construct */ public Delegator() { } /** * Create a new Delegator that forwards requests to a delegee * Scriptable object. * * @param obj the delegee * @see org.mozilla.javascript.Scriptable */ public Delegator(Scriptable obj) { this.obj = obj; } /** * Crete new Delegator instance. * The default implementation calls this.getClass().newInstance(). * * @see #construct(Context cx, Scriptable scope, Object[] args) */ protected Delegator newInstance() { try { return this.getClass().newInstance(); } catch (Exception ex) { throw Context.throwAsScriptRuntimeEx(ex); } } /** * Retrieve the delegee. * * @return the delegee */ public Scriptable getDelegee() { return obj; } /** * Set the delegee. * * @param obj the delegee * @see org.mozilla.javascript.Scriptable */ public void setDelegee(Scriptable obj) { this.obj = obj; } /** * @see org.mozilla.javascript.Scriptable#getClassName */ public String getClassName() { return obj.getClassName(); } /** * @see org.mozilla.javascript.Scriptable#get(String, Scriptable) */ public Object get(String name, Scriptable start) { return obj.get(name,start); } /** * @see org.mozilla.javascript.Scriptable#get(int, Scriptable) */ public Object get(int index, Scriptable start) { return obj.get(index,start); } /** * @see org.mozilla.javascript.Scriptable#has(String, Scriptable) */ public boolean has(String name, Scriptable start) { return obj.has(name,start); } /** * @see org.mozilla.javascript.Scriptable#has(int, Scriptable) */ public boolean has(int index, Scriptable start) { return obj.has(index,start); } /** * @see org.mozilla.javascript.Scriptable#put(String, Scriptable, Object) */ public void put(String name, Scriptable start, Object value) { obj.put(name,start,value); } /** * @see org.mozilla.javascript.Scriptable#put(int, Scriptable, Object) */ public void put(int index, Scriptable start, Object value) { obj.put(index,start,value); } /** * @see org.mozilla.javascript.Scriptable#delete(String) */ public void delete(String name) { obj.delete(name); } /** * @see org.mozilla.javascript.Scriptable#delete(int) */ public void delete(int index) { obj.delete(index); } /** * @see org.mozilla.javascript.Scriptable#getPrototype */ public Scriptable getPrototype() { return obj.getPrototype(); } /** * @see org.mozilla.javascript.Scriptable#setPrototype */ public void setPrototype(Scriptable prototype) { obj.setPrototype(prototype); } /** * @see org.mozilla.javascript.Scriptable#getParentScope */ public Scriptable getParentScope() { return obj.getParentScope(); } /** * @see org.mozilla.javascript.Scriptable#setParentScope */ public void setParentScope(Scriptable parent) { obj.setParentScope(parent); } /** * @see org.mozilla.javascript.Scriptable#getIds */ public Object[] getIds() { return obj.getIds(); } /** * Note that this method does not get forwarded to the delegee if * the hint parameter is null, * ScriptRuntime.ScriptableClass or * ScriptRuntime.FunctionClass. Instead the object * itself is returned. * * @param hint the type hint * @return the default value * * @see org.mozilla.javascript.Scriptable#getDefaultValue */ public Object getDefaultValue(Class hint) { return (hint == null || hint == ScriptRuntime.ScriptableClass || hint == ScriptRuntime.FunctionClass) ? this : obj.getDefaultValue(hint); } /** * @see org.mozilla.javascript.Scriptable#hasInstance */ public boolean hasInstance(Scriptable instance) { return obj.hasInstance(instance); } /** * @see org.mozilla.javascript.Function#call */ public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { return ((Function)obj).call(cx,scope,thisObj,args); } /** * Note that if the delegee is null, * this method creates a new instance of the Delegator itself * rathert than forwarding the call to the * delegee. This permits the use of Delegator * prototypes. * * @param cx the current Context for this thread * @param scope an enclosing scope of the caller except * when the function is called from a closure. * @param args the array of arguments * @return the allocated object * * @see Function#construct(Context, Scriptable, Object[]) */ public Scriptable construct(Context cx, Scriptable scope, Object[] args) { if (obj == null) { //this little trick allows us to declare prototype objects for //Delegators Delegator n = newInstance(); Scriptable delegee; if (args.length == 0) { delegee = new NativeObject(); } else { delegee = ScriptRuntime.toObject(cx, scope, args[0]); } n.setDelegee(delegee); return n; } else { return ((Function)obj).construct(cx,scope,args); } } } yui-compressor-2.4.7/src/org/mozilla/javascript/Scriptable.java0000644000175000017500000003226011753547210024556 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * This is interface that all objects in JavaScript must implement. * The interface provides for the management of properties and for * performing conversions. *

* Host system implementors may find it easier to extend the ScriptableObject * class rather than implementing Scriptable when writing host objects. *

* There are many static methods defined in ScriptableObject that perform * the multiple calls to the Scriptable interface needed in order to * manipulate properties in prototype chains. *

* * @see org.mozilla.javascript.ScriptableObject * @author Norris Boyd * @author Nick Thompson * @author Brendan Eich */ public interface Scriptable { /** * Get the name of the set of objects implemented by this Java class. * This corresponds to the [[Class]] operation in ECMA and is used * by Object.prototype.toString() in ECMA.

* See ECMA 8.6.2 and 15.2.4.2. */ public String getClassName(); /** * Value returned from get if the property is not * found. */ public static final Object NOT_FOUND = UniqueTag.NOT_FOUND; /** * Get a named property from the object. * * Looks property up in this object and returns the associated value * if found. Returns NOT_FOUND if not found. * Note that this method is not expected to traverse the prototype * chain. This is different from the ECMA [[Get]] operation. * * Depending on the property selector, the runtime will call * this method or the form of get that takes an * integer: * * * * * * * * * * *
JavaScript codeJava code
a.b a.get("b", a)
a["foo"] a.get("foo", a)
a[3] a.get(3, a)
a["3"] a.get(3, a)
a[3.0] a.get(3, a)
a["3.0"] a.get("3.0", a)
a[1.1] a.get("1.1", a)
a[-4] a.get(-4, a)
*

* The values that may be returned are limited to the following: *

    *
  • java.lang.Boolean objects
  • *
  • java.lang.String objects
  • *
  • java.lang.Number objects
  • *
  • org.mozilla.javascript.Scriptable objects
  • *
  • null
  • *
  • The value returned by Context.getUndefinedValue()
  • *
  • NOT_FOUND
  • *
* @param name the name of the property * @param start the object in which the lookup began * @return the value of the property (may be null), or NOT_FOUND * @see org.mozilla.javascript.Context#getUndefinedValue */ public Object get(String name, Scriptable start); /** * Get a property from the object selected by an integral index. * * Identical to get(String, Scriptable) except that * an integral index is used to select the property. * * @param index the numeric index for the property * @param start the object in which the lookup began * @return the value of the property (may be null), or NOT_FOUND * @see org.mozilla.javascript.Scriptable#get(String,Scriptable) */ public Object get(int index, Scriptable start); /** * Indicates whether or not a named property is defined in an object. * * Does not traverse the prototype chain.

* * The property is specified by a String name * as defined for the get method.

* * @param name the name of the property * @param start the object in which the lookup began * @return true if and only if the named property is found in the object * @see org.mozilla.javascript.Scriptable#get(String, Scriptable) * @see org.mozilla.javascript.ScriptableObject#getProperty(Scriptable, String) */ public boolean has(String name, Scriptable start); /** * Indicates whether or not an indexed property is defined in an object. * * Does not traverse the prototype chain.

* * The property is specified by an integral index * as defined for the get method.

* * @param index the numeric index for the property * @param start the object in which the lookup began * @return true if and only if the indexed property is found in the object * @see org.mozilla.javascript.Scriptable#get(int, Scriptable) * @see org.mozilla.javascript.ScriptableObject#getProperty(Scriptable, int) */ public boolean has(int index, Scriptable start); /** * Sets a named property in this object. *

* The property is specified by a string name * as defined for get. *

* The possible values that may be passed in are as defined for * get. A class that implements this method may choose * to ignore calls to set certain properties, in which case those * properties are effectively read-only.

* For properties defined in a prototype chain, * use putProperty in ScriptableObject.

* Note that if a property a is defined in the prototype p * of an object o, then evaluating o.a = 23 will cause * set to be called on the prototype p with * o as the start parameter. * To preserve JavaScript semantics, it is the Scriptable * object's responsibility to modify o.

* This design allows properties to be defined in prototypes and implemented * in terms of getters and setters of Java values without consuming slots * in each instance.

*

* The values that may be set are limited to the following: *

    *
  • java.lang.Boolean objects
  • *
  • java.lang.String objects
  • *
  • java.lang.Number objects
  • *
  • org.mozilla.javascript.Scriptable objects
  • *
  • null
  • *
  • The value returned by Context.getUndefinedValue()
  • *

* Arbitrary Java objects may be wrapped in a Scriptable by first calling * Context.toObject. This allows the property of a JavaScript * object to contain an arbitrary Java object as a value.

* Note that has will be called by the runtime first before * set is called to determine in which object the * property is defined. * Note that this method is not expected to traverse the prototype chain, * which is different from the ECMA [[Put]] operation. * @param name the name of the property * @param start the object whose property is being set * @param value value to set the property to * @see org.mozilla.javascript.Scriptable#has(String, Scriptable) * @see org.mozilla.javascript.Scriptable#get(String, Scriptable) * @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, String, Object) * @see org.mozilla.javascript.Context#toObject(Object, Scriptable) */ public void put(String name, Scriptable start, Object value); /** * Sets an indexed property in this object. *

* The property is specified by an integral index * as defined for get.

* * Identical to put(String, Scriptable, Object) except that * an integral index is used to select the property. * * @param index the numeric index for the property * @param start the object whose property is being set * @param value value to set the property to * @see org.mozilla.javascript.Scriptable#has(int, Scriptable) * @see org.mozilla.javascript.Scriptable#get(int, Scriptable) * @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, int, Object) * @see org.mozilla.javascript.Context#toObject(Object, Scriptable) */ public void put(int index, Scriptable start, Object value); /** * Removes a property from this object. * This operation corresponds to the ECMA [[Delete]] except that * the no result is returned. The runtime will guarantee that this * method is called only if the property exists. After this method * is called, the runtime will call Scriptable.has to see if the * property has been removed in order to determine the boolean * result of the delete operator as defined by ECMA 11.4.1. *

* A property can be made permanent by ignoring calls to remove * it.

* The property is specified by a String name * as defined for get. *

* To delete properties defined in a prototype chain, * see deleteProperty in ScriptableObject. * @param name the identifier for the property * @see org.mozilla.javascript.Scriptable#get(String, Scriptable) * @see org.mozilla.javascript.ScriptableObject#deleteProperty(Scriptable, String) */ public void delete(String name); /** * Removes a property from this object. * * The property is specified by an integral index * as defined for get. *

* To delete properties defined in a prototype chain, * see deleteProperty in ScriptableObject. * * Identical to delete(String) except that * an integral index is used to select the property. * * @param index the numeric index for the property * @see org.mozilla.javascript.Scriptable#get(int, Scriptable) * @see org.mozilla.javascript.ScriptableObject#deleteProperty(Scriptable, int) */ public void delete(int index); /** * Get the prototype of the object. * @return the prototype */ public Scriptable getPrototype(); /** * Set the prototype of the object. * @param prototype the prototype to set */ public void setPrototype(Scriptable prototype); /** * Get the parent scope of the object. * @return the parent scope */ public Scriptable getParentScope(); /** * Set the parent scope of the object. * @param parent the parent scope to set */ public void setParentScope(Scriptable parent); /** * Get an array of property ids. * * Not all property ids need be returned. Those properties * whose ids are not returned are considered non-enumerable. * * @return an array of Objects. Each entry in the array is either * a java.lang.String or a java.lang.Number */ public Object[] getIds(); /** * Get the default value of the object with a given hint. * The hints are String.class for type String, Number.class for type * Number, Scriptable.class for type Object, and Boolean.class for * type Boolean.

* * A hint of null means "no hint". * * See ECMA 8.6.2.6. * * @param hint the type hint * @return the default value */ public Object getDefaultValue(Class hint); /** * The instanceof operator. * *

* The JavaScript code "lhs instanceof rhs" causes rhs.hasInstance(lhs) to * be called. * *

* The return value is implementation dependent so that embedded host objects can * return an appropriate value. See the JS 1.3 language documentation for more * detail. * *

This operator corresponds to the proposed EMCA [[HasInstance]] operator. * * @param instance The value that appeared on the LHS of the instanceof * operator * * @return an implementation dependent value */ public boolean hasInstance(Scriptable instance); } yui-compressor-2.4.7/src/org/mozilla/javascript/EcmaError.java0000644000175000017500000001146511753547210024351 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Roger Lawrence * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * The class of exceptions raised by the engine as described in * ECMA edition 3. See section 15.11.6 in particular. */ public class EcmaError extends RhinoException { static final long serialVersionUID = -6261226256957286699L; private String errorName; private String errorMessage; /** * Create an exception with the specified detail message. * * Errors internal to the JavaScript engine will simply throw a * RuntimeException. * * @param sourceName the name of the source responsible for the error * @param lineNumber the line number of the source * @param columnNumber the columnNumber of the source (may be zero if * unknown) * @param lineSource the source of the line containing the error (may be * null if unknown) */ EcmaError(String errorName, String errorMessage, String sourceName, int lineNumber, String lineSource, int columnNumber) { recordErrorOrigin(sourceName, lineNumber, lineSource, columnNumber); this.errorName = errorName; this.errorMessage = errorMessage; } /** * @deprecated EcmaError error instances should not be constructed * explicitly since they are generated by the engine. */ public EcmaError(Scriptable nativeError, String sourceName, int lineNumber, int columnNumber, String lineSource) { this("InternalError", ScriptRuntime.toString(nativeError), sourceName, lineNumber, lineSource, columnNumber); } @Override public String details() { return errorName+": "+errorMessage; } /** * Gets the name of the error. * * ECMA edition 3 defines the following * errors: EvalError, RangeError, ReferenceError, * SyntaxError, TypeError, and URIError. Additional error names * may be added in the future. * * See ECMA edition 3, 15.11.7.9. * * @return the name of the error. */ public String getName() { return errorName; } /** * Gets the message corresponding to the error. * * See ECMA edition 3, 15.11.7.10. * * @return an implementation-defined string describing the error. */ public String getErrorMessage() { return errorMessage; } /** * @deprecated Use {@link RhinoException#sourceName()} from the super class. */ public String getSourceName() { return sourceName(); } /** * @deprecated Use {@link RhinoException#lineNumber()} from the super class. */ public int getLineNumber() { return lineNumber(); } /** * @deprecated * Use {@link RhinoException#columnNumber()} from the super class. */ public int getColumnNumber() { return columnNumber(); } /** * @deprecated Use {@link RhinoException#lineSource()} from the super class. */ public String getLineSource() { return lineSource(); } /** * @deprecated * Always returns null. */ public Scriptable getErrorObject() { return null; } } yui-compressor-2.4.7/src/org/mozilla/javascript/Function.java0000644000175000017500000000624011753547210024252 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * This is interface that all functions in JavaScript must implement. * The interface provides for calling functions and constructors. * * @see org.mozilla.javascript.Scriptable * @author Norris Boyd */ public interface Function extends Scriptable, Callable { /** * Call the function. * * Note that the array of arguments is not guaranteed to have * length greater than 0. * * @param cx the current Context for this thread * @param scope the scope to execute the function relative to. This is * set to the value returned by getParentScope() except * when the function is called from a closure. * @param thisObj the JavaScript this object * @param args the array of arguments * @return the result of the call */ public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args); /** * Call the function as a constructor. * * This method is invoked by the runtime in order to satisfy a use * of the JavaScript new operator. This method is * expected to create a new object and return it. * * @param cx the current Context for this thread * @param scope an enclosing scope of the caller except * when the function is called from a closure. * @param args the array of arguments * @return the allocated object */ public Scriptable construct(Context cx, Scriptable scope, Object[] args); } yui-compressor-2.4.7/src/org/mozilla/javascript/GeneratedClassLoader.java0000644000175000017500000000445011753547210026501 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Igor Bukanov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ // API class package org.mozilla.javascript; /** * Interface to define classes from generated byte code. */ public interface GeneratedClassLoader { /** * Define a new Java class. * Classes created via this method should have the same class loader. * * @param name fully qualified class name * @param data class byte code * @return new class object */ public Class defineClass(String name, byte[] data); /** * Link the given class. * * @param cl Class instance returned from the previous call to * {@link #defineClass(String, byte[])} * @see java.lang.ClassLoader */ public void linkClass(Class cl); } yui-compressor-2.4.7/src/org/mozilla/javascript/NativeNumber.java0000644000175000017500000002125711753547210025071 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * Mike McCabe * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * This class implements the Number native object. * * See ECMA 15.7. * * @author Norris Boyd */ final class NativeNumber extends IdScriptableObject { static final long serialVersionUID = 3504516769741512101L; private static final Object NUMBER_TAG = "Number"; private static final int MAX_PRECISION = 100; static void init(Scriptable scope, boolean sealed) { NativeNumber obj = new NativeNumber(0.0); obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); } private NativeNumber(double number) { doubleValue = number; } @Override public String getClassName() { return "Number"; } @Override protected void fillConstructorProperties(IdFunctionObject ctor) { final int attr = ScriptableObject.DONTENUM | ScriptableObject.PERMANENT | ScriptableObject.READONLY; ctor.defineProperty("NaN", ScriptRuntime.NaNobj, attr); ctor.defineProperty("POSITIVE_INFINITY", ScriptRuntime.wrapNumber(Double.POSITIVE_INFINITY), attr); ctor.defineProperty("NEGATIVE_INFINITY", ScriptRuntime.wrapNumber(Double.NEGATIVE_INFINITY), attr); ctor.defineProperty("MAX_VALUE", ScriptRuntime.wrapNumber(Double.MAX_VALUE), attr); ctor.defineProperty("MIN_VALUE", ScriptRuntime.wrapNumber(Double.MIN_VALUE), attr); super.fillConstructorProperties(ctor); } @Override protected void initPrototypeId(int id) { String s; int arity; switch (id) { case Id_constructor: arity=1; s="constructor"; break; case Id_toString: arity=1; s="toString"; break; case Id_toLocaleString: arity=1; s="toLocaleString"; break; case Id_toSource: arity=0; s="toSource"; break; case Id_valueOf: arity=0; s="valueOf"; break; case Id_toFixed: arity=1; s="toFixed"; break; case Id_toExponential: arity=1; s="toExponential"; break; case Id_toPrecision: arity=1; s="toPrecision"; break; default: throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(NUMBER_TAG, id, s, arity); } @Override public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(NUMBER_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); if (id == Id_constructor) { double val = (args.length >= 1) ? ScriptRuntime.toNumber(args[0]) : 0.0; if (thisObj == null) { // new Number(val) creates a new Number object. return new NativeNumber(val); } // Number(val) converts val to a number value. return ScriptRuntime.wrapNumber(val); } // The rest of Number.prototype methods require thisObj to be Number if (!(thisObj instanceof NativeNumber)) throw incompatibleCallError(f); double value = ((NativeNumber)thisObj).doubleValue; switch (id) { case Id_toString: case Id_toLocaleString: { // toLocaleString is just an alias for toString for now int base = (args.length == 0) ? 10 : ScriptRuntime.toInt32(args[0]); return ScriptRuntime.numberToString(value, base); } case Id_toSource: return "(new Number("+ScriptRuntime.toString(value)+"))"; case Id_valueOf: return ScriptRuntime.wrapNumber(value); case Id_toFixed: return num_to(value, args, DToA.DTOSTR_FIXED, DToA.DTOSTR_FIXED, -20, 0); case Id_toExponential: return num_to(value, args, DToA.DTOSTR_STANDARD_EXPONENTIAL, DToA.DTOSTR_EXPONENTIAL, 0, 1); case Id_toPrecision: return num_to(value, args, DToA.DTOSTR_STANDARD, DToA.DTOSTR_PRECISION, 1, 0); default: throw new IllegalArgumentException(String.valueOf(id)); } } @Override public String toString() { return ScriptRuntime.numberToString(doubleValue, 10); } private static String num_to(double val, Object[] args, int zeroArgMode, int oneArgMode, int precisionMin, int precisionOffset) { int precision; if (args.length == 0) { precision = 0; oneArgMode = zeroArgMode; } else { /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */ precision = ScriptRuntime.toInt32(args[0]); if (precision < precisionMin || precision > MAX_PRECISION) { String msg = ScriptRuntime.getMessage1( "msg.bad.precision", ScriptRuntime.toString(args[0])); throw ScriptRuntime.constructError("RangeError", msg); } } StringBuffer sb = new StringBuffer(); DToA.JS_dtostr(sb, oneArgMode, precision + precisionOffset, val); return sb.toString(); } // #string_id_map# @Override protected int findPrototypeId(String s) { int id; // #generated# Last update: 2007-05-09 08:15:50 EDT L0: { id = 0; String X = null; int c; L: switch (s.length()) { case 7: c=s.charAt(0); if (c=='t') { X="toFixed";id=Id_toFixed; } else if (c=='v') { X="valueOf";id=Id_valueOf; } break L; case 8: c=s.charAt(3); if (c=='o') { X="toSource";id=Id_toSource; } else if (c=='t') { X="toString";id=Id_toString; } break L; case 11: c=s.charAt(0); if (c=='c') { X="constructor";id=Id_constructor; } else if (c=='t') { X="toPrecision";id=Id_toPrecision; } break L; case 13: X="toExponential";id=Id_toExponential; break L; case 14: X="toLocaleString";id=Id_toLocaleString; break L; } if (X!=null && X!=s && !X.equals(s)) id = 0; break L0; } // #/generated# return id; } private static final int Id_constructor = 1, Id_toString = 2, Id_toLocaleString = 3, Id_toSource = 4, Id_valueOf = 5, Id_toFixed = 6, Id_toExponential = 7, Id_toPrecision = 8, MAX_PROTOTYPE_ID = 8; // #/string_id_map# private double doubleValue; } yui-compressor-2.4.7/src/org/mozilla/javascript/WrappedException.java0000644000175000017500000000565111753547210025753 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Norris Boyd * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; /** * A wrapper for runtime exceptions. * * Used by the JavaScript runtime to wrap and propagate exceptions that occur * during runtime. * * @author Norris Boyd */ public class WrappedException extends EvaluatorException { static final long serialVersionUID = -1551979216966520648L; /** * @see Context#throwAsScriptRuntimeEx(Throwable e) */ public WrappedException(Throwable exception) { super("Wrapped "+exception.toString()); this.exception = exception; Kit.initCause(this, exception); int[] linep = { 0 }; String sourceName = Context.getSourcePositionFromStack(linep); int lineNumber = linep[0]; if (sourceName != null) { initSourceName(sourceName); } if (lineNumber != 0) { initLineNumber(lineNumber); } } /** * Get the wrapped exception. * * @return the exception that was presented as a argument to the * constructor when this object was created */ public Throwable getWrappedException() { return exception; } /** * @deprecated Use {@link #getWrappedException()} instead. */ public Object unwrap() { return getWrappedException(); } private Throwable exception; } yui-compressor-2.4.7/src/org/mozilla/javascript/TokenStream.java0000644000175000017500000014542611753547210024733 0ustar drazzibdrazzib/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * 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 Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Roger Lawrence * Mike McCabe * Igor Bukanov * Ethan Hugg * Bob Jervis * Terry Lucas * Milen Nankov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.javascript; import java.io.*; /** * This class implements the JavaScript scanner. * * It is based on the C source files jsscan.c and jsscan.h * in the jsref package. * * @see org.mozilla.javascript.Parser * * @author Mike McCabe * @author Brendan Eich */ class TokenStream { /* * For chars - because we need something out-of-range * to check. (And checking EOF by exception is annoying.) * Note distinction from EOF token type! */ private final static int EOF_CHAR = -1; TokenStream(Parser parser, Reader sourceReader, String sourceString, int lineno) { this.parser = parser; this.lineno = lineno; if (sourceReader != null) { if (sourceString != null) Kit.codeBug(); this.sourceReader = sourceReader; this.sourceBuffer = new char[512]; this.sourceEnd = 0; } else { if (sourceString == null) Kit.codeBug(); this.sourceString = sourceString; this.sourceEnd = sourceString.length(); } this.sourceCursor = 0; } /* This function uses the cached op, string and number fields in * TokenStream; if getToken has been called since the passed token * was scanned, the op or string printed may be incorrect. */ String tokenToString(int token) { if (Token.printTrees) { String name = Token.name(token); switch (token) { case Token.STRING: case Token.REGEXP: case Token.NAME: return name + " `" + this.string + "'"; case Token.NUMBER: return "NUMBER " + this.number; } return name; } return ""; } static boolean isKeyword(String s) { return Token.EOF != stringToKeyword(s); } private static int stringToKeyword(String name) { // #string_id_map# // The following assumes that Token.EOF == 0 final int Id_break = Token.BREAK, Id_case = Token.CASE, Id_continue = Token.CONTINUE, Id_default = Token.DEFAULT, Id_delete = Token.DELPROP, Id_do = Token.DO, Id_else = Token.ELSE, Id_export = Token.EXPORT, Id_false = Token.FALSE, Id_for = Token.FOR, Id_function = Token.FUNCTION, Id_if = Token.IF, Id_in = Token.IN, Id_let = Token.LET, Id_new = Token.NEW, Id_null = Token.NULL, Id_return = Token.RETURN, Id_switch = Token.SWITCH, Id_this = Token.THIS, Id_true = Token.TRUE, Id_typeof = Token.TYPEOF, Id_var = Token.VAR, Id_void = Token.VOID, Id_while = Token.WHILE, Id_with = Token.WITH, Id_yield = Token.YIELD, // the following are #ifdef RESERVE_JAVA_KEYWORDS in jsscan.c Id_abstract = Token.RESERVED, Id_boolean = Token.RESERVED, Id_byte = Token.RESERVED, Id_catch = Token.CATCH, Id_char = Token.RESERVED, Id_class = Token.RESERVED, Id_const = Token.CONST, Id_debugger = Token.DEBUGGER, Id_double = Token.RESERVED, Id_enum = Token.RESERVED, Id_extends = Token.RESERVED, Id_final = Token.RESERVED, Id_finally = Token.FINALLY, Id_float = Token.RESERVED, Id_goto = Token.RESERVED, Id_implements = Token.RESERVED, Id_import = Token.IMPORT, Id_instanceof = Token.INSTANCEOF, Id_int = Token.RESERVED, Id_interface = Token.RESERVED, Id_long = Token.RESERVED, Id_native = Token.RESERVED, Id_package = Token.RESERVED, Id_private = Token.RESERVED, Id_protected = Token.RESERVED, Id_public = Token.RESERVED, Id_short = Token.RESERVED, Id_static = Token.RESERVED, Id_super = Token.RESERVED, Id_synchronized = Token.RESERVED, Id_throw = Token.THROW, Id_throws = Token.RESERVED, Id_transient = Token.RESERVED, Id_try = Token.TRY, Id_volatile = Token.RESERVED; int id; String s = name; // #generated# Last update: 2007-04-18 13:53:30 PDT L0: { id = 0; String X = null; int c; L: switch (s.length()) { case 2: c=s.charAt(1); if (c=='f') { if (s.charAt(0)=='i') {id=Id_if; break L0;} } else if (c=='n') { if (s.charAt(0)=='i') {id=Id_in; break L0;} } else if (c=='o') { if (s.charAt(0)=='d') {id=Id_do; break L0;} } break L; case 3: switch (s.charAt(0)) { case 'f': if (s.charAt(2)=='r' && s.charAt(1)=='o') {id=Id_for; break L0;} break L; case 'i': if (s.charAt(2)=='t' && s.charAt(1)=='n') {id=Id_int; break L0;} break L; case 'l': if (s.charAt(2)=='t' && s.charAt(1)=='e') {id=Id_let; break L0;} break L; case 'n': if (s.charAt(2)=='w' && s.charAt(1)=='e') {id=Id_new; break L0;} break L; case 't': if (s.charAt(2)=='y' && s.charAt(1)=='r') {id=Id_try; break L0;} break L; case 'v': if (s.charAt(2)=='r' && s.charAt(1)=='a') {id=Id_var; break L0;} break L; } break L; case 4: switch (s.charAt(0)) { case 'b': X="byte";id=Id_byte; break L; case 'c': c=s.charAt(3); if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='a') {id=Id_case; break L0;} } else if (c=='r') { if (s.charAt(2)=='a' && s.charAt(1)=='h') {id=Id_char; break L0;} } break L; case 'e': c=s.charAt(3); if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='l') {id=Id_else; break L0;} } else if (c=='m') { if (s.charAt(2)=='u' && s.charAt(1)=='n') {id=Id_enum; break L0;} } break L; case 'g': X="goto";id=Id_goto; break L; case 'l': X="long";id=Id_long; break L; case 'n': X="null";id=Id_null; break L; case 't': c=s.charAt(3); if (c=='e') { if (s.charAt(2)=='u' && s.charAt(1)=='r') {id=Id_true; break L0;} } else if (c=='s') { if (s.charAt(2)=='i' && s.charAt(1)=='h') {id=Id_this; break L0;} } break L; case 'v': X="void";id=Id_void; break L; case 'w': X="with";id=Id_with; break L; } break L; case 5: switch (s.charAt(2)) { case 'a': X="class";id=Id_class; break L; case 'e': c=s.charAt(0); if (c=='b') { X="break";id=Id_break; } else if (c=='y') { X="yield";id=Id_yield; } break L; case 'i': X="while";id=Id_while; break L; case 'l': X="false";id=Id_false; break L; case 'n': c=s.charAt(0); if (c=='c') { X="const";id=Id_const; } else if (c=='f') { X="final";id=Id_final; } break L; case 'o': c=s.charAt(0); if (c=='f') { X="float";id=Id_float; } else if (c=='s') { X="short";id=Id_short; } break L; case 'p': X="super";id=Id_super; break L; case 'r': X="throw";id=Id_throw; break L; case 't': X="catch";id=Id_catch; break L; } break L; case 6: switch (s.charAt(1)) { case 'a': X="native";id=Id_native; break L; case 'e': c=s.charAt(0); if (c=='d') { X="delete";id=Id_delete; } else if (c=='r') { X="return";id=Id_return; } break L; case 'h': X="throws";id=Id_throws; break L; case 'm': X="import";id=Id_import; break L; case 'o': X="double";id=Id_double; break L; case 't': X="static";id=Id_static; break L; case 'u': X="public";id=Id_public; break L; case 'w': X="switch";id=Id_switch; break L; case 'x': X="export";id=Id_export; break L; case 'y': X="typeof";id=Id_typeof; break L; } break L; case 7: switch (s.charAt(1)) { case 'a': X="package";id=Id_package; break L; case 'e': X="default";id=Id_default; break L; case 'i': X="finally";id=Id_finally; break L; case 'o': X="boolean";id=Id_boolean; break L; case 'r': X="private";id=Id_private; break L; case 'x': X="extends";id=Id_extends; break L; } break L; case 8: switch (s.charAt(0)) { case 'a': X="abstract";id=Id_abstract; break L; case 'c': X="continue";id=Id_continue; break L; case 'd': X="debugger";id=Id_debugger; break L; case 'f': X="function";id=Id_function; break L; case 'v': X="volatile";id=Id_volatile; break L; } break L; case 9: c=s.charAt(0); if (c=='i') { X="interface";id=Id_interface; } else if (c=='p') { X="protected";id=Id_protected; } else if (c=='t') { X="transient";id=Id_transient; } break L; case 10: c=s.charAt(1); if (c=='m') { X="implements";id=Id_implements; } else if (c=='n') { X="instanceof";id=Id_instanceof; } break L; case 12: X="synchronized";id=Id_synchronized; break L; } if (X!=null && X!=s && !X.equals(s)) id = 0; } // #/generated# // #/string_id_map# if (id == 0) { return Token.EOF; } return id & 0xff; } final int getLineno() { return lineno; } final String getString() { return string; } final double getNumber() { return number; } final boolean eof() { return hitEOF; } final int getToken() throws IOException { int c; retry: for (;;) { // Eat whitespace, possibly sensitive to newlines. for (;;) { c = getChar(); if (c == EOF_CHAR) { return Token.EOF; } else if (c == '\n') { dirtyLine = false; return Token.EOL; } else if (!isJSSpace(c)) { if (c != '-') { dirtyLine = true; } break; } } if (c == '@') return Token.XMLATTR; // identifier/keyword/instanceof? // watch out for starting with a boolean identifierStart; boolean isUnicodeEscapeStart = false; if (c == '\\') { c = getChar(); if (c == 'u') { identifierStart = true; isUnicodeEscapeStart = true; stringBufferTop = 0; } else { identifierStart = false; ungetChar(c); c = '\\'; } } else { identifierStart = Character.isJavaIdentifierStart((char)c); if (identifierStart) { stringBufferTop = 0; addToString(c); } } if (identifierStart) { boolean containsEscape = isUnicodeEscapeStart; for (;;) { if (isUnicodeEscapeStart) { // strictly speaking we should probably push-back // all the bad characters if the uXXXX // sequence is malformed. But since there isn't a // correct context(is there?) for a bad Unicode // escape sequence in an identifier, we can report // an error here. int escapeVal = 0; for (int i = 0; i != 4; ++i) { c = getChar(); escapeVal = Kit.xDigitToInt(c, escapeVal); // Next check takes care about c < 0 and bad escape if (escapeVal < 0) { break; } } if (escapeVal < 0) { parser.addError("msg.invalid.escape"); return Token.ERROR; } addToString(escapeVal); isUnicodeEscapeStart = false; } else { c = getChar(); if (c == '\\') { c = getChar(); if (c == 'u') { isUnicodeEscapeStart = true; containsEscape = true; } else { parser.addError("msg.illegal.character"); return Token.ERROR; } } else { if (c == EOF_CHAR || !Character.isJavaIdentifierPart((char)c)) { break; } addToString(c); } } } ungetChar(c); String str = getStringFromBuffer(); if (!containsEscape) { // OPT we shouldn't have to make a string (object!) to // check if it's a keyword. // Return the corresponding token if it's a keyword int result = stringToKeyword(str); if (result != Token.EOF) { if ((result == Token.LET || result == Token.YIELD) && parser.compilerEnv.getLanguageVersion() < Context.VERSION_1_7) { // LET and YIELD are tokens only in 1.7 and later string = result == Token.LET ? "let" : "yield"; result = Token.NAME; } if (result != Token.RESERVED) { return result; } else if (!parser.compilerEnv. isReservedKeywordAsIdentifier()) { return result; } else { // If implementation permits to use future reserved // keywords in violation with the EcmaScript, // treat it as name but issue warning parser.addWarning("msg.reserved.keyword", str); } } } this.string = (String)allStrings.intern(str); return Token.NAME; } // is it a number? if (isDigit(c) || (c == '.' && isDigit(peekChar()))) { stringBufferTop = 0; int base = 10; if (c == '0') { c = getChar(); if (c == 'x' || c == 'X') { base = 16; c = getChar(); } else if (isDigit(c)) { base = 8; } else { addToString('0'); } } if (base == 16) { while (0 <= Kit.xDigitToInt(c, 0)) { addToString(c); c = getChar(); } } else { while ('0' <= c && c <= '9') { /* * We permit 08 and 09 as decimal numbers, which * makes our behavior a superset of the ECMA * numeric grammar. We might not always be so * permissive, so we warn about it. */ if (base == 8 && c >= '8') { parser.addWarning("msg.bad.octal.literal", c == '8' ? "8" : "9"); base = 10; } addToString(c); c = getChar(); } } boolean isInteger = true; if (base == 10 && (c == '.' || c == 'e' || c == 'E')) { isInteger = false; if (c == '.') { do { addToString(c); c = getChar(); } while (isDigit(c)); } if (c == 'e' || c == 'E') { addToString(c); c = getChar(); if (c == '+' || c == '-') { addToString(c); c = getChar(); } if (!isDigit(c)) { parser.addError("msg.missing.exponent"); return Token.ERROR; } do { addToString(c); c = getChar(); } while (isDigit(c)); } } ungetChar(c); String numString = getStringFromBuffer(); double dval; if (base == 10 && !isInteger) { try { // Use Java conversion to number from string... dval = Double.valueOf(numString).doubleValue(); } catch (NumberFormatException ex) { parser.addError("msg.caught.nfe"); return Token.ERROR; } } else { dval = ScriptRuntime.stringToNumber(numString, 0, base); } this.number = dval; return Token.NUMBER; } // is it a string? if (c == '"' || c == '\'') { // We attempt to accumulate a string the fast way, by // building it directly out of the reader. But if there // are any escaped characters in the string, we revert to // building it out of a StringBuffer. int quoteChar = c; stringBufferTop = 0; c = getChar(); strLoop: while (c != quoteChar) { if (c == '\n' || c == EOF_CHAR) { ungetChar(c); parser.addError("msg.unterminated.string.lit"); return Token.ERROR; } if (c == '\\') { // We've hit an escaped character int escapeVal; c = getChar(); switch (c) { case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; // \v a late addition to the ECMA spec, // it is not in Java, so use 0xb case 'v': c = 0xb; break; case 'u': // Get 4 hex digits; if the u escape is not // followed by 4 hex digits, use 'u' + the // literal character sequence that follows. int escapeStart = stringBufferTop; addToString('u'); escapeVal = 0; for (int i = 0; i != 4; ++i) { c = getChar(); escapeVal = Kit.xDigitToInt(c, escapeVal); if (escapeVal < 0) { continue strLoop; } addToString(c); } // prepare for replace of stored 'u' sequence // by escape value stringBufferTop = escapeStart; c = escapeVal; break; case 'x': // Get 2 hex digits, defaulting to 'x'+literal // sequence, as above. c = getChar(); escapeVal = Kit.xDigitToInt(c, 0); if (escapeVal < 0) { addToString('x'); continue strLoop; } else { int c1 = c; c = getChar(); escapeVal = Kit.xDigitToInt(c, escapeVal); if (escapeVal < 0) { addToString('x'); addToString(c1); continue strLoop; } else { // got 2 hex digits c = escapeVal; } } break; case '\n': // Remove line terminator after escape to follow // SpiderMonkey and C/C++ c = getChar(); continue strLoop; default: if ('0' <= c && c < '8') { int val = c - '0'; c = getChar(); if ('0' <= c && c < '8') { val = 8 * val + c - '0'; c = getChar(); if ('0' <= c && c < '8' && val <= 037) { // c is 3rd char of octal sequence only // if the resulting val <= 0377 val = 8 * val + c - '0'; c = getChar(); } } ungetChar(c); c = val; } } } addToString(c); c = getChar(); } String str = getStringFromBuffer(); this.string = (String)allStrings.intern(str); return Token.STRING; } switch (c) { case ';': return Token.SEMI; case '[': return Token.LB; case ']': return Token.RB; case '{': return Token.LC; case '}': return Token.RC; case '(': return Token.LP; case ')': return Token.RP; case ',': return Token.COMMA; case '?': return Token.HOOK; case ':': if (matchChar(':')) { return Token.COLONCOLON; } else { return Token.COLON; } case '.': if (matchChar('.')) { return Token.DOTDOT; } else if (matchChar('(')) { return Token.DOTQUERY; } else { return Token.DOT; } case '|': if (matchChar('|')) { return Token.OR; } else if (matchChar('=')) { return Token.ASSIGN_BITOR; } else { return Token.BITOR; } case '^': if (matchChar('=')) { return Token.ASSIGN_BITXOR; } else { return Token.BITXOR; } case '&': if (matchChar('&')) { return Token.AND; } else if (matchChar('=')) { return Token.ASSIGN_BITAND; } else { return Token.BITAND; } case '=': if (matchChar('=')) { if (matchChar('=')) return Token.SHEQ; else return Token.EQ; } else { return Token.ASSIGN; } case '!': if (matchChar('=')) { if (matchChar('=')) return Token.SHNE; else return Token.NE; } else { return Token.NOT; } case '<': /* NB:treat HTML begin-comment as comment-till-eol */ if (matchChar('!')) { if (matchChar('-')) { if (matchChar('-')) { skipLine(); continue retry; } ungetCharIgnoreLineEnd('-'); } ungetCharIgnoreLineEnd('!'); } if (matchChar('<')) { if (matchChar('=')) { return Token.ASSIGN_LSH; } else { return Token.LSH; } } else { if (matchChar('=')) { return Token.LE; } else { return Token.LT; } } case '>': if (matchChar('>')) { if (matchChar('>')) { if (matchChar('=')) { return Token.ASSIGN_URSH; } else { return Token.URSH; } } else { if (matchChar('=')) { return Token.ASSIGN_RSH; } else { return Token.RSH; } } } else { if (matchChar('=')) { return Token.GE; } else { return Token.GT; } } case '*': if (matchChar('=')) { return Token.ASSIGN_MUL; } else { return Token.MUL; } case '/': // is it a // comment? if (matchChar('/')) { skipLine(); continue retry; } if (matchChar('*')) { boolean lookForSlash = false; for (;;) { c = getChar(); if (c == EOF_CHAR) { parser.addError("msg.unterminated.comment"); return Token.ERROR; } else if (c == '*') { lookForSlash = true; } else if (c == '/') { if (lookForSlash) { continue retry; } } else { lookForSlash = false; } } } if (matchChar('=')) { return Token.ASSIGN_DIV; } else { return Token.DIV; } case '%': if (matchChar('=')) { return Token.ASSIGN_MOD; } else { return Token.MOD; } case '~': return Token.BITNOT; case '+': if (matchChar('=')) { return Token.ASSIGN_ADD; } else if (matchChar('+')) { return Token.INC; } else { return Token.ADD; } case '-': if (matchChar('=')) { c = Token.ASSIGN_SUB; } else if (matchChar('-')) { if (!dirtyLine) { // treat HTML end-comment after possible whitespace // after line start as comment-utill-eol if (matchChar('>')) { skipLine(); continue retry; } } c = Token.DEC; } else { c = Token.SUB; } dirtyLine = true; return c; default: parser.addError("msg.illegal.character"); return Token.ERROR; } } } private static boolean isAlpha(int c) { // Use 'Z' < 'a' if (c <= 'Z') { return 'A' <= c; } else { return 'a' <= c && c <= 'z'; } } static boolean isDigit(int c) { return '0' <= c && c <= '9'; } /* As defined in ECMA. jsscan.c uses C isspace() (which allows * \v, I think.) note that code in getChar() implicitly accepts * '\r' == \u000D as well. */ static boolean isJSSpace(int c) { if (c <= 127) { return c == 0x20 || c == 0x9 || c == 0xC || c == 0xB; } else { return c == 0xA0 || Character.getType((char)c) == Character.SPACE_SEPARATOR; } } private static boolean isJSFormatChar(int c) { return c > 127 && Character.getType((char)c) == Character.FORMAT; } /** * Parser calls the method when it gets / or /= in literal context. */ void readRegExp(int startToken) throws IOException { stringBufferTop = 0; if (startToken == Token.ASSIGN_DIV) { // Miss-scanned /= addToString('='); } else { if (startToken != Token.DIV) Kit.codeBug(); } boolean inCharSet = false; // true if inside a '['..']' pair int c; while ((c = getChar()) != '/' || inCharSet) { if (c == '\n' || c == EOF_CHAR) { ungetChar(c); throw parser.reportError("msg.unterminated.re.lit"); } if (c == '\\') { addToString(c); c = getChar(); } else if (c == '[') { inCharSet = true; } else if (c == ']') { inCharSet = false; } addToString(c); } int reEnd = stringBufferTop; while (true) { if (matchChar('g')) addToString('g'); else if (matchChar('i')) addToString('i'); else if (matchChar('m')) addToString('m'); else break; } if (isAlpha(peekChar())) { throw parser.reportError("msg.invalid.re.flag"); } this.string = new String(stringBuffer, 0, reEnd); this.regExpFlags = new String(stringBuffer, reEnd, stringBufferTop - reEnd); } boolean isXMLAttribute() { return xmlIsAttribute; } int getFirstXMLToken() throws IOException { xmlOpenTagsCount = 0; xmlIsAttribute = false; xmlIsTagContent = false; ungetChar('<'); return getNextXMLToken(); } int getNextXMLToken() throws IOException { stringBufferTop = 0; // remember the XML for (int c = getChar(); c != EOF_CHAR; c = getChar()) { if (xmlIsTagContent) { switch (c) { case '>': addToString(c); xmlIsTagContent = false; xmlIsAttribute = false; break; case '/': addToString(c); if (peekChar() == '>') { c = getChar(); addToString(c); xmlIsTagContent = false; xmlOpenTagsCount--; } break; case '{': ungetChar(c); this.string = getStringFromBuffer(); return Token.XML; case '\'': case '"': addToString(c); if (!readQuotedString(c)) return Token.ERROR; break; case '=': addToString(c); xmlIsAttribute = true; break; case ' ': case '\t': case '\r': case '\n': addToString(c); break; default: addToString(c); xmlIsAttribute = false; break; } if (!xmlIsTagContent && xmlOpenTagsCount == 0) { this.string = getStringFromBuffer(); return Token.XMLEND; } } else { switch (c) { case '<': addToString(c); c = peekChar(); switch (c) { case '!': c = getChar(); // Skip ! addToString(c); c = peekChar(); switch (c) { case '-': c = getChar(); // Skip - addToString(c); c = getChar(); if (c == '-') { addToString(c); if(!readXmlComment()) return Token.ERROR; } else { // throw away the string in progress stringBufferTop = 0; this.string = null; parser.addError("msg.XML.bad.form"); return Token.ERROR; } break; case '[': c = getChar(); // Skip [ addToString(c); if (getChar() == 'C' && getChar() == 'D' && getChar() == 'A' && getChar() == 'T' && getChar() == 'A' && getChar() == '[') { addToString('C'); addToString('D'); addToString('A'); addToString('T'); addToString('A'); addToString('['); if (!readCDATA()) return Token.ERROR; } else { // throw away the string in progress stringBufferTop = 0; this.string = null; parser.addError("msg.XML.bad.form"); return Token.ERROR; } break; default: if(!readEntity()) return Token.ERROR; break; } break; case '?': c = getChar(); // Skip ? addToString(c); if (!readPI()) return Token.ERROR; break; case '/': // End tag c = getChar(); // Skip / addToString(c); if (xmlOpenTagsCount == 0) { // throw away the string in progress stringBufferTop = 0; this.string = null; parser.addError("msg.XML.bad.form"); return Token.ERROR; } xmlIsTagContent = true; xmlOpenTagsCount--; break; default: // Start tag xmlIsTagContent = true; xmlOpenTagsCount++; break; } break; case '{': ungetChar(c); this.string = getStringFromBuffer(); return Token.XML; default: addToString(c); break; } } } stringBufferTop = 0; // throw away the string in progress this.string = null; parser.addError("msg.XML.bad.form"); return Token.ERROR; } /** * */ private boolean readQuotedString(int quote) throws IOException { for (int c = getChar(); c != EOF_CHAR; c = getChar()) { addToString(c); if (c == quote) return true; } stringBufferTop = 0; // throw away the string in progress this.string = null; parser.addError("msg.XML.bad.form"); return false; } /** * */ private boolean readXmlComment() throws IOException { for (int c = getChar(); c != EOF_CHAR;) { addToString(c); if (c == '-' && peekChar() == '-') { c = getChar(); addToString(c); if (peekChar() == '>') { c = getChar(); // Skip > addToString(c); return true; } else { continue; } } c = getChar(); } stringBufferTop = 0; // throw away the string in progress this.string = null; parser.addError("msg.XML.bad.form"); return false; } /** * */ private boolean readCDATA() throws IOException { for (int c = getChar(); c != EOF_CHAR;) { addToString(c); if (c == ']' && peekChar() == ']') { c = getChar(); addToString(c); if (peekChar() == '>') { c = getChar(); // Skip > addToString(c); return true; } else { continue; } } c = getChar(); } stringBufferTop = 0; // throw away the string in progress this.string = null; parser.addError("msg.XML.bad.form"); return false; } /** * */ private boolean readEntity() throws IOException { int declTags = 1; for (int c = getChar(); c != EOF_CHAR; c = getChar()) { addToString(c); switch (c) { case '<': declTags++; break; case '>': declTags--; if (declTags == 0) return true; break; } } stringBufferTop = 0; // throw away the string in progress this.string = null; parser.addError("msg.XML.bad.form"); return false; } /** * */ private boolean readPI() throws IOException { for (int c = getChar(); c != EOF_CHAR; c = getChar()) { addToString(c); if (c == '?' && peekChar() == '>') { c = getChar(); // Skip > addToString(c); return true; } } stringBufferTop = 0; // throw away the string in progress this.string = null; parser.addError("msg.XML.bad.form"); return false; } private String getStringFromBuffer() { return new String(stringBuffer, 0, stringBufferTop); } private void addToString(int c) { int N = stringBufferTop; if (N == stringBuffer.length) { char[] tmp = new char[stringBuffer.length * 2]; System.arraycopy(stringBuffer, 0, tmp, 0, N); stringBuffer = tmp; } stringBuffer[N] = (char)c; stringBufferTop = N + 1; } private void ungetChar(int c) { // can not unread past across line boundary if (ungetCursor != 0 && ungetBuffer[ungetCursor - 1] == '\n') Kit.codeBug(); ungetBuffer[ungetCursor++] = c; } private boolean matchChar(int test) throws IOException { int c = getCharIgnoreLineEnd(); if (c == test) { return true; } else { ungetCharIgnoreLineEnd(c); return false; } } private int peekChar() throws IOException { int c = getChar(); ungetChar(c); return c; } private int getChar() throws IOException { if (ungetCursor != 0) { return ungetBuffer[--ungetCursor]; } for(;;) { int c; if (sourceString != null) { if (sourceCursor == sourceEnd) { hitEOF = true; return EOF_CHAR; } c = sourceString.charAt(sourceCursor++); } else { if (sourceCursor == sourceEnd) { if (!fillSourceBuffer()) { hitEOF = true; return EOF_CHAR; } } c = sourceBuffer[sourceCursor++]; } if (lineEndChar >= 0) { if (lineEndChar == '\r' && c == '\n') { lineEndChar = '\n'; continue; } lineEndChar = -1; lineStart = sourceCursor - 1; lineno++; } if (c <= 127) { if (c == '\n' || c == '\r') { lineEndChar = c; c = '\n'; } } else { if (isJSFormatChar(c)) { continue; } if (ScriptRuntime.isJSLineTerminator(c)) { lineEndChar = c; c = '\n'; } } return c; } } private int getCharIgnoreLineEnd() throws IOException { if (ungetCursor != 0) { return ungetBuffer[--ungetCursor]; } for(;;) { int c; if (sourceString != null) { if (sourceCursor == sourceEnd) { hitEOF = true; return EOF_CHAR; } c = sourceString.charAt(sourceCursor++); } else { if (sourceCursor == sourceEnd) { if (!fillSourceBuffer()) { hitEOF = true; return EOF_CHAR; } } c = sourceBuffer[sourceCursor++]; } if (c <= 127) { if (c == '\n' || c == '\r') { lineEndChar = c; c = '\n'; } } else { if (isJSFormatChar(c)) { continue; } if (ScriptRuntime.isJSLineTerminator(c)) { lineEndChar = c; c = '\n'; } } return c; } } private void ungetCharIgnoreLineEnd(int c) { ungetBuffer[ungetCursor++] = c; } private void skipLine() throws IOException { // skip to end of line int c; while ((c = getChar()) != EOF_CHAR && c != '\n') { } ungetChar(c); } final int getOffset() { int n = sourceCursor - lineStart; if (lineEndChar >= 0) { --n; } return n; } final String getLine() { if (sourceString != null) { // String case int lineEnd = sourceCursor; if (lineEndChar >= 0) { --lineEnd; } else { for (; lineEnd != sourceEnd; ++lineEnd) { int c = sourceString.charAt(lineEnd); if (ScriptRuntime.isJSLineTerminator(c)) { break; } } } return sourceString.substring(lineStart, lineEnd); } else { // Reader case int lineLength = sourceCursor - lineStart; if (lineEndChar >= 0) { --lineLength; } else { // Read until the end of line for (;; ++lineLength) { int i = lineStart + lineLength; if (i == sourceEnd) { try { if (!fillSourceBuffer()) { break; } } catch (IOException ioe) { // ignore it, we're already displaying an error... break; } // i recalculuation as fillSourceBuffer can move saved // line buffer and change lineStart i = lineStart + lineLength; } int c = sourceBuffer[i]; if (ScriptRuntime.isJSLineTerminator(c)) { break; } } } return new String(sourceBuffer, lineStart, lineLength); } } private boolean fillSourceBuffer() throws IOException { if (sourceString != null) Kit.codeBug(); if (sourceEnd == sourceBuffer.length) { if (lineStart != 0) { System.arraycopy(sourceBuffer, lineStart, sourceBuffer, 0, sourceEnd - lineStart); sourceEnd -= lineStart; sourceCursor -= lineStart; lineStart = 0; } else { char[] tmp = new char[sourceBuffer.length * 2]; System.arraycopy(sourceBuffer, 0, tmp, 0, sourceEnd); sourceBuffer = tmp; } } int n = sourceReader.read(sourceBuffer, sourceEnd, sourceBuffer.length - sourceEnd); if (n < 0) { return false; } sourceEnd += n; return true; } // stuff other than whitespace since start of line private boolean dirtyLine; String regExpFlags; // Set this to an initial non-null value so that the Parser has // something to retrieve even if an error has occurred and no // string is found. Fosters one class of error, but saves lots of // code. private String string = ""; private double number; private char[] stringBuffer = new char[128]; private int stringBufferTop; private ObjToIntMap allStrings = new ObjToIntMap(50); // Room to backtrace from to < on failed match of the last - in "); } result.append(token.getValue()); if (i == offset - 1) { result.append(" <--- "); } } return result.toString(); } private void warn(String message, boolean showDebugString) { if (verbose) { if (showDebugString) { message = message + "\n" + getDebugString(10); } logger.warning(message, null, -1, null, -1); } } private void parseFunctionDeclaration() { String symbol; JavaScriptToken token; ScriptOrFnScope currentScope, fnScope; JavaScriptIdentifier identifier; currentScope = getCurrentScope(); token = consumeToken(); if (token.getType() == Token.NAME) { if (mode == BUILDING_SYMBOL_TREE) { // Get the name of the function and declare it in the current scope. symbol = token.getValue(); if (currentScope.getIdentifier(symbol) != null) { warn("The function " + symbol + " has already been declared in the same scope...", true); } currentScope.declareIdentifier(symbol); } token = consumeToken(); } assert token.getType() == Token.LP; if (mode == BUILDING_SYMBOL_TREE) { fnScope = new ScriptOrFnScope(braceNesting, currentScope); indexedScopes.put(new Integer(offset), fnScope); } else { fnScope = (ScriptOrFnScope) indexedScopes.get(new Integer(offset)); } // Parse function arguments. int argpos = 0; while ((token = consumeToken()).getType() != Token.RP) { assert token.getType() == Token.NAME || token.getType() == Token.COMMA; if (token.getType() == Token.NAME && mode == BUILDING_SYMBOL_TREE) { symbol = token.getValue(); identifier = fnScope.declareIdentifier(symbol); if (symbol.equals("$super") && argpos == 0) { // Exception for Prototype 1.6... identifier.preventMunging(); } argpos++; } } token = consumeToken(); assert token.getType() == Token.LC; braceNesting++; token = getToken(0); if (token.getType() == Token.STRING && getToken(1).getType() == Token.SEMI) { // This is a hint. Hints are empty statements that look like // "localvar1:nomunge, localvar2:nomunge"; They allow developers // to prevent specific symbols from getting obfuscated (some heretic // implementations, such as Prototype 1.6, require specific variable // names, such as $super for example, in order to work appropriately. // Note: right now, only "nomunge" is supported in the right hand side // of a hint. However, in the future, the right hand side may contain // other values. consumeToken(); String hints = token.getValue(); // Remove the leading and trailing quotes... hints = hints.substring(1, hints.length() - 1).trim(); StringTokenizer st1 = new StringTokenizer(hints, ","); while (st1.hasMoreTokens()) { String hint = st1.nextToken(); int idx = hint.indexOf(':'); if (idx <= 0 || idx >= hint.length() - 1) { if (mode == BUILDING_SYMBOL_TREE) { // No need to report the error twice, hence the test... warn("Invalid hint syntax: " + hint, true); } break; } String variableName = hint.substring(0, idx).trim(); String variableType = hint.substring(idx + 1).trim(); if (mode == BUILDING_SYMBOL_TREE) { fnScope.addHint(variableName, variableType); } else if (mode == CHECKING_SYMBOL_TREE) { identifier = fnScope.getIdentifier(variableName); if (identifier != null) { if (variableType.equals("nomunge")) { identifier.preventMunging(); } else { warn("Unsupported hint value: " + hint, true); } } else { warn("Hint refers to an unknown identifier: " + hint, true); } } } } parseScope(fnScope); } private void parseCatch() { String symbol; JavaScriptToken token; ScriptOrFnScope currentScope; JavaScriptIdentifier identifier; token = getToken(-1); assert token.getType() == Token.CATCH; token = consumeToken(); assert token.getType() == Token.LP; token = consumeToken(); assert token.getType() == Token.NAME; symbol = token.getValue(); currentScope = getCurrentScope(); if (mode == BUILDING_SYMBOL_TREE) { // We must declare the exception identifier in the containing function // scope to avoid errors related to the obfuscation process. No need to // display a warning if the symbol was already declared here... currentScope.declareIdentifier(symbol); } else { identifier = getIdentifier(symbol, currentScope); identifier.incrementRefcount(); } token = consumeToken(); assert token.getType() == Token.RP; } private void parseExpression() { // Parse the expression until we encounter a comma or a semi-colon // in the same brace nesting, bracket nesting and paren nesting. // Parse functions if any... String symbol; JavaScriptToken token; ScriptOrFnScope currentScope; JavaScriptIdentifier identifier; int expressionBraceNesting = braceNesting; int bracketNesting = 0; int parensNesting = 0; int length = tokens.size(); while (offset < length) { token = consumeToken(); currentScope = getCurrentScope(); switch (token.getType()) { case Token.SEMI: case Token.COMMA: if (braceNesting == expressionBraceNesting && bracketNesting == 0 && parensNesting == 0) { return; } break; case Token.FUNCTION: parseFunctionDeclaration(); break; case Token.LC: braceNesting++; break; case Token.RC: braceNesting--; assert braceNesting >= expressionBraceNesting; break; case Token.LB: bracketNesting++; break; case Token.RB: bracketNesting--; break; case Token.LP: parensNesting++; break; case Token.RP: parensNesting--; break; case Token.CONDCOMMENT: if (mode == BUILDING_SYMBOL_TREE) { protectScopeFromObfuscation(currentScope); warn("Using JScript conditional comments is not recommended." + (munge ? " Moreover, using JScript conditional comments reduces the level of compression!" : ""), true); } break; case Token.NAME: symbol = token.getValue(); if (mode == BUILDING_SYMBOL_TREE) { if (symbol.equals("eval")) { protectScopeFromObfuscation(currentScope); warn("Using 'eval' is not recommended." + (munge ? " Moreover, using 'eval' reduces the level of compression!" : ""), true); } } else if (mode == CHECKING_SYMBOL_TREE) { if ((offset < 2 || (getToken(-2).getType() != Token.DOT && getToken(-2).getType() != Token.GET && getToken(-2).getType() != Token.SET)) && getToken(0).getType() != Token.OBJECTLIT) { identifier = getIdentifier(symbol, currentScope); if (identifier == null) { if (symbol.length() <= 3 && !builtin.contains(symbol)) { // Here, we found an undeclared and un-namespaced symbol that is // 3 characters or less in length. Declare it in the global scope. // We don't need to declare longer symbols since they won't cause // any conflict with other munged symbols. globalScope.declareIdentifier(symbol); // I removed the warning since was only being done when // for identifiers 3 chars or less, and was just causing // noise for people who happen to rely on an externally // declared variable that happen to be that short. We either // should always warn or never warn -- the fact that we // declare the short symbols in the global space doesn't // change anything. // warn("Found an undeclared symbol: " + symbol, true); } } else { identifier.incrementRefcount(); } } } break; } } } private void parseScope(ScriptOrFnScope scope) { String symbol; JavaScriptToken token; JavaScriptIdentifier identifier; int length = tokens.size(); enterScope(scope); while (offset < length) { token = consumeToken(); switch (token.getType()) { case Token.VAR: if (mode == BUILDING_SYMBOL_TREE && scope.incrementVarCount() > 1) { warn("Try to use a single 'var' statement per scope.", true); } /* FALLSTHROUGH */ case Token.CONST: // The var keyword is followed by at least one symbol name. // If several symbols follow, they are comma separated. for (; ;) { token = consumeToken(); assert token.getType() == Token.NAME; if (mode == BUILDING_SYMBOL_TREE) { symbol = token.getValue(); if (scope.getIdentifier(symbol) == null) { scope.declareIdentifier(symbol); } else { warn("The variable " + symbol + " has already been declared in the same scope...", true); } } token = getToken(0); assert token.getType() == Token.SEMI || token.getType() == Token.ASSIGN || token.getType() == Token.COMMA || token.getType() == Token.IN; if (token.getType() == Token.IN) { break; } else { parseExpression(); token = getToken(-1); if (token.getType() == Token.SEMI) { break; } } } break; case Token.FUNCTION: parseFunctionDeclaration(); break; case Token.LC: braceNesting++; break; case Token.RC: braceNesting--; assert braceNesting >= scope.getBraceNesting(); if (braceNesting == scope.getBraceNesting()) { leaveCurrentScope(); return; } break; case Token.WITH: if (mode == BUILDING_SYMBOL_TREE) { // Inside a 'with' block, it is impossible to figure out // statically whether a symbol is a local variable or an // object member. As a consequence, the only thing we can // do is turn the obfuscation off for the highest scope // containing the 'with' block. protectScopeFromObfuscation(scope); warn("Using 'with' is not recommended." + (munge ? " Moreover, using 'with' reduces the level of compression!" : ""), true); } break; case Token.CATCH: parseCatch(); break; case Token.CONDCOMMENT: if (mode == BUILDING_SYMBOL_TREE) { protectScopeFromObfuscation(scope); warn("Using JScript conditional comments is not recommended." + (munge ? " Moreover, using JScript conditional comments reduces the level of compression." : ""), true); } break; case Token.NAME: symbol = token.getValue(); if (mode == BUILDING_SYMBOL_TREE) { if (symbol.equals("eval")) { protectScopeFromObfuscation(scope); warn("Using 'eval' is not recommended." + (munge ? " Moreover, using 'eval' reduces the level of compression!" : ""), true); } } else if (mode == CHECKING_SYMBOL_TREE) { if ((offset < 2 || getToken(-2).getType() != Token.DOT) && getToken(0).getType() != Token.OBJECTLIT) { identifier = getIdentifier(symbol, scope); if (identifier == null) { if (symbol.length() <= 3 && !builtin.contains(symbol)) { // Here, we found an undeclared and un-namespaced symbol that is // 3 characters or less in length. Declare it in the global scope. // We don't need to declare longer symbols since they won't cause // any conflict with other munged symbols. globalScope.declareIdentifier(symbol); // warn("Found an undeclared symbol: " + symbol, true); } } else { identifier.incrementRefcount(); } } } break; } } } private void buildSymbolTree() { offset = 0; braceNesting = 0; scopes.clear(); indexedScopes.clear(); indexedScopes.put(new Integer(0), globalScope); mode = BUILDING_SYMBOL_TREE; parseScope(globalScope); } private void mungeSymboltree() { if (!munge) { return; } // One problem with obfuscation resides in the use of undeclared // and un-namespaced global symbols that are 3 characters or less // in length. Here is an example: // // var declaredGlobalVar; // // function declaredGlobalFn() { // var localvar; // localvar = abc; // abc is an undeclared global symbol // } // // In the example above, there is a slim chance that localvar may be // munged to 'abc', conflicting with the undeclared global symbol // abc, creating a potential bug. The following code detects such // global symbols. This must be done AFTER the entire file has been // parsed, and BEFORE munging the symbol tree. Note that declaring // extra symbols in the global scope won't hurt. // // Note: Since we go through all the tokens to do this, we also use // the opportunity to count how many times each identifier is used. offset = 0; braceNesting = 0; scopes.clear(); mode = CHECKING_SYMBOL_TREE; parseScope(globalScope); globalScope.munge(); } private StringBuffer printSymbolTree(int linebreakpos, boolean preserveAllSemiColons) throws IOException { offset = 0; braceNesting = 0; scopes.clear(); String symbol; JavaScriptToken token; ScriptOrFnScope currentScope; JavaScriptIdentifier identifier; int length = tokens.size(); StringBuffer result = new StringBuffer(); int linestartpos = 0; enterScope(globalScope); while (offset < length) { token = consumeToken(); symbol = token.getValue(); currentScope = getCurrentScope(); switch (token.getType()) { case Token.NAME: if (offset >= 2 && getToken(-2).getType() == Token.DOT || getToken(0).getType() == Token.OBJECTLIT) { result.append(symbol); } else { identifier = getIdentifier(symbol, currentScope); if (identifier != null) { if (identifier.getMungedValue() != null) { result.append(identifier.getMungedValue()); } else { result.append(symbol); } if (currentScope != globalScope && identifier.getRefcount() == 0) { warn("The symbol " + symbol + " is declared but is apparently never used.\nThis code can probably be written in a more compact way.", true); } } else { result.append(symbol); } } break; case Token.REGEXP: case Token.NUMBER: case Token.STRING: result.append(symbol); break; case Token.ADD: case Token.SUB: result.append((String) literals.get(new Integer(token.getType()))); if (offset < length) { token = getToken(0); if (token.getType() == Token.INC || token.getType() == Token.DEC || token.getType() == Token.ADD || token.getType() == Token.DEC) { // Handle the case x +/- ++/-- y // We must keep a white space here. Otherwise, x +++ y would be // interpreted as x ++ + y by the compiler, which is a bug (due // to the implicit assignment being done on the wrong variable) result.append(' '); } else if (token.getType() == Token.POS && getToken(-1).getType() == Token.ADD || token.getType() == Token.NEG && getToken(-1).getType() == Token.SUB) { // Handle the case x + + y and x - - y result.append(' '); } } break; case Token.FUNCTION: result.append("function"); token = consumeToken(); if (token.getType() == Token.NAME) { result.append(' '); symbol = token.getValue(); identifier = getIdentifier(symbol, currentScope); assert identifier != null; if (identifier.getMungedValue() != null) { result.append(identifier.getMungedValue()); } else { result.append(symbol); } if (currentScope != globalScope && identifier.getRefcount() == 0) { warn("The symbol " + symbol + " is declared but is apparently never used.\nThis code can probably be written in a more compact way.", true); } token = consumeToken(); } assert token.getType() == Token.LP; result.append('('); currentScope = (ScriptOrFnScope) indexedScopes.get(new Integer(offset)); enterScope(currentScope); while ((token = consumeToken()).getType() != Token.RP) { assert token.getType() == Token.NAME || token.getType() == Token.COMMA; if (token.getType() == Token.NAME) { symbol = token.getValue(); identifier = getIdentifier(symbol, currentScope); assert identifier != null; if (identifier.getMungedValue() != null) { result.append(identifier.getMungedValue()); } else { result.append(symbol); } } else if (token.getType() == Token.COMMA) { result.append(','); } } result.append(')'); token = consumeToken(); assert token.getType() == Token.LC; result.append('{'); braceNesting++; token = getToken(0); if (token.getType() == Token.STRING && getToken(1).getType() == Token.SEMI) { // This is a hint. Skip it! consumeToken(); consumeToken(); } break; case Token.RETURN: case Token.TYPEOF: result.append(literals.get(new Integer(token.getType()))); // No space needed after 'return' and 'typeof' when followed // by '(', '[', '{', a string or a regexp. if (offset < length) { token = getToken(0); if (token.getType() != Token.LP && token.getType() != Token.LB && token.getType() != Token.LC && token.getType() != Token.STRING && token.getType() != Token.REGEXP && token.getType() != Token.SEMI) { result.append(' '); } } break; case Token.CASE: case Token.THROW: result.append(literals.get(new Integer(token.getType()))); // White-space needed after 'case' and 'throw' when not followed by a string. if (offset < length && getToken(0).getType() != Token.STRING) { result.append(' '); } break; case Token.BREAK: case Token.CONTINUE: result.append(literals.get(new Integer(token.getType()))); if (offset < length && getToken(0).getType() != Token.SEMI) { // If 'break' or 'continue' is not followed by a semi-colon, it must // be followed by a label, hence the need for a white space. result.append(' '); } break; case Token.LC: result.append('{'); braceNesting++; break; case Token.RC: result.append('}'); braceNesting--; assert braceNesting >= currentScope.getBraceNesting(); if (braceNesting == currentScope.getBraceNesting()) { leaveCurrentScope(); } break; case Token.SEMI: // No need to output a semi-colon if the next character is a right-curly... if (preserveAllSemiColons || offset < length && getToken(0).getType() != Token.RC) { result.append(';'); } if (linebreakpos >= 0 && result.length() - linestartpos > linebreakpos) { // Some source control tools don't like it when files containing lines longer // than, say 8000 characters, are checked in. The linebreak option is used in // that case to split long lines after a specific column. result.append('\n'); linestartpos = result.length(); } break; case Token.CONDCOMMENT: case Token.KEEPCOMMENT: if (result.length() > 0 && result.charAt(result.length() - 1) != '\n') { result.append("\n"); } result.append("/*"); result.append(symbol); result.append("*/\n"); break; default: String literal = (String) literals.get(new Integer(token.getType())); if (literal != null) { result.append(literal); } else { warn("This symbol cannot be printed: " + symbol, true); } break; } } // Append a semi-colon at the end, even if unnecessary semi-colons are // supposed to be removed. This is especially useful when concatenating // several minified files (the absence of an ending semi-colon at the // end of one file may very likely cause a syntax error) if (!preserveAllSemiColons && result.length() > 0 && getToken(-1).getType() != Token.CONDCOMMENT && getToken(-1).getType() != Token.KEEPCOMMENT) { if (result.charAt(result.length() - 1) == '\n') { result.setCharAt(result.length() - 1, ';'); } else { result.append(';'); } } return result; } } yui-compressor-2.4.7/src/com/yahoo/platform/yui/compressor/JarClassLoader.java0000644000175000017500000001066011640627104027432 0ustar drazzibdrazzib/* * YUI Compressor * http://developer.yahoo.com/yui/compressor/ * Author: Julien Lecomte - http://www.julienlecomte.net/ * Copyright (c) 2011 Yahoo! Inc. All rights reserved. * The copyrights embodied in the content of this file are licensed * by Yahoo! Inc. under the BSD (revised) open source license. */ package com.yahoo.platform.yui.compressor; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class JarClassLoader extends ClassLoader { private static String jarPath; public Class loadClass(String name) throws ClassNotFoundException { // First check if the class is already loaded Class c = findLoadedClass(name); if (c == null) { c = findClass(name); } if (c == null) { c = ClassLoader.getSystemClassLoader().loadClass(name); } return c; } private static String getJarPath() { if (jarPath != null) { return jarPath; } String classname = JarClassLoader.class.getName().replace('.', '/') + ".class"; String classpath = System.getProperty("java.class.path"); String classpaths[] = classpath.split(System.getProperty("path.separator")); for (int i = 0; i < classpaths.length; i++) { String path = classpaths[i]; JarFile jarFile = null; JarEntry jarEntry = null; try { jarFile = new JarFile(path); jarEntry = findJarEntry(jarFile, classname); } catch (IOException ioe) { /* ignore */ } finally { if (jarFile != null) { try { jarFile.close(); } catch (IOException ioe) { /* ignore */ } } } if (jarEntry != null) { jarPath = path; break; } } return jarPath; } private static JarEntry findJarEntry(JarFile jarFile, String entryName) { Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = (JarEntry) entries.nextElement(); if (entry.getName().equals(entryName)) { return entry; } } return null; } protected Class findClass(String name) { Class c = null; String jarPath = getJarPath(); if (jarPath != null) { JarFile jarFile = null; try { jarFile = new JarFile(jarPath); c = loadClassData(jarFile, name); } catch (IOException ioe) { /* ignore */ } finally { if (jarFile != null) { try { jarFile.close(); } catch (IOException ioe) { /* ignore */ } } } } return c; } private Class loadClassData(JarFile jarFile, String className) { String entryName = className.replace('.', '/') + ".class"; JarEntry jarEntry = findJarEntry(jarFile, entryName); if (jarEntry == null) { return null; } // Create the necessary package if needed... int index = className.lastIndexOf('.'); if (index >= 0) { String packageName = className.substring(0, index); if (getPackage(packageName) == null) { definePackage(packageName, "", "", "", "", "", "", null); } } // Read the Jar File entry and define the class... Class c = null; try { InputStream is = jarFile.getInputStream(jarEntry); ByteArrayOutputStream os = new ByteArrayOutputStream(); copy(is, os); byte[] bytes = os.toByteArray(); c = defineClass(className, bytes, 0, bytes.length); } catch (IOException ioe) { /* ignore */ } return c; } private void copy(InputStream in, OutputStream out) throws IOException { byte[] buf = new byte[1024]; while (true) { int len = in.read(buf); if (len < 0) break; out.write(buf, 0, len); } } } yui-compressor-2.4.7/src/com/yahoo/platform/yui/compressor/CssCompressor.java0000644000175000017500000003502611640627104027411 0ustar drazzibdrazzib/* * YUI Compressor * http://developer.yahoo.com/yui/compressor/ * Author: Julien Lecomte - http://www.julienlecomte.net/ * Author: Isaac Schlueter - http://foohack.com/ * Author: Stoyan Stefanov - http://phpied.com/ * Copyright (c) 2011 Yahoo! Inc. All rights reserved. * The copyrights embodied in the content of this file are licensed * by Yahoo! Inc. under the BSD (revised) open source license. */ package com.yahoo.platform.yui.compressor; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.ArrayList; public class CssCompressor { private StringBuffer srcsb = new StringBuffer(); public CssCompressor(Reader in) throws IOException { // Read the stream... int c; while ((c = in.read()) != -1) { srcsb.append((char) c); } } // Leave data urls alone to increase parse performance. protected String extractDataUrls(String css, ArrayList preservedTokens) { int maxIndex = css.length() - 1; int appendIndex = 0; StringBuffer sb = new StringBuffer(); Pattern p = Pattern.compile("url\\(\\s*([\"']?)data\\:"); Matcher m = p.matcher(css); /* * Since we need to account for non-base64 data urls, we need to handle * ' and ) being part of the data string. Hence switching to indexOf, * to determine whether or not we have matching string terminators and * handling sb appends directly, instead of using matcher.append* methods. */ while (m.find()) { int startIndex = m.start() + 4; // "url(".length() String terminator = m.group(1); // ', " or empty (not quoted) if (terminator.length() == 0) { terminator = ")"; } boolean foundTerminator = false; int endIndex = m.end() - 1; while(foundTerminator == false && endIndex+1 <= maxIndex) { endIndex = css.indexOf(terminator, endIndex+1); if ((endIndex > 0) && (css.charAt(endIndex-1) != '\\')) { foundTerminator = true; if (!")".equals(terminator)) { endIndex = css.indexOf(")", endIndex); } } } // Enough searching, start moving stuff over to the buffer sb.append(css.substring(appendIndex, m.start())); if (foundTerminator) { String token = css.substring(startIndex, endIndex); token = token.replaceAll("\\s+", ""); preservedTokens.add(token); String preserver = "url(___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___)"; sb.append(preserver); appendIndex = endIndex + 1; } else { // No end terminator found, re-add the whole match. Should we throw/warn here? sb.append(css.substring(m.start(), m.end())); appendIndex = m.end(); } } sb.append(css.substring(appendIndex)); return sb.toString(); } public void compress(Writer out, int linebreakpos) throws IOException { Pattern p; Matcher m; String css = srcsb.toString(); int startIndex = 0; int endIndex = 0; int i = 0; int max = 0; ArrayList preservedTokens = new ArrayList(0); ArrayList comments = new ArrayList(0); String token; int totallen = css.length(); String placeholder; css = this.extractDataUrls(css, preservedTokens); StringBuffer sb = new StringBuffer(css); // collect all comment blocks... while ((startIndex = sb.indexOf("/*", startIndex)) >= 0) { endIndex = sb.indexOf("*/", startIndex + 2); if (endIndex < 0) { endIndex = totallen; } token = sb.substring(startIndex + 2, endIndex); comments.add(token); sb.replace(startIndex + 2, endIndex, "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + (comments.size() - 1) + "___"); startIndex += 2; } css = sb.toString(); // preserve strings so their content doesn't get accidentally minified sb = new StringBuffer(); p = Pattern.compile("(\"([^\\\\\"]|\\\\.|\\\\)*\")|(\'([^\\\\\']|\\\\.|\\\\)*\')"); m = p.matcher(css); while (m.find()) { token = m.group(); char quote = token.charAt(0); token = token.substring(1, token.length() - 1); // maybe the string contains a comment-like substring? // one, maybe more? put'em back then if (token.indexOf("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_") >= 0) { for (i = 0, max = comments.size(); i < max; i += 1) { token = token.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", comments.get(i).toString()); } } // minify alpha opacity in filter strings token = token.replaceAll("(?i)progid:DXImageTransform.Microsoft.Alpha\\(Opacity=", "alpha(opacity="); preservedTokens.add(token); String preserver = quote + "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___" + quote; m.appendReplacement(sb, preserver); } m.appendTail(sb); css = sb.toString(); // strings are safe, now wrestle the comments for (i = 0, max = comments.size(); i < max; i += 1) { token = comments.get(i).toString(); placeholder = "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___"; // ! in the first position of the comment means preserve // so push to the preserved tokens while stripping the ! if (token.startsWith("!")) { preservedTokens.add(token); css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___"); continue; } // \ in the last position looks like hack for Mac/IE5 // shorten that to /*\*/ and the next one to /**/ if (token.endsWith("\\")) { preservedTokens.add("\\"); css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___"); i = i + 1; // attn: advancing the loop preservedTokens.add(""); css = css.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___"); continue; } // keep empty comments after child selectors (IE7 hack) // e.g. html >/**/ body if (token.length() == 0) { startIndex = css.indexOf(placeholder); if (startIndex > 2) { if (css.charAt(startIndex - 3) == '>') { preservedTokens.add(""); css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___"); } } } // in all other cases kill the comment css = css.replace("/*" + placeholder + "*/", ""); } // Normalize all whitespace strings to single spaces. Easier to work with that way. css = css.replaceAll("\\s+", " "); // Remove the spaces before the things that should not have spaces before them. // But, be careful not to turn "p :link {...}" into "p:link{...}" // Swap out any pseudo-class colons with the token, and then swap back. sb = new StringBuffer(); p = Pattern.compile("(^|\\})(([^\\{:])+:)+([^\\{]*\\{)"); m = p.matcher(css); while (m.find()) { String s = m.group(); s = s.replaceAll(":", "___YUICSSMIN_PSEUDOCLASSCOLON___"); s = s.replaceAll( "\\\\", "\\\\\\\\" ).replaceAll( "\\$", "\\\\\\$" ); m.appendReplacement(sb, s); } m.appendTail(sb); css = sb.toString(); // Remove spaces before the things that should not have spaces before them. css = css.replaceAll("\\s+([!{};:>+\\(\\)\\],])", "$1"); // bring back the colon css = css.replaceAll("___YUICSSMIN_PSEUDOCLASSCOLON___", ":"); // retain space for special IE6 cases css = css.replaceAll(":first\\-(line|letter)(\\{|,)", ":first-$1 $2"); // no space after the end of a preserved comment css = css.replaceAll("\\*/ ", "*/"); // If there is a @charset, then only allow one, and push to the top of the file. css = css.replaceAll("^(.*)(@charset \"[^\"]*\";)", "$2$1"); css = css.replaceAll("^(\\s*@charset [^;]+;\\s*)+", "$1"); // Put the space back in some cases, to support stuff like // @media screen and (-webkit-min-device-pixel-ratio:0){ css = css.replaceAll("\\band\\(", "and ("); // Remove the spaces after the things that should not have spaces after them. css = css.replaceAll("([!{}:;>+\\(\\[,])\\s+", "$1"); // remove unnecessary semicolons css = css.replaceAll(";+}", "}"); // Replace 0(px,em,%) with 0. css = css.replaceAll("([\\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)", "$1$2"); // Replace 0 0 0 0; with 0. css = css.replaceAll(":0 0 0 0(;|})", ":0$1"); css = css.replaceAll(":0 0 0(;|})", ":0$1"); css = css.replaceAll(":0 0(;|})", ":0$1"); // Replace background-position:0; with background-position:0 0; // same for transform-origin sb = new StringBuffer(); p = Pattern.compile("(?i)(background-position|transform-origin|webkit-transform-origin|moz-transform-origin|o-transform-origin|ms-transform-origin):0(;|})"); m = p.matcher(css); while (m.find()) { m.appendReplacement(sb, m.group(1).toLowerCase() + ":0 0" + m.group(2)); } m.appendTail(sb); css = sb.toString(); // Replace 0.6 to .6, but only when preceded by : or a white-space css = css.replaceAll("(:|\\s)0+\\.(\\d+)", "$1.$2"); // Shorten colors from rgb(51,102,153) to #336699 // This makes it more likely that it'll get further compressed in the next step. p = Pattern.compile("rgb\\s*\\(\\s*([0-9,\\s]+)\\s*\\)"); m = p.matcher(css); sb = new StringBuffer(); while (m.find()) { String[] rgbcolors = m.group(1).split(","); StringBuffer hexcolor = new StringBuffer("#"); for (i = 0; i < rgbcolors.length; i++) { int val = Integer.parseInt(rgbcolors[i]); if (val < 16) { hexcolor.append("0"); } hexcolor.append(Integer.toHexString(val)); } m.appendReplacement(sb, hexcolor.toString()); } m.appendTail(sb); css = sb.toString(); // Shorten colors from #AABBCC to #ABC. Note that we want to make sure // the color is not preceded by either ", " or =. Indeed, the property // filter: chroma(color="#FFFFFF"); // would become // filter: chroma(color="#FFF"); // which makes the filter break in IE. // We also want to make sure we're only compressing #AABBCC patterns inside { }, not id selectors ( #FAABAC {} ) // We also want to avoid compressing invalid values (e.g. #AABBCCD to #ABCD) p = Pattern.compile("(\\=\\s*?[\"']?)?" + "#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])" + "(:?\\}|[^0-9a-fA-F{][^{]*?\\})"); m = p.matcher(css); sb = new StringBuffer(); int index = 0; while (m.find(index)) { sb.append(css.substring(index, m.start())); boolean isFilter = (m.group(1) != null && !"".equals(m.group(1))); if (isFilter) { // Restore, as is. Compression will break filters sb.append(m.group(1) + "#" + m.group(2) + m.group(3) + m.group(4) + m.group(5) + m.group(6) + m.group(7)); } else { if( m.group(2).equalsIgnoreCase(m.group(3)) && m.group(4).equalsIgnoreCase(m.group(5)) && m.group(6).equalsIgnoreCase(m.group(7))) { // #AABBCC pattern sb.append("#" + (m.group(3) + m.group(5) + m.group(7)).toLowerCase()); } else { // Non-compressible color, restore, but lower case. sb.append("#" + (m.group(2) + m.group(3) + m.group(4) + m.group(5) + m.group(6) + m.group(7)).toLowerCase()); } } index = m.end(7); } sb.append(css.substring(index)); css = sb.toString(); // border: none -> border:0 sb = new StringBuffer(); p = Pattern.compile("(?i)(border|border-top|border-right|border-bottom|border-right|outline|background):none(;|})"); m = p.matcher(css); while (m.find()) { m.appendReplacement(sb, m.group(1).toLowerCase() + ":0" + m.group(2)); } m.appendTail(sb); css = sb.toString(); // shorter opacity IE filter css = css.replaceAll("(?i)progid:DXImageTransform.Microsoft.Alpha\\(Opacity=", "alpha(opacity="); // Remove empty rules. css = css.replaceAll("[^\\}\\{/;]+\\{\\}", ""); // TODO: Should this be after we re-insert tokens. These could alter the break points. However then // we'd need to make sure we don't break in the middle of a string etc. if (linebreakpos >= 0) { // Some source control tools don't like it when files containing lines longer // than, say 8000 characters, are checked in. The linebreak option is used in // that case to split long lines after a specific column. i = 0; int linestartpos = 0; sb = new StringBuffer(css); while (i < sb.length()) { char c = sb.charAt(i++); if (c == '}' && i - linestartpos > linebreakpos) { sb.insert(i, '\n'); linestartpos = i; } } css = sb.toString(); } // Replace multiple semi-colons in a row by a single one // See SF bug #1980989 css = css.replaceAll(";;+", ";"); // restore preserved comments and strings for(i = 0, max = preservedTokens.size(); i < max; i++) { css = css.replace("___YUICSSMIN_PRESERVED_TOKEN_" + i + "___", preservedTokens.get(i).toString()); } // Trim the final string (for any leading or trailing white spaces) css = css.trim(); // Write the output... out.write(css); } } yui-compressor-2.4.7/src/com/yahoo/platform/yui/compressor/Bootstrap.java0000644000175000017500000000145611640627104026561 0ustar drazzibdrazzib/* * YUI Compressor * http://developer.yahoo.com/yui/compressor/ * Author: Julien Lecomte - http://www.julienlecomte.net/ * Copyright (c) 2011 Yahoo! Inc. All rights reserved. * The copyrights embodied in the content of this file are licensed * by Yahoo! Inc. under the BSD (revised) open source license. */ package com.yahoo.platform.yui.compressor; import java.lang.reflect.Method; public class Bootstrap { public static void main(String args[]) throws Exception { ClassLoader loader = new JarClassLoader(); Thread.currentThread().setContextClassLoader(loader); Class c = loader.loadClass(YUICompressor.class.getName()); Method main = c.getMethod("main", new Class[]{String[].class}); main.invoke(null, new Object[]{args}); } } yui-compressor-2.4.7/ports/0000755000175000017500000000000011640627104015570 5ustar drazzibdrazzibyui-compressor-2.4.7/ports/js/0000755000175000017500000000000011640627104016204 5ustar drazzibdrazzibyui-compressor-2.4.7/ports/js/cssmin.js0000644000175000017500000003134611640627104020045 0ustar drazzibdrazzib/** * cssmin.js * Author: Stoyan Stefanov - http://phpied.com/ * This is a JavaScript port of the CSS minification tool * distributed with YUICompressor, itself a port * of the cssmin utility by Isaac Schlueter - http://foohack.com/ * Permission is hereby granted to use the JavaScript version under the same * conditions as the YUICompressor (original YUICompressor note below). */ /* * YUI Compressor * http://developer.yahoo.com/yui/compressor/ * Author: Julien Lecomte - http://www.julienlecomte.net/ * Copyright (c) 2011 Yahoo! Inc. All rights reserved. * The copyrights embodied in the content of this file are licensed * by Yahoo! Inc. under the BSD (revised) open source license. */ var YAHOO = YAHOO || {}; YAHOO.compressor = YAHOO.compressor || {}; /** * Utility method to replace all data urls with tokens before we start * compressing, to avoid performance issues running some of the subsequent * regexes against large strings chunks. * * @private * @method _extractDataUrls * @param {String} css The input css * @param {Array} The global array of tokens to preserve * @returns String The processed css */ YAHOO.compressor._extractDataUrls = function (css, preservedTokens) { // Leave data urls alone to increase parse performance. var maxIndex = css.length - 1, appendIndex = 0, startIndex, endIndex, terminator, foundTerminator, sb = [], m, preserver, token, pattern = /url\(\s*(["']?)data\:/g; // Since we need to account for non-base64 data urls, we need to handle // ' and ) being part of the data string. Hence switching to indexOf, // to determine whether or not we have matching string terminators and // handling sb appends directly, instead of using matcher.append* methods. while ((m = pattern.exec(css)) !== null) { startIndex = m.index + 4; // "url(".length() terminator = m[1]; // ', " or empty (not quoted) if (terminator.length === 0) { terminator = ")"; } foundTerminator = false; endIndex = pattern.lastIndex - 1; while(foundTerminator === false && endIndex+1 <= maxIndex) { endIndex = css.indexOf(terminator, endIndex + 1); // endIndex == 0 doesn't really apply here if ((endIndex > 0) && (css.charAt(endIndex - 1) !== '\\')) { foundTerminator = true; if (")" != terminator) { endIndex = css.indexOf(")", endIndex); } } } // Enough searching, start moving stuff over to the buffer sb.push(css.substring(appendIndex, m.index)); if (foundTerminator) { token = css.substring(startIndex, endIndex); token = token.replace(/\s+/g, ""); preservedTokens.push(token); preserver = "url(___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___)"; sb.push(preserver); appendIndex = endIndex + 1; } else { // No end terminator found, re-add the whole match. Should we throw/warn here? sb.push(css.substring(m.index, pattern.lastIndex)); appendIndex = pattern.lastIndex; } } sb.push(css.substring(appendIndex)); return sb.join(""); }; /** * Utility method to compress hex color values of the form #AABBCC to #ABC. * * DOES NOT compress CSS ID selectors which match the above pattern (which would break things). * e.g. #AddressForm { ... } * * DOES NOT compress IE filters, which have hex color values (which would break things). * e.g. filter: chroma(color="#FFFFFF"); * * DOES NOT compress invalid hex values. * e.g. background-color: #aabbccdd * * @private * @method _compressHexColors * @param {String} css The input css * @returns String The processed css */ YAHOO.compressor._compressHexColors = function(css) { // Look for hex colors inside { ... } (to avoid IDs) and which don't have a =, or a " in front of them (to avoid filters) var pattern = /(\=\s*?["']?)?#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])(\}|[^0-9a-f{][^{]*?\})/gi, m, index = 0, isFilter, sb = []; while ((m = pattern.exec(css)) !== null) { sb.push(css.substring(index, m.index)); isFilter = m[1]; if (isFilter) { // Restore, maintain case, otherwise filter will break sb.push(m[1] + "#" + (m[2] + m[3] + m[4] + m[5] + m[6] + m[7])); } else { if (m[2].toLowerCase() == m[3].toLowerCase() && m[4].toLowerCase() == m[5].toLowerCase() && m[6].toLowerCase() == m[7].toLowerCase()) { // Compress. sb.push("#" + (m[3] + m[5] + m[7]).toLowerCase()); } else { // Non compressible color, restore but lower case. sb.push("#" + (m[2] + m[3] + m[4] + m[5] + m[6] + m[7]).toLowerCase()); } } index = pattern.lastIndex = pattern.lastIndex - m[8].length; } sb.push(css.substring(index)); return sb.join(""); }; YAHOO.compressor.cssmin = function (css, linebreakpos) { var startIndex = 0, endIndex = 0, i = 0, max = 0, preservedTokens = [], comments = [], token = '', totallen = css.length, placeholder = ''; css = this._extractDataUrls(css, preservedTokens); // collect all comment blocks... while ((startIndex = css.indexOf("/*", startIndex)) >= 0) { endIndex = css.indexOf("*/", startIndex + 2); if (endIndex < 0) { endIndex = totallen; } token = css.slice(startIndex + 2, endIndex); comments.push(token); css = css.slice(0, startIndex + 2) + "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + (comments.length - 1) + "___" + css.slice(endIndex); startIndex += 2; } // preserve strings so their content doesn't get accidentally minified css = css.replace(/("([^\\"]|\\.|\\)*")|('([^\\']|\\.|\\)*')/g, function (match) { var i, max, quote = match.substring(0, 1); match = match.slice(1, -1); // maybe the string contains a comment-like substring? // one, maybe more? put'em back then if (match.indexOf("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_") >= 0) { for (i = 0, max = comments.length; i < max; i = i + 1) { match = match.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", comments[i]); } } // minify alpha opacity in filter strings match = match.replace(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/gi, "alpha(opacity="); preservedTokens.push(match); return quote + "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___" + quote; }); // strings are safe, now wrestle the comments for (i = 0, max = comments.length; i < max; i = i + 1) { token = comments[i]; placeholder = "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___"; // ! in the first position of the comment means preserve // so push to the preserved tokens keeping the ! if (token.charAt(0) === "!") { preservedTokens.push(token); css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___"); continue; } // \ in the last position looks like hack for Mac/IE5 // shorten that to /*\*/ and the next one to /**/ if (token.charAt(token.length - 1) === "\\") { preservedTokens.push("\\"); css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___"); i = i + 1; // attn: advancing the loop preservedTokens.push(""); css = css.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___"); continue; } // keep empty comments after child selectors (IE7 hack) // e.g. html >/**/ body if (token.length === 0) { startIndex = css.indexOf(placeholder); if (startIndex > 2) { if (css.charAt(startIndex - 3) === '>') { preservedTokens.push(""); css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.length - 1) + "___"); } } } // in all other cases kill the comment css = css.replace("/*" + placeholder + "*/", ""); } // Normalize all whitespace strings to single spaces. Easier to work with that way. css = css.replace(/\s+/g, " "); // Remove the spaces before the things that should not have spaces before them. // But, be careful not to turn "p :link {...}" into "p:link{...}" // Swap out any pseudo-class colons with the token, and then swap back. css = css.replace(/(^|\})(([^\{:])+:)+([^\{]*\{)/g, function (m) { return m.replace(":", "___YUICSSMIN_PSEUDOCLASSCOLON___"); }); css = css.replace(/\s+([!{};:>+\(\)\],])/g, '$1'); css = css.replace(/___YUICSSMIN_PSEUDOCLASSCOLON___/g, ":"); // retain space for special IE6 cases css = css.replace(/:first-(line|letter)(\{|,)/g, ":first-$1 $2"); // no space after the end of a preserved comment css = css.replace(/\*\/ /g, '*/'); // If there is a @charset, then only allow one, and push to the top of the file. css = css.replace(/^(.*)(@charset "[^"]*";)/gi, '$2$1'); css = css.replace(/^(\s*@charset [^;]+;\s*)+/gi, '$1'); // Put the space back in some cases, to support stuff like // @media screen and (-webkit-min-device-pixel-ratio:0){ css = css.replace(/\band\(/gi, "and ("); // Remove the spaces after the things that should not have spaces after them. css = css.replace(/([!{}:;>+\(\[,])\s+/g, '$1'); // remove unnecessary semicolons css = css.replace(/;+\}/g, "}"); // Replace 0(px,em,%) with 0. css = css.replace(/([\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)/gi, "$1$2"); // Replace 0 0 0 0; with 0. css = css.replace(/:0 0 0 0(;|\})/g, ":0$1"); css = css.replace(/:0 0 0(;|\})/g, ":0$1"); css = css.replace(/:0 0(;|\})/g, ":0$1"); // Replace background-position:0; with background-position:0 0; // same for transform-origin css = css.replace(/(background-position|transform-origin|webkit-transform-origin|moz-transform-origin|o-transform-origin|ms-transform-origin):0(;|\})/gi, function(all, prop, tail) { return prop.toLowerCase() + ":0 0" + tail; }); // Replace 0.6 to .6, but only when preceded by : or a white-space css = css.replace(/(:|\s)0+\.(\d+)/g, "$1.$2"); // Shorten colors from rgb(51,102,153) to #336699 // This makes it more likely that it'll get further compressed in the next step. css = css.replace(/rgb\s*\(\s*([0-9,\s]+)\s*\)/gi, function () { var i, rgbcolors = arguments[1].split(','); for (i = 0; i < rgbcolors.length; i = i + 1) { rgbcolors[i] = parseInt(rgbcolors[i], 10).toString(16); if (rgbcolors[i].length === 1) { rgbcolors[i] = '0' + rgbcolors[i]; } } return '#' + rgbcolors.join(''); }); // Shorten colors from #AABBCC to #ABC. css = this._compressHexColors(css); // border: none -> border:0 css = css.replace(/(border|border-top|border-right|border-bottom|border-right|outline|background):none(;|\})/gi, function(all, prop, tail) { return prop.toLowerCase() + ":0" + tail; }); // shorter opacity IE filter css = css.replace(/progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/gi, "alpha(opacity="); // Remove empty rules. css = css.replace(/[^\};\{\/]+\{\}/g, ""); if (linebreakpos >= 0) { // Some source control tools don't like it when files containing lines longer // than, say 8000 characters, are checked in. The linebreak option is used in // that case to split long lines after a specific column. startIndex = 0; i = 0; while (i < css.length) { i = i + 1; if (css[i - 1] === '}' && i - startIndex > linebreakpos) { css = css.slice(0, i) + '\n' + css.slice(i); startIndex = i; } } } // Replace multiple semi-colons in a row by a single one // See SF bug #1980989 css = css.replace(/;;+/g, ";"); // restore preserved comments and strings for (i = 0, max = preservedTokens.length; i < max; i = i + 1) { css = css.replace("___YUICSSMIN_PRESERVED_TOKEN_" + i + "___", preservedTokens[i]); } // Trim the final string (for any leading or trailing white spaces) css = css.replace(/^\s+|\s+$/g, ""); return css; }; yui-compressor-2.4.7/doc/0000755000175000017500000000000011640627104015166 5ustar drazzibdrazzibyui-compressor-2.4.7/doc/README0000644000175000017500000001212311640627104016045 0ustar drazzibdrazzib============================================================================== YUI Compressor ============================================================================== NAME YUI Compressor - The Yahoo! JavaScript and CSS Compressor SYNOPSIS Usage: java -jar yuicompressor-x.y.z.jar [options] [input file] Global Options -h, --help Displays this information --type Specifies the type of the input file --charset Read the input file using --line-break Insert a line break after the specified column number -v, --verbose Display informational messages and warnings -o Place the output into or a file pattern. Defaults to stdout. JavaScript Options --nomunge Minify only, do not obfuscate --preserve-semi Preserve all semicolons --disable-optimizations Disable all micro optimizations DESCRIPTION The YUI Compressor is a JavaScript compressor which, in addition to removing comments and white-spaces, obfuscates local variables using the smallest possible variable name. This obfuscation is safe, even when using constructs such as 'eval' or 'with' (although the compression is not optimal is those cases) Compared to jsmin, the average savings is around 20%. The YUI Compressor is also able to safely compress CSS files. The decision on which compressor is being used is made on the file extension (js or css) GLOBAL OPTIONS -h, --help Prints help on how to use the YUI Compressor --line-break Some source control tools don't like files containing lines longer than, say 8000 characters. The linebreak option is used in that case to split long lines after a specific column. It can also be used to make the code more readable, easier to debug (especially with the MS Script Debugger) Specify 0 to get a line break after each semi-colon in JavaScript, and after each rule in CSS. --type js|css The type of compressor (JavaScript or CSS) is chosen based on the extension of the input file name (.js or .css) This option is required if no input file has been specified. Otherwise, this option is only required if the input file extension is neither 'js' nor 'css'. --charset character-set If a supported character set is specified, the YUI Compressor will use it to read the input file. Otherwise, it will assume that the platform's default character set is being used. The output file is encoded using the same character set. -o outfile Place output in file outfile. If not specified, the YUI Compressor will default to the standard output, which you can redirect to a file. Supports a filter syntax for expressing the output pattern when there are multiple input files. ex: java -jar yuicompressor.jar -o '.css$:-min.css' *.css ... will minify all .css files and save them as -min.css -v, --verbose Display informational messages and warnings. JAVASCRIPT ONLY OPTIONS --nomunge Minify only. Do not obfuscate local symbols. --preserve-semi Preserve unnecessary semicolons (such as right before a '}') This option is useful when compressed code has to be run through JSLint (which is the case of YUI for example) --disable-optimizations Disable all the built-in micro optimizations. NOTES + If no input file is specified, it defaults to stdin. + Supports wildcards for specifying multiple input files. + The YUI Compressor requires Java version >= 1.5. + It is possible to prevent a local variable, nested function or function argument from being obfuscated by using "hints". A hint is a string that is located at the very beginning of a function body like so: function fn (arg1, arg2, arg3) { "arg2:nomunge, localVar:nomunge, nestedFn:nomunge"; ... var localVar; ... function nestedFn () { .... } ... } The hint itself disappears from the compressed file. + C-style comments starting with /*! are preserved. This is useful with comments containing copyright/license information. For example: /*! * TERMS OF USE - EASING EQUATIONS * Open source under the BSD License. * Copyright 2001 Robert Penner All rights reserved. */ becomes: /* * TERMS OF USE - EASING EQUATIONS * Open source under the BSD License. * Copyright 2001 Robert Penner All rights reserved. */ MODIFIED RHINO FILES YUI Compressor uses a modified version of the Rhino library (http://www.mozilla.org/rhino/) The changes were made to support JScript conditional comments, preserved comments, unescaped slash characters in regular expressions, and to allow for the optimization of escaped quotes in string literals. COPYRIGHT AND LICENSE Copyright (c) 2011 Yahoo! Inc. All rights reserved. The copyrights embodied in the content of this file are licensed by Yahoo! Inc. under the BSD (revised) open source license. yui-compressor-2.4.7/doc/CHANGELOG0000644000175000017500000002444311640627104016407 0ustar drazzibdrazzibYUI Compressor 2.4.7 -------------------- + Handle data urls without blowing up Java memory (regex) + Updated docs to reflect Java >= 1.5 required for CssCompressor + Fixed issue where we were breaking #AABBCC id selectors, with the #AABBCC -> #ABC color compression. YUI Compressor 2.4.6 -------------------- + Show usage information when started without arguments. YUI Compressor 2.4.5 -------------------- + Default file encoding changed from system default to UTF-8. + Errors/messages/usage info all are sent to stderr. + Removed unnecessary warning about short undeclared global symbols. + Added support for processing multiple files with a single invokation + $ in CSS files doesn't throw exceptions + white space in ! important comments preserved in CSS + fix in greedy empty CSS declaration blocks removal + safe handling of strings and comments in CSS files + shorter alpha opacity CSS filers + shorter Mac/IE5 hack -> /*\*/ hack {mac: 1} /**/ + JS port of the CSS minifier + safe @media queries handling + stripping the trailing ; in CSS declaration blocks + shorter border:none->0 where applicable + fixed transform-origin: 0 0 [bug 2528060] + tests++ YUI Compressor 2.4.4 -------------------- + Interim 2.4.5 release YUI Compressor 2.4.3 -------------------- + Changed custodian to ci-tools@ YUI Compressor 2.4.2 -------------------------------- + Preserved comments shouldn't prevent obfuscation (Thanks to Matjaz Lipus) YUI Compressor 2.4.1 -------------------- + Use preferentially lower case letters for obfuscated variable names. Since JavaScript keywords use lower case letters most often, this improves the efficiency of any compression algorithm (gzipping) used after minification. + Don't append a semi-colon at the end of a JavaScript file when the last token is a special comment. YUI Compressor 2.4 ------------------ + Allowed the YUI Compressor (which uses a modified version of Rhino) to work alongside the original (unmodified) rhino library by using a custom class loader. + Added all that's necessary to build the YUI Compressor to the downloable package. + Fixed unnecessary white space after return / typeof when possible. YUI Compressor 2.3.6 -------------------- + Fixed a few minor bugs with the CSS compressor + Changed packaging. The original Rhino library, which is used to build the YUI Compressor, is not part of the downloadable archive. Too many people put it in their classpath, generating a lot of invalid bugs. YUI Compressor 2.3.5 -------------------- + Added a warning when more than one 'var' statement is used in a single scope. Automatic coalescence is extremely complicated, and would be unsafe if not done properly. YUI Compressor 2.3.4 -------------------- + Expanded the list of reserved words used by isValidIdentifier() YUI Compressor 2.3.3 -------------------- + C-style comments starting with /*! are preserved. This is especially useful with comments containing copyright/license information. YUI Compressor 2.3.2 -------------------- + Compressing an empty JS file throws an error [SourceForge bug #1884207] + When a string is the first token in a function body, it was removed from the compressed file [SourceForge bug #1884314] YUI Compressor 2.3.1 -------------------- + Added test against list of reserved words in method isValidIdentifier. YUI Compressor 2.3 ------------------ + Always output a ';' at the end of a minified JavaScript file. This allows the concatenating of several minified files without the fear of introducing a syntax error. + Removed all System.exit() statements. Throw exceptions instead. This is especially useful when running the compressor from within a J2EE container. [SourceForge bug #1834750] + Transform obj["foo"] into obj.foo whenever possible, saving 3 bytes. + Transform 'foo': ... into foo: ... whenever possible, saving 2 bytes. + Added support for multi-line string literals [SourceForge bug #1871453] + Added support for unescaped slashes inside character classes in regexp. + Minor performance improvements. + Preserve the escaping for an octal representation of a character in string literals [SourceForge bug #1844894] var a = '\001'; + CSS: Preserve comments that hide CSS rules from IE Mac: /* Hides from IE-mac \*/ ... /* End hide from IE-mac */ + CSS: Added support for box model hack [SourceForge bug #1862107] div.content { width:400px; voice-family: "\"}\""; voice-family:inherit; width:300px; } YUI Compressor 2.2.5 -------------------- + Remove line terminator after escape in string literals. YUI Compressor 2.2.4 -------------------- + Fixed the way quote characters are counted in string literals [SourceForge bug #1804576] + Do not use a regular expression using non-greedy matching to remove CSS comments (if the comment is more than 800 characters long or so, a stack overflow exception gets thrown) Instead, use good old parsing... + Fix unnecessary quote escaping in string literals. YUI Compressor 2.2.3 -------------------- + Transform <'+'/script>' completely useless. + When converting decimal rgb color values to hexadecimal color values, prepend a '0' if the value is less than 16. Otherwise, rgb(0,124,114) for instance becomes #07c72, which is incorrect. + In CSS files, do not change color names into their corresponding color codes (and vice-versa) due to the high potential of introducing bugs (rolled back from 2.2.1) YUI Compressor 2.2.1 -------------------- + Optimize quote escaping in JavaScript string literals by using the best quote character (' or " depending on the occurrence of this character in the string) + Fixed minor bug in the CSS compressor. Colors should not be shortened in filter: chroma(color="#FFFFFF"); Otherwise, it makes the filter break in Internet Explorer. + In CSS files, change color names into their corresponding color codes (and vice-versa) if that change yields any savings. YUI Compressor 2.2 ------------------ + Don't obfuscate function argument named $super if it is the first function argument listed. This is to support Prototype 1.6's heretic implementation. + Added support for stdin/stdout (see README for more info) + Shorten colors from rgb(51,102,153) to #336699 in CSS files. + Shorten values from 0.8em to .8em in CSS files. + Added support for Internet Explorer's conditional comments in JavaScript files. Note that the presence of a conditional comment inside a function (i.e. not in the global scope) will reduce the level of compression for the same reason the use of 'eval' or 'with' reduces the level of compression (conditional comments, which do not get parsed, may refer to local variables, which get obfuscated) In any case, the use of Internet Explorer's conditional comment is to be avoided. YUI Compressor 2.1.2 -------------------- + Added --preserve-semi option + Modified --line-break option YUI Compressor 2.1.1 -------------------- + Fixed missing space in CSS background:url('foo.png')no-repeat causing a background not to appear on Internet Explorer. YUI Compressor 2.1 ------------------ + Pass the --line-break option to the CSS compressor. + Allow the output file to overwrite the input file (with version 2.0, in this case, the output file was always empty) + Remove spaces before and after '(' and ')' as in background:url('xxx'); + Merge (if possible) string literals that are appended in JavaScript files. This not only makes the code smaller, it makes the code faster, but allows you to maintain some readability in your source code. + Handle constructs such as a + ++ b or a + + "1" (in which case the space between the operators must be kept!) and other similar cases... + Pass ErrorReporter instance to the constructor of class JavaScriptCompressor (as suggested by David Bernard for his integration of the YUI Compressor as a maven plugin) YUI Compressor 2.0 ------------------ + Switched from Rhino 1.6R6 to Rhino 1.6R7 + Integrated Isaac Schlueter's CSS compressor. + Refactored code to make it easier to use the compressor from a servlet environment or another Java app (no need to pass in file names anymore) + Output a white-space character after 'throw' only when necessary. + Output a white-space character after 'break' and 'continue' when followed by a label. YUI Compressor 1.1 ------------------ + Java source now in package com.yahoo.platform.yui.compressor + Added --line-break option that adds a line feed character after each semi-colon character (may help debugging with the MS Script debugger) + Added support for missing JavaScript features (get, set, const) + Do not show the entire stack trace when the input file cannot be found. + Removed the randomization of obfuscated symbols. When compressed code is checked in CVS, unchanged files would otherwise end up being versioned. + Added web-based front-end to the YUI Compressor as part of the dist package. + Added a public entry point that makes the YUI Compressor easy to integrate with an already existing Java application. + Simplified code by using the same parsing routines used to build the symbol tree while looking for undeclared symbols. + Count how many times each identifier is used, and display a warning when an identifier seems to be unused (code cannot safely be removed automatically) + Remove ';' when followed by a '}'. This yields an additional ~1.5% savings on yahoo-dom-event.js compared to the JSMin version. + Output a white-space character after 'return' and 'case' only when necessary.