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

Моя Америка

Бывают в жизни моменты, ради которых стоило жить… Вот вдруг, неожиданно, увидела я своих одесских учеников, моих мальчиков и девочек, моих детей. Приехали они ко мне – и ушла земля из-под ног, и как будто не было более чем 30-летней разлуки… Перед моими глазами были не взрослые, зрелые люди, а милые мои девчоночки в белых передничках, с аккуратнейшими тетрадками и всегда выполненными домашними заданиями… И вечно растрепанные, драчливые и абсолютно непредсказуемые мои мальчишки…
Как и все на свете, прошла и наша встреча…
А вот как описывает свое путешествие из Одессы в США и обратно моя «звездочка» – моя Марьяша, ясноглазый Человек светлой души.


1. Идея.

7 апреля 2008г. На автомате проверяю электронку – ночь, все спят – можно поглядеть, что в мире творится, – и в спаме, который я также регулярно проверяю, лежит странное письмецо: «Добрый день, как дела?» Автор – Саша – высокий большеглазый паренек из глубокого школьного прошлого, страшно сказать – 33 года прошло… Сразу вспомнилась родная школа, учителя, школьная солидарность, книги, читаемые ночью под одеялом с фонариком, чтобы мама не ругалась. Читали то, что не разрешалось, передавали друг другу на один день и глотали это по ночам. У Саши всегда было, что попросить почитать. И он всегда делился даже самыми редкими книгами, книгами, которые нельзя было достать ни за какие деньги. Да, помню, но… нет времени на воспоминания, темп сегодняшней жизни не позволяет расслабиться, хотя – отвечу: «Спасибо, нормально, а ты?» Получаю ответ: «Есть такой сайт Одноклассники.ru – выходи!» И я вышла. И как в омут с головой!
Не читайте, братцы, спам, ох, не читайте… Полилась потоком информация, схлестнулись прошлое и настоящее, в мою жизнь ворвались судьбы людей, с которыми можно говорить без слов, которые понимают меня с полувзгляда и которых я чувствую на любом расстоянии. Невозможно передать те ощущения, которые ворвались в мою серьезную, взрослую, размеренную жизнь. Думаю, многие это испытали, но каждый отреагировал по-своему. Оказывается, мы не меняемся и узнаваемы в любом возрасте. Остаются голоса и наши души, и только обрамления душ – наши бренные тела – выдают прошедшие годы. И волосы – седые волосы наших мальчишек, а иногда и лысинки, храбро выставляемые или скромно маскируемые. А животики, ух, уж эти животики… не хотят втягиваться…
Животики нажились и мальчишками и девчонками, но девчонки, конечно, сохранили себя лучше.
И чем сложнее судьба, тем краше девочки и спокойнее, крупнее мальчики…
Но когда я получила то первое письмо, ничего я этого не знала, да и не было времени и желания что-либо узнавать. Сижу я, как все мы, в своей скорлупе – работа, дом, дети. И вдруг – «Приезжай к нам в Америку, покажем наш мир». И оказалось, что в США живут как минимум 8 моих одноклассников и сокурсников. И был задан вопрос одним из них, Олегом – денди нашего класса: «А ты и в правду хочешь приехать?» И поняла я – это серьезно, и желание мое увидеть старых друзей захлестнуло, стало основным. На второй план улетели дом, работа, дети, увлечения. Родилась ИДЕЯ и начала расти.

2. Вагончик тронется, перрон останется

20 мая 2008 г. Борисполь. Рейс «Киев – Нью-Йорк». А интересно – действительно работают электронные билеты, или спокойно вернусь домой, и родные и друзья в Одессе радостно вздохнут, и мы напьемся за сохранность нервов у всех нас? Нет, к моему восхищению, – по электронному номеру печатаются реальные билеты, и я попадаю в длинную очередь счастливчиков, вылетающих в США. Родная таможня заставляет выпить или выбросить из ручной клади все водяные запасы, которые я предусмотрительно приобрела для комфортного перелета (сок и минералочка, хорошо не водка – выпила бы на глазах у таможенников, и дальше бы было все совсем великолепно). Досматривали серьезно, и цель поездки – дружба – вызывала серьезное подозрение, но виза в паспорте стояла четкая, и ничего запретного не обнаружили. Полчемодана занимала гипсовая статуя Дюка де Ришелье, обильно обмотанная упаковочными материалами. Чемодан просвечивали, вертели, вероятно, искали подвох в статуе. А подвох был в шутке: один из моих друзей-сокурсников Юрик, сказал: «Ничего мне не надо, если очень хочешь что-то привезти, привези Дюка де Ришелье». Он думал, что удачно пошутил, но с одесситками так не шутят, – и в США летела точная копия нашего любимого Одесского Дюка собственной уменьшенной персоной. Забегая вперед, скажу – долетел Дюк удачно, но руки при перевозке американские грузчики ему обломали. Долетела, ну… Венера Милосская с лицом Дюка и одетая… Посмеялись потом в Канзас Сити вволю и руки приклеили на место суперамериканским клеем. Отлично получилось. А тогда, при посадке, смотрели на меня подозрительно и украинские, и американские таможенники. Но я отвечала на их взгляды снисходительной улыбкой (типа – вам не понять, но я вас не виню), держась крепко за горячее желание увидеть своих друзей и США. Если честно – страшно было очень. Как ни крути, лечу одна, в неизвестность, через океан, через часовые пояса, лечу в прошлое, которое вдруг начинает приобретать черты настоящего.
Боинг 767 – летающий кинотеатр, идет на взлет. Панически ищу заготовленный Орбит Арбузная корочка, без сахара и, старательно сглатывая, взлетаю вместе с самолетом… Через полчаса, проверив наличие пломб в зубах (жевательная резинка – коварная штука для пломб, бывало, знаю), вздыхаю счастливо и выплевываю безвкусную резинку, к которой на этот раз не приклеилась свежесделанная пломба… Повезло… Неплохое начало. Храбро выглядываю в окно… «Красота-то какая, лепота…» Голова идет кругом; чтобы не стало плохо, холодеющими руками нащупываю припасенный домашний банан и, с трудом очищая его, запихиваю в рот. Неожиданно вырастает рядом красивая, очень полная, но быстрая черная стюардесса со столиком напитков – стаканчик минералки спасает «отца русской демократии» – ничего другого в голову не лезет, тем более, что пришлось напрячься и понять, что тебе предлагают на английском языке и выдавить самое простое – «water». Я даже внутренне залюбовалась собой – ай да я, «ай да молодец» – заговорила на английском! Так я таки да – лечу!
Итак, приключения начинаются.

3. «Свобода нас встретит радостно у входа».

Лечу, ребята, лечу! Помните сказку о Лягушке-путешественнице? Я молчала, чтобы не свалиться с палочки вместе с Боингом, а в Боинг бил забортный ветер в 130 км/час, температура – 50 градусов по Цельсию. Летели 10 часов, вставать не разрешили из-за болтанки, внизу был океан – не шуточки вам. То, чем сидели, приобрело форму того, на чем сидели, все онемело и заклякло. Старалась больше жевать и не смотреть в окно, периодически впадая в состояние полусна, из которого вытаскивала черная стюардесса, покачивая пышными формами, задававшая понятные, заботливые вопросы на английском языке («У вас все в порядке?», «Ничего не надо?») Отвечала в том же духе: «Спасибо, все ОК!» А внутренний голос вопил: «Надо! На землю надо, домой, к маме! Ну, куда тебя несет?»
Сели, тяжело шлепнулись на шасси, и долго, благодарно хлопали экипажу – довезли. Аэропорт Кеннеди, Нью-Йорк. Тут первый пограничный пункт. Нас выстроили в длинную очередь и проверили по полной программе. Меня спросили адрес моего пребывания в США – сказала, что меня встречают, телефон знаю, адрес – не помню, он записан на бумажке в багаже, будет багаж – скажу. «Это ваша проблема – багаж вам не дадим – он на территории США, а вы пока не прошли контроль» – так я поняла то, что мне ответил серьезный сотрудник эмиграционной службы. Я не поняла серьезности ситуации из-за усталости и непоколебимой уверенности в собственной правоте. После очередной попытки прорваться через эмиграционную службу, я начала понимать – надо включать смекалку, а мысли после тяжелого перелета путались и никак не переводились на английский язык. В голове звучала единственная фраза – «Это ваша проблема». А ведь права была мама: «Дома надо сидеть, а не по Америкам шастать!» Ох, поздно, маму надо было слушать: мамы… они всегда правы…
Тяжесть положения я поняла, когда на меня за вынутый мобильный телефон бросился охранник: здесь спецзона – использование мобильных телефонов запрещено. Что одной украиночке на чужой американской стороне делать? Мне даже в голову не пришло, что могли меня сразу развернуть и отправить на Украину и были бы совершенно правы. А я переживала только, что скоро улетит мой самолет на Сан-Франциско… Не встретит меня Олег. Стало мне обидно за напрасно выброшенные деньги и стыдно перед Одноклассниками.
Не бывать такому, одессит не сдается! И я заговорила по-английски: «Помогите мне, я все равно никуда не уйду, пока вы не наберете моего друга и не заполните с его помощью все нужные для вас документы. Пригласите вашего начальника». Сказала и села в кресло спокойно, нога на ногу. Вздохнули несчастные американцы, бросили свои дела и начали звонить моим друзьям, а те не берут мобильники, срабатывают автоответчики на всех телефонах. Дозванивались минут 30 молча, упорно, а я сидела и «руководила»… Дозвонились-таки – продиктовал Олег свой адрес, они все записали в мою декларацию, повеселевший сотрудник эмиграционной полиции отметил мне визу, таможенники подхватили меня, передали дежурным по аэропорту, и меня почти на руках занесли в отлетающий в Сан-Франциско самолет. Вот теперь я точно в Америке.
В самолете, первым делом, поискала я свою Орбит Арбузную корочку, не нашла, плюнула, да и взлетела без нее, тут же воды потребовала – благо, тут был удивительный стюард – ну просто мастер своего дела и, к тому же, очень симпатичный. Перед взлетом, обязательно, на пальцах, стюардесса показывает, что надо делать в случае аварийной ситуации: ремни, запасные выходы. Этот стюард показывал все, как заправский артист – просто представление получилось, мы ему даже похлопали, поднял он мне своим показательным выступлением тонус, да и сок со льдом принес.
А жизнь-то налаживается. И полетела я уже в чисто американском самолете, в окружении американцев, прислушиваясь к незнакомой быстрой речи, понимая, что это будет моей жизнью на ближайшие 3 недели. Посадка прошла нормально, экипаж поприветствовал нас в Сан-Франциско, и пассажиры рассыпались по американской, пока виртуальной земле.

4. Здравствуй, Америка!

Дружелюбным потоком извиняющихся и улыбающихся американцев меня вынесло к череде движущихся пешеходных дорожек и даже к поезду, очень красивому и большому, в который я села именно потому, что туда шел народ, и не было сил думать… Какой длинный путь, как я устала, как тревожно на душе, где же все-таки твердая настоящая земля Олега и моих друзей? Из окон поезда был виден огромный аэропорт, десятки самолетов разных размеров готовились к взлету или высаживали пассажиров, сновали погрузчики, где-то должен быть и мой чемоданчик… А был ли чемоданчик? Поезд остановился, и мои мысли рванулись на поиски Олега. А вдруг его нет, а может, я его не узнала и пропустила? И тут из-за колонны прямо на меня выходит красивый, улыбающийся джентльмен и родным голосом, слегка картавя, говорит: «Привет, Марьяша, вот ты и долетела, молодец». Я молча уткнулась в его плечо, чтобы не разреветься, слезы готовы были хлынуть вместе с бурным рассказом о моих неприятностях, но потом внутренний голос напомнил мне, что я сильная, и я одесситка, а «одессит не плачет», и я счастливо улыбнулась. Олег понял мое состояние без слов. Восхитительно, 30 лет прошло, а будто вчера расстались после школы. Вот только копна слегка серебряных непослушных волос Олега и не тоненькая, а статная фигура подтверждала прошедшие годы, но внутри светился тот самый худенький, серьезно-веселый паренек, которого я знала, и ничто не смогло его изменить. Наш денди!
Не помню, как нашли мой чемодан (изрядно помятый, но целый, хотя бы внешне), как шли к выходу… Спустились мы в странное место – подземный паркинг – прямо в сцену из фильма «Терминатор» (Арнольд Шварценеггер, на приглушенно рычащем мотоцикле, с автоматом наперевес, медленно едет между машинами). Машин было не много, ночь… Стало жутковато. Мало ли что? Шварценеггер – мужчина серьезный (кстати – губернатор Калифорнии, где я и очутилась, – странное совпадение). Олег, почувствовав мое беспокойство, указал на Мерседес: «Присаживайся!», галантно открыв дверцу темно-красного сверкающего Мерседеса, а на светло-коричневом кожаном сидении красовался букет орхидей. Ахххх. Точно, Олежка!
А вроде ж я в Америке, Колумб с сайта Одноклассники…

[Продолжение следует]


Одесситов бывших не бывает!

Прочел на одном

Прочел на одном дыхание, аж самому захотелось кого то к себе в гости пригласить из старых друзей-одноклассников. Завидую...

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

Содержимое этого поля хранится скрыто и не будет показываться публично.
  • Допустимые 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.
Больше информации о возможностях форматирования