diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-84407-AJAXRequestMethodsInRsaEncryptionEncoder.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-84407-AJAXRequestMethodsInRsaEncryptionEncoder.rst new file mode 100644 index 000000000000..ccfe68079dbf --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-84407-AJAXRequestMethodsInRsaEncryptionEncoder.rst @@ -0,0 +1,42 @@ +.. include:: ../../Includes.txt + +================================================================== +Deprecation: #84407 - AJAX request methods in RsaEncryptionEncoder +================================================================== + +See :issue:`84407` + +Description +=========== + +All methods related to AJAX requests in :php:`\TYPO3\CMS\Rsaauth\RsaEncryptionEncoder` have been +deprecated: + +* :php:`getRsaPublicKey()` +* :php:`getRsaPublicKeyAjaxHandler()` + +The ``rsa_publickey`` AJAX route has been adapted to use the +:php:`\TYPO3\CMS\Rsaauth\Controller\RsaPublicKeyGenerationController` which was already used for +RSA key retrieval via eID in the frontend. + + +Impact +====== + +Calling one of the above methods on an instance of :php:`RsaEncryptionEncoder` will throw a +deprecation warning in v9 and a PHP fatal in v10. + + +Affected Installations +====================== + +All extensions that call the deprecated methods are affected. + + +Migration +========= + +Extensions should not use the deprecated methods but directly request a key pair via the RSA +backend API. + +.. index:: Backend, Frontend, PHP-API, FullyScanned diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-84407-RSAPublicKeyGenerationWithoutContentTypeApplicationJson.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-84407-RSAPublicKeyGenerationWithoutContentTypeApplicationJson.rst new file mode 100644 index 000000000000..8d635422e63c --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-84407-RSAPublicKeyGenerationWithoutContentTypeApplicationJson.rst @@ -0,0 +1,48 @@ +.. include:: ../../Includes.txt + +======================================================================================== +Deprecation: #84407 - RSA public key generation without "Content-Type: application/json" +======================================================================================== + +See :issue:`84407` + +Description +=========== + +The default response of the :php:`RsaPublicKeyGenerationController` eID script was broken since it +claimed to return a JSON response but in fact returned a simple string containing a concatenation of +public key modulus and exponent. + +The eID script now returns a proper JSON response if requested with the +`Content-Type: application/json` HTTP header: + +.. code-block:: javascript + + { + "publicKeyModulus": "ABC...", + "exponent": "10..." + } + + +Impact +====== + +Extensions performing custom AJAX requests against the :php:`RsaPublicKeyGenerationController` +eID script without the `Content-Type: application/json` HTTP header will trigger a deprecation +warning in v9 and an error response in v10. + + +Affected Installations +====================== + +Sites which do not use the default RSA encryption JavaScript to handle form value encryption. + + +Migration +========= + +The default RSA encryption JavaScript has been migrated, custom implementations must add the +`Content-Type: application/json` HTTP header to AJAX requests and parse the JSON response +accordingly. + +.. index:: Backend, Frontend, JavaScript, PHP-API, FullyScanned, ext:rsaauth diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php index 321b027fdb82..405cce2d379d 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php @@ -2011,4 +2011,18 @@ 'Deprecation-84338-ProtectedMethodsAndPropertiesInTableController.rst', ], ], + 'TYPO3\CMS\Rsaauth\RsaEncryptionEncoder->getRsaPublicKey' => [ + 'numberOfMandatoryArguments' => 0, + 'maximumNumberOfArguments' => 0, + 'restFiles' => [ + 'Deprecation-84407-AJAXRequestMethodsInRsaEncryptionEncoder.rst', + ], + ], + 'TYPO3\CMS\Rsaauth\RsaEncryptionEncoder->getRsaPublicKeyAjaxHandler' => [ + 'numberOfMandatoryArguments' => 0, + 'maximumNumberOfArguments' => 0, + 'restFiles' => [ + 'Deprecation-84407-AJAXRequestMethodsInRsaEncryptionEncoder.rst', + ], + ], ]; diff --git a/typo3/sysext/rsaauth/Classes/Controller/RsaPublicKeyGenerationController.php b/typo3/sysext/rsaauth/Classes/Controller/RsaPublicKeyGenerationController.php index 3bb91ea365f5..c9a49eeed9b2 100644 --- a/typo3/sysext/rsaauth/Classes/Controller/RsaPublicKeyGenerationController.php +++ b/typo3/sysext/rsaauth/Classes/Controller/RsaPublicKeyGenerationController.php @@ -34,6 +34,7 @@ public function processRequest(ServerRequestInterface $request): ResponseInterfa { /** @var \TYPO3\CMS\Rsaauth\Backend\AbstractBackend $backend */ $backend = BackendFactory::getBackend(); + if ($backend === null) { // add a HTTP 500 error code, if an error occurred return new JsonResponse(null, 500); @@ -43,10 +44,25 @@ public function processRequest(ServerRequestInterface $request): ResponseInterfa $storage = StorageFactory::getStorage(); $storage->put($keyPair->getPrivateKey()); session_commit(); - $content = $keyPair->getPublicKeyModulus() . ':' . sprintf('%x', $keyPair->getExponent()) . ':'; - $response = new Response('php://temp', 200, ['Content-Type' => 'application/json; charset=utf-8']); - $response->getBody()->write($content); + switch ($request->getHeaderLine('content-type')) { + case 'application/json': + $data = [ + 'publicKeyModulus' => $keyPair->getPublicKeyModulus(), + 'exponent' => sprintf('%x', $keyPair->getExponent()), + ]; + $response = new JsonResponse($data); + break; + + default: + trigger_error('Requesting RSA public keys without "Content-Type: application/json" will be removed in v10. Add this header to your AJAX request.', E_USER_DEPRECATED); + + $content = $keyPair->getPublicKeyModulus() . ':' . sprintf('%x', $keyPair->getExponent()) . ':'; + $response = new Response('php://temp', 200, ['Content-Type' => 'application/json; charset=utf-8']); + $response->getBody()->write($content); + break; + } + return $response; } } diff --git a/typo3/sysext/rsaauth/Classes/RsaEncryptionEncoder.php b/typo3/sysext/rsaauth/Classes/RsaEncryptionEncoder.php index 001ba3c4def0..1383328d41d3 100644 --- a/typo3/sysext/rsaauth/Classes/RsaEncryptionEncoder.php +++ b/typo3/sysext/rsaauth/Classes/RsaEncryptionEncoder.php @@ -89,9 +89,13 @@ public function isAvailable() * Gets RSA Public Key. * * @return Keypair|null + * + * @deprecated since TYPO3 v9. Will be removed in v10. */ public function getRsaPublicKey() { + trigger_error('Method getRsaPublicKey() will be removed in v10.', E_USER_DEPRECATED); + $keyPair = null; $backend = Backend\BackendFactory::getBackend(); if ($backend !== null) { @@ -108,9 +112,13 @@ public function getRsaPublicKey() * Ajax handler to return a RSA public key. * * @return ResponseInterface + * + * @deprecated since TYPO3 v9. Will be removed in v10. */ public function getRsaPublicKeyAjaxHandler(): ResponseInterface { + trigger_error('Method getRsaPublicKeyAjaxHandler() will be removed in v10.', E_USER_DEPRECATED); + $keyPair = $this->getRsaPublicKey(); if ($keyPair !== null) { return new HtmlResponse( diff --git a/typo3/sysext/rsaauth/Configuration/Backend/AjaxRoutes.php b/typo3/sysext/rsaauth/Configuration/Backend/AjaxRoutes.php index 7af395f0fa47..13df42f1b473 100644 --- a/typo3/sysext/rsaauth/Configuration/Backend/AjaxRoutes.php +++ b/typo3/sysext/rsaauth/Configuration/Backend/AjaxRoutes.php @@ -7,7 +7,7 @@ // Get RSA public key 'rsa_publickey' => [ 'path' => '/rsa/publickey', - 'target' => \TYPO3\CMS\Rsaauth\RsaEncryptionEncoder::class . '::getRsaPublicKeyAjaxHandler', + 'target' => \TYPO3\CMS\Rsaauth\Controller\RsaPublicKeyGenerationController::class . '::processRequest', 'access' => 'public', 'parameters' => [ 'skipSessionUpdate' => 1 diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryption.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryption.js index 1a84f5c442de..f095823aa8d8 100644 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryption.js +++ b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryption.js @@ -46,7 +46,15 @@ TYPO3RsaEncryptionPublicKeyUrl, // defined in PHP rsaEncryption, function(response) { - rsaEncryption.handlePublicKeyResponse(response, rsaEncryption); + var keyData = null; + + try { + keyData = JSON.parse(response.responseText); + } catch (e) { + // Nothing to do here, error will be handled by callback + } + + rsaEncryption.handlePublicKeyResponse(keyData, rsaEncryption); } ); @@ -91,18 +99,19 @@ }; rsaEncryption.xhr.open('GET', url, true); + rsaEncryption.xhr.setRequestHeader('Content-Type', 'application/json'); rsaEncryption.xhr.send(''); }; - this.handlePublicKeyResponse = function(response, rsaEncryption) { - var publicKey = response.responseText.split(':'); - if (!publicKey[0] || !publicKey[1]) { + this.handlePublicKeyResponse = function(keyData, rsaEncryption) { + if (!keyData) { alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.'); return false; } var rsa = new RSAKey(); - rsa.setPublic(publicKey[0], publicKey[1]); + rsa.setPublic(keyData.publicKeyModulus, keyData.exponent); + for (var i = rsaEncryption.fields.length; i--;) { var field = rsaEncryption.fields[i]; var encryptedValue = rsa.encrypt(field.value); diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionModule.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionModule.js index a814e644b1be..6d89d548d01c 100644 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionModule.js +++ b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionModule.js @@ -75,7 +75,9 @@ define(['jquery', './RsaLibrary'], function($) { $.ajax({ url: TYPO3.settings.ajaxUrls['rsa_publickey'], - success: RsaEncryption.handlePublicKeyResponse + contentType: 'application/json', + success: RsaEncryption.handlePublicKeyResponse, + error: RsaEncryption.handlePublicKeyError, }); return false; @@ -87,19 +89,14 @@ define(['jquery', './RsaLibrary'], function($) { }, /** - * Parses the Json response and triggers submission of the form + * Triggers submission of the form * - * @param {Object} response Ajax response object + * @param {Object} key data object */ - handlePublicKeyResponse: function(response) { - var publicKey = response.split(':'); - if (!publicKey[0] || !publicKey[1]) { - alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.'); - return; - } - + handlePublicKeyResponse: function(keyData) { var rsa = new RSAKey(); - rsa.setPublic(publicKey[0], publicKey[1]); + rsa.setPublic(keyData.publicKeyModulus, keyData.exponent); + RsaEncryption.$currentForm.find(':input[data-rsa-encryption]').each(function() { var $this = $(this); var encryptedValue = rsa.encrypt($this.val()); @@ -144,6 +141,15 @@ define(['jquery', './RsaLibrary'], function($) { // Submit the form RsaEncryption.$currentForm.trigger('submit'); } + }, + + /** + * Handles errors on public key retrieval + * + * @param {Object} response Ajax response object + */ + handlePublicKeyError: function() { + alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.'); } }; diff --git a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionWithLib.min.js b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionWithLib.min.js index 5b96106b9556..cd67cec885d7 100644 --- a/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionWithLib.min.js +++ b/typo3/sysext/rsaauth/Resources/Public/JavaScript/RsaEncryptionWithLib.min.js @@ -1 +1 @@ -var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64padchar="=";function hex2b64(h){var i;var c;var ret="";for(i=0;i+3<=h.length;i+=3){c=parseInt(h.substring(i,i+3),16);ret+=b64map.charAt(c>>6)+b64map.charAt(c&63)}if(i+1==h.length){c=parseInt(h.substring(i,i+1),16);ret+=b64map.charAt(c<<2)}else if(i+2==h.length){c=parseInt(h.substring(i,i+2),16);ret+=b64map.charAt(c>>2)+b64map.charAt((c&3)<<4)}while((ret.length&3)>0)ret+=b64padchar;return ret}function b64tohex(s){var ret="";var i;var k=0;var slop;for(i=0;i>2);slop=v&3;k=1}else if(k==1){ret+=int2char(slop<<2|v>>4);slop=v&15;k=2}else if(k==2){ret+=int2char(slop);ret+=int2char(v>>2);slop=v&3;k=3}else{ret+=int2char(slop<<2|v>>4);ret+=int2char(v&15);k=0}}if(k==1)ret+=int2char(slop<<2);return ret}function b64toBA(s){var h=b64tohex(s);var i;var a=new Array;for(i=0;2*i=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}if(j_lm&&navigator.appName=="Microsoft Internet Explorer"){BigInteger.prototype.am=am2;dbits=30}else if(j_lm&&navigator.appName!="Netscape"){BigInteger.prototype.am=am1;dbits=26}else{BigInteger.prototype.am=am3;dbits=28}BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=x<0?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+this.DV;else this.t=0}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var k;if(b==16)k=4;else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{this.fromRadix(s,b);return}this.t=0;this.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=k==8?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue}mi=false;if(sh==0)this[this.t++]=x;else if(sh+k>this.DB){this[this.t-1]|=(x&(1<>this.DB-sh}else this[this.t-1]|=x<=this.DB)sh-=this.DB}if(k==8&&(s[0]&128)!=0){this.s=-1;if(sh>0)this[this.t-1]|=(1<0&&this[this.t-1]==c)--this.t}function bnToString(b){if(this.s<0)return"-"+this.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return this.toRadix(b);var km=(1<0){if(p>p)>0){m=true;r=int2char(d)}while(i>=0){if(p>(p+=this.DB-k)}else{d=this[i]>>(p-=k)&km;if(p<=0){p+=this.DB;--i}}if(d>0)m=true;if(m)r+=int2char(d)}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return this.s<0?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i=0;--i){r[i+ds+1]=this[i]>>cbs|c;c=(this[i]&bm)<=0;--i)r[i]=0;r[ds]=c;r.t=this.t+ds+1;r.s=this.s;r.clamp()}function bnpRShiftTo(n,r){r.s=this.s;var ds=Math.floor(n/this.DB);if(ds>=this.t){r.t=0;return}var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<>bs;for(var i=ds+1;i>bs}if(bs>0)r[this.t-ds-1]|=(this.s&bm)<>=this.DB}if(a.t>=this.DB}c+=this.s}else{c+=this.s;while(i>=this.DB}c-=a.s}r.s=c<0?-1:0;if(c<-1)r[i++]=this.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i=0)r[i]=0;for(i=0;i=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var pm=m.abs();if(pm.t<=0)return;var pt=this.abs();if(pt.t0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<1?y[ys-2]>>this.F2:0);var d1=this.FV/yt,d2=(1<=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t=0){var qd=r[--i]==y0?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r)}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=y*(2-(x&15)*y)&15;y=y*(2-(x&255)*y)&255;y=y*(2-((x&65535)*y&65535))&65535;y=y*(2-x*y%this.DV)%this.DV;return y>0?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<0)this.m.subTo(r,r);return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2)x[x.t++]=0;for(var i=0;i>15)*this.mpl&this.um)<<15)&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x)}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&1<0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function Arcfour(){this.i=0;this.j=0;this.S=new Array}function ARC4init(key){var i,j,t;for(i=0;i<256;++i)this.S[i]=i;j=0;for(i=0;i<256;++i){j=j+this.S[i]+key[i%key.length]&255;t=this.S[i];this.S[i]=this.S[j];this.S[j]=t}this.i=0;this.j=0}function ARC4next(){var t;this.i=this.i+1&255;this.j=this.j+this.S[this.i]&255;t=this.S[this.i];this.S[this.i]=this.S[this.j];this.S[this.j]=t;return this.S[t+this.S[this.i]&255]}Arcfour.prototype.init=ARC4init;Arcfour.prototype.next=ARC4next;function prng_newstate(){return new Arcfour}var rng_psize=256;var rng_state;var rng_pool;var rng_pptr;function rng_seed_int(x){rng_pool[rng_pptr++]^=x&255;rng_pool[rng_pptr++]^=x>>8&255;rng_pool[rng_pptr++]^=x>>16&255;rng_pool[rng_pptr++]^=x>>24&255;if(rng_pptr>=rng_psize)rng_pptr-=rng_psize}function rng_seed_time(){rng_seed_int((new Date).getTime())}if(rng_pool==null){rng_pool=new Array;rng_pptr=0;var t;if(window.crypto&&window.crypto.getRandomValues){var ua=new Uint8Array(32);window.crypto.getRandomValues(ua);for(t=0;t<32;++t)rng_pool[rng_pptr++]=ua[t]}if(navigator.appName=="Netscape"&&navigator.appVersion<"5"&&window.crypto){var z=window.crypto.random(32);for(t=0;t>>8;rng_pool[rng_pptr++]=t&255}rng_pptr=0;rng_seed_time()}function rng_get_byte(){if(rng_state==null){rng_seed_time();rng_state=prng_newstate();rng_state.init(rng_pool);for(rng_pptr=0;rng_pptr=0&&n>0){var c=s.charCodeAt(i--);if(c<128){ba[--n]=c}else if(c>127&&c<2048){ba[--n]=c&63|128;ba[--n]=c>>6|192}else{ba[--n]=c&63|128;ba[--n]=c>>6&63|128;ba[--n]=c>>12|224}}ba[--n]=0;var rng=new SecureRandom;var x=new Array;while(n>2){x[0]=0;while(x[0]==0)rng.nextBytes(x);ba[--n]=x[0]}ba[--n]=2;ba[--n]=0;return new BigInteger(ba)}function RSAKey(){this.n=null;this.e=0;this.d=null;this.p=null;this.q=null;this.dmp1=null;this.dmq1=null;this.coeff=null}function RSASetPublic(N,E){if(N!=null&&E!=null&&N.length>0&&E.length>0){this.n=parseBigInt(N,16);this.e=parseInt(E,16)}else alert("Invalid RSA public key")}function RSADoPublic(x){return x.modPowInt(this.e,this.n)}function RSAEncrypt(text){var m=pkcs1pad2(text,this.n.bitLength()+7>>3);if(m==null)return null;var c=this.doPublic(m);if(c==null)return null;var h=c.toString(16);if((h.length&1)==0)return h;else return"0"+h}RSAKey.prototype.doPublic=RSADoPublic;RSAKey.prototype.setPublic=RSASetPublic;RSAKey.prototype.encrypt=RSAEncrypt;(function(){"use strict";var documentReadyFunctionCalled=false;var rsaEncryption=function(form){this.form=form;this.fields=[];this.xhr=null;this.fetchedRsaKey=false;this.handleFormSubmitRequest=function(event){if(event.cancelBubble){return}var rsaEncryption=this.rsaEncryption||event.srcElement.rsaEncryption;if(!rsaEncryption){return}if(rsaEncryption.fields.length&&!rsaEncryption.fetchedRsaKey){rsaEncryption.fetchedRsaKey=true;rsaEncryption.ajaxCall(TYPO3RsaEncryptionPublicKeyUrl,rsaEncryption,function(response){rsaEncryption.handlePublicKeyResponse(response,rsaEncryption)});if(event.preventDefault){event.preventDefault()}else if(window.event){window.event.returnValue=false}}};this.ajaxCall=function(url,rsaEncryption,callback){if(rsaEncryption.xhr){rsaEncryption.xhr.abort()}if(typeof XMLHttpRequest!=="undefined"){rsaEncryption.xhr=new XMLHttpRequest}else{var versions=["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp.2.0","Microsoft.XmlHttp"];for(var i=0,count=versions.length;i0){callback(rsaEncryption.xhr)}};rsaEncryption.xhr.open("GET",url,true);rsaEncryption.xhr.send("")};this.handlePublicKeyResponse=function(response,rsaEncryption){var publicKey=response.responseText.split(":");if(!publicKey[0]||!publicKey[1]){alert("No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.");return false}var rsa=new RSAKey;rsa.setPublic(publicKey[0],publicKey[1]);for(var i=rsaEncryption.fields.length;i--;){var field=rsaEncryption.fields[i];var encryptedValue=rsa.encrypt(field.value);field.value="rsa:"+hex2b64(encryptedValue)}for(var j=rsaEncryption.form.elements.length;j--;){var submitField=rsaEncryption.form.elements[j];if(["input","button"].indexOf(submitField.nodeName.toLowerCase())>-1&&["submit","image","button"].indexOf(submitField.type.toLowerCase())>-1){submitField.click()}}}};function ready(){if(documentReadyFunctionCalled){return}documentReadyFunctionCalled=true;rng_seed_time();for(var i=document.forms.length;i--;){var form=document.forms[i];for(var j=form.elements.length;j--;){var field=form.elements[j];if(field.nodeName.toLowerCase()==="input"){var dataAttribute=field.getAttribute("data-rsa-encryption");if(dataAttribute||dataAttribute===""&&field.outerHTML.match(/ data-rsa-encryption=""/)){if(!form.rsaEncryption){form.rsaEncryption=new rsaEncryption(form);if(form.addEventListener){form.addEventListener("submit",form.rsaEncryption.handleFormSubmitRequest,false)}else if(form.attachEvent){form.attachEvent("onsubmit",form.rsaEncryption.handleFormSubmitRequest)}}form.rsaEncryption.fields.push(field)}}}}}if(document.readyState==="complete"){setTimeout(ready,1)}else{if(document.addEventListener){document.addEventListener("DOMContentLoaded",ready,false);window.addEventListener("load",ready,false)}else{document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){ready()}});window.attachEvent("onload",ready)}}})(); +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64padchar="=";function hex2b64(h){var i;var c;var ret="";for(i=0;i+3<=h.length;i+=3){c=parseInt(h.substring(i,i+3),16);ret+=b64map.charAt(c>>6)+b64map.charAt(c&63)}if(i+1==h.length){c=parseInt(h.substring(i,i+1),16);ret+=b64map.charAt(c<<2)}else if(i+2==h.length){c=parseInt(h.substring(i,i+2),16);ret+=b64map.charAt(c>>2)+b64map.charAt((c&3)<<4)}while((ret.length&3)>0)ret+=b64padchar;return ret}function b64tohex(s){var ret="";var i;var k=0;var slop;for(i=0;i>2);slop=v&3;k=1}else if(k==1){ret+=int2char(slop<<2|v>>4);slop=v&15;k=2}else if(k==2){ret+=int2char(slop);ret+=int2char(v>>2);slop=v&3;k=3}else{ret+=int2char(slop<<2|v>>4);ret+=int2char(v&15);k=0}}if(k==1)ret+=int2char(slop<<2);return ret}function b64toBA(s){var h=b64tohex(s);var i;var a=new Array;for(i=0;2*i=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}if(j_lm&&navigator.appName=="Microsoft Internet Explorer"){BigInteger.prototype.am=am2;dbits=30}else if(j_lm&&navigator.appName!="Netscape"){BigInteger.prototype.am=am1;dbits=26}else{BigInteger.prototype.am=am3;dbits=28}BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=x<0?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+this.DV;else this.t=0}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var k;if(b==16)k=4;else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{this.fromRadix(s,b);return}this.t=0;this.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=k==8?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue}mi=false;if(sh==0)this[this.t++]=x;else if(sh+k>this.DB){this[this.t-1]|=(x&(1<>this.DB-sh}else this[this.t-1]|=x<=this.DB)sh-=this.DB}if(k==8&&(s[0]&128)!=0){this.s=-1;if(sh>0)this[this.t-1]|=(1<0&&this[this.t-1]==c)--this.t}function bnToString(b){if(this.s<0)return"-"+this.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return this.toRadix(b);var km=(1<0){if(p>p)>0){m=true;r=int2char(d)}while(i>=0){if(p>(p+=this.DB-k)}else{d=this[i]>>(p-=k)&km;if(p<=0){p+=this.DB;--i}}if(d>0)m=true;if(m)r+=int2char(d)}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return this.s<0?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i=0;--i){r[i+ds+1]=this[i]>>cbs|c;c=(this[i]&bm)<=0;--i)r[i]=0;r[ds]=c;r.t=this.t+ds+1;r.s=this.s;r.clamp()}function bnpRShiftTo(n,r){r.s=this.s;var ds=Math.floor(n/this.DB);if(ds>=this.t){r.t=0;return}var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<>bs;for(var i=ds+1;i>bs}if(bs>0)r[this.t-ds-1]|=(this.s&bm)<>=this.DB}if(a.t>=this.DB}c+=this.s}else{c+=this.s;while(i>=this.DB}c-=a.s}r.s=c<0?-1:0;if(c<-1)r[i++]=this.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i=0)r[i]=0;for(i=0;i=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var pm=m.abs();if(pm.t<=0)return;var pt=this.abs();if(pt.t0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<1?y[ys-2]>>this.F2:0);var d1=this.FV/yt,d2=(1<=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t=0){var qd=r[--i]==y0?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r)}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=y*(2-(x&15)*y)&15;y=y*(2-(x&255)*y)&255;y=y*(2-((x&65535)*y&65535))&65535;y=y*(2-x*y%this.DV)%this.DV;return y>0?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<0)this.m.subTo(r,r);return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2)x[x.t++]=0;for(var i=0;i>15)*this.mpl&this.um)<<15)&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x)}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&1<0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function Arcfour(){this.i=0;this.j=0;this.S=new Array}function ARC4init(key){var i,j,t;for(i=0;i<256;++i)this.S[i]=i;j=0;for(i=0;i<256;++i){j=j+this.S[i]+key[i%key.length]&255;t=this.S[i];this.S[i]=this.S[j];this.S[j]=t}this.i=0;this.j=0}function ARC4next(){var t;this.i=this.i+1&255;this.j=this.j+this.S[this.i]&255;t=this.S[this.i];this.S[this.i]=this.S[this.j];this.S[this.j]=t;return this.S[t+this.S[this.i]&255]}Arcfour.prototype.init=ARC4init;Arcfour.prototype.next=ARC4next;function prng_newstate(){return new Arcfour}var rng_psize=256;var rng_state;var rng_pool;var rng_pptr;function rng_seed_int(x){rng_pool[rng_pptr++]^=x&255;rng_pool[rng_pptr++]^=x>>8&255;rng_pool[rng_pptr++]^=x>>16&255;rng_pool[rng_pptr++]^=x>>24&255;if(rng_pptr>=rng_psize)rng_pptr-=rng_psize}function rng_seed_time(){rng_seed_int((new Date).getTime())}if(rng_pool==null){rng_pool=new Array;rng_pptr=0;var t;if(window.crypto&&window.crypto.getRandomValues){var ua=new Uint8Array(32);window.crypto.getRandomValues(ua);for(t=0;t<32;++t)rng_pool[rng_pptr++]=ua[t]}if(navigator.appName=="Netscape"&&navigator.appVersion<"5"&&window.crypto){var z=window.crypto.random(32);for(t=0;t>>8;rng_pool[rng_pptr++]=t&255}rng_pptr=0;rng_seed_time()}function rng_get_byte(){if(rng_state==null){rng_seed_time();rng_state=prng_newstate();rng_state.init(rng_pool);for(rng_pptr=0;rng_pptr=0&&n>0){var c=s.charCodeAt(i--);if(c<128){ba[--n]=c}else if(c>127&&c<2048){ba[--n]=c&63|128;ba[--n]=c>>6|192}else{ba[--n]=c&63|128;ba[--n]=c>>6&63|128;ba[--n]=c>>12|224}}ba[--n]=0;var rng=new SecureRandom;var x=new Array;while(n>2){x[0]=0;while(x[0]==0)rng.nextBytes(x);ba[--n]=x[0]}ba[--n]=2;ba[--n]=0;return new BigInteger(ba)}function RSAKey(){this.n=null;this.e=0;this.d=null;this.p=null;this.q=null;this.dmp1=null;this.dmq1=null;this.coeff=null}function RSASetPublic(N,E){if(N!=null&&E!=null&&N.length>0&&E.length>0){this.n=parseBigInt(N,16);this.e=parseInt(E,16)}else alert("Invalid RSA public key")}function RSADoPublic(x){return x.modPowInt(this.e,this.n)}function RSAEncrypt(text){var m=pkcs1pad2(text,this.n.bitLength()+7>>3);if(m==null)return null;var c=this.doPublic(m);if(c==null)return null;var h=c.toString(16);if((h.length&1)==0)return h;else return"0"+h}RSAKey.prototype.doPublic=RSADoPublic;RSAKey.prototype.setPublic=RSASetPublic;RSAKey.prototype.encrypt=RSAEncrypt;(function(){"use strict";var documentReadyFunctionCalled=false;var rsaEncryption=function(form){this.form=form;this.fields=[];this.xhr=null;this.fetchedRsaKey=false;this.handleFormSubmitRequest=function(event){if(event.cancelBubble){return}var rsaEncryption=this.rsaEncryption||event.srcElement.rsaEncryption;if(!rsaEncryption){return}if(rsaEncryption.fields.length&&!rsaEncryption.fetchedRsaKey){rsaEncryption.fetchedRsaKey=true;rsaEncryption.ajaxCall(TYPO3RsaEncryptionPublicKeyUrl,rsaEncryption,function(response){var keyData=null;try{keyData=JSON.parse(response.responseText)}catch(e){}rsaEncryption.handlePublicKeyResponse(keyData,rsaEncryption)});if(event.preventDefault){event.preventDefault()}else if(window.event){window.event.returnValue=false}}};this.ajaxCall=function(url,rsaEncryption,callback){if(rsaEncryption.xhr){rsaEncryption.xhr.abort()}if(typeof XMLHttpRequest!=="undefined"){rsaEncryption.xhr=new XMLHttpRequest}else{var versions=["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp.2.0","Microsoft.XmlHttp"];for(var i=0,count=versions.length;i0){callback(rsaEncryption.xhr)}};rsaEncryption.xhr.open("GET",url,true);rsaEncryption.xhr.setRequestHeader("Content-Type","application/json");rsaEncryption.xhr.send("")};this.handlePublicKeyResponse=function(keyData,rsaEncryption){if(!keyData){alert("No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.");return false}var rsa=new RSAKey;rsa.setPublic(keyData.publicKeyModulus,keyData.exponent);for(var i=rsaEncryption.fields.length;i--;){var field=rsaEncryption.fields[i];var encryptedValue=rsa.encrypt(field.value);field.value="rsa:"+hex2b64(encryptedValue)}for(var j=rsaEncryption.form.elements.length;j--;){var submitField=rsaEncryption.form.elements[j];if(["input","button"].indexOf(submitField.nodeName.toLowerCase())>-1&&["submit","image","button"].indexOf(submitField.type.toLowerCase())>-1){submitField.click()}}}};function ready(){if(documentReadyFunctionCalled){return}documentReadyFunctionCalled=true;rng_seed_time();for(var i=document.forms.length;i--;){var form=document.forms[i];for(var j=form.elements.length;j--;){var field=form.elements[j];if(field.nodeName.toLowerCase()==="input"){var dataAttribute=field.getAttribute("data-rsa-encryption");if(dataAttribute||dataAttribute===""&&field.outerHTML.match(/ data-rsa-encryption=""/)){if(!form.rsaEncryption){form.rsaEncryption=new rsaEncryption(form);if(form.addEventListener){form.addEventListener("submit",form.rsaEncryption.handleFormSubmitRequest,false)}else if(form.attachEvent){form.attachEvent("onsubmit",form.rsaEncryption.handleFormSubmitRequest)}}form.rsaEncryption.fields.push(field)}}}}}if(document.readyState==="complete"){setTimeout(ready,1)}else{if(document.addEventListener){document.addEventListener("DOMContentLoaded",ready,false);window.addEventListener("load",ready,false)}else{document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){ready()}});window.attachEvent("onload",ready)}}})();