mirror of
https://github.com/phpbb/phpbb.git
synced 2025-07-31 05:50:42 +02:00
[ticket/11854] Move captcha stuff to phpbb/ and use DI for plugins
PHPBB3-11854
This commit is contained in:
83
phpBB/phpbb/captcha/factory.php
Normal file
83
phpBB/phpbb/captcha/factory.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha;
|
||||
|
||||
/**
|
||||
* A small class for 3.0.x (no autoloader in 3.0.x)
|
||||
*/
|
||||
class factory
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\DependencyInjection\ContainerInterface
|
||||
*/
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* @var \phpbb\di\service_collection
|
||||
*/
|
||||
private $plugins;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
|
||||
* @param \phpbb\di\service_collection $plugins
|
||||
*/
|
||||
public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container,\phpbb\di\service_collection $plugins)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->plugins = $plugins;
|
||||
}
|
||||
|
||||
//static public function get_instance($name)
|
||||
|
||||
public function get_instance($name)
|
||||
{
|
||||
return $this->container->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the garbage collector
|
||||
*/
|
||||
function garbage_collect($name)
|
||||
{
|
||||
$captcha = $this->get_instance($name);
|
||||
$captcha->garbage_collect(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a list of all registered CAPTCHA plugins
|
||||
*/
|
||||
function get_captcha_types()
|
||||
{
|
||||
$captchas = array(
|
||||
'available' => array(),
|
||||
'unavailable' => array(),
|
||||
);
|
||||
|
||||
foreach ($this->plugins as $plugin => $plugin_instance)
|
||||
{
|
||||
if ($plugin_instance->is_available())
|
||||
{
|
||||
$captchas['available'][$plugin] = $plugin_instance->get_name();
|
||||
}
|
||||
else
|
||||
{
|
||||
$captchas['unavailable'][$plugin] = $plugin_instance->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
return $captchas;
|
||||
}
|
||||
}
|
2623
phpBB/phpbb/captcha/gd.php
Normal file
2623
phpBB/phpbb/captcha/gd.php
Normal file
File diff suppressed because it is too large
Load Diff
845
phpBB/phpbb/captcha/gd_wave.php
Normal file
845
phpBB/phpbb/captcha/gd_wave.php
Normal file
@@ -0,0 +1,845 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha;
|
||||
|
||||
/**
|
||||
* Wave3D CAPTCHA
|
||||
*/
|
||||
class gd_wave
|
||||
{
|
||||
var $width = 360;
|
||||
var $height = 96;
|
||||
|
||||
function execute($code, $seed)
|
||||
{
|
||||
global $starttime;
|
||||
|
||||
// seed the random generator
|
||||
mt_srand($seed);
|
||||
|
||||
// set height and width
|
||||
$img_x = $this->width;
|
||||
$img_y = $this->height;
|
||||
|
||||
// Generate image
|
||||
$img = imagecreatetruecolor($img_x, $img_y);
|
||||
$x_grid = mt_rand(6, 10);
|
||||
$y_grid = mt_rand(6, 10);
|
||||
|
||||
// Ok, so lets cut to the chase. We could accurately represent this in 3d and
|
||||
// do all the appropriate linear transforms. my questions is... why bother?
|
||||
// The computational overhead is unnecessary when you consider the simple fact:
|
||||
// we're not here to accurately represent a model, but to just show off some random-ish
|
||||
// polygons
|
||||
|
||||
// Conceive of 3 spaces.
|
||||
// 1) planar-space (discrete "pixel" grid)
|
||||
// 2) 3-space. (planar-space with z/height aspect)
|
||||
// 3) image space (pixels on the screen)
|
||||
// resolution of the planar-space we're embedding the text code in
|
||||
$plane_x = 100;
|
||||
$plane_y = 30;
|
||||
|
||||
$subdivision_factor = 3;
|
||||
|
||||
// $box is the 4 points in img_space that correspond to the corners of the plane in 3-space
|
||||
$box = array(
|
||||
'upper_left' => array(
|
||||
'x' => mt_rand(5, 15),
|
||||
'y' => mt_rand(10, 15)
|
||||
),
|
||||
'upper_right' => array(
|
||||
'x' => mt_rand($img_x - 35, $img_x - 19),
|
||||
'y' => mt_rand(10, 17)
|
||||
),
|
||||
'lower_left' => array(
|
||||
'x' => mt_rand($img_x - 45, $img_x - 5),
|
||||
'y' => mt_rand($img_y - 15, $img_y - 0),
|
||||
),
|
||||
);
|
||||
|
||||
$box['lower_right'] = array(
|
||||
'x' => $box['lower_left']['x'] + $box['upper_left']['x'] - $box['upper_right']['x'],
|
||||
'y' => $box['lower_left']['y'] + $box['upper_left']['y'] - $box['upper_right']['y'],
|
||||
);
|
||||
|
||||
// TODO
|
||||
$background = imagecolorallocate($img, mt_rand(155, 255), mt_rand(155, 255), mt_rand(155, 255));
|
||||
imagefill($img, 0, 0, $background);
|
||||
$black = imagecolorallocate($img, 0, 0, 0);
|
||||
|
||||
$random = array();
|
||||
$fontcolors = array();
|
||||
|
||||
for ($i = 0; $i < 15; ++$i)
|
||||
{
|
||||
$random[$i] = imagecolorallocate($img, mt_rand(120, 255), mt_rand(120, 255), mt_rand(120, 255));
|
||||
}
|
||||
|
||||
$fontcolors[0] = imagecolorallocate($img, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));
|
||||
|
||||
$colors = array();
|
||||
|
||||
$minr = mt_rand(20, 30);
|
||||
$ming = mt_rand(20, 30);
|
||||
$minb = mt_rand(20, 30);
|
||||
|
||||
$maxr = mt_rand(150, 230);
|
||||
$maxg = mt_rand(150, 230);
|
||||
$maxb = mt_rand(150, 230);
|
||||
|
||||
for ($i = -30; $i <= 30; ++$i)
|
||||
{
|
||||
$coeff1 = ($i + 12) / 45;
|
||||
$coeff2 = 1 - $coeff1;
|
||||
$colors[$i] = imagecolorallocate($img, ($coeff2 * $maxr) + ($coeff1 * $minr), ($coeff2 * $maxg) + ($coeff1 * $ming), ($coeff2 * $maxb) + ($coeff1 * $minb));
|
||||
}
|
||||
|
||||
// $img_buffer is the last row of 3-space positions (converted to img-space), cached
|
||||
// (using this means we don't need to recalculate all 4 positions for each new polygon,
|
||||
// merely the newest point that we're adding, which is then cached.
|
||||
$img_buffer = array(array(), array());
|
||||
|
||||
// In image-space, the x- and y-offset necessary to move one unit in the x-direction in planar-space
|
||||
$dxx = ($box['upper_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_x);
|
||||
$dxy = ($box['upper_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_x);
|
||||
|
||||
// In image-space, the x- and y-offset necessary to move one unit in the y-direction in planar-space
|
||||
$dyx = ($box['lower_right']['x'] - $box['upper_left']['x']) / ($subdivision_factor * $plane_y);
|
||||
$dyy = ($box['lower_right']['y'] - $box['upper_left']['y']) / ($subdivision_factor * $plane_y);
|
||||
|
||||
// Initial captcha-letter offset in planar-space
|
||||
$plane_offset_x = mt_rand(3, 8);
|
||||
$plane_offset_y = mt_rand( 12, 15);
|
||||
|
||||
// character map
|
||||
$map = $this->captcha_bitmaps();
|
||||
|
||||
// matrix
|
||||
$plane = array();
|
||||
|
||||
// for each character, we'll silkscreen it into our boolean pixel plane
|
||||
for ($c = 0, $code_num = strlen($code); $c < $code_num; ++$c)
|
||||
{
|
||||
$letter = $code[$c];
|
||||
|
||||
for ($x = $map['width'] - 1; $x >= 0; --$x)
|
||||
{
|
||||
for ($y = $map['height'] - 1; $y >= 0; --$y)
|
||||
{
|
||||
if ($map['data'][$letter][$y][$x])
|
||||
{
|
||||
$plane[$y + $plane_offset_y + (($c & 1) ? 1 : -1)][$x + $plane_offset_x] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$plane_offset_x += 11;
|
||||
}
|
||||
|
||||
// calculate our first buffer, we can't actually draw polys with these yet
|
||||
// img_pos_prev == screen x,y location to our immediate left.
|
||||
// img_pos_cur == current screen x,y location
|
||||
// we calculate screen position of our
|
||||
// current cell based on the difference from the previous cell
|
||||
// rather than recalculating from absolute coordinates
|
||||
// What we cache into the $img_buffer contains the raised text coordinates.
|
||||
$img_pos_prev = $img_buffer[0][0] = array($box['upper_left']['x'], $box['upper_left']['y']);
|
||||
$cur_height = $prev_height = $this->wave_height(0, 0, $subdivision_factor);
|
||||
$full_x = $plane_x * $subdivision_factor;
|
||||
$full_y = $plane_y * $subdivision_factor;
|
||||
|
||||
for ($x = 1; $x <= $full_x; ++$x)
|
||||
{
|
||||
$cur_height = $this->wave_height($x, 0, $subdivision_factor);
|
||||
$offset = $cur_height - $prev_height;
|
||||
$img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
|
||||
|
||||
$img_buffer[0][$x] = $img_pos_cur;
|
||||
$img_pos_prev = $img_pos_cur;
|
||||
$prev_height = $cur_height;
|
||||
}
|
||||
|
||||
for ($y = 1; $y <= $full_y; ++$y)
|
||||
{
|
||||
// swap buffers
|
||||
$buffer_cur = $y & 1;
|
||||
$buffer_prev = 1 - $buffer_cur;
|
||||
|
||||
$prev_height = $this->wave_height(0, $y, $subdivision_factor);
|
||||
$offset = $prev_height - $this->wave_height(0, $y - 1, $subdivision_factor);
|
||||
$img_pos_cur = array($img_buffer[$buffer_prev][0][0] + $dyx, min($img_buffer[$buffer_prev][0][1] + $dyy + $offset, $img_y - 1));
|
||||
|
||||
// make sure we don't try to write off the page
|
||||
$img_pos_prev = $img_pos_cur;
|
||||
|
||||
$img_buffer[$buffer_cur][0] = $img_pos_cur;
|
||||
|
||||
for ($x = 1; $x <= $full_x; ++$x)
|
||||
{
|
||||
$cur_height = $this->wave_height($x, $y, $subdivision_factor) + $this->grid_height($x, $y, $x_grid, $y_grid, 1);
|
||||
|
||||
// height is a z-factor, not a y-factor
|
||||
$offset = $cur_height - $prev_height;
|
||||
$img_pos_cur = array($img_pos_prev[0] + $dxx, $img_pos_prev[1] + $dxy + $offset);
|
||||
|
||||
// height is float, index it to an int, get closest color
|
||||
$color = $colors[intval($cur_height)];
|
||||
$img_pos_prev = $img_pos_cur;
|
||||
$prev_height = $cur_height;
|
||||
|
||||
$y_index_old = intval(($y - 1) / $subdivision_factor);
|
||||
$y_index_new = intval($y / $subdivision_factor);
|
||||
$x_index_old = intval(($x - 1) / $subdivision_factor);
|
||||
$x_index_new = intval($x / $subdivision_factor);
|
||||
|
||||
if (!empty($plane[$y_index_new][$x_index_new]))
|
||||
{
|
||||
$img_pos_cur[1] += $this->wave_height($x, $y, $subdivision_factor, 1) - 30 - $cur_height;
|
||||
$color = $colors[20];
|
||||
}
|
||||
$img_pos_cur[1] = min($img_pos_cur[1], $img_y - 1);
|
||||
$img_buffer[$buffer_cur][$x] = $img_pos_cur;
|
||||
|
||||
// Smooth the edges as much as possible by having not more than one low<->high traingle per square
|
||||
// Otherwise, just
|
||||
$diag_down = (empty($plane[$y_index_old][$x_index_old]) == empty($plane[$y_index_new][$x_index_new]));
|
||||
$diag_up = (empty($plane[$y_index_old][$x_index_new]) == empty($plane[$y_index_new][$x_index_old]));
|
||||
|
||||
// natural switching
|
||||
$mode = ($x + $y) & 1;
|
||||
|
||||
// override if it requires it
|
||||
if ($diag_down != $diag_up)
|
||||
{
|
||||
$mode = $diag_up;
|
||||
}
|
||||
|
||||
if ($mode)
|
||||
{
|
||||
// +-/ /
|
||||
// 1 |/ 2 /|
|
||||
// / /-+
|
||||
$poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x]);
|
||||
$poly2 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_cur][$x], $img_buffer[$buffer_prev][$x]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// \ \-+
|
||||
// 1 |\ 2 \|
|
||||
// +-\ \
|
||||
$poly1 = array_merge($img_buffer[$buffer_cur][$x - 1], $img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_cur][$x]);
|
||||
$poly2 = array_merge($img_buffer[$buffer_prev][$x - 1], $img_buffer[$buffer_prev][$x], $img_buffer[$buffer_cur][$x]);
|
||||
}
|
||||
|
||||
imagefilledpolygon($img, $poly1, 3, $color);
|
||||
imagefilledpolygon($img, $poly2, 3, $color);
|
||||
}
|
||||
}
|
||||
|
||||
// Output image
|
||||
header('Content-Type: image/png');
|
||||
header('Cache-control: no-cache, no-store');
|
||||
//$mtime = explode(' ', microtime());
|
||||
//$totaltime = $mtime[0] + $mtime[1] - $starttime;
|
||||
|
||||
//echo $totaltime . "<br />\n";
|
||||
//echo memory_get_usage() - $tmp;
|
||||
imagepng($img);
|
||||
imagedestroy($img);
|
||||
}
|
||||
|
||||
function wave_height($x, $y, $factor = 1, $tweak = 0.7)
|
||||
{
|
||||
// stretch the wave. TODO: pretty it up
|
||||
$x = $x/5 + 180;
|
||||
$y = $y/4;
|
||||
return ((sin($x / (3 * $factor)) + sin($y / (3 * $factor))) * 10 * $tweak);
|
||||
}
|
||||
|
||||
function grid_height($x, $y, $x_grid, $y_grid, $factor = 1)
|
||||
{
|
||||
return ((!($x % ($x_grid * $factor)) || !($y % ($y_grid * $factor))) ? 3 : 0);
|
||||
}
|
||||
|
||||
function captcha_bitmaps()
|
||||
{
|
||||
return array(
|
||||
'width' => 9,
|
||||
'height' => 13,
|
||||
'data' => array(
|
||||
'A' => array(
|
||||
array(0,0,1,1,1,1,0,0,0),
|
||||
array(0,1,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,1,1,1,1,1,1,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'B' => array(
|
||||
array(1,1,1,1,1,1,0,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,1,1,1,1,1,0,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,1,1,1,1,1,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'C' => array(
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'D' => array(
|
||||
array(1,1,1,1,1,1,1,0,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,1,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'E' => array(
|
||||
array(0,0,1,1,1,1,1,1,1),
|
||||
array(0,1,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,1,1,1,1,1,1,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(0,1,0,0,0,0,0,0,0),
|
||||
array(0,0,1,1,1,1,1,1,1),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'F' => array(
|
||||
array(0,0,1,1,1,1,1,1,0),
|
||||
array(0,1,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,1,1,1,1,1,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'G' => array(
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,1,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'H' => array(
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,1,1,1,1,1,1,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'I' => array(
|
||||
array(0,1,1,1,1,1,1,1,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,1,1,1,1,1,1,1,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'J' => array(
|
||||
array(0,0,0,0,0,0,1,1,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,0,1),
|
||||
array(0,0,1,0,0,0,0,1,0),
|
||||
array(0,0,0,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'K' => array(
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,1,0,0,0),
|
||||
array(1,0,0,0,1,0,0,0,0),
|
||||
array(1,0,0,1,0,0,0,0,0),
|
||||
array(1,0,1,0,0,0,0,0,0),
|
||||
array(1,1,0,0,0,0,0,0,0),
|
||||
array(1,0,1,0,0,0,0,0,0),
|
||||
array(1,0,0,1,0,0,0,0,0),
|
||||
array(1,0,0,0,1,0,0,0,0),
|
||||
array(1,0,0,0,0,1,0,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'L' => array(
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(0,1,0,0,0,0,0,0,0),
|
||||
array(0,0,1,1,1,1,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'M' => array(
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,1,1,0,0,0,1,1,0),
|
||||
array(0,1,0,1,0,1,0,1,0),
|
||||
array(0,1,0,0,1,0,0,1,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'N' => array(
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,1,0,0,0,0,0,0,1),
|
||||
array(1,0,1,0,0,0,0,0,1),
|
||||
array(1,0,0,1,0,0,0,0,1),
|
||||
array(1,0,0,0,1,0,0,0,1),
|
||||
array(1,0,0,0,0,1,0,0,1),
|
||||
array(1,0,0,0,0,0,1,0,1),
|
||||
array(1,0,0,0,0,0,0,1,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'O' => array(
|
||||
array(0,0,0,1,1,1,0,0,0),
|
||||
array(0,0,1,0,0,0,1,0,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,0,0,0,1,0,0),
|
||||
array(0,0,0,1,1,1,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'P' => array(
|
||||
array(1,1,1,1,1,1,0,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,1,1,1,1,1,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'Q' => array(
|
||||
array(0,0,1,1,1,1,0,0,0),
|
||||
array(0,1,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,1,0,0,1,0),
|
||||
array(1,0,0,0,0,1,0,1,0),
|
||||
array(0,1,0,0,0,0,1,0,0),
|
||||
array(0,0,1,1,1,1,0,1,0),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'R' => array(
|
||||
array(1,1,1,1,1,1,0,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(1,1,1,1,1,1,0,0,0),
|
||||
array(1,0,1,0,0,0,0,0,0),
|
||||
array(1,0,0,1,0,0,0,0,0),
|
||||
array(1,0,0,0,1,0,0,0,0),
|
||||
array(1,0,0,0,0,1,0,0,0),
|
||||
array(1,0,0,0,0,0,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'S' => array(
|
||||
array(0,0,1,1,1,1,1,1,1),
|
||||
array(0,1,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(0,1,0,0,0,0,0,0,0),
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(1,1,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'T' => array(
|
||||
array(1,1,1,1,1,1,1,1,1),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'U' => array(
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'V' => array(
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,0,0,0,1,0,0),
|
||||
array(0,0,0,1,0,1,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'W' => array(
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,1,0,0,0,1),
|
||||
array(1,0,0,1,0,1,0,0,1),
|
||||
array(1,0,1,0,0,0,1,0,1),
|
||||
array(1,1,0,0,0,0,0,1,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'X' => array(
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,0,0,0,1,0,0),
|
||||
array(0,0,0,1,0,1,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,1,0,1,0,0,0),
|
||||
array(0,0,1,0,0,0,1,0,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'Y' => array(
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,0,0,0,1,0,0),
|
||||
array(0,0,0,1,0,1,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'Z' => array(
|
||||
array(1,1,1,1,1,1,1,1,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,1,0,0),
|
||||
array(0,0,0,0,0,1,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,1,0,0,0,0,0),
|
||||
array(0,0,1,0,0,0,0,0,0),
|
||||
array(0,1,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,1,1,1,1,1,1,1,1),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'1' => array(
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,1,1,0,0,0,0),
|
||||
array(0,0,1,0,1,0,0,0,0),
|
||||
array(0,1,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,1,1,1,1,1,1,1,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'2' => array(
|
||||
array(0,0,0,1,1,1,0,0,0),
|
||||
array(0,0,1,0,0,0,1,0,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,1,0,0),
|
||||
array(0,0,0,0,0,1,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,1,0,0,0,0,0),
|
||||
array(0,0,1,0,0,0,0,0,0),
|
||||
array(0,1,1,1,1,1,1,1,1),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'3' => array(
|
||||
array(0,0,0,1,1,1,1,0,0),
|
||||
array(0,0,1,0,0,0,0,1,0),
|
||||
array(0,1,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,0,1),
|
||||
array(0,0,1,0,0,0,0,1,0),
|
||||
array(0,0,0,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'4' => array(
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,1,1,0),
|
||||
array(0,0,0,0,0,1,0,1,0),
|
||||
array(0,0,0,0,1,0,0,1,0),
|
||||
array(0,0,0,1,0,0,0,1,0),
|
||||
array(0,0,1,0,0,0,0,1,0),
|
||||
array(0,1,1,1,1,1,1,1,1),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'5' => array(
|
||||
array(1,1,1,1,1,1,1,1,1),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(0,1,0,0,0,0,0,0,0),
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'6' => array(
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,0,0,0,0,0,0),
|
||||
array(1,0,0,1,1,1,1,0,0),
|
||||
array(1,0,1,0,0,0,0,1,0),
|
||||
array(1,1,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'7' => array(
|
||||
array(1,1,1,1,1,1,1,1,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,1,0),
|
||||
array(0,0,0,0,0,0,1,0,0),
|
||||
array(0,0,0,0,0,1,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,1,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'8' => array(
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(1,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,0),
|
||||
array(0,0,1,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
'9' => array(
|
||||
array(0,0,0,1,1,1,1,0,0),
|
||||
array(0,0,1,0,0,0,0,1,0),
|
||||
array(0,1,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,1,1),
|
||||
array(0,0,1,1,1,1,1,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,0,0,0,0,0,0,0,1),
|
||||
array(0,1,0,0,0,0,0,0,1),
|
||||
array(0,0,1,0,0,0,0,1,0),
|
||||
array(0,0,0,1,1,1,1,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
array(0,0,0,0,0,0,0,0,0),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
386
phpBB/phpbb/captcha/non_gd.php
Normal file
386
phpBB/phpbb/captcha/non_gd.php
Normal file
@@ -0,0 +1,386 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha;
|
||||
|
||||
/**
|
||||
* Main non-gd captcha class
|
||||
* @ignore
|
||||
*/
|
||||
class non_gd
|
||||
{
|
||||
var $filtered_pngs;
|
||||
var $width = 320;
|
||||
var $height = 50;
|
||||
|
||||
/**
|
||||
* Define filtered pngs on init
|
||||
*/
|
||||
function captcha()
|
||||
{
|
||||
// If we can we will generate a single filtered png, we avoid nastiness via emulation of some Zlib stuff
|
||||
$this->define_filtered_pngs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the image containing $code with a seed of $seed
|
||||
*/
|
||||
function execute($code, $seed)
|
||||
{
|
||||
$img_height = $this->height - 10;
|
||||
$img_width = 0;
|
||||
|
||||
mt_srand($seed);
|
||||
|
||||
$char_widths = $hold_chars = array();
|
||||
$code_len = strlen($code);
|
||||
|
||||
for ($i = 0; $i < $code_len; $i++)
|
||||
{
|
||||
$char = $code[$i];
|
||||
|
||||
$width = mt_rand(0, 4);
|
||||
$raw_width = $this->filtered_pngs[$char]['width'];
|
||||
$char_widths[$i] = $width;
|
||||
$img_width += $raw_width - $width;
|
||||
|
||||
// Split the char into chunks of $raw_width + 1 length
|
||||
if (empty($hold_chars[$char]))
|
||||
{
|
||||
$hold_chars[$char] = str_split(base64_decode($this->filtered_pngs[$char]['data']), $raw_width + 1);
|
||||
}
|
||||
}
|
||||
|
||||
$offset_x = mt_rand(0, $this->width - $img_width);
|
||||
$offset_y = mt_rand(0, $this->height - $img_height);
|
||||
|
||||
$image = '';
|
||||
for ($i = 0; $i < $this->height; $i++)
|
||||
{
|
||||
$image .= chr(0);
|
||||
|
||||
if ($i > $offset_y && $i < $offset_y + $img_height)
|
||||
{
|
||||
for ($j = 0; $j < $offset_x; $j++)
|
||||
{
|
||||
$image .= chr(mt_rand(140, 255));
|
||||
}
|
||||
|
||||
for ($j = 0; $j < $code_len; $j++)
|
||||
{
|
||||
$image .= $this->randomise(substr($hold_chars[$code{$j}][$i - $offset_y - 1], 1), $char_widths[$j]);
|
||||
}
|
||||
|
||||
for ($j = $offset_x + $img_width; $j < $this->width; $j++)
|
||||
{
|
||||
$image .= chr(mt_rand(140, 255));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ($j = 0; $j < $this->width; $j++)
|
||||
{
|
||||
$image .= chr(mt_rand(140, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($hold_chars);
|
||||
|
||||
$image = $this->create_png($image, $this->width, $this->height);
|
||||
|
||||
// Output image
|
||||
header('Content-Type: image/png');
|
||||
header('Cache-control: no-cache, no-store');
|
||||
echo $image;
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is designed to randomise the pixels of the image data within
|
||||
* certain limits so as to keep it readable. It also varies the image
|
||||
* width a little
|
||||
*/
|
||||
function randomise($scanline, $width)
|
||||
{
|
||||
$new_line = '';
|
||||
|
||||
$end = strlen($scanline) - ceil($width/2);
|
||||
for ($i = (int) floor($width / 2); $i < $end; $i++)
|
||||
{
|
||||
$pixel = ord($scanline{$i});
|
||||
|
||||
if ($pixel < 190)
|
||||
{
|
||||
$new_line .= chr(mt_rand(0, 205));
|
||||
}
|
||||
else if ($pixel > 190)
|
||||
{
|
||||
$new_line .= chr(mt_rand(145, 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
$new_line .= $scanline{$i};
|
||||
}
|
||||
}
|
||||
|
||||
return $new_line;
|
||||
}
|
||||
|
||||
/**
|
||||
* This creates a chunk of the given type, with the given data
|
||||
* of the given length adding the relevant crc
|
||||
*/
|
||||
function png_chunk($length, $type, $data)
|
||||
{
|
||||
$raw = $type . $data;
|
||||
|
||||
return pack('N', $length) . $raw . pack('N', crc32($raw));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates greyscale 8bit png - The PNG spec can be found at
|
||||
* http://www.libpng.org/pub/png/spec/PNG-Contents.html we use
|
||||
* png because it's a fully recognised open standard and supported
|
||||
* by practically all modern browsers and OSs
|
||||
*/
|
||||
function create_png($raw_image, $width, $height)
|
||||
{
|
||||
// SIG
|
||||
$image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10);
|
||||
|
||||
// IHDR
|
||||
$raw = pack('N2', $width, $height);
|
||||
$raw .= pack('C5', 8, 0, 0, 0, 0);
|
||||
$image .= $this->png_chunk(13, 'IHDR', $raw);
|
||||
|
||||
// IDAT
|
||||
if (@extension_loaded('zlib'))
|
||||
{
|
||||
$raw_image = gzcompress($raw_image);
|
||||
$length = strlen($raw_image);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The total length of this image, uncompressed, is just a calculation of pixels
|
||||
$length = ($width + 1) * $height;
|
||||
|
||||
// Adler-32 hash generation
|
||||
// Note: The hash is _backwards_ so we must reverse it
|
||||
|
||||
if (@extension_loaded('hash'))
|
||||
{
|
||||
$adler_hash = strrev(hash('adler32', $raw_image, true));
|
||||
}
|
||||
else if (@extension_loaded('mhash'))
|
||||
{
|
||||
$adler_hash = strrev(mhash(MHASH_ADLER32, $raw_image));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Optimized Adler-32 loop ported from the GNU Classpath project
|
||||
$temp_length = $length;
|
||||
$s1 = 1;
|
||||
$s2 = $index = 0;
|
||||
|
||||
while ($temp_length > 0)
|
||||
{
|
||||
// We can defer the modulo operation:
|
||||
// s1 maximally grows from 65521 to 65521 + 255 * 3800
|
||||
// s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
|
||||
$substract_value = ($temp_length < 3800) ? $temp_length : 3800;
|
||||
$temp_length -= $substract_value;
|
||||
|
||||
while (--$substract_value >= 0)
|
||||
{
|
||||
$s1 += ord($raw_image[$index]);
|
||||
$s2 += $s1;
|
||||
|
||||
$index++;
|
||||
}
|
||||
|
||||
$s1 %= 65521;
|
||||
$s2 %= 65521;
|
||||
}
|
||||
$adler_hash = pack('N', ($s2 << 16) | $s1);
|
||||
}
|
||||
|
||||
// This is the same thing as gzcompress($raw_image, 0) but does not need zlib
|
||||
$raw_image = pack('C3v2', 0x78, 0x01, 0x01, $length, ~$length) . $raw_image . $adler_hash;
|
||||
|
||||
// The Zlib header + Adler hash make us add on 11
|
||||
$length += 11;
|
||||
}
|
||||
|
||||
// IDAT
|
||||
$image .= $this->png_chunk($length, 'IDAT', $raw_image);
|
||||
|
||||
// IEND
|
||||
$image .= $this->png_chunk(0, 'IEND', '');
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* png image data
|
||||
* Each 'data' element is base64_encoded uncompressed IDAT
|
||||
*/
|
||||
function define_filtered_pngs()
|
||||
{
|
||||
$this->filtered_pngs = array(
|
||||
'0' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////olFAkBAAAGDyA4P///M31/////////////wD////////////////0dAgAAAAAAAAAAAAEcPipFGHn////////////AP//////////////6DAAAAAAAAAAAAAAAAAALSEAN+T///////////8A//////////////xAAAAAAAAAAAAAAAAAAAAAACPA/////////////wD/////////////oAAAAAAAAAAAAAAAAAAAAAAAev//////////////AP////////////8oAAAAAAAAPNj/zDAAAAAAAABD//////////////8A////////////1AAAAAAAABjw////5BAAAAAAAADo/////////////wD///////////+QAAAAAAAAbP//////QgAAAAAAAKj/////////////AP///////////1wAAAAAAACs/////8AXAAAAAAAAcP////////////8A////////////OAAAAAAAAND////dNwAAAAAAAABI/////////////wD///////////8gAAAAAAAA4P//7koACwAAAAAAACT/////////////AP///////////wgAAAAAAAD///VqAwaPAAAAAAAAEP////////////8A////////////AAAAAAAAAP/8kQYDavUAAAAAAAAA/////////////wD///////////8AAAAAAAAA/6kNAEru/wAAAAAAAAD/////////////AP///////////wAAAAAAAADAIwA33f//AAAAAAAAAP////////////8A////////////FAAAAAAAADYAI8D///8AAAAAAAAQ/////////////wD///////////8kAAAAAAAAAA2p////5AAAAAAAACD/////////////AP///////////0gAAAAAAAAFkfz////UAAAAAAAAQP////////////8A////////////cAAAAAAAAET1/////7AAAAAAAABo/////////////wD///////////+oAAAAAAAAXfX/////sAAAAAAAAGj/////////////AAAAALgAAAAAAAAwAAAAAAAAAAAAAAD////////////oAAAAAAAACOT////oEAAAAAAAAOD/////////////AP////////////8+AAAAAAAAKMz/zDQAAAAAAAA0//////////////8A////////////7jgAAAAAAAAAAAAAAAAAAAAAAKT//////////////wD///////////VqAwIAAAAAAAAAAAAAAAAAAAA8////////////////AP//////////rQcDaVEAAAAAAAAAAAAAAAAAKOj///////////////8A///////////nblnu/IAIAAAAAAAAAAAAAFzw/////////////////wD////////////79////+iITCAAAAAgSITg////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////w==',
|
||||
'width' => 40
|
||||
),
|
||||
'1' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////8BAAAAAAAP//////////////////AP////////////////////////9sAAAAAAAA//////////////////8A////////////////////////pAAAAAAAAAD//////////////////wD//////////////////////6wEAAAAAAAAAP//////////////////AP////////////////////h4AAAAAAAAAAAA//////////////////8A//////////////////ygJAAAAAAAAAAAAAD//////////////////wD//////////////9x8HAAAAAAAAAAAAAAAAP//////////////////AP//////////////AAAAAAAAAAAAAAAAAAAA//////////////////8A//////////////8AAAAAAAAAAAAAAAAAAAD//////////////////wD//////////////wAAAAAAAAR4AAAAAAAAAP//////////////////AP//////////////AAAAAAA4zP8AAAAAAAAA//////////////////8A//////////////8AAAA4sP///wAAAAAAAAD//////////////////wD//////////////yR80P//////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'2' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////okFAkCAAABCBIfNT///////////////////8A///////////////8hAgAAAAAAAAAAAAAAFTo/////////////////wD//////////////1QAAAAAAAAAAAAAAAAAACjo////////////////AP////////////+MAAAAAAAAAAAAAAAAAAAAADj///////////////8A////////////9BAAAAAAAAAAAAAAAAAAAAAAALD//////////////wD///////////+gAAAAAAAAAHjs+KwMAAAAAAAAVP//////////////AP///////////1gAAAAAAABM/////6QAAAAAAAAU//////////////8A////////////KAAAAAAAALj/////+AAAAAAAAAD//////////////wD///////////+MfGBMOCAI8P/////wAAAAAAAACP//////////////AP///////////////////////////5wAAAAAAAAw//////////////8A///////////////////////////oFAAAAAAAAHz//////////////wD/////////////////////////6CgAAAAAAAAE3P//////////////AP///////////////////////9ggAAAAAAAAAHT///////////////8A//////////////////////+0DAAAAAAAAAA8+P///////////////wD/////////////////////gAAAAAAAAAAAKOj/////////////////AP//////////////////9FAAAAAAAAAAADzw//////////////////8A/////////////////+g4AAAAAAAAAABk/P///////////////////wD////////////////oKAAAAAAAAAAMqP//////////////////////AP//////////////6CgAAAAAAAAAMNz///////////////////////8A//////////////g4AAAAAAAAAFT0/////////////////////////wD/////////////bAAAAAAAAABU/P//////////////////////////AP///////////8wAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A////////////SAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////9AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////xAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'3' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////8sGg0FAAAACA4cLz8////////////////////AP//////////////rBgAAAAAAAAAAAAAACTA//////////////////8A/////////////3QAAAAAAAAAAAAAAAAAAASs/////////////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAjc////////////////AP//////////6AwAAAAAAAAAAAAAAAAAAAAAAGT///////////////8A//////////94AAAAAAAABJDw/8g4AAAAAAAAHP///////////////wD//////////yAAAAAAAACE/////9gAAAAAAAAA////////////////AP///////////NSwiGQ4FOT//////AAAAAAAABD///////////////8A//////////////////////////+YAAAAAAAAVP///////////////wD//////////////////////P/ggAQAAAAAAATM////////////////AP////////////////////9gAAAAAAAAAAAElP////////////////8A/////////////////////0AAAAAAAAAAHLj//////////////////wD/////////////////////OAAAAAAAAAAwkPj/////////////////AP////////////////////8gAAAAAAAAAAAAINj///////////////8A/////////////////////xAAAAAAAAAAAAAAIPD//////////////wD/////////////////////uOz/4HgEAAAAAAAAhP//////////////AP///////////////////////////3wAAAAAAAAw//////////////8A////////////////////////////6AAAAAAAAAj//////////////wD/////////////////////////////AAAAAAAAAP//////////////AP//////////tJh8YEQoDNz//////+AAAAAAAAAY//////////////8A//////////88AAAAAAAAaP//////dAAAAAAAAEz//////////////wD//////////6QAAAAAAAAAdOD/5HQAAAAAAAAApP//////////////AP///////////CgAAAAAAAAAAAAAAAAAAAAAACD4//////////////8A////////////yAQAAAAAAAAAAAAAAAAAAAAEuP///////////////wD/////////////rAQAAAAAAAAAAAAAAAAABJD/////////////////AP//////////////zDQAAAAAAAAAAAAAACTA//////////////////8A/////////////////8BwOCAAAAAUNGi0/P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'4' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////////////nAAAAAAAAAD///////////////8A/////////////////////////8AEAAAAAAAAAP///////////////wD////////////////////////gGAAAAAAAAAAA////////////////AP//////////////////////9DAAAAAAAAAAAAD///////////////8A//////////////////////9UAAAAAAAAAAAAAP///////////////wD/////////////////////hAAAAAAAAAAAAAAA////////////////AP///////////////////7QAAAAAAAAAAAAAAAD///////////////8A///////////////////UDAAAAAAUAAAAAAAAAP///////////////wD/////////////////7CQAAAAABMAAAAAAAAAA////////////////AP////////////////xEAAAAAACU/wAAAAAAAAD///////////////8A////////////////cAAAAAAAZP//AAAAAAAAAP///////////////wD//////////////6AAAAAAADz8//8AAAAAAAAA////////////////AP/////////////IBAAAAAAc6P///wAAAAAAAAD///////////////8A////////////5BgAAAAADMz/////AAAAAAAAAP///////////////wD///////////g0AAAAAACk//////8AAAAAAAAA////////////////AP//////////XAAAAAAAfP///////wAAAAAAAAD///////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP///////////////////////////wAAAAAAAAD///////////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'5' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////8AAAAAAAAAAAAAAAAAAAAAAA//////////////8A///////////////MAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////6wAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////iAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////////9kAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////0QAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////IAAAAAAAYP////////////////////////////8A//////////////wAAAAAAAB8/////////////////////////////wD/////////////3AAAAAAAAIj/////////////////////////////AP////////////+4AAAAAAAAoLRYHAAEKGTE//////////////////8A/////////////5QAAAAAAAAQAAAAAAAAAABY9P///////////////wD/////////////dAAAAAAAAAAAAAAAAAAAAAA89P//////////////AP////////////9QAAAAAAAAAAAAAAAAAAAAAABg//////////////8A/////////////zAAAAAAAAAAAAAAAAAAAAAAAADQ/////////////wD/////////////IAAAAAAAAGjY/+h4BAAAAAAAAGz/////////////AP//////////////9NS0lHSc//////90AAAAAAAALP////////////8A/////////////////////////////9QAAAAAAAAE/////////////wD//////////////////////////////wAAAAAAAAD/////////////AP/////////////////////////////8AAAAAAAAEP////////////8A////////////pIRwWEAgDOD//////8wAAAAAAAA8/////////////wD///////////9EAAAAAAAAaP//////ZAAAAAAAAHz/////////////AP///////////6QAAAAAAAAAaOD/4GQAAAAAAAAE4P////////////8A/////////////CQAAAAAAAAAAAAAAAAAAAAAAGD//////////////wD/////////////yAQAAAAAAAAAAAAAAAAAAAAc7P//////////////AP//////////////rAwAAAAAAAAAAAAAAAAAGNj///////////////8A////////////////0EAAAAAAAAAAAAAAAFTo/////////////////wD//////////////////8h4QCAAAAAcQHzU////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'6' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////+0ZCwMAAAUNGjI////////////////////AP/////////////////EMAAAAAAAAAAAAABM6P////////////////8A////////////////lAQAAAAAAAAAAAAAAAAo6P///////////////wD//////////////6wAAAAAAAAAAAAAAAAAAABI////////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAACw//////////////8A/////////////3AAAAAAAAAoxP/YPAAAAAAAAEj//////////////wD////////////4EAAAAAAACOD////YDCBAVGiAoP//////////////AP///////////7gAAAAAAABY//////////////////////////////8A////////////eAAAAAAAAJT//////////////////////////////wD///////////9MAAAAAAAAvP/IXBgABCx03P//////////////////AP///////////ygAAAAAAADcdAAAAAAAAAAEiP////////////////8A////////////FAAAAAAAAFAAAAAAAAAAAAAAcP///////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAlP//////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAQ8P////////////8A////////////AAAAAAAAAABAyP/kZAAAAAAAAACQ/////////////wD///////////8MAAAAAAAALPj/////WAAAAAAAAET/////////////AP///////////yQAAAAAAACY///////MAAAAAAAAFP////////////8A////////////SAAAAAAAAMD///////wAAAAAAAAA/////////////wD///////////9wAAAAAAAAvP///////wAAAAAAAAD/////////////AP///////////7QAAAAAAACI///////UAAAAAAAAJP////////////8A////////////+AwAAAAAACDw/////2wAAAAAAABY/////////////wD/////////////cAAAAAAAADC8/Ox4AAAAAAAAAKj/////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAAAk/P////////////8A//////////////+oAAAAAAAAAAAAAAAAAAAABLj//////////////wD///////////////+QAAAAAAAAAAAAAAAAAACQ////////////////AP////////////////+0JAAAAAAAAAAAAAAkuP////////////////8A///////////////////8sGg0FAAADCxgqPz//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'7' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAABP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAy4/////////////wD//////////////////////////+QUAAAAAAAEuP//////////////AP/////////////////////////8QAAAAAAAAKT///////////////8A/////////////////////////4wAAAAAAAB0/////////////////wD////////////////////////cCAAAAAAANPz/////////////////AP///////////////////////0QAAAAAAATY//////////////////8A//////////////////////+0AAAAAAAAeP///////////////////wD//////////////////////CQAAAAAABTw////////////////////AP////////////////////+gAAAAAAAAkP////////////////////8A/////////////////////ywAAAAAABDw/////////////////////wD///////////////////+4AAAAAAAAbP//////////////////////AP///////////////////1wAAAAAAADQ//////////////////////8A///////////////////4DAAAAAAAMP///////////////////////wD//////////////////7QAAAAAAAB8////////////////////////AP//////////////////aAAAAAAAAMj///////////////////////8A//////////////////8oAAAAAAAM/P///////////////////////wD/////////////////8AAAAAAAAET/////////////////////////AP////////////////+0AAAAAAAAcP////////////////////////8A/////////////////4wAAAAAAACY/////////////////////////wD/////////////////WAAAAAAAAMD/////////////////////////AP////////////////80AAAAAAAA4P////////////////////////8A/////////////////xAAAAAAAAD4/////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'8' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////////IdDQUAAAEIEiA1P//////////////////AP/////////////////gRAAAAAAAAAAAAAAAROD///////////////8A////////////////0BgAAAAAAAAAAAAAAAAAEMj//////////////wD///////////////AcAAAAAAAAAAAAAAAAAAAAHPD/////////////AP//////////////hAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A//////////////8sAAAAAAAAKMz/zCgAAAAAAAAs/////////////wD//////////////wAAAAAAAADM////zAAAAAAAAAD/////////////AP//////////////BAAAAAAAAP//////AAAAAAAABP////////////8A//////////////8sAAAAAAAAzP///9QAAAAAAAAw/////////////wD//////////////3wAAAAAAAAoyP/YNAAAAAAAAIT/////////////AP//////////////7BgAAAAAAAAAAAAAAAAAAAAc8P////////////8A////////////////xBgAAAAAAAAAAAAAAAAAGNj//////////////wD/////////////////tAQAAAAAAAAAAAAAAACo////////////////AP///////////////HAAAAAAAAAAAAAAAAAAAAB8//////////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB8/////////////wD/////////////wAAAAAAAAABk4P/UWAAAAAAAAATQ////////////AP////////////9UAAAAAAAAaP//////XAAAAAAAAGT///////////8A/////////////xgAAAAAAADg///////cAAAAAAAAJP///////////wD/////////////AAAAAAAAAP////////8AAAAAAAAA////////////AP////////////8AAAAAAAAA4P//////3AAAAAAAAAT///////////8A/////////////ygAAAAAAABg//////9cAAAAAAAALP///////////wD/////////////ZAAAAAAAAABY1P/cXAAAAAAAAABw////////////AP/////////////QAAAAAAAAAAAAAAAAAAAAAAAABNz///////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB0/////////////wD///////////////Q8AAAAAAAAAAAAAAAAAAAAUPz/////////////AP////////////////x4CAAAAAAAAAAAAAAAEIT8//////////////8A///////////////////smFQwGAAAABg0ZKT0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'9' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////ysYCwMAAAUNGiw/P//////////////////AP////////////////+4JAAAAAAAAAAAAAAkuP////////////////8A////////////////lAQAAAAAAAAAAAAAAAAAkP///////////////wD//////////////8AEAAAAAAAAAAAAAAAAAAAAqP//////////////AP/////////////8JAAAAAAAAAAAAAAAAAAAAAAQ7P////////////8A/////////////6wAAAAAAAAAfOz8vCwAAAAAAABw/////////////wD/////////////WAAAAAAAAHD/////7BgAAAAAAAz4////////////AP////////////8kAAAAAAAA1P//////hAAAAAAAALT///////////8A/////////////wAAAAAAAAD///////+4AAAAAAAAcP///////////wD/////////////AAAAAAAAAPz//////8AAAAAAAABI////////////AP////////////8UAAAAAAAAzP//////lAAAAAAAACT///////////8A/////////////0QAAAAAAABY//////gsAAAAAAAADP///////////wD/////////////kAAAAAAAAABw5P/IPAAAAAAAAAAA////////////AP/////////////wEAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////////+UAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////9wAAAAAAAAAAAAAFAAAAAAAAAU////////////AP////////////////+IBAAAAAAAAABw3AAAAAAAACj///////////8A///////////////////cdCwEABhcxP+8AAAAAAAATP///////////wD//////////////////////////////5AAAAAAAAB4////////////AP//////////////////////////////UAAAAAAAALj///////////8A//////////////+kgGxUQCAM2P///+AIAAAAAAAQ+P///////////wD//////////////0gAAAAAAAA42P/EKAAAAAAAAHD/////////////AP//////////////sAAAAAAAAAAAAAAAAAAAAAAQ6P////////////8A////////////////TAAAAAAAAAAAAAAAAAAAAKz//////////////wD////////////////oKAAAAAAAAAAAAAAAAASU////////////////AP/////////////////sUAAAAAAAAAAAAAAwxP////////////////8A////////////////////yHA0FAAADCxktP///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'A' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////+QAAAAAAAAAAAAAAOT/////////////////AP//////////////////kAAAAAAAAAAAAAAAkP////////////////8A//////////////////88AAAAAAAAAAAAAAA8/////////////////wD/////////////////5AAAAAAAAAAAAAAAAADk////////////////AP////////////////+QAAAAAAAAAAAAAAAAAJD///////////////8A/////////////////zwAAAAAAAAAAAAAAAAAPP///////////////wD////////////////kAAAAAAAAAAgAAAAAAAAA5P//////////////AP///////////////5AAAAAAAAAAgAAAAAAAAACQ//////////////8A////////////////PAAAAAAAAAz8HAAAAAAAADz//////////////wD//////////////+QAAAAAAAAAWP9kAAAAAAAAANz/////////////AP//////////////kAAAAAAAAACk/7wAAAAAAAAAhP////////////8A//////////////88AAAAAAAABOz//BQAAAAAAAAw/////////////wD/////////////4AAAAAAAAAA8////ZAAAAAAAAADc////////////AP////////////+EAAAAAAAAAIj///+8AAAAAAAAAIT///////////8A/////////////zAAAAAAAAAA2P////wQAAAAAAAAMP///////////wD////////////cAAAAAAAAACT//////1wAAAAAAAAA3P//////////AP///////////4QAAAAAAAAAAAAAAAAAAAAAAAAAAACE//////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAAAAAADD//////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANz/////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhP////////8A//////////8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/////////wD/////////3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc////////AP////////+EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIT///////8A/////////zAAAAAAAAAAhP///////////2QAAAAAAAAAMP///////wD////////cAAAAAAAAAADM////////////vAAAAAAAAAAA3P//////AP///////4QAAAAAAAAAHP/////////////4DAAAAAAAAACE//////8A////////MAAAAAAAAABk//////////////9cAAAAAAAAADD//////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'B' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAEDh83P///////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAEhP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAeP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAABY////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAABT///////////8A//////////8AAAAAAAAAAP/////4zEwAAAAAAAAAAP///////////wD//////////wAAAAAAAAAA////////7AAAAAAAAAAQ////////////AP//////////AAAAAAAAAAD////////sAAAAAAAAAEj///////////8A//////////8AAAAAAAAAAP/////4zEQAAAAAAAAAtP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAFz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAiA/P////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAIjPj//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAGKz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJT///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAABNz//////////wD//////////wAAAAAAAAAA///////sqCAAAAAAAAAAbP//////////AP//////////AAAAAAAAAAD/////////yAAAAAAAAAAs//////////8A//////////8AAAAAAAAAAP//////////AAAAAAAAAAT//////////wD//////////wAAAAAAAAAA/////////7wAAAAAAAAAAP//////////AP//////////AAAAAAAAAAD//////+ikGAAAAAAAAAAY//////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFT//////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsP//////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADj///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAc6P///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAATOj/////////////AP//////////AAAAAAAAAAAAAAAAAAAEIEBkkNj///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'C' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////5JRULBAAAAgkTIDQ//////////////////8A////////////////1FAAAAAAAAAAAAAAAABAyP///////////////wD//////////////4gEAAAAAAAAAAAAAAAAAAAElP//////////////AP////////////9wAAAAAAAAAAAAAAAAAAAAAAAAlP////////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAEyP///////////wD//////////9wIAAAAAAAAAAAAAAAAAAAAAAAAAAAw////////////AP//////////WAAAAAAAAAAAWMz/8JwQAAAAAAAAAACw//////////8A/////////+wEAAAAAAAAAID//////9QMAAAAAAAAAET//////////wD/////////nAAAAAAAAAAo/P///////3wAAAAABDBspP//////////AP////////9gAAAAAAAAAIz/////////3BxQjMT0//////////////8A/////////zQAAAAAAAAAzP///////////////////////////////wD/////////GAAAAAAAAADo////////////////////////////////AP////////8AAAAAAAAAAP////////////////////////////////8A/////////wAAAAAAAAAA/////////////////////////////////wD/////////AAAAAAAAAAD/////////////////////////////////AP////////8cAAAAAAAAAOj///////////////////////////////8A/////////zgAAAAAAAAA0P/////////kIGio7P///////////////wD/////////bAAAAAAAAACg/////////5wAAAAAMHS49P//////////AP////////+oAAAAAAAAAEz/////////PAAAAAAAAAAc//////////8A//////////QIAAAAAAAAALz//////6QAAAAAAAAAAGT//////////wD//////////3AAAAAAAAAADIzo/+SEBAAAAAAAAAAAyP//////////AP//////////7BAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////rAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD/////////////fAAAAAAAAAAAAAAAAAAAAAAAAJz/////////////AP//////////////iAQAAAAAAAAAAAAAAAAAAASY//////////////8A////////////////yEAAAAAAAAAAAAAAAAA8yP///////////////wD//////////////////9yIUCwQAAAAIEB4yP//////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'D' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAADChQkOT/////////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAABGjw//////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAACDY/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAABjk////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKj//////////wD///////////8AAAAAAAAAAP///+isSAAAAAAAAAAANP//////////AP///////////wAAAAAAAAAA////////hAAAAAAAAAAA2P////////8A////////////AAAAAAAAAAD/////////MAAAAAAAAACQ/////////wD///////////8AAAAAAAAAAP////////+MAAAAAAAAAFj/////////AP///////////wAAAAAAAAAA/////////8gAAAAAAAAAMP////////8A////////////AAAAAAAAAAD/////////5AAAAAAAAAAY/////////wD///////////8AAAAAAAAAAP//////////AAAAAAAAAAD/////////AP///////////wAAAAAAAAAA//////////8AAAAAAAAAAP////////8A////////////AAAAAAAAAAD//////////wAAAAAAAAAA/////////wD///////////8AAAAAAAAAAP/////////wAAAAAAAAABD/////////AP///////////wAAAAAAAAAA/////////9QAAAAAAAAAJP////////8A////////////AAAAAAAAAAD/////////qAAAAAAAAABI/////////wD///////////8AAAAAAAAAAP////////9QAAAAAAAAAHj/////////AP///////////wAAAAAAAAAA////////uAAAAAAAAAAAvP////////8A////////////AAAAAAAAAAD////w0HwEAAAAAAAAACT8/////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAADz8//////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAY6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAKNz/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAACHT0//////////////8A////////////AAAAAAAAAAAAAAAAABg4bKj0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'E' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'F' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'G' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////MB8TCgQAAAACCA4YJzs////////////////AP///////////////JQcAAAAAAAAAAAAAAAAAAhw8P////////////8A/////////////9gwAAAAAAAAAAAAAAAAAAAAAAAk2P///////////wD////////////EDAAAAAAAAAAAAAAAAAAAAAAAAAAc7P//////////AP//////////2AwAAAAAAAAAAAAAAAAAAAAAAAAAAABY//////////8A//////////wwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ/////////wD/////////kAAAAAAAAAAAEHzQ/P/gmCAAAAAAAAAAAFz/////////AP////////wcAAAAAAAAACjg////////8CwAAAAAAAAgWP////////8A////////vAAAAAAAAAAI2P//////////yBRAcJjI8P///////////wD///////94AAAAAAAAAGD/////////////////////////////////AP///////0AAAAAAAAAAsP////////////////////////////////8A////////IAAAAAAAAADc/////////////////////////////////wD///////8AAAAAAAAAAP///////wAAAAAAAAAAAAAAAAD/////////AP///////wAAAAAAAAAA////////AAAAAAAAAAAAAAAAAP////////8A////////AAAAAAAAAAD///////8AAAAAAAAAAAAAAAAA/////////wD///////8gAAAAAAAAAOD//////wAAAAAAAAAAAAAAAAD/////////AP///////0AAAAAAAAAAtP//////AAAAAAAAAAAAAAAAAP////////8A////////cAAAAAAAAABw//////8AAAAAAAAAAAAAAAAA/////////wD///////+8AAAAAAAAABDs////////////AAAAAAAAAAD/////////AP////////wYAAAAAAAAADz0//////////AAAAAAAAAAAP////////8A/////////5AAAAAAAAAAACCY4P//3KhcCAAAAAAAAAAA/////////wD/////////+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AP//////////xAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP////////8A////////////rAQAAAAAAAAAAAAAAAAAAAAAAAAAAGTw/////////wD/////////////vBQAAAAAAAAAAAAAAAAAAAAAADjI////////////AP//////////////8HAQAAAAAAAAAAAAAAAAAEiw//////////////8A//////////////////iwcEAgBAAABCA4aKDk/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'H' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'I' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'J' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAj//////////////wD//////////+zMrIxwUDAQ//////wAAAAAAAAAIP//////////////AP//////////DAAAAAAAAADo////2AAAAAAAAAA0//////////////8A//////////8wAAAAAAAAAKj///+YAAAAAAAAAFj//////////////wD//////////2gAAAAAAAAAIND/yBgAAAAAAAAAkP//////////////AP//////////vAAAAAAAAAAAAAAAAAAAAAAAAADc//////////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAUP///////////////wD////////////EBAAAAAAAAAAAAAAAAAAAABjk////////////////AP////////////+sBAAAAAAAAAAAAAAAAAAY2P////////////////8A///////////////EMAAAAAAAAAAAAAAAVOj//////////////////wD/////////////////vHBAIAAAABg8fNT/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'K' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////8AAAAAAAAAAP//////////wAQAAAAAAAAAAABw////////AP///////wAAAAAAAAAA/////////9AMAAAAAAAAAAAAcP////////8A////////AAAAAAAAAAD////////cGAAAAAAAAAAAAHD//////////wD///////8AAAAAAAAAAP//////6CgAAAAAAAAAAABs////////////AP///////wAAAAAAAAAA//////Q0AAAAAAAAAAAAVPz///////////8A////////AAAAAAAAAAD////8RAAAAAAAAAAAAFT8/////////////wD///////8AAAAAAAAAAP///1gAAAAAAAAAAABU/P//////////////AP///////wAAAAAAAAAA//9wAAAAAAAAAAAASPz///////////////8A////////AAAAAAAAAAD/jAAAAAAAAAAAADz0/////////////////wD///////8AAAAAAAAAAKQAAAAAAAAAAAA89P//////////////////AP///////wAAAAAAAAAABAAAAAAAAAAAFPT///////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAApP///////////////////wD///////8AAAAAAAAAAAAAAAAAAAAAAAAU8P//////////////////AP///////wAAAAAAAAAAAAAAAAAAAAAAAABk//////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAAAADE/////////////////wD///////8AAAAAAAAAAAAAAAAoEAAAAAAAACz8////////////////AP///////wAAAAAAAAAAAAAAGNiAAAAAAAAAAIj///////////////8A////////AAAAAAAAAAAAABjY//gYAAAAAAAACOD//////////////wD///////8AAAAAAAAAAAAY2P///5wAAAAAAAAASP//////////////AP///////wAAAAAAAAAAGNj//////CgAAAAAAAAAqP////////////8A////////AAAAAAAAAADI////////sAAAAAAAAAAc8P///////////wD///////8AAAAAAAAAAP//////////QAAAAAAAAABs////////////AP///////wAAAAAAAAAA///////////IAAAAAAAAAATI//////////8A////////AAAAAAAAAAD///////////9YAAAAAAAAADD8/////////wD///////8AAAAAAAAAAP///////////9wEAAAAAAAAAJD/////////AP///////wAAAAAAAAAA/////////////3AAAAAAAAAADOT///////8A////////AAAAAAAAAAD/////////////7BAAAAAAAAAAUP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'L' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'M' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////8AAAAAAAAAAAAAAHz//////3wAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAATP//////UAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAc//////8cAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAADw////8AAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAAALz////AAAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAAkP///5AAAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAABc////ZAAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAoAAAAADD///8wAAAAACQAAAAAAAAA////////AP//////AAAAAAAAAFwAAAAABPz//AgAAAAAXAAAAAAAAAD///////8A//////8AAAAAAAAAkAAAAAAA0P/UAAAAAACQAAAAAAAAAP///////wD//////wAAAAAAAADMAAAAAACg/6gAAAAAAMQAAAAAAAAA////////AP//////AAAAAAAAAPgEAAAAAHD/dAAAAAAE+AAAAAAAAAD///////8A//////8AAAAAAAAA/zQAAAAAQP9IAAAAADD/AAAAAAAAAP///////wD//////wAAAAAAAAD/bAAAAAAQ/xQAAAAAaP8AAAAAAAAA////////AP//////AAAAAAAAAP+gAAAAAADQAAAAAACc/wAAAAAAAAD///////8A//////8AAAAAAAAA/9QAAAAAAGgAAAAAAND/AAAAAAAAAP///////wD//////wAAAAAAAAD//wwAAAAAFAAAAAAM/P8AAAAAAAAA////////AP//////AAAAAAAAAP//RAAAAAAAAAAAADz//wAAAAAAAAD///////8A//////8AAAAAAAAA//94AAAAAAAAAAAAcP//AAAAAAAAAP///////wD//////wAAAAAAAAD//7AAAAAAAAAAAACo//8AAAAAAAAA////////AP//////AAAAAAAAAP//5AAAAAAAAAAAANz//wAAAAAAAAD///////8A//////8AAAAAAAAA////HAAAAAAAAAAQ////AAAAAAAAAP///////wD//////wAAAAAAAAD///9QAAAAAAAAAEz///8AAAAAAAAA////////AP//////AAAAAAAAAP///4gAAAAAAAAAfP///wAAAAAAAAD///////8A//////8AAAAAAAAA////vAAAAAAAAACw////AAAAAAAAAP///////wD//////wAAAAAAAAD////wAAAAAAAAAOz///8AAAAAAAAA////////AP//////AAAAAAAAAP////8sAAAAAAAc/////wAAAAAAAAD///////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'N' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAALD/////////////AAAAAAAAAP//////////AP////////8AAAAAAAAAFOj///////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAASP///////////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAkP//////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAI1P////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAw+P///////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAABw////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAC8//////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAABzs/////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAFD/////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAJz///8AAAAAAAAA//////////8A/////////wAAAAAAAAAUAAAAAAAADNz//wAAAAAAAAD//////////wD/////////AAAAAAAAALQAAAAAAAAANPz/AAAAAAAAAP//////////AP////////8AAAAAAAAA/2wAAAAAAAAAfP8AAAAAAAAA//////////8A/////////wAAAAAAAAD/+CwAAAAAAAAExAAAAAAAAAD//////////wD/////////AAAAAAAAAP//0AQAAAAAAAAgAAAAAAAAAP//////////AP////////8AAAAAAAAA////jAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////RAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP/////kFAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA//////+sAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD///////9kAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP////////QkAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA/////////8wEAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD//////////4QAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP///////////DwAAAAAAAAAAP//////////AP////////8AAAAAAAAA////////////4BAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////////////qAAAAAAAAAD//////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'O' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////0qGw4HAAAABw4aKT0/////////////////wD////////////////wcAwAAAAAAAAAAAAAAAho6P//////////////AP//////////////uBQAAAAAAAAAAAAAAAAAAAAMoP////////////8A/////////////6AEAAAAAAAAAAAAAAAAAAAAAAAAkP///////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP//////////8BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAM5P////////8A//////////9wAAAAAAAAAAAsrPD/7KQsAAAAAAAAAABg/////////wD/////////+BAAAAAAAAAAUPj///////hQAAAAAAAAAAjs////////AP////////+sAAAAAAAAABDw//////////AYAAAAAAAAAKD///////8A/////////2wAAAAAAAAAdP///////////3wAAAAAAAAAYP///////wD/////////OAAAAAAAAAC4////////////xAAAAAAAAAAw////////AP////////8cAAAAAAAAAOD////////////oAAAAAAAAABT///////8A/////////wAAAAAAAAAA//////////////8AAAAAAAAAAP///////wD/////////AAAAAAAAAAD//////////////wAAAAAAAAAA////////AP////////8AAAAAAAAAAP/////////////8AAAAAAAAAAD///////8A/////////xwAAAAAAAAA5P///////////+AAAAAAAAAAHP///////wD/////////NAAAAAAAAAC8////////////uAAAAAAAAAA4////////AP////////9oAAAAAAAAAHj///////////98AAAAAAAAAGT///////8A/////////6gAAAAAAAAAGPD/////////+BgAAAAAAAAApP///////wD/////////9AwAAAAAAAAAUPz///////xcAAAAAAAAAAjs////////AP//////////cAAAAAAAAAAALKjs//CwOAAAAAAAAAAAYP////////8A///////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzk/////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP////////////+QAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A//////////////+sEAAAAAAAAAAAAAAAAAAAAAyg/////////////wD////////////////oZAgAAAAAAAAAAAAAAARg4P//////////////AP//////////////////9KhsOCAAAAAUMFyc7P////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'P' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////wAAAAAAAAAAAAAAAAAACCxguP////////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAOOD//////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAGOD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAARP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAABo////////////AP///////////wAAAAAAAAAA////6JwMAAAAAAAAADD///////////8A////////////AAAAAAAAAAD//////6AAAAAAAAAADP///////////wD///////////8AAAAAAAAAAP//////9AAAAAAAAAAA////////////AP///////////wAAAAAAAAAA///////0AAAAAAAAAAD///////////8A////////////AAAAAAAAAAD//////5gAAAAAAAAAHP///////////wD///////////8AAAAAAAAAAP///9iICAAAAAAAAABI////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAIT/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAABU/P////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAIhPz//////////////wD///////////8AAAAAAAAAAAAAAAAABCRMkOz/////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'Q' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////SoaDQcAAAAHDhoqPT///////////////////8A//////////////BwDAAAAAAAAAAAAAAACHDo/////////////////wD///////////+4FAAAAAAAAAAAAAAAAAAAABCo////////////////AP//////////nAQAAAAAAAAAAAAAAAAAAAAAAACQ//////////////8A/////////7gEAAAAAAAAAAAAAAAAAAAAAAAAAACg/////////////wD////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzo////////////AP///////3AAAAAAAAAAACyo8P/sqCwAAAAAAAAAAGT///////////8A///////4EAAAAAAAAABM+P///////FQAAAAAAAAACPT//////////wD//////7AAAAAAAAAAFPD/////////9BgAAAAAAAAApP//////////AP//////bAAAAAAAAAB4////////////fAAAAAAAAABk//////////8A//////84AAAAAAAAALz///////////+8AAAAAAAAADT//////////wD//////xwAAAAAAAAA6P///////////+QAAAAAAAAAHP//////////AP//////AAAAAAAAAAD//////////////wAAAAAAAAAA//////////8A//////8AAAAAAAAAAP//////////////AAAAAAAAAAD//////////wD//////wAAAAAAAAAA/P////////////8AAAAAAAAAAP//////////AP//////GAAAAAAAAADg////////////4AAAAAAAAAAc//////////8A//////84AAAAAAAAALT////MJHTo//+8AAAAAAAAADT//////////wD//////2wAAAAAAAAAdP///2AAABCg/3wAAAAAAAAAZP//////////AP//////rAAAAAAAAAAY9P/sCAAAAABMGAAAAAAAAACk//////////8A///////4EAAAAAAAAABU/P+0OAAAAAAAAAAAAAAACPT//////////wD///////94AAAAAAAAAAA4sPD/gAAAAAAAAAAAAABk////////////AP////////AcAAAAAAAAAAAAAAAAAAAAAAAAAAAADOT///////////8A/////////7wEAAAAAAAAAAAAAAAAAAAAAAAAAACQ/////////////wD//////////6wEAAAAAAAAAAAAAAAAAAAAAAAAABSs////////////AP///////////7gUAAAAAAAAAAAAAAAAAAAAAAAAAABAwP////////8A//////////////BwDAAAAAAAAAAAAAAABAgAAAAAAAA8/////////wD////////////////0qGg0GAAAABgwXJjkxBgAAAAAALD/////////AP//////////////////////////////////5DQAAAAk/P////////8A////////////////////////////////////+GwAAJD//////////wD//////////////////////////////////////8A49P//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'R' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////wAAAAAAAAAAAAAAAAAAAAQgOGSk+P///////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAcuP//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAEsP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ6P///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADD///////////8A/////////wAAAAAAAAAA///////svDgAAAAAAAAACP///////////wD/////////AAAAAAAAAAD/////////7AAAAAAAAAAA////////////AP////////8AAAAAAAAAAP/////////cAAAAAAAAABD///////////8A/////////wAAAAAAAAAA//////DQoCQAAAAAAAAAQP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACU////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPj///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAzU/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAA02P//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAxctPz///////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAEDY/////////////////wD/////////AAAAAAAAAAD/9LAsAAAAAAAAAAzc////////////////AP////////8AAAAAAAAAAP///+wkAAAAAAAAADD8//////////////8A/////////wAAAAAAAAAA/////8QAAAAAAAAAAJD//////////////wD/////////AAAAAAAAAAD//////1QAAAAAAAAAFPD/////////////AP////////8AAAAAAAAAAP//////3AQAAAAAAAAAgP////////////8A/////////wAAAAAAAAAA////////aAAAAAAAAAAM6P///////////wD/////////AAAAAAAAAAD////////oCAAAAAAAAABs////////////AP////////8AAAAAAAAAAP////////+AAAAAAAAAAATc//////////8A/////////wAAAAAAAAAA//////////AUAAAAAAAAAFj//////////wD/////////AAAAAAAAAAD//////////5AAAAAAAAAAAND/////////AP////////8AAAAAAAAAAP//////////+CQAAAAAAAAAQP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'S' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////8vHBEIAgAAAQgQHC8/P////////////////8A////////////////pCQAAAAAAAAAAAAAAAAcoP///////////////wD//////////////FwAAAAAAAAAAAAAAAAAAAAAXP//////////////AP////////////9oAAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A////////////zAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////9cAAAAAAAAAAAAAAAAAAAAAAAAAACA////////////AP///////////xgAAAAAAAAAUOD/8KwkAAAAAAAAADj///////////8A////////////AAAAAAAAAAD0/////8wABCAgICxASP///////////wD///////////8MAAAAAAAAAMz/////////////////////////////AP///////////0AAAAAAAAAACFiQxPT///////////////////////8A////////////oAAAAAAAAAAAAAAAADBwtPT//////////////////wD////////////8QAAAAAAAAAAAAAAAAAAACFTA////////////////AP/////////////oOAAAAAAAAAAAAAAAAAAAAABM6P////////////8A///////////////4fAgAAAAAAAAAAAAAAAAAAAAY2P///////////wD/////////////////7IwwAAAAAAAAAAAAAAAAAAAo+P//////////AP/////////////////////koGw0BAAAAAAAAAAAAACU//////////8A///////////////////////////4uFgAAAAAAAAAADz//////////wD//////////2BgSEA0IBwA6P///////5QAAAAAAAAADP//////////AP//////////JAAAAAAAAACc/////////AAAAAAAAAAA//////////8A//////////9YAAAAAAAAACDo///////AAAAAAAAAABT//////////wD//////////6QAAAAAAAAAACCk7P/snBQAAAAAAAAAUP//////////AP//////////+BAAAAAAAAAAAAAAAAAAAAAAAAAAAACs//////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAAOP///////////wD////////////8RAAAAAAAAAAAAAAAAAAAAAAAABjc////////////AP/////////////0PAAAAAAAAAAAAAAAAAAAAAAg2P////////////8A///////////////8hBQAAAAAAAAAAAAAAAAMdPT//////////////wD/////////////////+LRwSCAMAAAAHDhoqPT/////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'T' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'U' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////JAAAAAAAAADk/////////+gAAAAAAAAAHP//////////AP////////9MAAAAAAAAAJz/////////nAAAAAAAAABE//////////8A/////////4gAAAAAAAAAHOj//////+ggAAAAAAAAAHz//////////wD/////////0AAAAAAAAAAAIJzs/+ykIAAAAAAAAAAA0P//////////AP//////////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A///////////IBAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAAAAJj/////////////AP////////////+UBAAAAAAAAAAAAAAAAAAAAASU//////////////8A///////////////IPAAAAAAAAAAAAAAAAAAwyP///////////////wD/////////////////0IxYOCAIAAAEIEiAyP//////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'V' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////zAAAAAAAAAAYP//////////////ZAAAAAAAAAAw////////AP//////kAAAAAAAAAAU/P////////////8UAAAAAAAAAJD///////8A///////oBAAAAAAAAADE////////////xAAAAAAAAAAE7P///////wD///////9MAAAAAAAAAHD///////////94AAAAAAAAAEz/////////AP///////6gAAAAAAAAAJP///////////yQAAAAAAAAArP////////8A////////+BAAAAAAAAAA1P/////////YAAAAAAAAABT4/////////wD/////////aAAAAAAAAACE/////////4QAAAAAAAAAbP//////////AP/////////EAAAAAAAAADT/////////OAAAAAAAAADM//////////8A//////////8kAAAAAAAAAOT//////+QAAAAAAAAAKP///////////wD//////////4QAAAAAAAAAmP//////nAAAAAAAAACI////////////AP//////////5AAAAAAAAABE//////9EAAAAAAAABOT///////////8A////////////QAAAAAAAAAT0////9AgAAAAAAABI/////////////wD///////////+gAAAAAAAAAKT///+kAAAAAAAAAKj/////////////AP////////////QIAAAAAAAAXP///1wAAAAAAAAM+P////////////8A/////////////1wAAAAAAAAM+P/8DAAAAAAAAGT//////////////wD/////////////vAAAAAAAAAC8/7wAAAAAAAAAxP//////////////AP//////////////HAAAAAAAAGj/aAAAAAAAACT///////////////8A//////////////94AAAAAAAAHP8cAAAAAAAAhP///////////////wD//////////////9gAAAAAAAAAkAAAAAAAAADk////////////////AP///////////////zgAAAAAAAAQAAAAAAAAQP////////////////8A////////////////lAAAAAAAAAAAAAAAAACg/////////////////wD////////////////sCAAAAAAAAAAAAAAADPT/////////////////AP////////////////9QAAAAAAAAAAAAAABg//////////////////8A/////////////////7AAAAAAAAAAAAAAAMD//////////////////wD//////////////////BQAAAAAAAAAAAAc////////////////////AP//////////////////cAAAAAAAAAAAAHz///////////////////8A///////////////////MAAAAAAAAAAAA3P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'W' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//8cAAAAAAAAALz/////4AAAAAAAAAAA6P////+8AAAAAAAAABz//wD//1QAAAAAAAAAjP////+gAAAAAAAAAACo/////4wAAAAAAAAAUP//AP//jAAAAAAAAABU/////2AAAAAAAAAAAGj/////VAAAAAAAAACM//8A///EAAAAAAAAACT/////IAAAAAAAAAAAKP////8kAAAAAAAAAMT//wD///gEAAAAAAAAAPD//+AAAAAAAAAAAAAA6P//8AAAAAAAAAAE9P//AP///zAAAAAAAAAAvP//oAAAAAAAAAAAAACo//+8AAAAAAAAADD///8A////bAAAAAAAAACM//9gAAAAAAAAAAAAAGT//4wAAAAAAAAAaP///wD///+kAAAAAAAAAFT//yAAAAAAAAAAAAAAIP//VAAAAAAAAACc////AP///9gAAAAAAAAAJP/gAAAAAAAAAAAAAAAA4P8kAAAAAAAAANT///8A/////xAAAAAAAAAA8KAAAAAAAAAAAAAAAACg8AAAAAAAAAAQ/////wD/////TAAAAAAAAAC8YAAAAAAAAAAAAAAAAGC8AAAAAAAAAET/////AP////+AAAAAAAAAAIwgAAAAAAAAAAAAAAAAIIwAAAAAAAAAfP////8A/////7gAAAAAAAAANAAAAAAAACwwAAAAAAAANAAAAAAAAACw/////wD/////8AAAAAAAAAAAAAAAAAAAdHgAAAAAAAAAAAAAAAAAAOz/////AP//////KAAAAAAAAAAAAAAAAAC4vAAAAAAAAAAAAAAAAAAg//////8A//////9gAAAAAAAAAAAAAAAACPj4CAAAAAAAAAAAAAAAAFj//////wD//////5QAAAAAAAAAAAAAAABE//9IAAAAAAAAAAAAAAAAkP//////AP//////0AAAAAAAAAAAAAAAAIj//4wAAAAAAAAAAAAAAADI//////8A///////8DAAAAAAAAAAAAAAAzP//1AAAAAAAAAAAAAAABPj//////wD///////88AAAAAAAAAAAAABT/////GAAAAAAAAAAAAAA0////////AP///////3QAAAAAAAAAAAAAWP////9gAAAAAAAAAAAAAHD///////8A////////sAAAAAAAAAAAAACg/////6QAAAAAAAAAAAAApP///////wD////////kAAAAAAAAAAAAAOT/////6AAAAAAAAAAAAADc////////AP////////8cAAAAAAAAAAAo////////MAAAAAAAAAAAEP////////8A/////////1QAAAAAAAAAAHD///////94AAAAAAAAAABM/////////wD/////////jAAAAAAAAAAAtP///////7wAAAAAAAAAAID/////////AP/////////EAAAAAAAAAAT0////////+AgAAAAAAAAAuP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'X' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////9UAAAAAAAAAKz///////////+sAAAAAAAAAFD/////////AP///////+QQAAAAAAAAFOT/////////8BwAAAAAAAAM5P////////8A/////////5gAAAAAAAAATP////////9kAAAAAAAAAJD//////////wD//////////0AAAAAAAAAAoP//////wAAAAAAAAAA0/P//////////AP//////////2AgAAAAAAAAQ4P////gkAAAAAAAABMz///////////8A////////////iAAAAAAAAABA////dAAAAAAAAABw/////////////wD////////////8MAAAAAAAAACU/9AEAAAAAAAAHPD/////////////AP/////////////IBAAAAAAAAAzYMAAAAAAAAACs//////////////8A//////////////90AAAAAAAAABAAAAAAAAAATP///////////////wD///////////////QgAAAAAAAAAAAAAAAAAAzg////////////////AP///////////////7wAAAAAAAAAAAAAAAAAjP////////////////8A/////////////////2AAAAAAAAAAAAAAADD8/////////////////wD/////////////////7BQAAAAAAAAAAAAEyP//////////////////AP/////////////////gDAAAAAAAAAAAAAjY//////////////////8A/////////////////0AAAAAAAAAAAAAAADj8/////////////////wD///////////////+UAAAAAAAAAAAAAAAAAJD/////////////////AP//////////////4AwAAAAAAAAAAAAAAAAADOD///////////////8A//////////////9AAAAAAAAAAAAAAAAAAAAAQP///////////////wD/////////////nAAAAAAAAAAAWAAAAAAAAAAAlP//////////////AP///////////+QQAAAAAAAAAGD/YAAAAAAAAAAM4P////////////8A////////////TAAAAAAAAAAs9P/0LAAAAAAAAABM/////////////wD//////////6AAAAAAAAAADNT////UDAAAAAAAAACg////////////AP/////////kEAAAAAAAAACg//////+gAAAAAAAAABDk//////////8A/////////0wAAAAAAAAAYP////////9gAAAAAAAAAEz//////////wD///////+oAAAAAAAAACz0//////////QsAAAAAAAAAKT/////////AP//////7BQAAAAAAAAM1P///////////9QMAAAAAAAAFOz///////8A//////9UAAAAAAAAAKD//////////////6AAAAAAAAAAVP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'Y' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////1QAAAAAAAAAAGj//////////2gAAAAAAAAAAFT///////8A////////5BAAAAAAAAAAAMT////////EAAAAAAAAAAAQ5P///////wD/////////mAAAAAAAAAAAKPj/////+CgAAAAAAAAAAJj/////////AP//////////PAAAAAAAAAAAgP////+AAAAAAAAAAAA8//////////8A///////////YCAAAAAAAAAAE2P//2AQAAAAAAAAACNj//////////wD///////////+AAAAAAAAAAAA4//84AAAAAAAAAACA////////////AP////////////woAAAAAAAAAACUlAAAAAAAAAAAKPz///////////8A/////////////8gAAAAAAAAAABAQAAAAAAAAAADI/////////////wD//////////////2wAAAAAAAAAAAAAAAAAAAAAbP//////////////AP//////////////8BwAAAAAAAAAAAAAAAAAABzw//////////////8A////////////////tAAAAAAAAAAAAAAAAAAAtP///////////////wD/////////////////VAAAAAAAAAAAAAAAAFT/////////////////AP/////////////////oEAAAAAAAAAAAAAAQ6P////////////////8A//////////////////+cAAAAAAAAAAAAAJz//////////////////wD///////////////////9AAAAAAAAAAABA////////////////////AP///////////////////9gAAAAAAAAAANj///////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
'Z' => array(
|
||||
'data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAQ//////////////8A/////////////////////////1AAAAAAAAAABLz//////////////wD///////////////////////98AAAAAAAAAACY////////////////AP//////////////////////pAAAAAAAAAAAaP////////////////8A/////////////////////8QIAAAAAAAAAET8/////////////////wD////////////////////gGAAAAAAAAAAo9P//////////////////AP//////////////////9CwAAAAAAAAAFNz///////////////////8A//////////////////xMAAAAAAAAAATA/////////////////////wD/////////////////eAAAAAAAAAAAnP//////////////////////AP///////////////5wAAAAAAAAAAHT///////////////////////8A///////////////ABAAAAAAAAABM/P///////////////////////wD/////////////3BQAAAAAAAAALPT/////////////////////////AP////////////QoAAAAAAAAABjg//////////////////////////8A///////////8SAAAAAAAAAAExP///////////////////////////wD//////////2wAAAAAAAAAAKD/////////////////////////////AP////////+YAAAAAAAAAAB8//////////////////////////////8A/////////wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=',
|
||||
'width' => 40
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
372
phpBB/phpbb/captcha/plugins/captcha_abstract.php
Normal file
372
phpBB/phpbb/captcha/plugins/captcha_abstract.php
Normal file
@@ -0,0 +1,372 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha\plugins;
|
||||
|
||||
/**
|
||||
* This class holds the code shared by the two default 3.0.x CAPTCHAs.
|
||||
*/
|
||||
abstract class captcha_abstract
|
||||
{
|
||||
var $confirm_id;
|
||||
var $confirm_code;
|
||||
var $code;
|
||||
var $seed;
|
||||
var $attempts = 0;
|
||||
var $type;
|
||||
var $solved = 0;
|
||||
var $captcha_vars = false;
|
||||
|
||||
function init($type)
|
||||
{
|
||||
global $config, $db, $user;
|
||||
|
||||
// read input
|
||||
$this->confirm_id = request_var('confirm_id', '');
|
||||
$this->confirm_code = request_var('confirm_code', '');
|
||||
$refresh = request_var('refresh_vc', false) && $config['confirm_refresh'];
|
||||
|
||||
$this->type = (int) $type;
|
||||
|
||||
if (!strlen($this->confirm_id) || !$this->load_code())
|
||||
{
|
||||
// we have no confirm ID, better get ready to display something
|
||||
$this->generate_code();
|
||||
}
|
||||
else if ($refresh)
|
||||
{
|
||||
$this->regenerate_code();
|
||||
}
|
||||
}
|
||||
|
||||
function execute_demo()
|
||||
{
|
||||
global $user;
|
||||
|
||||
$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
|
||||
$this->seed = hexdec(substr(unique_id(), 4, 10));
|
||||
|
||||
// compute $seed % 0x7fffffff
|
||||
$this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
|
||||
|
||||
$generator = $this->get_generator_class();
|
||||
$captcha = new $generator();
|
||||
define('IMAGE_OUTPUT', 1);
|
||||
$captcha->execute($this->code, $this->seed);
|
||||
}
|
||||
|
||||
function execute()
|
||||
{
|
||||
if (empty($this->code))
|
||||
{
|
||||
if (!$this->load_code())
|
||||
{
|
||||
// invalid request, bail out
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$generator = $this->get_generator_class();
|
||||
$captcha = new $generator();
|
||||
define('IMAGE_OUTPUT', 1);
|
||||
$captcha->execute($this->code, $this->seed);
|
||||
}
|
||||
|
||||
function get_template()
|
||||
{
|
||||
global $config, $user, $template, $phpEx, $phpbb_root_path;
|
||||
|
||||
if ($this->is_solved())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$link = append_sid($phpbb_root_path . 'ucp.' . $phpEx, 'mode=confirm&confirm_id=' . $this->confirm_id . '&type=' . $this->type);
|
||||
$contact_link = phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx);
|
||||
$explain = $user->lang(($this->type != CONFIRM_POST) ? 'CONFIRM_EXPLAIN' : 'POST_CONFIRM_EXPLAIN', '<a href="' . $contact_link . '">', '</a>');
|
||||
|
||||
$template->assign_vars(array(
|
||||
'CONFIRM_IMAGE_LINK' => $link,
|
||||
'CONFIRM_IMAGE' => '<img src="' . $link . '" />',
|
||||
'CONFIRM_IMG' => '<img src="' . $link . '" />',
|
||||
'CONFIRM_ID' => $this->confirm_id,
|
||||
'S_CONFIRM_CODE' => true,
|
||||
'S_TYPE' => $this->type,
|
||||
'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh'] && $this->type == CONFIRM_REG) ? true : false,
|
||||
'L_CONFIRM_EXPLAIN' => $explain,
|
||||
));
|
||||
|
||||
return 'captcha_default.html';
|
||||
}
|
||||
}
|
||||
|
||||
function get_demo_template($id)
|
||||
{
|
||||
global $config, $user, $template, $phpbb_admin_path, $phpEx;
|
||||
|
||||
$variables = '';
|
||||
|
||||
if (is_array($this->captcha_vars))
|
||||
{
|
||||
foreach ($this->captcha_vars as $captcha_var => $template_var)
|
||||
{
|
||||
$variables .= '&' . rawurlencode($captcha_var) . '=' . request_var($captcha_var, (int) $config[$captcha_var]);
|
||||
}
|
||||
}
|
||||
|
||||
// acp_captcha has a delivery function; let's use it
|
||||
$template->assign_vars(array(
|
||||
'CONFIRM_IMAGE' => append_sid($phpbb_admin_path . 'index.' . $phpEx, 'captcha_demo=1&mode=visual&i=' . $id . '&select_captcha=' . $this->get_service_name()) . $variables,
|
||||
'CONFIRM_ID' => $this->confirm_id,
|
||||
));
|
||||
|
||||
return 'captcha_default_acp_demo.html';
|
||||
}
|
||||
|
||||
function get_hidden_fields()
|
||||
{
|
||||
$hidden_fields = array();
|
||||
|
||||
// this is required for posting.php - otherwise we would forget about the captcha being already solved
|
||||
if ($this->solved)
|
||||
{
|
||||
$hidden_fields['confirm_code'] = $this->confirm_code;
|
||||
}
|
||||
$hidden_fields['confirm_id'] = $this->confirm_id;
|
||||
return $hidden_fields;
|
||||
}
|
||||
|
||||
function garbage_collect($type)
|
||||
{
|
||||
global $db, $config;
|
||||
|
||||
$sql = 'SELECT DISTINCT c.session_id
|
||||
FROM ' . CONFIRM_TABLE . ' c
|
||||
LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id)
|
||||
WHERE s.session_id IS NULL' .
|
||||
((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type);
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
if ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$sql_in = array();
|
||||
do
|
||||
{
|
||||
$sql_in[] = (string) $row['session_id'];
|
||||
}
|
||||
while ($row = $db->sql_fetchrow($result));
|
||||
|
||||
if (sizeof($sql_in))
|
||||
{
|
||||
$sql = 'DELETE FROM ' . CONFIRM_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('session_id', $sql_in);
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
function uninstall()
|
||||
{
|
||||
$this->garbage_collect(0);
|
||||
}
|
||||
|
||||
function install()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
function validate()
|
||||
{
|
||||
global $config, $db, $user;
|
||||
|
||||
if (empty($user->lang))
|
||||
{
|
||||
$user->setup();
|
||||
}
|
||||
|
||||
$error = '';
|
||||
if (!$this->confirm_id)
|
||||
{
|
||||
$error = $user->lang['CONFIRM_CODE_WRONG'];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->check_code())
|
||||
{
|
||||
$this->solved = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$error = $user->lang['CONFIRM_CODE_WRONG'];
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($error))
|
||||
{
|
||||
// okay, incorrect answer. Let's ask a new question.
|
||||
$this->new_attempt();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The old way to generate code, suitable for GD and non-GD. Resets the internal state.
|
||||
*/
|
||||
function generate_code()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
|
||||
$this->confirm_id = md5(unique_id($user->ip));
|
||||
$this->seed = hexdec(substr(unique_id(), 4, 10));
|
||||
$this->solved = 0;
|
||||
// compute $seed % 0x7fffffff
|
||||
$this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
|
||||
|
||||
$sql = 'INSERT INTO ' . CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array(
|
||||
'confirm_id' => (string) $this->confirm_id,
|
||||
'session_id' => (string) $user->session_id,
|
||||
'confirm_type' => (int) $this->type,
|
||||
'code' => (string) $this->code,
|
||||
'seed' => (int) $this->seed)
|
||||
);
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* New Question, if desired.
|
||||
*/
|
||||
function regenerate_code()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
|
||||
$this->seed = hexdec(substr(unique_id(), 4, 10));
|
||||
$this->solved = 0;
|
||||
// compute $seed % 0x7fffffff
|
||||
$this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
|
||||
|
||||
$sql = 'UPDATE ' . CONFIRM_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array(
|
||||
'code' => (string) $this->code,
|
||||
'seed' => (int) $this->seed)) . '
|
||||
WHERE
|
||||
confirm_id = \'' . $db->sql_escape($this->confirm_id) . '\'
|
||||
AND session_id = \'' . $db->sql_escape($user->session_id) . '\'';
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* New Question, if desired.
|
||||
*/
|
||||
function new_attempt()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
|
||||
$this->seed = hexdec(substr(unique_id(), 4, 10));
|
||||
$this->solved = 0;
|
||||
// compute $seed % 0x7fffffff
|
||||
$this->seed -= 0x7fffffff * floor($this->seed / 0x7fffffff);
|
||||
|
||||
$sql = 'UPDATE ' . CONFIRM_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array(
|
||||
'code' => (string) $this->code,
|
||||
'seed' => (int) $this->seed)) . '
|
||||
, attempts = attempts + 1
|
||||
WHERE
|
||||
confirm_id = \'' . $db->sql_escape($this->confirm_id) . '\'
|
||||
AND session_id = \'' . $db->sql_escape($user->session_id) . '\'';
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up everything we need for painting&checking.
|
||||
*/
|
||||
function load_code()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
$sql = 'SELECT code, seed, attempts
|
||||
FROM ' . CONFIRM_TABLE . "
|
||||
WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "'
|
||||
AND session_id = '" . $db->sql_escape($user->session_id) . "'
|
||||
AND confirm_type = " . $this->type;
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($row)
|
||||
{
|
||||
$this->code = $row['code'];
|
||||
$this->seed = $row['seed'];
|
||||
$this->attempts = $row['attempts'];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function check_code()
|
||||
{
|
||||
return (strcasecmp($this->code, $this->confirm_code) === 0);
|
||||
}
|
||||
|
||||
function get_attempt_count()
|
||||
{
|
||||
return $this->attempts;
|
||||
}
|
||||
|
||||
function reset()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
$sql = 'DELETE FROM ' . CONFIRM_TABLE . "
|
||||
WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
|
||||
AND confirm_type = " . (int) $this->type;
|
||||
$db->sql_query($sql);
|
||||
|
||||
// we leave the class usable by generating a new question
|
||||
$this->generate_code();
|
||||
}
|
||||
|
||||
function is_solved()
|
||||
{
|
||||
if (request_var('confirm_code', false) && $this->solved === 0)
|
||||
{
|
||||
$this->validate();
|
||||
}
|
||||
return (bool) $this->solved;
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function has_config()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the name of the service corresponding to the plugin
|
||||
*/
|
||||
abstract function get_service_name();
|
||||
|
||||
/**
|
||||
* @return string the name of the class used to generate the captcha
|
||||
*/
|
||||
abstract function get_generator_class();
|
||||
}
|
138
phpBB/phpbb/captcha/plugins/gd.php
Normal file
138
phpBB/phpbb/captcha/plugins/gd.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha\plugins;
|
||||
|
||||
class gd extends captcha_abstract
|
||||
{
|
||||
var $captcha_vars = array(
|
||||
'captcha_gd_x_grid' => 'CAPTCHA_GD_X_GRID',
|
||||
'captcha_gd_y_grid' => 'CAPTCHA_GD_Y_GRID',
|
||||
'captcha_gd_foreground_noise' => 'CAPTCHA_GD_FOREGROUND_NOISE',
|
||||
// 'captcha_gd' => 'CAPTCHA_GD_PREVIEWED',
|
||||
'captcha_gd_wave' => 'CAPTCHA_GD_WAVE',
|
||||
'captcha_gd_3d_noise' => 'CAPTCHA_GD_3D_NOISE',
|
||||
'captcha_gd_fonts' => 'CAPTCHA_GD_FONTS',
|
||||
);
|
||||
|
||||
public function is_available()
|
||||
{
|
||||
return @extension_loaded('gd');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the name of the service corresponding to the plugin
|
||||
*/
|
||||
function get_service_name()
|
||||
{
|
||||
return 'core.captcha.plugins.gd';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the name of the class used to generate the captcha
|
||||
*/
|
||||
function get_generator_class()
|
||||
{
|
||||
return '\\phpbb\\captcha\\gd';
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function has_config()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
return 'CAPTCHA_GD';
|
||||
}
|
||||
|
||||
function acp_page($id, &$module)
|
||||
{
|
||||
global $db, $user, $auth, $template;
|
||||
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
|
||||
|
||||
$user->add_lang('acp/board');
|
||||
|
||||
$config_vars = array(
|
||||
'enable_confirm' => 'REG_ENABLE',
|
||||
'enable_post_confirm' => 'POST_ENABLE',
|
||||
'confirm_refresh' => 'CONFIRM_REFRESH',
|
||||
'captcha_gd' => 'CAPTCHA_GD',
|
||||
);
|
||||
|
||||
$module->tpl_name = 'captcha_gd_acp';
|
||||
$module->page_title = 'ACP_VC_SETTINGS';
|
||||
$form_key = 'acp_captcha';
|
||||
add_form_key($form_key);
|
||||
|
||||
$submit = request_var('submit', '');
|
||||
|
||||
if ($submit && check_form_key($form_key))
|
||||
{
|
||||
$captcha_vars = array_keys($this->captcha_vars);
|
||||
foreach ($captcha_vars as $captcha_var)
|
||||
{
|
||||
$value = request_var($captcha_var, 0);
|
||||
if ($value >= 0)
|
||||
{
|
||||
set_config($captcha_var, $value);
|
||||
}
|
||||
}
|
||||
|
||||
add_log('admin', 'LOG_CONFIG_VISUAL');
|
||||
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action));
|
||||
}
|
||||
else if ($submit)
|
||||
{
|
||||
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($module->u_action));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($this->captcha_vars as $captcha_var => $template_var)
|
||||
{
|
||||
$var = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, 0) : $config[$captcha_var];
|
||||
$template->assign_var($template_var, $var);
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'CAPTCHA_PREVIEW' => $this->get_demo_template($id),
|
||||
'CAPTCHA_NAME' => $this->get_service_name(),
|
||||
'U_ACTION' => $module->u_action,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
function execute_demo()
|
||||
{
|
||||
global $config;
|
||||
|
||||
$config_old = $config;
|
||||
|
||||
$config = new \phpbb\config\config(array());
|
||||
foreach ($config_old as $key => $value)
|
||||
{
|
||||
$config->set($key, $value);
|
||||
}
|
||||
|
||||
foreach ($this->captcha_vars as $captcha_var => $template_var)
|
||||
{
|
||||
$config->set($captcha_var, request_var($captcha_var, (int) $config[$captcha_var]));
|
||||
}
|
||||
parent::execute_demo();
|
||||
$config = $config_old;
|
||||
}
|
||||
|
||||
}
|
50
phpBB/phpbb/captcha/plugins/gd_wave.php
Normal file
50
phpBB/phpbb/captcha/plugins/gd_wave.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha\plugins;
|
||||
|
||||
class gd_wave extends captcha_abstract
|
||||
{
|
||||
public function is_available()
|
||||
{
|
||||
return @extension_loaded('gd');
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
return 'CAPTCHA_GD_3D';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the name of the service corresponding to the plugin
|
||||
*/
|
||||
function get_service_name()
|
||||
{
|
||||
return 'core.captcha.plugins.gd_wave';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the name of the class used to generate the captcha
|
||||
*/
|
||||
function get_generator_class()
|
||||
{
|
||||
return '\\phpbb\\captcha\\gd_wave';
|
||||
}
|
||||
|
||||
function acp_page($id, &$module)
|
||||
{
|
||||
global $config, $db, $template, $user;
|
||||
|
||||
trigger_error($user->lang['CAPTCHA_NO_OPTIONS'] . adm_back_link($module->u_action));
|
||||
}
|
||||
}
|
50
phpBB/phpbb/captcha/plugins/nogd.php
Normal file
50
phpBB/phpbb/captcha/plugins/nogd.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha\plugins;
|
||||
|
||||
class nogd extends captcha_abstract
|
||||
{
|
||||
public function is_available()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
return 'CAPTCHA_NO_GD';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the name of the service corresponding to the plugin
|
||||
*/
|
||||
function get_service_name()
|
||||
{
|
||||
return 'core.captcha.plugins.nogd';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the name of the class used to generate the captcha
|
||||
*/
|
||||
function get_generator_class()
|
||||
{
|
||||
return '\\phpbb\\captcha\\non_gd';
|
||||
}
|
||||
|
||||
function acp_page($id, &$module)
|
||||
{
|
||||
global $user;
|
||||
|
||||
trigger_error($user->lang['CAPTCHA_NO_OPTIONS'] . adm_back_link($module->u_action));
|
||||
}
|
||||
}
|
982
phpBB/phpbb/captcha/plugins/qa.php
Normal file
982
phpBB/phpbb/captcha/plugins/qa.php
Normal file
@@ -0,0 +1,982 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha\plugins;
|
||||
|
||||
global $table_prefix;
|
||||
|
||||
define('CAPTCHA_QUESTIONS_TABLE', $table_prefix . 'captcha_questions');
|
||||
define('CAPTCHA_ANSWERS_TABLE', $table_prefix . 'captcha_answers');
|
||||
define('CAPTCHA_QA_CONFIRM_TABLE', $table_prefix . 'qa_confirm');
|
||||
|
||||
/**
|
||||
* And now to something completely different. Let's make a captcha without extending the abstract class.
|
||||
* QA CAPTCHA sample implementation
|
||||
*/
|
||||
class qa
|
||||
{
|
||||
var $confirm_id;
|
||||
var $answer;
|
||||
var $question_ids;
|
||||
var $question_text;
|
||||
var $question_lang;
|
||||
var $question_strict;
|
||||
var $attempts = 0;
|
||||
var $type;
|
||||
// dirty trick: 0 is false, but can still encode that the captcha is not yet validated
|
||||
var $solved = 0;
|
||||
|
||||
/**
|
||||
* @param int $type as per the CAPTCHA API docs, the type
|
||||
*/
|
||||
function init($type)
|
||||
{
|
||||
global $config, $db, $user;
|
||||
|
||||
// load our language file
|
||||
$user->add_lang('captcha_qa');
|
||||
|
||||
// read input
|
||||
$this->confirm_id = request_var('qa_confirm_id', '');
|
||||
$this->answer = utf8_normalize_nfc(request_var('qa_answer', '', true));
|
||||
|
||||
$this->type = (int) $type;
|
||||
$this->question_lang = $user->lang_name;
|
||||
|
||||
// we need all defined questions - shouldn't be too many, so we can just grab them
|
||||
// try the user's lang first
|
||||
$sql = 'SELECT question_id
|
||||
FROM ' . CAPTCHA_QUESTIONS_TABLE . "
|
||||
WHERE lang_iso = '" . $db->sql_escape($user->lang_name) . "'";
|
||||
$result = $db->sql_query($sql, 3600);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$this->question_ids[$row['question_id']] = $row['question_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// fallback to the board default lang
|
||||
if (!sizeof($this->question_ids))
|
||||
{
|
||||
$this->question_lang = $config['default_lang'];
|
||||
|
||||
$sql = 'SELECT question_id
|
||||
FROM ' . CAPTCHA_QUESTIONS_TABLE . "
|
||||
WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
|
||||
$result = $db->sql_query($sql, 7200);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$this->question_ids[$row['question_id']] = $row['question_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
// okay, if there is a confirm_id, we try to load that confirm's state. If not, we try to find one
|
||||
if (!$this->load_answer() && (!$this->load_confirm_id() || !$this->load_answer()))
|
||||
{
|
||||
// we have no valid confirm ID, better get ready to ask something
|
||||
$this->select_question();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the captcha has created its tables.
|
||||
*/
|
||||
public function is_installed()
|
||||
{
|
||||
global $db;
|
||||
|
||||
$db_tool = new \phpbb\db\tools($db);
|
||||
|
||||
return $db_tool->sql_table_exists(CAPTCHA_QUESTIONS_TABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* API function - for the captcha to be available, it must have installed itself and there has to be at least one question in the board's default lang
|
||||
*/
|
||||
public function is_available()
|
||||
{
|
||||
global $config, $db, $phpbb_root_path, $phpEx, $user;
|
||||
|
||||
// load language file for pretty display in the ACP dropdown
|
||||
$user->add_lang('captcha_qa');
|
||||
|
||||
if (!$this->is_installed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = 'SELECT COUNT(question_id) AS question_count
|
||||
FROM ' . CAPTCHA_QUESTIONS_TABLE . "
|
||||
WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
return ((bool) $row['question_count']);
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function has_config()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
static public function get_name()
|
||||
{
|
||||
return 'CAPTCHA_QA';
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function get_service_name()
|
||||
{
|
||||
return 'core.captcha.plugins.qa';
|
||||
}
|
||||
|
||||
/**
|
||||
* API function - not needed as we don't display an image
|
||||
*/
|
||||
function execute_demo()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* API function - not needed as we don't display an image
|
||||
*/
|
||||
function execute()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* API function - send the question to the template
|
||||
*/
|
||||
function get_template()
|
||||
{
|
||||
global $template;
|
||||
|
||||
if ($this->is_solved())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'QA_CONFIRM_QUESTION' => $this->question_text,
|
||||
'QA_CONFIRM_ID' => $this->confirm_id,
|
||||
'S_CONFIRM_CODE' => true,
|
||||
'S_TYPE' => $this->type,
|
||||
));
|
||||
|
||||
return 'captcha_qa.html';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* API function - we just display a mockup so that the captcha doesn't need to be installed
|
||||
*/
|
||||
function get_demo_template()
|
||||
{
|
||||
global $config, $db, $template;
|
||||
|
||||
if ($this->is_available())
|
||||
{
|
||||
$sql = 'SELECT question_text
|
||||
FROM ' . CAPTCHA_QUESTIONS_TABLE . "
|
||||
WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
|
||||
$result = $db->sql_query_limit($sql, 1);
|
||||
if ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'QA_CONFIRM_QUESTION' => $row['question_text'],
|
||||
));
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
return 'captcha_qa_acp_demo.html';
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function get_hidden_fields()
|
||||
{
|
||||
$hidden_fields = array();
|
||||
|
||||
// this is required - otherwise we would forget about the captcha being already solved
|
||||
if ($this->solved)
|
||||
{
|
||||
$hidden_fields['qa_answer'] = $this->answer;
|
||||
}
|
||||
$hidden_fields['qa_confirm_id'] = $this->confirm_id;
|
||||
|
||||
return $hidden_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function garbage_collect($type = 0)
|
||||
{
|
||||
global $db, $config;
|
||||
|
||||
$sql = 'SELECT c.confirm_id
|
||||
FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' c
|
||||
LEFT JOIN ' . SESSIONS_TABLE . ' s
|
||||
ON (c.session_id = s.session_id)
|
||||
WHERE s.session_id IS NULL' .
|
||||
((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type);
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
if ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$sql_in = array();
|
||||
|
||||
do
|
||||
{
|
||||
$sql_in[] = (string) $row['confirm_id'];
|
||||
}
|
||||
while ($row = $db->sql_fetchrow($result));
|
||||
|
||||
if (sizeof($sql_in))
|
||||
{
|
||||
$sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('confirm_id', $sql_in);
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* API function - we don't drop the tables here, as that would cause the loss of all entered questions.
|
||||
*/
|
||||
function uninstall()
|
||||
{
|
||||
$this->garbage_collect(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* API function - set up shop
|
||||
*/
|
||||
function install()
|
||||
{
|
||||
global $db;
|
||||
|
||||
$db_tool = new \phpbb\db\tools($db);
|
||||
|
||||
$tables = array(CAPTCHA_QUESTIONS_TABLE, CAPTCHA_ANSWERS_TABLE, CAPTCHA_QA_CONFIRM_TABLE);
|
||||
|
||||
$schemas = array(
|
||||
CAPTCHA_QUESTIONS_TABLE => array (
|
||||
'COLUMNS' => array(
|
||||
'question_id' => array('UINT', Null, 'auto_increment'),
|
||||
'strict' => array('BOOL', 0),
|
||||
'lang_id' => array('UINT', 0),
|
||||
'lang_iso' => array('VCHAR:30', ''),
|
||||
'question_text' => array('TEXT_UNI', ''),
|
||||
),
|
||||
'PRIMARY_KEY' => 'question_id',
|
||||
'KEYS' => array(
|
||||
'lang' => array('INDEX', 'lang_iso'),
|
||||
),
|
||||
),
|
||||
CAPTCHA_ANSWERS_TABLE => array (
|
||||
'COLUMNS' => array(
|
||||
'question_id' => array('UINT', 0),
|
||||
'answer_text' => array('STEXT_UNI', ''),
|
||||
),
|
||||
'KEYS' => array(
|
||||
'qid' => array('INDEX', 'question_id'),
|
||||
),
|
||||
),
|
||||
CAPTCHA_QA_CONFIRM_TABLE => array (
|
||||
'COLUMNS' => array(
|
||||
'session_id' => array('CHAR:32', ''),
|
||||
'confirm_id' => array('CHAR:32', ''),
|
||||
'lang_iso' => array('VCHAR:30', ''),
|
||||
'question_id' => array('UINT', 0),
|
||||
'attempts' => array('UINT', 0),
|
||||
'confirm_type' => array('USINT', 0),
|
||||
),
|
||||
'KEYS' => array(
|
||||
'session_id' => array('INDEX', 'session_id'),
|
||||
'lookup' => array('INDEX', array('confirm_id', 'session_id', 'lang_iso')),
|
||||
),
|
||||
'PRIMARY_KEY' => 'confirm_id',
|
||||
),
|
||||
);
|
||||
|
||||
foreach($schemas as $table => $schema)
|
||||
{
|
||||
if (!$db_tool->sql_table_exists($table))
|
||||
{
|
||||
$db_tool->sql_create_table($table, $schema);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* API function - see what has to be done to validate
|
||||
*/
|
||||
function validate()
|
||||
{
|
||||
global $config, $db, $user;
|
||||
|
||||
$error = '';
|
||||
|
||||
if (!sizeof($this->question_ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->confirm_id)
|
||||
{
|
||||
$error = $user->lang['CONFIRM_QUESTION_WRONG'];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->check_answer())
|
||||
{
|
||||
$this->solved = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$error = $user->lang['CONFIRM_QUESTION_WRONG'];
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($error))
|
||||
{
|
||||
// okay, incorrect answer. Let's ask a new question.
|
||||
$this->new_attempt();
|
||||
$this->solved = false;
|
||||
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a question
|
||||
*/
|
||||
function select_question()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
if (!sizeof($this->question_ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$this->confirm_id = md5(unique_id($user->ip));
|
||||
$this->question = (int) array_rand($this->question_ids);
|
||||
|
||||
$sql = 'INSERT INTO ' . CAPTCHA_QA_CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array(
|
||||
'confirm_id' => (string) $this->confirm_id,
|
||||
'session_id' => (string) $user->session_id,
|
||||
'lang_iso' => (string) $this->question_lang,
|
||||
'confirm_type' => (int) $this->type,
|
||||
'question_id' => (int) $this->question,
|
||||
));
|
||||
$db->sql_query($sql);
|
||||
|
||||
$this->load_answer();
|
||||
}
|
||||
|
||||
/**
|
||||
* New Question, if desired.
|
||||
*/
|
||||
function reselect_question()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
if (!sizeof($this->question_ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->question = (int) array_rand($this->question_ids);
|
||||
$this->solved = 0;
|
||||
|
||||
$sql = 'UPDATE ' . CAPTCHA_QA_CONFIRM_TABLE . '
|
||||
SET question_id = ' . (int) $this->question . "
|
||||
WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "'
|
||||
AND session_id = '" . $db->sql_escape($user->session_id) . "'";
|
||||
$db->sql_query($sql);
|
||||
|
||||
$this->load_answer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrong answer, so we increase the attempts and use a different question.
|
||||
*/
|
||||
function new_attempt()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
// yah, I would prefer a stronger rand, but this should work
|
||||
$this->question = (int) array_rand($this->question_ids);
|
||||
$this->solved = 0;
|
||||
|
||||
$sql = 'UPDATE ' . CAPTCHA_QA_CONFIRM_TABLE . '
|
||||
SET question_id = ' . (int) $this->question . ",
|
||||
attempts = attempts + 1
|
||||
WHERE confirm_id = '" . $db->sql_escape($this->confirm_id) . "'
|
||||
AND session_id = '" . $db->sql_escape($user->session_id) . "'";
|
||||
$db->sql_query($sql);
|
||||
|
||||
$this->load_answer();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See if there is already an entry for the current session.
|
||||
*/
|
||||
function load_confirm_id()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
$sql = 'SELECT confirm_id
|
||||
FROM ' . CAPTCHA_QA_CONFIRM_TABLE . "
|
||||
WHERE
|
||||
session_id = '" . $db->sql_escape($user->session_id) . "'
|
||||
AND lang_iso = '" . $db->sql_escape($this->question_lang) . "'
|
||||
AND confirm_type = " . $this->type;
|
||||
$result = $db->sql_query_limit($sql, 1);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($row)
|
||||
{
|
||||
$this->confirm_id = $row['confirm_id'];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up everything we need and populate the instance variables.
|
||||
*/
|
||||
function load_answer()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
if (!strlen($this->confirm_id) || !sizeof($this->question_ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = 'SELECT con.question_id, attempts, question_text, strict
|
||||
FROM ' . CAPTCHA_QA_CONFIRM_TABLE . ' con, ' . CAPTCHA_QUESTIONS_TABLE . " qes
|
||||
WHERE con.question_id = qes.question_id
|
||||
AND confirm_id = '" . $db->sql_escape($this->confirm_id) . "'
|
||||
AND session_id = '" . $db->sql_escape($user->session_id) . "'
|
||||
AND qes.lang_iso = '" . $db->sql_escape($this->question_lang) . "'
|
||||
AND confirm_type = " . $this->type;
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($row)
|
||||
{
|
||||
$this->question = $row['question_id'];
|
||||
|
||||
$this->attempts = $row['attempts'];
|
||||
$this->question_strict = $row['strict'];
|
||||
$this->question_text = $row['question_text'];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual validation
|
||||
*/
|
||||
function check_answer()
|
||||
{
|
||||
global $db;
|
||||
|
||||
$answer = ($this->question_strict) ? utf8_normalize_nfc(request_var('qa_answer', '', true)) : utf8_clean_string(utf8_normalize_nfc(request_var('qa_answer', '', true)));
|
||||
|
||||
$sql = 'SELECT answer_text
|
||||
FROM ' . CAPTCHA_ANSWERS_TABLE . '
|
||||
WHERE question_id = ' . (int) $this->question;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$solution = ($this->question_strict) ? $row['answer_text'] : utf8_clean_string($row['answer_text']);
|
||||
|
||||
if ($solution === $answer)
|
||||
{
|
||||
$this->solved = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
return $this->solved;
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function get_attempt_count()
|
||||
{
|
||||
return $this->attempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function reset()
|
||||
{
|
||||
global $db, $user;
|
||||
|
||||
$sql = 'DELETE FROM ' . CAPTCHA_QA_CONFIRM_TABLE . "
|
||||
WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
|
||||
AND confirm_type = " . (int) $this->type;
|
||||
$db->sql_query($sql);
|
||||
|
||||
// we leave the class usable by generating a new question
|
||||
$this->select_question();
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function is_solved()
|
||||
{
|
||||
if (request_var('qa_answer', false) && $this->solved === 0)
|
||||
{
|
||||
$this->validate();
|
||||
}
|
||||
|
||||
return (bool) $this->solved;
|
||||
}
|
||||
|
||||
/**
|
||||
* API function - The ACP backend, this marks the end of the easy methods
|
||||
*/
|
||||
function acp_page($id, &$module)
|
||||
{
|
||||
global $db, $user, $auth, $template;
|
||||
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
|
||||
|
||||
$user->add_lang('acp/board');
|
||||
$user->add_lang('captcha_qa');
|
||||
|
||||
if (!self::is_installed())
|
||||
{
|
||||
$this->install();
|
||||
}
|
||||
|
||||
$module->tpl_name = 'captcha_qa_acp';
|
||||
$module->page_title = 'ACP_VC_SETTINGS';
|
||||
$form_key = 'acp_captcha';
|
||||
add_form_key($form_key);
|
||||
|
||||
$submit = request_var('submit', false);
|
||||
$question_id = request_var('question_id', 0);
|
||||
$action = request_var('action', '');
|
||||
|
||||
// we have two pages, so users might want to navigate from one to the other
|
||||
$list_url = $module->u_action . "&configure=1&select_captcha=" . $this->get_service_name();
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_ACTION' => $module->u_action,
|
||||
'QUESTION_ID' => $question_id ,
|
||||
'CLASS' => $this->get_service_name(),
|
||||
));
|
||||
|
||||
// show the list?
|
||||
if (!$question_id && $action != 'add')
|
||||
{
|
||||
$this->acp_question_list($module);
|
||||
}
|
||||
else if ($question_id && $action == 'delete')
|
||||
{
|
||||
if ($this->get_service_name() !== $config['captcha_plugin'] || !$this->acp_is_last($question_id))
|
||||
{
|
||||
if (confirm_box(true))
|
||||
{
|
||||
$this->acp_delete_question($question_id);
|
||||
|
||||
trigger_error($user->lang['QUESTION_DELETED'] . adm_back_link($list_url));
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
|
||||
'question_id' => $question_id,
|
||||
'action' => $action,
|
||||
'configure' => 1,
|
||||
'select_captcha' => $this->get_service_name(),
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error($user->lang['QA_LAST_QUESTION'] . adm_back_link($list_url), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// okay, show the editor
|
||||
$error = false;
|
||||
$input_question = request_var('question_text', '', true);
|
||||
$input_answers = request_var('answers', '', true);
|
||||
$input_lang = request_var('lang_iso', '', true);
|
||||
$input_strict = request_var('strict', false);
|
||||
$langs = $this->get_languages();
|
||||
|
||||
foreach ($langs as $lang => $entry)
|
||||
{
|
||||
$template->assign_block_vars('langs', array(
|
||||
'ISO' => $lang,
|
||||
'NAME' => $entry['name'],
|
||||
));
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_LIST' => $list_url,
|
||||
));
|
||||
|
||||
if ($question_id)
|
||||
{
|
||||
if ($question = $this->acp_get_question_data($question_id))
|
||||
{
|
||||
$answers = (isset($input_answers[$lang])) ? $input_answers[$lang] : implode("\n", $question['answers']);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'QUESTION_TEXT' => ($input_question) ? $input_question : $question['question_text'],
|
||||
'LANG_ISO' => ($input_lang) ? $input_lang : $question['lang_iso'],
|
||||
'STRICT' => (isset($_REQUEST['strict'])) ? $input_strict : $question['strict'],
|
||||
'ANSWERS' => $answers,
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'QUESTION_TEXT' => $input_question,
|
||||
'LANG_ISO' => $input_lang,
|
||||
'STRICT' => $input_strict,
|
||||
'ANSWERS' => $input_answers,
|
||||
));
|
||||
}
|
||||
|
||||
if ($submit && check_form_key($form_key))
|
||||
{
|
||||
$data = $this->acp_get_question_input();
|
||||
|
||||
if (!$this->validate_input($data))
|
||||
{
|
||||
$template->assign_vars(array(
|
||||
'S_ERROR' => true,
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($question_id)
|
||||
{
|
||||
$this->acp_update_question($data, $question_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->acp_add_question($data);
|
||||
}
|
||||
|
||||
add_log('admin', 'LOG_CONFIG_VISUAL');
|
||||
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($list_url));
|
||||
}
|
||||
}
|
||||
else if ($submit)
|
||||
{
|
||||
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($list_url), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This handles the list overview
|
||||
*/
|
||||
function acp_question_list(&$module)
|
||||
{
|
||||
global $db, $template;
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM ' . CAPTCHA_QUESTIONS_TABLE;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'S_LIST' => true,
|
||||
));
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$url = $module->u_action . "&question_id={$row['question_id']}&configure=1&select_captcha=" . $this->get_service_name() . '&';
|
||||
|
||||
$template->assign_block_vars('questions', array(
|
||||
'QUESTION_TEXT' => $row['question_text'],
|
||||
'QUESTION_ID' => $row['question_id'],
|
||||
'QUESTION_LANG' => $row['lang_iso'],
|
||||
'U_DELETE' => "{$url}action=delete",
|
||||
'U_EDIT' => "{$url}action=edit",
|
||||
));
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab a question and bring it into a format the editor understands
|
||||
*/
|
||||
function acp_get_question_data($question_id)
|
||||
{
|
||||
global $db;
|
||||
|
||||
if ($question_id)
|
||||
{
|
||||
$sql = 'SELECT *
|
||||
FROM ' . CAPTCHA_QUESTIONS_TABLE . '
|
||||
WHERE question_id = ' . $question_id;
|
||||
$result = $db->sql_query($sql);
|
||||
$question = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$question)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$question['answers'] = array();
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM ' . CAPTCHA_ANSWERS_TABLE . '
|
||||
WHERE question_id = ' . $question_id;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$question['answers'][] = $row['answer_text'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
return $question;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab a question from input and bring it into a format the editor understands
|
||||
*/
|
||||
function acp_get_question_input()
|
||||
{
|
||||
$answers = utf8_normalize_nfc(request_var('answers', '', true));
|
||||
$question = array(
|
||||
'question_text' => request_var('question_text', '', true),
|
||||
'strict' => request_var('strict', false),
|
||||
'lang_iso' => request_var('lang_iso', ''),
|
||||
'answers' => (strlen($answers)) ? explode("\n", $answers) : '',
|
||||
);
|
||||
|
||||
return $question;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a question.
|
||||
* param mixed $data : an array as created from acp_get_question_input or acp_get_question_data
|
||||
*/
|
||||
function acp_update_question($data, $question_id)
|
||||
{
|
||||
global $db, $cache;
|
||||
|
||||
// easier to delete all answers than to figure out which to update
|
||||
$sql = 'DELETE FROM ' . CAPTCHA_ANSWERS_TABLE . " WHERE question_id = $question_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
$langs = $this->get_languages();
|
||||
$question_ary = $data;
|
||||
$question_ary['lang_id'] = $langs[$question_ary['lang_iso']]['id'];
|
||||
unset($question_ary['answers']);
|
||||
|
||||
$sql = 'UPDATE ' . CAPTCHA_QUESTIONS_TABLE . '
|
||||
SET ' . $db->sql_build_array('UPDATE', $question_ary) . "
|
||||
WHERE question_id = $question_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
$this->acp_insert_answers($data, $question_id);
|
||||
|
||||
$cache->destroy('sql', CAPTCHA_QUESTIONS_TABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a question.
|
||||
* param mixed $data : an array as created from acp_get_question_input or acp_get_question_data
|
||||
*/
|
||||
function acp_add_question($data)
|
||||
{
|
||||
global $db, $cache;
|
||||
|
||||
$langs = $this->get_languages();
|
||||
$question_ary = $data;
|
||||
|
||||
$question_ary['lang_id'] = $langs[$data['lang_iso']]['id'];
|
||||
unset($question_ary['answers']);
|
||||
|
||||
$sql = 'INSERT INTO ' . CAPTCHA_QUESTIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $question_ary);
|
||||
$db->sql_query($sql);
|
||||
|
||||
$question_id = $db->sql_nextid();
|
||||
|
||||
$this->acp_insert_answers($data, $question_id);
|
||||
|
||||
$cache->destroy('sql', CAPTCHA_QUESTIONS_TABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the answers.
|
||||
* param mixed $data : an array as created from acp_get_question_input or acp_get_question_data
|
||||
*/
|
||||
function acp_insert_answers($data, $question_id)
|
||||
{
|
||||
global $db, $cache;
|
||||
|
||||
foreach ($data['answers'] as $answer)
|
||||
{
|
||||
$answer_ary = array(
|
||||
'question_id' => $question_id,
|
||||
'answer_text' => $answer,
|
||||
);
|
||||
|
||||
$sql = 'INSERT INTO ' . CAPTCHA_ANSWERS_TABLE . ' ' . $db->sql_build_array('INSERT', $answer_ary);
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
|
||||
$cache->destroy('sql', CAPTCHA_ANSWERS_TABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a question.
|
||||
*/
|
||||
function acp_delete_question($question_id)
|
||||
{
|
||||
global $db, $cache;
|
||||
|
||||
$tables = array(CAPTCHA_QUESTIONS_TABLE, CAPTCHA_ANSWERS_TABLE);
|
||||
|
||||
foreach ($tables as $table)
|
||||
{
|
||||
$sql = "DELETE FROM $table
|
||||
WHERE question_id = $question_id";
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
|
||||
$cache->destroy('sql', $tables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the entered data can be inserted/used
|
||||
* param mixed $data : an array as created from acp_get_question_input or acp_get_question_data
|
||||
*/
|
||||
function validate_input($question_data)
|
||||
{
|
||||
$langs = $this->get_languages();
|
||||
|
||||
if (!isset($question_data['lang_iso']) ||
|
||||
!isset($question_data['question_text']) ||
|
||||
!isset($question_data['strict']) ||
|
||||
!isset($question_data['answers']))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($langs[$question_data['lang_iso']]) ||
|
||||
!strlen($question_data['question_text']) ||
|
||||
!sizeof($question_data['answers']) ||
|
||||
!is_array($question_data['answers']))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the installed language packs
|
||||
*/
|
||||
function get_languages()
|
||||
{
|
||||
global $db;
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM ' . LANG_TABLE;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$langs = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$langs[$row['lang_iso']] = array(
|
||||
'name' => $row['lang_local_name'],
|
||||
'id' => (int) $row['lang_id'],
|
||||
);
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
return $langs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* See if there is a question other than the one we have
|
||||
*/
|
||||
function acp_is_last($question_id)
|
||||
{
|
||||
global $config, $db;
|
||||
|
||||
if ($question_id)
|
||||
{
|
||||
$sql = 'SELECT question_id
|
||||
FROM ' . CAPTCHA_QUESTIONS_TABLE . "
|
||||
WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'
|
||||
AND question_id <> " . (int) $question_id;
|
||||
$result = $db->sql_query_limit($sql, 1);
|
||||
$question = $db->sql_fetchrow($result);
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$question)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
338
phpBB/phpbb/captcha/plugins/recaptcha.php
Normal file
338
phpBB/phpbb/captcha/plugins/recaptcha.php
Normal file
@@ -0,0 +1,338 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha\plugins;
|
||||
|
||||
class recaptcha extends \phpbb\captcha\plugins\captcha_abstract
|
||||
{
|
||||
var $recaptcha_server = 'http://www.google.com/recaptcha/api';
|
||||
var $recaptcha_server_secure = 'https://www.google.com/recaptcha/api'; // class constants :(
|
||||
|
||||
// We are opening a socket to port 80 of this host and send
|
||||
// the POST request asking for verification to the path specified here.
|
||||
var $recaptcha_verify_server = 'www.google.com';
|
||||
var $recaptcha_verify_path = '/recaptcha/api/verify';
|
||||
|
||||
var $challenge;
|
||||
var $response;
|
||||
|
||||
// PHP4 Constructor
|
||||
function phpbb_recaptcha()
|
||||
{
|
||||
global $request;
|
||||
$this->recaptcha_server = $request->is_secure() ? $this->recaptcha_server_secure : $this->recaptcha_server;
|
||||
}
|
||||
|
||||
function init($type)
|
||||
{
|
||||
global $config, $db, $user;
|
||||
|
||||
$user->add_lang('captcha_recaptcha');
|
||||
parent::init($type);
|
||||
$this->challenge = request_var('recaptcha_challenge_field', '');
|
||||
$this->response = request_var('recaptcha_response_field', '');
|
||||
}
|
||||
|
||||
public function is_available()
|
||||
{
|
||||
global $config, $user;
|
||||
$user->add_lang('captcha_recaptcha');
|
||||
return (isset($config['recaptcha_pubkey']) && !empty($config['recaptcha_pubkey']));
|
||||
}
|
||||
|
||||
/**
|
||||
* API function
|
||||
*/
|
||||
function has_config()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static public function get_name()
|
||||
{
|
||||
return 'CAPTCHA_RECAPTCHA';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the name of the service corresponding to the plugin
|
||||
*/
|
||||
function get_service_name()
|
||||
{
|
||||
return 'core.captcha.plugins.recaptcha';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the name of the class used to generate the captcha
|
||||
*/
|
||||
function get_generator_class()
|
||||
{
|
||||
throw new \Exception('Go out devil!');
|
||||
}
|
||||
|
||||
function acp_page($id, &$module)
|
||||
{
|
||||
global $config, $db, $template, $user;
|
||||
|
||||
$captcha_vars = array(
|
||||
'recaptcha_pubkey' => 'RECAPTCHA_PUBKEY',
|
||||
'recaptcha_privkey' => 'RECAPTCHA_PRIVKEY',
|
||||
);
|
||||
|
||||
$module->tpl_name = 'captcha_recaptcha_acp';
|
||||
$module->page_title = 'ACP_VC_SETTINGS';
|
||||
$form_key = 'acp_captcha';
|
||||
add_form_key($form_key);
|
||||
|
||||
$submit = request_var('submit', '');
|
||||
|
||||
if ($submit && check_form_key($form_key))
|
||||
{
|
||||
$captcha_vars = array_keys($captcha_vars);
|
||||
foreach ($captcha_vars as $captcha_var)
|
||||
{
|
||||
$value = request_var($captcha_var, '');
|
||||
if ($value)
|
||||
{
|
||||
set_config($captcha_var, $value);
|
||||
}
|
||||
}
|
||||
|
||||
add_log('admin', 'LOG_CONFIG_VISUAL');
|
||||
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($module->u_action));
|
||||
}
|
||||
else if ($submit)
|
||||
{
|
||||
trigger_error($user->lang['FORM_INVALID'] . adm_back_link($module->u_action));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($captcha_vars as $captcha_var => $template_var)
|
||||
{
|
||||
$var = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, '') : ((isset($config[$captcha_var])) ? $config[$captcha_var] : '');
|
||||
$template->assign_var($template_var, $var);
|
||||
}
|
||||
|
||||
$template->assign_vars(array(
|
||||
'CAPTCHA_PREVIEW' => $this->get_demo_template($id),
|
||||
'CAPTCHA_NAME' => $this->get_service_name(),
|
||||
'U_ACTION' => $module->u_action,
|
||||
));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// not needed
|
||||
function execute_demo()
|
||||
{
|
||||
}
|
||||
|
||||
// not needed
|
||||
function execute()
|
||||
{
|
||||
}
|
||||
|
||||
function get_template()
|
||||
{
|
||||
global $config, $user, $template, $phpbb_root_path, $phpEx;
|
||||
|
||||
if ($this->is_solved())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$contact_link = phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx);
|
||||
$explain = $user->lang(($this->type != CONFIRM_POST) ? 'CONFIRM_EXPLAIN' : 'POST_CONFIRM_EXPLAIN', '<a href="' . $contact_link . '">', '</a>');
|
||||
|
||||
$template->assign_vars(array(
|
||||
'RECAPTCHA_SERVER' => $this->recaptcha_server,
|
||||
'RECAPTCHA_PUBKEY' => isset($config['recaptcha_pubkey']) ? $config['recaptcha_pubkey'] : '',
|
||||
'RECAPTCHA_ERRORGET' => '',
|
||||
'S_RECAPTCHA_AVAILABLE' => self::is_available(),
|
||||
'S_CONFIRM_CODE' => true,
|
||||
'S_TYPE' => $this->type,
|
||||
'L_CONFIRM_EXPLAIN' => $explain,
|
||||
));
|
||||
|
||||
return 'captcha_recaptcha.html';
|
||||
}
|
||||
}
|
||||
|
||||
function get_demo_template($id)
|
||||
{
|
||||
return $this->get_template();
|
||||
}
|
||||
|
||||
function get_hidden_fields()
|
||||
{
|
||||
$hidden_fields = array();
|
||||
|
||||
// this is required for posting.php - otherwise we would forget about the captcha being already solved
|
||||
if ($this->solved)
|
||||
{
|
||||
$hidden_fields['confirm_code'] = $this->code;
|
||||
}
|
||||
$hidden_fields['confirm_id'] = $this->confirm_id;
|
||||
return $hidden_fields;
|
||||
}
|
||||
|
||||
function uninstall()
|
||||
{
|
||||
$this->garbage_collect(0);
|
||||
}
|
||||
|
||||
function install()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
function validate()
|
||||
{
|
||||
if (!parent::validate())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->recaptcha_check_answer();
|
||||
}
|
||||
}
|
||||
|
||||
// Code from here on is based on recaptchalib.php
|
||||
/*
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
* - Documentation and latest version
|
||||
* http://recaptcha.net/plugins/php/
|
||||
* - Get a reCAPTCHA API Key
|
||||
* http://recaptcha.net/api/getkey
|
||||
* - Discussion group
|
||||
* http://groups.google.com/group/recaptcha
|
||||
*
|
||||
* Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
|
||||
* AUTHORS:
|
||||
* Mike Crawford
|
||||
* Ben Maurer
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Submits an HTTP POST to a reCAPTCHA server
|
||||
* @param string $host
|
||||
* @param string $path
|
||||
* @param array $data
|
||||
* @param int port
|
||||
* @return array response
|
||||
*/
|
||||
function _recaptcha_http_post($host, $path, $data, $port = 80)
|
||||
{
|
||||
$req = $this->_recaptcha_qsencode ($data);
|
||||
|
||||
$http_request = "POST $path HTTP/1.0\r\n";
|
||||
$http_request .= "Host: $host\r\n";
|
||||
$http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
|
||||
$http_request .= "Content-Length: " . strlen($req) . "\r\n";
|
||||
$http_request .= "User-Agent: reCAPTCHA/PHP/phpBB\r\n";
|
||||
$http_request .= "\r\n";
|
||||
$http_request .= $req;
|
||||
|
||||
$response = '';
|
||||
if (false == ($fs = @fsockopen($host, $port, $errno, $errstr, 10)))
|
||||
{
|
||||
trigger_error('RECAPTCHA_SOCKET_ERROR', E_USER_ERROR);
|
||||
}
|
||||
|
||||
fwrite($fs, $http_request);
|
||||
|
||||
while (!feof($fs))
|
||||
{
|
||||
// One TCP-IP packet
|
||||
$response .= fgets($fs, 1160);
|
||||
}
|
||||
fclose($fs);
|
||||
$response = explode("\r\n\r\n", $response, 2);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls an HTTP POST function to verify if the user's guess was correct
|
||||
* @param array $extra_params an array of extra variables to post to the server
|
||||
* @return ReCaptchaResponse
|
||||
*/
|
||||
function recaptcha_check_answer($extra_params = array())
|
||||
{
|
||||
global $config, $user;
|
||||
|
||||
//discard spam submissions
|
||||
if ($this->challenge == null || strlen($this->challenge) == 0 || $this->response == null || strlen($this->response) == 0)
|
||||
{
|
||||
return $user->lang['RECAPTCHA_INCORRECT'];
|
||||
}
|
||||
|
||||
$response = $this->_recaptcha_http_post($this->recaptcha_verify_server, $this->recaptcha_verify_path,
|
||||
array(
|
||||
'privatekey' => $config['recaptcha_privkey'],
|
||||
'remoteip' => $user->ip,
|
||||
'challenge' => $this->challenge,
|
||||
'response' => $this->response
|
||||
) + $extra_params
|
||||
);
|
||||
|
||||
$answers = explode("\n", $response[1]);
|
||||
|
||||
if (trim($answers[0]) === 'true')
|
||||
{
|
||||
$this->solved = true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $user->lang['RECAPTCHA_INCORRECT'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the given data into a query string format
|
||||
* @param $data - array of string elements to be encoded
|
||||
* @return string - encoded request
|
||||
*/
|
||||
function _recaptcha_qsencode($data)
|
||||
{
|
||||
$req = '';
|
||||
foreach ($data as $key => $value)
|
||||
{
|
||||
$req .= $key . '=' . urlencode(stripslashes($value)) . '&';
|
||||
}
|
||||
|
||||
// Cut the last '&'
|
||||
$req = substr($req, 0, strlen($req) - 1);
|
||||
return $req;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user