Logo Search packages:      
Sourcecode: faumachine version File versions  Download package

monitor.c

/*
 *  $Id: monitor.c,v 1.50 2009-01-28 12:59:21 potyra Exp $
 *
 *  Implemenation of the monitor component simulator.
 *
 * Copyright (C) 2007-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */


#include "config.h"

#include <assert.h>
#include <stdio.h>
#include <inttypes.h>

#include "glue-main.h"
#include "glue-shm.h"
#include "glue-log.h"

#include "monitor.h"

#define COMP "monitor"

struct cpssp {

      /* Ports */
      struct sig_opt_rgb *port_opt_video;

      /* Signals */

      /* State */
      uint8_t pixel_buffer[MAX_WIDTH * MAX_HEIGHT * MAX_DEPTH / 8];
      int last_width;
      int last_height;
      unsigned int width;
      unsigned int height;
      unsigned int x;
      unsigned int y;
      enum {
            BLANKING,
            SHOW_SYNC_MSG,
            INVALID,
            VALID
      } sync_state;

      /* Processes */

      /* Components */
      /* -- EEPROM with EDID information connected to ddc */
      #define NAME      edid_eeprom
      #define STATE
      #include "arch_philips_pcx8582X-2.c"
      #undef STATE
      #undef NAME
};

#define NAME            edid_eeprom
#define NAME_(x)  edid_eeprom_ ## x
#define BEHAVIOR
#include "arch_philips_pcx8582X-2.c"
#undef BEHAVIOR
#undef NAME_
#undef NAME

/*
 * EDID block for ddc eeprom.
 * Taken from cirrus_vga_bios/cirrus_vga.c
 */
static const unsigned char edidblock[256] = {
      /* EDID Header */
      0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
      /* Vendor Information */
      0x05, 0xb4, /* Manufacturer ID */
      0x30, 0x55, /* Product Code */
      0xbb, 0x02, 0x00, 0x00, /* Serial No. */
      0x29, 0x09, /* Week, Year-1990 */
      /* EDID Structure Versioning */
      0x01, 0x01, /* Version, Revision */
      /* Basic Display Parameters */
      0x1e, /* Video Input Definition: analog */
      36, 27, /* X,Y Size in cm */
      0x78, 0xe8, /* Gamma, Supported Features */
      /* Color Characteristics */
      0x07, 0xb3, 0xa0, 0x57, 0x4a, 0x9a, 0x26, 0x11, 0x48, 0x4f,
      /* Established Timings */
      0xbc, 0xe7, 0x80,
      /* Standard Timing Identification */
      /* First byte
       *   Horizontal resolution.  Multiply by 8, then add 248 for actual value.
       * Second byte
       *   bit 7-6: Aspect ratio.  00=16:10, 01=4:3, 10=5:4, 11=16:9
       *   bit 5-0: Vertical frequeny.  Add 60 to get actual value.
       */
      0xa9, 0x4f, /* 1600x1200 75 Hz */
      0xa9, 0x4a, /* 1600x1200 70 Hz */
      0x61, 0x59, /* 1024x768 85 Hz */
      0x31, 0x59, /* 640x480 85 Hz */
      0x45, 0x59, /* 800x600 85 Hz */
      0x31, 0x4a, /* 640x480 70 Hz */
      0xa9, 0x45, /* 1600x1200 65 Hz */
      0x01, 0x01, /* unused */
      /* Detailed Timing Description #1 */
      0x1a, 0x4f, 0x40, 0x30, 0x62, 0xb0, 0x32, 0x40, 0x40, 0xc0,
      0x13, 0x00, 0x8e, 0x2b, 0x11, 0x00, 0x00, 0x1e,
      /* Detailed Timing Description #2 */
      0xd4, 0x49, 0x40, 0x30, 0x62, 0xb0, 0x32, 0x40, 0x40, 0xc0,
      0x13, 0x00, 0x8e, 0x2b, 0x11, 0x00, 0x00, 0x1e,
      /* Detailed Timing Description #3 */
      0xea, 0x24, 0x00, 0x60, 0x41, 0x00, 0x28, 0x30, 0x30, 0x60,
      0x13, 0x00, 0x8e, 0x2b, 0x11, 0x00, 0x00, 0x1e,
      /* Detailed Timing Description #4 */
      0x40, 0x1f, 0x00, 0x30, 0x41, 0x00, 0x24, 0x30, 0x20, 0x60,
      0x33, 0x00, 0x8e, 0x2b, 0x11, 0x00, 0x00, 0x02,
      /* Extension Flag */
      0x00,
      /* Checksum: 1-byte sum of all 128 bytes in block must be 0 */
      0xc3
      /* rest is not set */
};

/*  GIMP header image file format (RGB) */
/*  RGB data for the text: "sync out of range" */

#define MSG_IMAGE_WIDTH  273
#define MSG_IMAGE_HEIGHT  29

/*  Call this macro repeatedly.  After each use, the pixel data can be extracted  */
#define HEADER_PIXEL(data,pixel) {\
  pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \
  pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \
  pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \
  data += 4; \
}
static const char *header_data =
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!``]!"
      "``]!``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!"
      "!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!``]!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!"
      "``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!``]!``]!``]!"
      "``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!``]!``]!``]!"
      "``]!``]!``]!``]!``]!``]!``]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";

/* callback for power_230v */

static void
monitor_power_230v_set(void *_cpssp, unsigned int val)
{
      /* FIXME */
}

/* callbacks and helpers for sig_video */

static void
monitor_pixel_set(
      struct cpssp *cpssp,
      unsigned int x, unsigned int y,
      uint8_t r, uint8_t g, uint8_t b
)
{
      uint8_t *buffer = &cpssp->pixel_buffer[y * MAX_HEIGHT * 4 + x * 4];

      if (buffer[0] != b
            || buffer[1] != g
            || buffer[2] != r) {
            buffer[0] = b;
            buffer[1] = g;
            buffer[2] = r;
            sig_opt_rgb_pixel_set(cpssp->port_opt_video, 
                        cpssp, x, y, r, g, b);
      }
}

static void
monitor_check_sync(void *_cpssp)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      int y;
      int x;
      int xmin, ymin;
      uint8_t rgb[4];
      const char *data = header_data;

      if (cpssp->sync_state == VALID) {
            cpssp->sync_state = BLANKING;
      } else if (cpssp->sync_state == BLANKING) {
            cpssp->sync_state = SHOW_SYNC_MSG;
      } else if (cpssp->sync_state == SHOW_SYNC_MSG) {
            cpssp->sync_state = INVALID;
      }

      /* reset monitor state */
      sig_opt_rgb_size_set(cpssp->port_opt_video, cpssp,
                  MONITOR_WIDTH, MONITOR_HEIGHT);

      xmin = (MONITOR_WIDTH / 2) - (MSG_IMAGE_WIDTH / 2);
      ymin = (MONITOR_HEIGHT / 2) - (MSG_IMAGE_HEIGHT / 2);
      for (y = 0; y < MONITOR_HEIGHT; y++) {
            for (x = 0; x < MONITOR_WIDTH; x++) {
                  if (cpssp->sync_state == SHOW_SYNC_MSG
                              && xmin <= x
                              && x < xmin + MSG_IMAGE_WIDTH
                              && ymin <= y
                              && y < ymin + MSG_IMAGE_HEIGHT) {

                        HEADER_PIXEL(data, rgb);
                        monitor_pixel_set(cpssp, x, y,
                                    rgb[0], rgb[1], rgb[2]);
                  } else {
                        monitor_pixel_set(cpssp, x, y, 0, 0, 0);
                  }
            }
      }

      if (cpssp->sync_state == BLANKING
            || cpssp->sync_state == SHOW_SYNC_MSG) {

            time_call_after(TIME_HZ * 5, monitor_check_sync, cpssp);
      }
}

static void
monitor_found_sync(struct cpssp *cpssp)
{
      time_call_delete(monitor_check_sync, cpssp);
      cpssp->sync_state = VALID;
}

static void
monitor_no_sync(void *_cpssp)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      if (cpssp->sync_state == VALID) { 
            monitor_check_sync(cpssp);
      }

      sig_opt_rgb_sync(cpssp->port_opt_video, cpssp);
}

static void
monitor_out(
      void *_cpssp,
      uint8_t red,
      uint8_t green,
      uint8_t blue
)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      monitor_pixel_set(cpssp,
                  cpssp->x & MAX_WIDTH_MASK,
                  cpssp->y & MAX_HEIGHT_MASK,
                  red, green, blue);

      cpssp->x++;
}

static void
monitor_hor_retrace(void *_cpssp)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      cpssp->width = cpssp->x;
      cpssp->y++;
      if (cpssp->x < MONITOR_WIDTH && cpssp->y <= MONITOR_HEIGHT) {

            if (cpssp->width < cpssp->last_width && cpssp->last_width != -1) {
                  /* lines became shorter
                   * -> fill the rest with ,,black'' */
                  while (cpssp->x < cpssp->last_width) {
                        monitor_out(cpssp, 0, 0, 0);
                  }
            }
      }

      cpssp->x = 0;
}


static void
monitor_vert_retrace(void *_cpssp)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      if (cpssp->width < MONITOR_WIDTH && cpssp->y < MONITOR_HEIGHT) {
            cpssp->height = cpssp->y;

            if (cpssp->width != cpssp->last_width
                        || cpssp->height != cpssp->last_height) {

                  if (cpssp->height < cpssp->last_height && cpssp->last_height != -1) {
                        /* fewer lines
                         * -> fill the rest with black */
                        while (cpssp->y < cpssp->last_height) {
                              while (cpssp->x < cpssp->last_width) {
                                    monitor_out(cpssp, 0, 0, 0);
                              }
                              cpssp->x = 0;
                              cpssp->y++;
                        }
                  }

                  cpssp->last_width = cpssp->width;
                  cpssp->last_height = cpssp->height;

                  sig_opt_rgb_size_set(cpssp->port_opt_video, cpssp, cpssp->width, cpssp->height);
            }

            monitor_found_sync(cpssp);
      } else {
            monitor_no_sync(cpssp);
      }

      sig_opt_rgb_sync(cpssp->port_opt_video, cpssp);

      cpssp->x = 0;
      cpssp->y = 0;
}

/* callbacks for ddc */

static void
monitor_stop_transaction(void *_cpssp)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      edid_eeprom_stop_transaction(cpssp);
}

static void
monitor_read_byte(void *_cpssp, unsigned char *val)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      edid_eeprom_read_byte(cpssp, val);
}

static bool
monitor_write_byte(void *_cpssp, unsigned char val)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      return edid_eeprom_write_byte(cpssp, val);
}

static bool
monitor_ack_addr(void *_cpssp, unsigned char addr)
{
      struct cpssp *cpssp = (struct cpssp *) _cpssp;

      return edid_eeprom_ack_addr(cpssp, addr);
}

void
monitor_init(
      unsigned int nr,
      struct sig_boolean *port_power_230v,
      struct sig_vga *port_vga,
      struct sig_opt_rgb *port_opt_video,
      struct sig_integer *port_screenshot
)
{
      static const struct sig_boolean_funcs power_230v_funcs = {
            .set = monitor_power_230v_set,
      };
      static const struct sig_video_funcs video_funcs = {
            .out = monitor_out,
            .vert_retrace = monitor_vert_retrace,
            .hor_retrace = monitor_hor_retrace,
            .no_sync = monitor_no_sync,
      };
      static const struct sig_i2c_bus_funcs ddc_funcs = {
            .ack_addr = monitor_ack_addr,
            .stop_transaction = monitor_stop_transaction,
            .read_byte = monitor_read_byte,
            .write_byte = monitor_write_byte,
      };
      struct cpssp *cpssp;

      cpssp = shm_map(COMP, nr, sizeof(*cpssp), 0);

      edid_eeprom_init(cpssp, edidblock);
      edid_eeprom_a2_set(cpssp, 0);
      edid_eeprom_a1_set(cpssp, 0);
      edid_eeprom_a0_set(cpssp, 0);

      memset(cpssp->pixel_buffer, 0, sizeof(cpssp->pixel_buffer));
      cpssp->last_width = -1;
      cpssp->last_height = -1;
      cpssp->width = 0;
      cpssp->height = 0;
      cpssp->x = 0;
      cpssp->y = 0;
      cpssp->sync_state = VALID;

      /* Call */
      sig_i2c_bus_connect_cooked(port_vga->ddc, cpssp, &ddc_funcs);

      /* Out */
      cpssp->port_opt_video = port_opt_video;

      /* In */
      sig_boolean_connect_in(port_power_230v, cpssp, &power_230v_funcs);
      sig_video_connect(port_vga->video, cpssp, &video_funcs);
}

void
monitor_create(unsigned int nr, const char *name)
{
      struct cpssp *cpssp;

      shm_create(COMP, nr, sizeof(*cpssp));
      cpssp = shm_map(COMP, nr, sizeof(*cpssp), 0);

      shm_unmap(cpssp, sizeof(*cpssp));
}

void
monitor_destroy(unsigned int nr)
{
      struct cpssp *cpssp;

      cpssp = shm_map(COMP, nr, sizeof(*cpssp), 0);

      shm_unmap(cpssp, sizeof(*cpssp));
      shm_destroy(COMP, nr);
}

Generated by  Doxygen 1.6.0   Back to index