Implements an image recognition captcha.

"; break; case 'admin/modules#description': case 'admin/modules/textimage': case 'admin/textimage': $output = t('Implements an image recognition captcha.'); break; } return $output; } function textimage_captchachallenge(&$form) { $form['captcha_response'] = array ( '#type' => 'textfield', '#title' => t('Captcha Validation'), '#default_value' => '', '#required' => TRUE, '#validate' => array('_captcha_validate' => array()), '#description' => t('Please type in the letters/numbers that are shown in the image above.'), '#prefix' => 'Captcha Image: you will need to recognize the text in it.', ); return $form; } function textimage_captchavalidate(&$captcha_word, &$correct) { $captcha_word = drupal_strtolower($captcha_word); if (($_SESSION['captcha'] != '') && $captcha_word == $_SESSION['captcha']) { $correct = true; } else { $correct = false; form_set_error('captcha_response', t('The image verification code you entered is incorrect.')); } } /** * Implementation of hook_menu(). */ function textimage_menu($may_cache) { $items = array(); $suffix = ''; if (arg(2)!=null) $suffix='/'.arg(2); $items[] = array( 'path' => '_textimage/image'.$suffix, 'title' => t('textimage'), 'callback' => '_textimage_image', 'access' => user_access('access textimages'), 'type' => MENU_CALLBACK ); return $items; } function textimage_perm() { return array('access textimages'); } function textimage_settings() { $fonts_path = variable_get("textimage_fonts_path", ""); $images_path = variable_get("textimage_images_path", ""); //check for GD if (!function_exists(imagecreate)) drupal_set_message(t('Image library not available. Textimage needs the GD library extension to be installed. Please install GD.')); //check for TTF support elseif (!function_exists(imagettftext)) drupal_set_message(t('Your image library does not seem to have TrueType font support. Textimage will work, but will use the default inbuilt font.'),'status'); //check for valid font path elseif ($fonts_path!="" && !is_dir($fonts_path)) drupal_set_message(t('The current font path is invalid. The default font will be used.')); //check for valid image path if ($images_path!="" && !is_dir($images_path)) drupal_set_message(t('The current images path is invalid. No images will be used.')); //Fonts settings $form['fonts'] = array( '#type' => 'fieldset', '#title' => t('Fonts settings'), '#collapsible' => TRUE, '#collapsed' => FALSE ); $form['fonts']['textimage_use_only_upper'] = array( '#type' => 'checkbox', '#title' => t('Use only Uppercase'), '#default_value' => variable_get('textimage_use_only_upper',0) ); $form['fonts']['textimage_fonts_path'] = array( '#type' => 'textfield', '#title' => t('TrueType Fonts Path'), '#default_value' => $fonts_path, '#size' => 30, '#maxlength' => 255, '#description' => t('Location of the directory where the Truetype (.ttf) fonts are stored. If you do not provide any fonts, the module will use the default font for text. Relative paths will be resolved relative to the Drupal installation directory.'), ); $form['fonts']['textimage_font_size'] = array( '#type' => 'textfield', '#title' => t('Font Size'), '#default_value' => variable_get('textimage_font_size',24), '#size' => 5, '#maxlength' => 2, '#description' => t('Font size of Captcha text (in pixels).'), '#validate' => array("_textimage_number_validate" => array("textimage_font_size")), ); $form['fonts']['textimage_char_spacing_max'] = array( '#type' => 'textfield', '#title' => t('Character Spacing'), '#default_value' => variable_get('textimage_char_spacing_max',10), '#size' => 5, '#maxlength' => 4, '#description' => t('Sets the kerning between letters in Captcha. Higher numbers indicate more spacing.'), '#validate' => array("_textimage_number_validate" => array("textimage_char_spacing_max")), ); $form['fonts']['textimage_char_jiggle_amount'] = array( '#type' => 'textfield', '#title' => t('Character Jiggle'), '#default_value' => variable_get('textimage_char_jiggle_amount',5), '#size' => 5, '#maxlength' => 2, '#description' => t('Sets the amount of up and down movement in the Captcha letters. Higher numbers indicate more jiggling.'), '#validate' => array("_textimage_number_validate" => array("textimage_char_jiggle_amount")), ); $form['fonts']['textimage_char_rotate_amount'] = array( '#type' => 'textfield', '#title' => t('Character Rotation'), '#default_value' => variable_get('textimage_char_rotate_amount',5), '#size' => 5, '#maxlength' => 2, '#description' => t('Sets the amount of rotation in the Captcha letters (in degrees, only works with non-default fonts).'), '#validate' => array("_textimage_number_validate" => array("textimage_char_rotate_amount")), ); $form['fonts']['textimage_char_size_amount'] = array( '#type' => 'textfield', '#title' => t('Character Size Adjustment'), '#default_value' => variable_get('textimage_char_size_amount',2), '#size' => 5, '#maxlength' => 2, '#description' => t('Sets the amount of variation in size between the different letters in the Captcha (in pixels).'), '#validate' => array("_textimage_number_validate" => array("textimage_char_size_amount")), ); //Image settings $form['images'] = array( '#type' => 'fieldset', '#title' => t('Image settings'), '#collapsible' => TRUE, '#collapsed' => FALSE ); $form['images']['textimage_images_path'] = array( '#type' => 'textfield', '#title' => t('Background Images Path'), '#default_value' => $images_path, '#size' => 30, '#maxlength' => 255, '#description' => t('Location of the directory where the background images are stored. If you do not provide a directory, solid colors will be used. Relative paths will be resolved relative to the Drupal installation directory.'), ); $form['images']['textimage_image_noise'] = array( '#type' => 'textfield', '#title' => t('Image Noise (pixels)'), '#default_value' => variable_get('textimage_image_noise',4), '#size' => 5, '#maxlength' => 4, '#description' => t('Sets the amount of noise (random pixels) in the Captcha image. Higher numbers indicate more noise.'), '#validate' => array("_textimage_number_validate" => array("textimage_image_noise")), ); $form['images']['textimage_image_lines'] = array( '#type' => 'textfield', '#title' => t('Image Noise (lines)'), '#default_value' => variable_get('textimage_image_lines',4), '#size' => 5, '#maxlength' => 4, '#description' => t('Sets the amount of noise (random lines) in the Captcha image. Higher numbers indicate more noise.'), '#validate' => array("_textimage_number_validate" => array("textimage_image_lines")), ); $form['images']['textimage_image_margin'] = array( '#type' => 'textfield', '#title' => t('Image Margin'), '#default_value' => variable_get('textimage_image_margin',10), '#size' => 5, '#maxlength' => 4, '#description' => t('Set a distance between the Captcha letters and the edges of the image.'), '#validate' => array("_textimage_number_validate" => array("textimage_image_margin")), ); $form['info'] = array( '#type' => 'fieldset', '#title' => t('Image and font information'), '#collapsible' => TRUE, '#collapsed' => FALSE ); if (isset($fonts_path)) { $imagefontinfo .= t('Number of fonts found: ').count(_textimage_font_list()); } if (isset($images_path)) { $imagefontinfo .= '
'.t('Number of background images found: ').count(_textimage_image_list()); } $gdinfo = gd_info(); $imagefontinfo .= '
'.t('GD Version: ').$gdinfo["GD Version"]; $imagefontinfo .= '
'.t(' FreeType Support: '); $imagefontinfo .= ($gdinfo["FreeType Support"]==true) ? 'True' : 'False'; $imagefontinfo .= '
'; $form['info']['captcha_info'] = array ( '#type' => 'item', '#value' => $imagefontinfo, ); return $form; } function textimage_settings_form_validate ($form_id,$form) { //check for valid font path if ($form['textimage_fonts_path'] !="" && !is_dir($form['textimage_fonts_path'])) form_set_error('textimage_fonts_path', t('The entered font path is invalid')); //check for valid image path if ($form['textimage_images_path'] !="" && !is_dir($form['textimage_images_path'])) form_set_error('textimage_images_path', t('The entered image path is invalid')); } function _textimage_number_validate ($field,$fieldName) { if (!is_numeric($field['#value'])) { form_set_error($fieldName,t("The value for")." ".t($field['#title'])." ".t("must be a number")); } } /** * Prints an image containing a textimage code. */ function _textimage_image() { //if we don't have GD2 functions, we can't generate the image if (!function_exists('imagecreatetruecolor')) return; // Set headers header('Expires: Mon, 01 Jan 1997 05:00:00 GMT'); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Cache-Control: post-check=0, pre-check=0', false); header('Pragma: no-cache'); header('Content-type: image/png'); $string = _textimage_code(); // Get truetype font list $fonts = _textimage_font_list(); // Get the background images list $images = _textimage_image_list(); // Randomization amounts: $charSpacingMax = variable_get('textimage_char_spacing_max',10); // Letter spacing max (pixels) $charSpacingMin = max($charSpacingMax*.5,0); // Letter spacing minimum (pixels) $charJiggleAmount = variable_get('textimage_char_jiggle_amount',5); // Up and down randomization (pixels) $charRotateAmount = variable_get('textimage_char_rotate_amount',5); // Character rotation amount (degrees) $charSizeAmount = variable_get('textimage_char_size_amount',2); // Character size amount (pixels) $imageRotateAmount = variable_get('captcha_image_rotate_amount',12); // Image rotation amount (degrees) // Static amounts: $charInitialSize = variable_get('textimage_font_size',24); // Initial Font $imageNoise = variable_get('textimage_image_noise',4); // Amount of noise added to image $imageLines = variable_get('textimage_image_lines',4); // Amount of noise added to image $imageMargin = variable_get('textimage_image_margin',10); // Margin around image (pixels) // write text using a truetype font if (function_exists(imagettftext) && count($fonts) > 0) { // Initialize variables for the loop $characterDetails = array(); // contains the final info about each character // Build a list of character settings for the captcha string for ($i=0;$i $charSize, "angle" => $charAngle, "x" => $x, "y" => $y, "color" => $foreground, "font" => $font, "char" => $char ); // Increment the image size $imageWidth = $x + $charWidth; $imageHeight = max($imageHeight,$y+$charJiggleAmount); } // Create the image based off the string length and margin if (count($images) > 0) { // We're going to be using an image, and need a tranparent background to start with $im = _textimage_create_transparent_image($imageWidth+2*$imageMargin, $imageHeight+2*$imageMargin); $noisecolor = imagecolorallocatealpha($im, 0, 0, 0, 127); } else { // Just make a plain-jane color brackground $im = imagecreatetruecolor($imageWidth+2*$imageMargin, $imageHeight+2*$imageMargin); $background = imagecolorallocate($im, rand(180, 250), rand(180, 250), rand(180, 250)); $noisecolor = $background; imagefill($im, 0, 0, $background); } // Specify colors to be used in the image $foreground = imagecolorallocate($im, rand(0, 80), rand(0, 80), rand(0, 80)); foreach($characterDetails as $char) { // draw character imagettftext($im,$char['size'],$char['angle'],$char['x']+$imageMargin,$char['y']+$imageMargin,$foreground,$char['font'],$char['char']); } } else { // write text using a built-in font $x = 0; $y = 0; $imageWidth = 60 + drupal_strlen($string)*$charSpacingMax*.35; $imageHeight = 30 + $charJiggleAmount; // Create the image if (count($images) > 0 && function_exists(imagecolorallocatealpha)) { // We're going to be using an image, and need a tranparent background to start with $im = _textimage_create_transparent_image($imageWidth, $imageHeight); $noisecolor = imagecolorallocatealpha($im, 0, 0, 0, 127); } else { // Just make a plain-jane color brackground $im = imagecreatetruecolor($imageWidth, $imageHeight); $background = imagecolorallocate($im, rand(180, 250), rand(180, 250), rand(180, 250)); $noisecolor = $background; imagefill($im, 0, 0, $background); } // Add the text for ($i=0;$i 0) { // Prepare a larger image with a background image $im2 = _textimage_create_transparent_image($imageWidth, $imageHeight); } else { // Prepare a larger image with a solid color $im2 = imagecreatetruecolor($imageWidth, $imageHeight); imagefill($im2, 0, 0, $background); } $result = imagecopyresampled ($im2, $im, $imageMargin, $imageMargin, 0, 0, $imageWidth, $imageHeight, imagesx($im), imagesy($im)); $im = $im2; } // strikethrough imageline($im, rand(0, 120), rand(0, 120), rand(0, 120), rand(0, 120), $foreground); // Add Noise for ($x=0; $x<$imageWidth; $x++) { for ($row=0; $row<$imageNoise;$row++) { $y = rand(0,$imageHeight); imagesetpixel($im, $x, $y, $noisecolor); } } // Add Lines and Ellipses for ($x=0; $x<$imageLines;$x++) { imageline($im, rand(0, $imageWidth), rand(0, $imageHeight), rand(0, $imageWidth), rand(0, $imageHeight), $noisecolor); imageellipse($im, rand(0, $imageWidth), rand(0, $imageHeight), rand(0, $imageWidth), rand(0, $imageHeight), $noisecolor); } // Fill image with a random background image if available if (count($images) > 0) { $image = $images[rand(0,count($images)-1)]; _textimage_apply_background_image($im,$image); } //output to browser imagepng($im); imagedestroy($im); } /** * Returns a random string for use in a captcha */ function _textimage_code() { $consts='bcdgjxvmnprst'; $vowels='aeiou'; for ($x=0; $x < 6; $x++) { mt_srand ((double) microtime() * 1000000); $const[$x] = drupal_substr($consts,mt_rand(0,drupal_strlen($consts)-1),1); $vow[$x] = drupal_substr($vowels,mt_rand(0,drupal_strlen($vowels)-1),1); } $string = $const[0] . $vow[0] .$const[2] . $const[1] . $vow[1] . $const[3] . $vow[3] . $const[4]; $string = drupal_substr($string,0,rand(4,6)); //everytime we create a new code, we write it to session $_SESSION['captcha'] = drupal_strtolower($string); if(variable_get('textimage_use_only_upper',0)) $string = drupal_strtoupper($string); return $string; } /** * Returns an array of files with TTF extensions in the specified directory. */ function _textimage_font_list() { $fontdir = variable_get("textimage_fonts_path", ""); $filelist = array(); if (is_dir($fontdir) && $handle = opendir($fontdir)) { while ($file = readdir($handle)) { if (preg_match("/\.ttf$/i",$file) == 1) $filelist[] = $fontdir.'/'.$file; } closedir($handle); } return $filelist; } /** * Returns an array of files with jpg, png, and gif extensions in the specified directory. */ function _textimage_image_list() { $imagesdir = variable_get("textimage_images_path", ""); $filelist = array(); if (is_dir($imagesdir) && $handle = opendir($imagesdir)) { while ($file = readdir($handle)) { if (preg_match("/\.gif|\.png|\.jpg$/i",$file) == 1) $filelist[] = $imagesdir.'/'.$file; } closedir($handle); } return $filelist; } /** * Overlays an image to the supplied image resource */ function _textimage_apply_background_image (&$imageResource,$imageFile) { $backgroundResource = image_gd_open($imageFile,substr($imageFile,-3)); // Copy the text onto the background $backX = imagesx($backgroundResource); $backY = imagesy($backgroundResource); $textX = imagesx($imageResource); $textY = imagesy($imageResource); $randomBackX = rand(0,$backX-$textX); $randomBackY = rand(0,$backY-$textY); // Place the text onto a random location of the background image imagecopyresampled($backgroundResource,$imageResource,$randomBackX,$randomBackY,0,0,$textX,$textY,$textX,$textY); // Crop the background image to the original image size imagecopyresampled($imageResource,$backgroundResource,0,0,$randomBackX,$randomBackY,$textX,$textY,$textX,$textY); } /** * Creates transparent image resources for images with graphic backgrounds */ function _textimage_create_transparent_image($x, $y) { $i = imagecreatetruecolor($x, $y); $b = imagecreatefromstring(base64_decode(_text_image_blankpng())); imagealphablending($i, false); imagesavealpha($i, true); imagecopyresized($i, $b ,0 ,0 ,0 ,0 ,$x, $y, imagesx($b), imagesy($b)); return $i; } function _text_image_blankpng() { $c = "iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m"; $c .= "dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADqSURBVHjaYvz//z/DYAYAAcTEMMgBQAANegcCBNCg"; $c .= "dyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAAN"; $c .= "egcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQ"; $c .= "oHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAA"; $c .= "DXoHAgTQoHcgQAANegcCBNCgdyBAgAEAMpcDTTQWJVEAAAAASUVORK5CYII="; return $c; } ?> Комедианты | Odesskiy Listok


Между Кустанаем и Карагандой на севере Казахстана затерялся маленький, утопающий зимой в снегах, а весной и осенью в непролазной грязи областной центр – Кокчетав. В далекие времена в этот город – большую деревню – ссылали кулаков и бывших заключенных. Затем во время войны по приказу отца народов Сталина сюда пришли эшелоны с выселенными немцами с Поволжья. Были здесь и чеченцы с ингушами. Казахов, уйгуров, татар были единицы. Единственное высшее учебное заведение – педагогический институт – имел много факультетов, так как готовил учительские кадры для школ области. Профессорско-преподавательский состав славился высокой квалификацией. Многие студенты из столичных вузов приезжали сюда «по распределению».
…Моя дочь окончила 11 классов. Два раза в неделю к нам приходил А. А. Миллер, который обучал девочку английскому языку в течение 7 лет. Она читала, писала и говорила легко и свободно. Было решено подать документы в институт иностранных языков. Ректор – сравнительно молодая казашка, деловая и умная – сразу сказала мне и дочери, что фамилия Рабинович ей режет ухо, и они предпочитают брать студенток из глубинок, то есть национальные кадры, но документы приняла.
За два дня до вступительных экзаменов она позвонила мне домой. Разговор был предельно ясен и короток.
- Я советую вам документы забрать. Никаких шансов. Пока не поздно, поезжайте куда-нибудь на периферию, например, в Кокчетав. Там есть английский факультет.
Вступительные экзамены начинаются 1 августа, а позвонила она 30 июля. Что такое два дня?
В Кокчетав можно попасть самолетом, но билеты не достать. Наскоро сложив необходимое и оставив записку мужу, мчимся в такси на аэродром. Настроение – хуже некуда. Перезвонила всем друзьям прямо из кабинета начальника аэропорта. Он пообещал отправить нас ближайшим рейсом без билетов.
Сидим на ступеньках, ждем сообщения по радио о посадке на наш рейс.
Захрипело радио над головой и объявило, что вылет рейса №… откладывается на два часа, так как в Кокчетаве проливной дождь и гроза, аэродром не принимает. От нечего делать стала я рассматривать пассажиров, улетающих в Кокчетав. Вот у ограды сидят группа пожилых людей – человек 12-15. Видно, что они как-то связаны между собой. Их опекает маленький, абсолютно лысый, но шустрый старикашка в потрепанном пиджаке. Он суетится, что-то объясняет и успокаивает людей. Среди них я отметила женщину в лиловом, выцветшем от времени платье. Лицо полное, под глазами мешки, жиденькие крашеные волосы. Да и другие в таком же плане: какие-то изношенные, уставшие, неопрятные.
Дочка попросила мороженое. Когда я вернулась с двумя пачками пломбира, женщина в бывшем лиловом платье спросила меня – сколько стоит. Я ответила:
- Пломбир по 22 копейки пачка.
Немного помолчав, она спросила:
- А фруктового по 8 копеек нет?
Когда, в конце концов, объявили посадку, мне было не до них. Мы побежали к кабине пилота. Он поговорил со стюардессой, и все решилось по-семейному – мы оплатили двойной тариф и получили два места в хвосте самолета.
Самолет приземлился за 30 минут до закрытия приемной комиссии, так как еще три часа мы просидели в Караганде. К счастью, удалось сесть в такси. Ехали всего минут 10. Проехали мимо двух больших домов на центральной площади. Таксист с гордостью рассказывал о «достопримечательностях» Кокчетава. Большие дома – это обком партии и облисполком. Только здесь была заасфальтирована одна улица и площадь с памятником Ленину.
После дождя город походил больше на огромное болото. Люди прыгали по разбросанным по грязи кирпичам и доскам.
Вдоль улиц в основном стояли частные дома за высокими глухими заборами. Во дворах лаяли собаки. Таксист посоветовал посещать танцплощадку в парке.
Буквально в последнюю минуту у нас приняли документы. Декан факультета профессор Бирюков тут же в аудитории провел собеседование с дочкой. Через полчаса он сказал мне:
- Мама! Вы можете спокойно возвращаться домой. Считайте, что она уже принята. Прекрасные знания по всем дисциплинам.
Я была счастлива.
В городе Кокчетаве была одна гостиница. Одноэтажный кирпичный барак с крохотными кельями. На окнах – решетки, под потолком – тусклая лампочка. И как поет Владимир Высоцкий – «на 38 комнаток всего одна уборная». Вода из крана текла тонкой струйкой, зато ее было в избытке на разбитом цементном полу. Я сняла лучший номер на двоих. Выкрашенные зеленой краской железные кровати с провисшими сетками почти до пола. А о матрасах, подушках и одеялах желтого цвета и влажных – даже вспоминать не хочется.
Не успели мы разложить наши припасы на столике, как кто-то постучал в дверь.
- Нет ли у вас грелки? - спросила женщина, и я вспомнила ее лицо. Это была одна из группы, вылетавшей в Кокчетав.
- Видите ли, - продолжала она, - у одной нашей актрисы разыгрался радикулит.
- Нет, - сказала я, видя, как она глазами пожирала батон и колбасу. Я отрезала ей и то, и другое.
После ужина я вышла в коридор. Ко мне тут же подошел маленький лысый человечек. Он представился:
- Фамилия моя Козель. Я – художественный руководитель выездной бригады Госмосконцерта.
Я тоже представилась, сказав, что я врач, и рассказала о цели нашего с дочерью приезда. Глядя на его бледное лицо с синими кругами вокруг глаз, было ясно, что он давно не ел.
Утром, устроив дочь в общежитие института, я возвратилась в гостиницу.
У меня был большой запас провианта. Я следовала советам своего отца – «едешь на сутки, бери харчей на семь». И это вполне себя оправдывало.
Не успела я переступить порог этого мрачного и грязного приюта для приезжих, как ко мне подошел Козель. Видимо, он меня дожидался.
- Лидия Израйлевна! Весь коллектив нашей бригады просит оказать нам небольшую услугу…
Он замялся, а я решила – будет просить денег в долг. Но я ошиблась. Козель протянул мне 1 рубль, помните, такой желто-оранжевый, и говорит:
- Видите ли, сегодня в клубе в 12 часов дня городское начальство делает смотр нашей программы – полного концерта. Таков здесь порядок. Пожалуйста, возьмите этот рубль. Мы очень просим вас к 12 часам прийти в клуб – он рядом с гостиницей. Когда я по ходу концерта обращусь к воображаемой публике – кто может временно дать мне рубль? – подойдите к сцене и дайте мне его. Но только этот, не спутайте. Я потом его верну вам. Боже упаси вас перепутать! Положите его отдельно. Только этот!
Я покрутила в руках этот довольно измятый рубль и не заметила ничего особенного. Я положила его в сумочку и обещала прийти. Мой поезд уходил ночью в три часа. Чем сидеть в своей полутемной клетке, то уж лучше пойти развлечься. Я понятия не имела, зачем ему это нужно.
К двенадцати часам в красивом модном платье я пошла искать клуб. Рядом с гостиницей стоял длинный-предлинный сарай, сколоченный из досок. Я прошла раз-другой мимо сарая и уже собиралась уйти, как вдруг услышала пение. Оказалось, что это и есть «концертный зал» Кокчетава. Внутри зал оказался еще хуже, чем снаружи. В глубине была сцена, а по всему залу стояли деревянные скамейки. Пол был усеян подсолнечной лузгой. Пахло давно немытым помещением. Окон не было.
В первом и втором ряду вместо скамеек стояли стулья. На них расположилось местное областное начальство – человек 12-15. Мужчины и женщины. Они были прилично одеты, и я даже уловила запах духов «Красная Москва». Шик! От этих ценителей искусства зависела судьба горстки вышедших давно в тираж артистов.
Я села где-то в десятом ряду. Концерт, видимо, только начался. На сцене стоял конферансье в черном костюме. На белой рубашке красовался галстук-бабочка. Красивая шевелюра темно-каштановых волос и хороший грим делали его весьма симпатичным. Хорошо поставленным голосом он обращался к воображаемой публике, шутил и объявлял следующий номер.
Появилась из-за кулис певица в красном платье с кружевной накидкой. Блондинка, щеки румяные, глаза подведены. Она сложила ладони и прижала их к сердцу. Я тут же узнала полную даму, которая могла купить себе мороженое только за 8 копеек.
Она запела, а я – заплакала. Эта старая дура «исполняла» хорошо известную песню о том, как 18-летняя девушка ждет жениха. Полное отсутствие голоса она заменяла речитативами и модуляцией от верхней до нижней октавы. Это было ужасно. Слезы лились из моих глаз, а горло сжал спазм. Какое жалкое, унизительное зрелище! Потом она стала раскланиваться и приседать. Я вспомнила, что накануне вечером искали грелку, так как у одной певицы разболелась поясница, а теперь она кокетливо приседала, превозмогая боль.
Тети и дяди сидели, как каменные. Они ворочали своими извилинами – годится ли это для кокчетавской публики. Конферансье благодарил «глубинку» за теплый прием. Я хотела тут же покинуть этот вонючий барак, но… я же обещала дать рубль!
На сцене появился жонглер. То ли от волнения, то ли от старости у него без конца кольца и палочки падали на пол. Это было больше похоже на клоунаду.
Потом кто-то танцевал, но я уже на сцену не смотрела. Я ждала своего часа. Отдам рубль и убегу.
А лысый все не выходил. Вдруг мое сердце екнуло.
- Уважаемая публика! Кто может временно дать мне рубль?!
Только теперь я поняла, что этот кудрявый шатен и есть лысый мужчина в парике и гриме. Медленно я пошла к сцене и протянула ему этот злосчастный рубль. Глазами он спросил: «Тот самый»? Я кивнула. Я не поверила своим ушам, когда он громко сказал:
- Милая дама! Пожалуйста, поднимитесь на сцену!
Что делать? Такого уговора не было! Я стояла в нерешительности. Пауза слишком затянулась, но все выглядело натурально. Он протянул руку, и я поднялась по ступенькам, совершенно не понимая, что еще от меня требуется. Я думаю, что со стороны я выглядела полной идиоткой.
Козель ловко свернул рубль трубочкой и положил на маленький столик, ни разу не взглянув на него. Потом он вручил, вернее, всучил мне книжку среднего формата в картонном переплете и сказал: «Откройте на любой странице».
Увы! Листы книги все были склеены, и открылась только одна половина. Это была бутафория.
- Назовите, пожалуйста, букву пятую на шестой строке сверху.
- «Ю» - сказала я. На странице всего-то было десять строчек.
- А теперь - 4-ю букву на последней строке снизу.
- «К» - сказала я. И так восемь раз. Не такая уж я дура, чтобы не понять, что это афера чистой воды, и как я оказываю «небольшую услугу». Затем он подносит мне этот треклятый рубль, что-то подсчитывает в уме, напрягая мышцы лица, закатывает глаза…
- Разверните банкноту, - говорит он, - и проверьте. Серия БМ №1176384.
Публика должна была ахнуть!
Я проверила – точно! Маг и чародей! Мессинг!
- Возьмите свой рубль, спасибо!
Я спрыгнула со сцены и тут же выбежала из зала вон, лицо мое горело от стыда.
Днем я постучала к нему в номер. Я приготовила речь, но увидев его без парика и грима, не смогла произнести ни слова. Он взял протянутый рубль, этот реквизит и, глядя на меня голодными глазами, сказал:
- Очень близко от гостиницы есть столовая. Суп гороховый – 19 копеек, котлета с капустой – 37, плюс хлеб на три копейки. За 59 копеек можно хорошо пообедать. Если вы одолжите мне 6 рублей, я смогу прокормить всю труппу. Мне завтра обещали аванс, и я верну вам деньги. Нам разрешили дать три концерта.
Он сиял от счастья!
Я припечатала в его старческую ладонь 10 рублей, сказав: «Можете не возвращать, я ночью уезжаю».
Поезд на Алма-Ату приходил из Кустаная в три часа ночи. Стоянка – 10 минут. Маленький, пропахший дезинфекцией зал ожидания, с единственной тусклой лампочкой под потолком, был набит до отказа. Над окошком кассы висела вечная табличка «Билетов нет». Под ней на цементном полу спали женщины с малыми детьми. Пахло кислятиной и мочой.
Я вышла на перрон. Билет до Алма-Аты стоит от силы рублей 19. Я достала сторублевку. Кассу так и не открыли. Показался поезд. Я побежала к служебному купейному вагону. Сунула проводнице «свой билет» и забралась в вагон.
В купе, которое я открыла, спали пожилая женщина и напротив нее девица. Я забралась на верхнюю полку. Несмотря на дикую усталость и напряжение последних дней, спать я не могла. Перед моими глазами стояла не труппа московской эстрады, а трупы московской эстрады. Как дошли они до жизни такой? Одинокие, бездомные горемычные бродяги. Может быть, очень давно они имели успех у публики. Память о прошлом не отпускала их. Слова «сцена» и «выход» въелись в их кровь и плоть. Пуще глаз они берегли единственное платье или костюм, в котором могли выйти на сцену. Что ждало их в будущем – инвалидность, больничная койка и, может быть, братская могила…
Я лежала без матраца на жесткой полке, и сердце сжималось от жалости. Я невольно улыбнулась, вспомнив свою «роль». Да, я помогла им получить разрешение на три концерта. Да поможет им Бог!
Медленно пробуждаясь от сна, я почувствовала божественный запах. Я свесила голову с верней полки и увидела, как старуха, видимо, бабушка, запихивала внучке лет 14-ти румяные пирожки в рот. На столике лежали яйца, огурчики, куски жареной курицы.
Всю еду я оставила дочери, надеясь поесть в вагоне-ресторане, но поезд – «почтовый» такого не имел. Я спустилась вниз и села рядом с Настей, как называла ее бабушка. Настя лениво жевала. Я улыбнулась и пыталась завязать знакомство, повторяя: «Как вкусно пахнет, пирожки – просто прелесть!» На меня – ноль внимания, даже не поздоровались. Я вспомнила голодные глаза Козеля и выскочила из купе. От голода и запахов у меня кружилась голова.
Проводница напоила меня чаем и накормила. Десять лет своей жизни я проработала на железнодорожном транспорте, и нам было о чем поговорить. Я рассказала ей о своих попутчиках. Да! Дома за высокими заборами, лающие во дворах собаки и таблички «Осторожно! Во дворе злые люди»…
А дома еще долгое время снился мне желто-оранжевый рубль серии БМ №1176384.


Уважаемая Лидия. Какие годы Вашего визита в Кокчетав Вы описываете? Я такого ужаса не припомню. Просто страшилка для слабонервных. О главном забыли написать. Дочь Ваша закончила-таки Кокчетавский пединститут? Ведь преподаватели там на самом деле были высокими профессионалами.


спасибо за этот рассказ!

Отправить новый комментарий

Содержимое этого поля хранится скрыто и не будет показываться публично.
  • Допустимые HTML-теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <img> <p> <br> <tr> <td> <table>
  • Строки и параграфы переносятся автоматически.
  • Images can be added to this post.
Больше информации о возможностях форматирования