File: blk03381.txt

/ViaBTC/Mined by meno5371/,
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474nd
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474nC
FjDOUT:3D9F0A0449D91C3343F0BFEF3EB23AA18B601B147213F9A4559BA64718E8AF0E
IjGREFUND:56077326FC10BAAB6E0230AF2A8E293F37BAF1EF14CD5A0D4F4C1C3FA04A0262
FjDOUT:96BECFE94CA30AD066515B74539F97AF51EABF2945E03DCC80D0A406DF0DA249
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n
text/html;charset=utf-8
<!doctypehtml><html lang="en"><meta charset="UTF-8"><title>600 000 000 000</title><style>body{background:#f7931a;color:#fff;text-align:center}h1{font-weight:700;margin:0;font-size:666px;line-height:.9;font-family:sans}</style><h1>600 000 000 000</h1>
GjE=:LTC.LTC:ltc1qtwfdwwp3adpwdgyvejj8k4mcrawnqvdr7gtzr6:2497261523:t:30
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n4%
c/Foundry USA Pool #dropgold/
Bj@=:ETH.ETH:0xa34fc44e304de518b781bfb3eadef606e5fe9cab:204141549:t
Aj?=:ETH.ETH:0x002eF02188CD5Af452662BAB7B0d217C98edc4c8:61461:te:0
Bj@=:BNB.BNB:bnb1z203xu68awz2ucee2ld92redjwh5kk4f7ttga0:260675:te:0
CjA=:BNB.BNB:bnb1277llrkm5luch2ac8p32g06qmwapczffgdy7d6:1135575:te:0
GjE=:BNB.BTCB-1DE:bnb1xnfqwtwzlxp5d6kk4teejkwt6n7kh665a5t86t:156826:te:0
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474nh
DjB=:ETH.ETH:0xf3BF52129B6aB158bA6d52BB4eD9ba830D837744:23625389:te:0
c/Foundry USA Pool #dropgold/
8j6BERNSTEIN 2.0 REG f039ea5c-096d-4530-8e95-756b5b652d79
FjD=:THOR.RUNE:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n:396898401658
7j5ion:10.QmY1BXnLuPWpG886pjZySeHZvfdF9QY5DYkmkw5PKcWRhc
LjJs:GAIA.ATOM:cosmos1j0gdax9mfqk46msh25wh6l9gdhrqjdmeffw30e:13271266013:ss:0
Bj@=:ETH.ETH:0x4d7d7c6cC1171f52eEE75a4FAB1F45FAe66afdc2:182237:te:0
CjA=:BNB.BNB:bnb1xnfqwtwzlxp5d6kk4teejkwt6n7kh665a5t86t:2639585:te:0
JjH=:BNB.TWT-8C2:bnb1qfl4g38saelylhw6exkcf3ndcrtajy8k8248zk:1681715407:te:0
KjI=:BNB.BUSD-BD1:bnb1rwtf79az0wu49aju63kcaxayq7aql6qt6uq4mv:2310102804:te:0
FjDOUT:F862F6564CB1139A350C0E40300C50281EDBE5DB5292D1D4B715845C044BF004
IjGREFUND:86892234ED3FA22800E2B0461A4A63E11A976120D8618C42A0F444B5ECBD50F8
EjCs:ETH.ETH:0x749885b96c8989C32DF08480E5F064BcAE8C5Fa3:116120048:ss:0
CjA=:BNB.BNB:bnb17svwgfv49na3xz0e2v90aje5naht5y3k0xz23c:1564930:te:0
c/Foundry USA Pool #dropgold/
FjDOUT:55348E9171D3FE3300F4C09C34E021057116D71E8F309288045F0CF3E2D3DC5B
FjDOUT:3DEA8A61D52864F6A2DB10F76B5BD3800276C0263DC542E5CEE0699A5131B53F
FjDOUT:5B05C23B4CBB896A730AB2775BEBB53E74B3C8499FD1AD381083FE2D6B7B676A
FjDOUT:42273D42823F4157B5640FD5177779052747563AEFC8BF880A152060143197E9
CjAs:DOGE.DOGE:DQB6j8npPxMAd5haECgcoHX2t33kwVSKBm:1036183033564:ss:0
SjLPs:ETH.USDT-13D831EC7:0x32EeD2A329794589294C321b76AE7fF49113a1C2:99371668544:ss:0
Bj@=:ETH.ETH:0xA34fc44E304dE518b781Bfb3eadEF606e5Fe9cAB:202490329:t2
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n
4j2DC-L5:UE664nEDRqD3F9LQMtKVrcqEvtCZwKLSYQyUr3iTMVE=
=j;Stell Dir vor es ist Krieg und keiner  geht hin fuck Putin Q
/ViaBTC/Mined by amosss1/,
KjISWAPTX:0x9da3abe6075f8e967bbb07467408cad6833ce759e7c03eeaf107d7902206e7e5
text/plain;charset=utf-8
Ordinals Puzzle #2 ...
... dropping soon on the timechain.
This is a key piece to solving the puzzle.
Follow @ordinalsindex on Twitter for updates.
:j8=:RUNE:thor1y5mhjjz8pkzsyha06clwse64s2e48w0y4grttj::wr:0
/ViaBTC/Mined by fermakgbmk/,
Bj@=:ETH.ETH:0x5e8f151E9bc6E30bc99c03b5e1D3198DE8d12D54:837634:te:0
Bj@=:BNB.BNB:bnb1hj0trl02xw5jyk9sgwyq2eraa5tzxf27tlvd72:340214:te:0
Bj@=:ETH.ETH:0x1D45997F8f6ea825A48Eb7aB5B9EbE035b86658c:124526:te:0
KjI=:BNB.TWT-8C2:bnb1jnfpv4jc9w7dam2k2436ny57460jcg36wfslsg:22309929123:te:0
LjJ=:BNB.BUSD-BD1:bnb1lp2c45aa6zdqdevtdjy5eg89t4zfw4tjlke8tj:32491936277:te:0
CjA=:BNB.BNB:bnb1hv9czre8fl6p39wah5f6vg3v9rxcd3pkassjez:2898773:te:0
1\ Powered by Luxor Tech \
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n
IjGREFUND:E74A26F47301A40D04B406B894AD3CC1E5FDD988C2B70B030CE70D66547BE3DB
IjGREFUND:E19F8EF750D74D4456A618E44F81F5EAD1D6F6ED7EC405940C15FF9CA0826602
KjI=:BNB.BUSD-BD1:bnb1yhpptekq6n78d89w50d4d9ywgrle33p7dc0guv:5970795845:te:0
FjD=:LTC.LTC:ltc1qqx9v7r4e6s39u5twr22trf5lxnlt4qxsj9qfwj:169947468:t:30
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n
SjLPs:ETH.USDC-E3606EB48:0x834bf675dAf52B5D6fD953a57c83e824521E5ab6:44729677632:ss:0
FjDOUT:0822E39D05D2A2EC8B3F7B76C24CB6A745AF54C82D29959E70BC6F1AA52D0FB9
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n4J
FjDOUT:A9133BC8DB0377D8E62B2CBEC40E11E4FE3CF46FA7E4E727FFA3EFAFE844F5B4
FjDOUT:0B343EF4DB83F7E26A7E99923530DCDFA3A94D6C48EE918AC8D9A6DABAD86C0A
FjDOUT:65C2EEA9B1495C224076CD341CE6F877E456AED4016092CDB09134C5C0A17FB5
FjDOUT:929E96C055817046DF38568F05ED344E1826363DF414D5A79DF7FBC0D38870F9
FjDOUT:BD9B469110DE9DE96318B455976D3F9028FBD2AE527B0B07B5377617B66F4570
FjDOUT:58808E85E050B8E58933F660199022A6A6EDF384AD197D378E6F9EDC5CD470DE
DjB=:BNB.BNB:bnb1zf0k59rcpqr5r40p2acyqvsep07xklde6d5tv5:22297495:te:0
LjJ=:BNB.BUSD-BD1:bnb1lp2c45aa6zdqdevtdjy5eg89t4zfw4tjlke8tj:24531416280:te:0
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474nc
FjDOUT:F66CAA38058DFE211215945AD96A60148C46D8868D78DAEC42D7FBF51B989FE6
FjDOUT:2004FE2E7DC28F5ABC76CFC86C0227F417E12E6E977277866815E3E461C65758
FjDOUT:D7E7451B4579E1E5F1E2367C124F9D7543AE0070D54EF5FB7F0CDA6FBCC6BF2B
7j5ion:15.QmbK6uUxWaBS8uqh6pd1iXp4ikQN3xa8AuoYrdvjNVDDzL
Bj@=:ETH.ETH:0x422b204F960ea7A70144D4469ECE10EBE3F3f586:367636:te:0
c/Foundry USA Pool #dropgold/
KjISWAPTX:0x1a0276204b506559f45d1be3834b6e84cbbfee2f1b8e98d0712ec038e7d815b3
FjDOUT:6A3C40F228718A34B8F78AF954C1D62803A9ED5577D798279737EACF67598ABA
FjDOUT:D39DDC050E29BD7172B573535E74CFDDA9CDA576843A557E603521A9C3725FF1
Bj@=:BNB.BNB:bnb1cxdmzc5dk8wrk8v5lr9zksmhzfmm0wwa4f90wr:441835:te:0
 2ce981b37a0440f7353880d1546c91ecH0E
c/Foundry USA Pool #dropgold/
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n[
FjDOUT:E7F8B93686B68EA211F92E2FF95F6E1DEBC24DFC33DA41617BA5B6A34046E94D
FjDOUT:E7255F20E202A6A113F374C435BA2D9DC38E590F9BF22B0A0FB1FCFFE7CA4A94
DjB=:BNB.BNB:bnb1xlrj688ksx7sw2qatvhrkful7t088l0r282wfd:28216438:te:0
KjI=:BNB.BUSD-BD1:bnb1lp2c45aa6zdqdevtdjy5eg89t4zfw4tjlke8tj:5987743462:te:0
text/html;charset=utf-8
  <title>Basic Missile Command HTML Game</title>
  <meta charset="UTF-8">
    background: black;
    align-items: center;
    justify-content: center;
    cursor: crosshair;
    border: 1px solid white;
<canvas width="800" height="550" id="game"></canvas>
const canvas = document.getElementById('game');
const context = canvas.getContext('2d');M
const groundY = 500;  // y position of where the ground starts
const cityWidth = 45;  // how wide a city rect is
const cityHeight = 25;  // how tall a city rect is
const cityY = groundY - cityHeight;  // y position of the city
const siloY = groundY - 30;  // y position of the top of the silo
const missileSize = 4;  // the radius/size of a missile
const missileSpeed = 1;  // how fast a missile moves
const counterMissileSpeed = 15;  // how fast a counter-missile moves
// information about each missile
let counterMissiles = [];
// information about each explosion
let explosions = [];
// how many missiles to spawn at each interval of the level (in this
// case spawn 4 missiles at the start of level 1 and 4 more missiles
// at the next interval of level 1)
const levels = [ [4, 4] ];
let currInterval = 0;
// the x/y position of all cities and if the city is currently alive
  { x: 140, y: cityY, alive: true },
  { x: 220, y: cityY, alive: true },
  { x: 300, y: cityY, aliveM
  { x: 500, y: cityY, alive: true },
  { x: 580, y: cityY, alive: true },
  { x: 660, y: cityY, alive: true }
// the x position of each of the 3 silos
const siloPos = [ 55, canvas.width / 2, 745 ];
// the x/y position of each silo, the number of missiles left, and if
// it is still alive
  { x: siloPos[0], y: siloY, missiles: 10, alive: true },
  { x: siloPos[1], y: siloY, missiles: 10, alive: true },
  { x: siloPos[2], y: siloY, missiles: 10, alive: true }
// the x/y position of eaM
ch missile spawn point. missiles spawn
// directly above each city and silo plus the two edges
const missileSpawns = cities
  .concat([{ x: 0, y: 0 }, { x: canvas.width, y: 0 }])
  .map(pos => ({ x: pos.x, y: 0 }));
// return a random integer between min (inclusive) and max (inclusive)
// @see https://stackoverflow.com/a/1527820/2124254
function randInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
// get the angle between two points
function angleBetweenPoints(source,M
  // atan2 returns the counter-clockwise angle in respect to the
  // x-axis, but the canvas rotation system is based on the y-axis
  // (rotation of 0 = up).
  // so we need to add a quarter rotation to return a
  // counter-clockwise rotation in respect to the y-axis
  return Math.atan2(target.y - source.y, target.x - source.x) + Math.PI / 2;
// distance between two points
function distance(source, target) {
  return Math.hypot(source.x - target.x, source.y - target.y);
// spawn a missile by choM
osing a spawn point and a target.
// a missile can target any city or silo
function spawnMissile() {
  const targets = cities.concat(silos);
  const randSpawn = randInt(0, missileSpawns.length - 1);
  const randTarget = randInt(0, targets.length - 1);
  const start = missileSpawns[randSpawn];
  const target = targets[randTarget];
  const angle = angleBetweenPoints(start, target);
    start,  // where the missile started
    target, // where the missile is going
    pos: { x: start.x, y: start.y M
},  // current position
    alive: true,  // if we should still draw the missile
    // used to update the position every frame
    dx: missileSpeed * Math.sin(angle),
    dy: missileSpeed * -Math.cos(angle)
// start at -2 seconds (time is in milliseconds) to give the player 1
// second before the missiles start
let lastTime = -2000;
function loop(time) {
  requestAnimationFrame(loop);
  context.clearRect(0,0,canvas.width,canvas.height);
  // spawn missiles every interval of 3 seconds (if thM
  if (time - lastTime > 3000 && currInterval < levels[currLevel].length) {
    for (let i = 0; i < levels[currLevel][currInterval]; i++) {
      spawnMissile();
    lastTime = time;
  context.fillStyle = 'blue';
  cities.forEach(city => {
    // center the city on the x position
    context.fillRect(city.x - cityWidth / 2, city.y, cityWidth, cityHeight);
  // draw ground and silos
  context.fillStyle = 'yellow';
  context.moveTo(0, canvas.height);
  context.lineTo(0, groundY);
  // draw each silo hill
  siloPos.forEach(x => {
    context.lineTo(x - 40, groundY);
    context.lineTo(x - 20, siloY);
    context.lineTo(x + 20, siloY);
    context.lineTo(x + 40, groundY);
  context.lineTo(canvas.width, groundY);
  context.lineTo(canvas.width, canvas.height);
  // draw the number of counter-missiles each silo
  context.fillStyle = 'black';
  silos.forEach(silo => {
    // draw missiles in aM
 triangular shape by incrementing how many
    // missiles we can draw per row
    let missilesPerRow = 1;
    let y = silo.y + 5;
    for (let i = 0; i < silo.missiles; i++) {
      context.fillRect(x, y, 4, 10);
      if (++count === missilesPerRow) {
        x = silo.x - 6 * count;
        missilesPerRow++;
  // update and draw missiles
  context.strokeStyle = 'red';
  context.lineWidth = 2;
te color based on time so it "blinks"
  // by dividing by a number and seeing if it's odd or even we can
  // change the speed of the blinking
  context.fillStyle = 'white';
  if (Math.round(time / 2) % 2 === 0) {
    context.fillStyle = 'black';
  missiles.forEach(missile => {
    missile.pos.x += missile.dx;
    missile.pos.y += missile.dy;
    // check if the missile hit an explosion by doing a circle-circle
    // collision check
    explosions.forEach(explosion => {
      const dist = distance(explosion,M
      if (dist < missileSize + explosion.size) {
        missile.alive = false;
    // if missile is close the the target we blow it up
    const dist = distance(missile.pos, missile.target);
    if (dist < missileSpeed) {
      missile.alive = false;
      missile.target.alive = false;
    if (missile.alive) {
      context.beginPath();
      context.moveTo(missile.start.x, missile.start.y);
      context.lineTo(missile.pos.x, missile.pos.y);
      context.stroke();
 center the head of the missile to the x/y position
      context.fillRect(missile.pos.x - missileSize / 2, missile.pos.y - missileSize / 2, missileSize, missileSize);
    // a dead missile spawns an explosion
      explosions.push({
        x: missile.pos.x,
        y: missile.pos.y,
  // update and draw counter missiles
  context.strokeStyle = 'blue';
  context.fillStyle = 'white';
  counterMissiles.forEach(missile => {
   missile.pos.x += missile.dx;
    missile.pos.y += missile.dy;
    // if missile is close the the target we blow it up
    const dist = distance(missile.pos, missile.target);
    if (dist < counterMissileSpeed) {
      missile.alive = false;
      explosions.push({
        x: missile.pos.x,
        y: missile.pos.y,
      context.beginPath();
      context.moveTo(missile.start.x, missile.start.y);
      context.lineTo(missile.pos.x, M
      context.stroke();
      context.fillRect(missile.pos.x - 2, missile.pos.y - 2, 4, 4);
  // update and draw explosions
  explosions.forEach(explosion => {
    explosion.size += 0.35 * explosion.dir;
    // change the direction of the explosion to wane
    if (explosion.size > 30) {
      explosion.dir = -1;
    // remove the explosion
    if (explosion.size <= 0) {
      explosion.alive = false;
      context.fillStyle = 'white';
      if (Math.round(time M
        context.fillStyle = 'blue';
      context.beginPath();
      context.arc(explosion.x, explosion.y, explosion.size, 0, 2 * Math.PI);
      context.fill();
  // remove dead missiles, explosions, cities, and silos
  missiles = missiles.filter(missile => missile.alive);
  counterMissiles = counterMissiles.filter(missile => missile.alive);
  explosions = explosions.filter(explosion => explosion.alive);
  cities = cities.filter(city => city.alive);
  silos = silos.filter(siM
// listen to mouse events to fire counter-missiles
canvas.addEventListener('click', e => {
  // get the x/y position of the mouse pointer by subtracting the x/y
  // position of the canvas element from the x/y position of the
  const x = e.clientX - e.target.offsetLeft;
  const y = e.clientY - e.target.offsetTop;
  // determine which silo is closest to the pointer and fire a
  // counter-missile from it
  let launchSilo = null;
  let siloDistance = Infinity;  // start at the largM
  silos.forEach(silo => {
    const dist = distance({ x, y }, silo);
    if (dist < siloDistance && silo.missiles) {
      siloDistance = dist;
      launchSilo = silo;
    const start = { x: launchSilo.x, y: launchSilo.y };
    const target = { x, y };
    const angle = angleBetweenPoints(start, target);
    launchSilo.missiles--;
    counterMissiles.push({
      pos: { x: launchSilo.x, y: launchSilo. y},
      dx: counterMissileSpeed * Math.siL
      dy: counterMissileSpeed * -Math.cos(angle),
requestAnimationFrame(loop);
c/Foundry USA Pool #dropgold/
7j5=:BTC/BTC:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n
SjLPs:ETH.FOX-D808EE52D:0x1B9bB0A0A55f30edAA6A03D55190C0Ad72CacaE5:241474682209:ss:0
FjDOUT:9B16F1F08FF0A18A233ADC125C2F22992BCB915282ED375718A0CF1E3CAB0DB0
FjDOUT:23E09844249581E34AFC600F74676C74035825C0A15212AE97CC82B986BE7F11
FjDOUT:C3405794A3B01D9868B96CFBA26E2C1E9950BAAADABEE89BDE6FEACBF01B39A4
IjGREFUND:D3FE02B230362B719DF221E068738DD82244F463594A249384FCAE5568160EFE
LjJ=:BNB.BUSD-BD1:bnb16hjkt6tfdwsmy7saqdymh3qy7c24uerep79mts:14478139561:te:0
text/html;charset=utf-8
  <title>Basic Doodle Jump HTML Game</title>
  <meta charset="UTF-8">
    align-items: center;
    justify-content: center;
    border: 1px solid black;
<canvas width="375" height="667" id="game"></canvas>
const canvas = document.getElementById('game');
const context = canvas.getContext('2d');
// width and height of each platform and where pM
const platformWidth = 65;
const platformHeight = 20;
const platformStart = canvas.height - 50;
const gravity = 0.33;
const bounceVelocity = -12.5;
// minimum and maximum vertical space between each platform
let minPlatformSpace = 15;
let maxPlatformSpace = 20;
// information about each platform. the first platform starts in the
// bottom middle of the screen
  x: canvas.width / 2 - platformWidth / 2,
// get a random numM
ber between the min (inclusive) and max (exclusive)
function random(min, max) {
  return Math.random() * (max - min) + min;
// fill the initial screen with platforms
let y = platformStart;
  // the next platform can be placed above the previous one with a space
  // somewhere between the min and max space
  y -= platformHeight + random(minPlatformSpace, maxPlatformSpace);
  // a platform can be placed anywhere 25px from the left edge of the canvas
  // and 25px from the right edge of the canvas M
(taking into account platform
  // however the first few platforms cannot be placed in the center so
  // that the player will bounce up and down without going up the screen
  // until they are ready to move
    x = random(25, canvas.width - 25 - platformWidth);
    y > canvas.height / 2 &&
    x > canvas.width / 2 - platformWidth * 1.5 &&
    x < canvas.width / 2 + platformWidth / 2
  platforms.push({ x, y });
// the doodle jumper
  x: canvas.width / 2 - 20,
  y: platformStart - 60,
// keep track of player direction and actions
let keydown = false;
let prevDoodleY = doodle.y;
  requestAnimationFrame(loop);
  context.clearRect(0,0,canvas.width,canvas.height);
  // apply gravity to doodle
  doodle.dy += gravity;
  // if doodle reaches the middle of the screen, move the platforms down
  // instead of doodle up to make it look like doodle is going M
  if (doodle.y < canvas.height / 2 && doodle.dy < 0) {
    platforms.forEach(function(platform) {
      platform.y += -doodle.dy;
    // add more platforms to the top of the screen as doodle moves up
    while (platforms[platforms.length - 1].y > 0) {
      platforms.push({
        x: random(25, canvas.width - 25 - platformWidth),
        y: platforms[platforms.length - 1].y - (platformHeight + random(minPlatformSpace, maxPlatformSpace))
      // add a bit to the min/max platform space as the M
      minPlatformSpace += 0.5;
      maxPlatformSpace += 0.5;
      // cap max space
      maxPlatformSpace = Math.min(maxPlatformSpace, canvas.height / 2);
    doodle.y += doodle.dy;
  // only apply drag to horizontal movement if key is not pressed
    if (playerDir < 0) {
      doodle.dx += drag;
      // don't let dx go above 0
      if (doodle.dx > 0) {
        doodle.dx = 0;
        playerDir = 0;
    else if (playerDir > 0) {
      if (doodle.dx < 0) {
        doodle.dx = 0;
        playerDir = 0;
  doodle.x += doodle.dx;
  // make doodle wrap the screen
  if (doodle.x + doodle.width < 0) {
    doodle.x = canvas.width;
  else if (doodle.x > canvas.width) {
    doodle.x = -doodle.width;
  context.fillStyle = 'green';
  platforms.forEach(function(platform) {
    context.fillRect(platform.x, platform.y, platformWidth, platformHeight);
    // make doodle jump if it collides wiM
th a platform from above
      // doodle is falling
      doodle.dy > 0 &&
      // doodle was previous above the platform
      prevDoodleY + doodle.height <= platform.y &&
      // doodle collides with platform
      // (Axis Aligned Bounding Box [AABB] collision check)
      doodle.x < platform.x + platformWidth &&
      doodle.x + doodle.width > platform.x &&
      doodle.y < platform.y + platformHeight &&
      doodle.y + doodle.height > platform.y
      // reset doodle position so it's on tM
      doodle.y = platform.y - doodle.height;
      doodle.dy = bounceVelocity;
  context.fillStyle = 'yellow';
  context.fillRect(doodle.x, doodle.y, doodle.width, doodle.height);
  prevDoodleY = doodle.y;
  // remove any platforms that have gone offscreen
  platforms = platforms.filter(function(platform) {
    return platform.y < canvas.height;
// listen to keyboard events to move doodle
document.addEventListener('keydown', function(e) {
  // left arrow keMa
  if (e.which === 37) {
  // right arrow key
  else if (e.which === 39) {
document.addEventListener('keyup', function(e) {
requestAnimationFrame(loop);

%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X'
c/Foundry USA Pool #dropgold/
Bj@=:ETH.ETH:0x7c5C5cf47141389d3D9fA90dd5250Cb19d5b2064:551599:te:0
EjCs:RUNE:thor1k8dd70sddrwcq3r5xsfvy3veqjylxm4qhs2z6k:35497349738:ss:0
IjGREFUND:ED77D2FB6F9CA99819AE78C4BBD01D4D38861B4E4B2691046A914C9261B42B5A
IjGREFUND:F36D2F52AC6FF5BEF334485B58DEA40CACA20440947BBC30E4817C6C4E44F48D
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
  <title>Bitcoin Face</title>
  <g style="isolation:isolate"><rect id="Background-5" width="1025" height="1025" style="fill:#f8f3c1" /><g id="Body-8"><rect x="161.21" y="452.66" width="687.79" height="552.16" style="fill:#ba3d11" /><rect x="309.41" y="451.15" width="382.27" height="553.67" style="fill:#542f5f" /><rect x="500.36" y="451.15" width="194.64" height="553.67" style="fill:#172027" /></g><g id="Head-11"><path d="M164.72,490.82C164.72,683.66,3M
17,840,504.85,840S845,683.66,845,490.82" transform="translate(0.28)" style="fill:#f5b659" /><path d="M186,490.82c0,180.79,142.76,327.34,318.87,327.34S823.71,671.61,823.71,490.82" transform="translate(0.28)" style="fill:#ecdea0" /><path d="M228.5,490.82c0,156.68,123.72,283.7,276.35,283.7s276.34-127,276.34-283.7" transform="translate(0.28)" style="fill:#e18d27" /><polygon points="506.79 774.52 503.45 774.52 503.45 510.93 781.47 510.93 781.47 514.36 506.79 514.36 506.79 774.52" style="fill:#ecdea0" /><polygon points="M
695.33 688.51 497.93 508.38 760.74 598.31 759.68 601.56 512.31 516.91 697.55 685.94 695.33 688.51" style="fill:#ecdea0" /><polygon points="609.89 753.4 503.6 513.35 506.64 511.94 612.93 751.98 609.89 753.4" style="fill:#ecdea0" /><polygon points="506.79 774.52 503.45 774.52 503.45 514.36 228.77 514.36 228.77 510.93 506.79 510.93 506.79 774.52" style="fill:#ecdea0" /><polygon points="314.91 688.51 312.69 685.94 497.93 516.91 250.56 601.56 249.5 598.31 512.31 508.38 314.91 688.51" style="fill:#ecdea0" /><polygon poinM
ts="400.35 753.4 397.31 751.98 503.6 511.94 506.64 513.35 400.35 753.4" style="fill:#ecdea0" /><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M664.28,601.65A12.63,12.63,0,1,1,676.58,589,12.47,12.47,0,0,1,664.28,601.65Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.09,9.09,0,0,0,664.28,579.83Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M643,579.83a12.63,12.63,0,1,1,12.3-12.63A12.49,12.49,0,0,1,643,579.83ZM643,558a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,643,5M
58Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M738.68,579.83c-12.64,0-22.93-10.56-22.93-23.54s10.29-23.54,22.93-23.54,22.92,10.56,22.92,23.54S751.32,579.83,738.68,579.83Zm0-43.65c-10.8,0-19.59,9-19.59,20.11s8.79,20.11,19.59,20.11,19.58-9,19.58-20.11S749.48,536.18,738.68,536.18Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M685.53,536.18a12.63,12.63,0,1,1,12.3-12.63A12.47,12.47,0,0M
,1,685.53,536.18Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.08,9.08,0,0,0,685.53,514.36Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M483.59,732.59c-12.64,0-22.93-10.56-22.93-23.54s10.29-23.54,22.93-23.54,22.93,10.56,22.93,23.54S496.23,732.59,483.59,732.59Zm0-43.65c-10.8,0-19.59,9-19.59,20.11s8.79,20.11,19.59,20.11,19.58-9,19.58-20.11S494.39,688.94,483.59,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:oveM
rlay"><path d="M451.7,688.94A12.63,12.63,0,1,1,464,676.32,12.48,12.48,0,0,1,451.7,688.94Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,451.7,667.12Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M387.93,601.65A12.63,12.63,0,1,1,400.23,589,12.48,12.48,0,0,1,387.93,601.65Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.09,9.09,0,0,0,387.93,579.83Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M324.16,558M
a12.63,12.63,0,1,1,12.3-12.62A12.47,12.47,0,0,1,324.16,558Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,324.16,536.18Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M260.38,558a12.63,12.63,0,1,1,12.3-12.62A12.47,12.47,0,0,1,260.38,558Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,260.38,536.18Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M292.27,645.3c-12.64,0-22.93-10.56-22.93-23.54sM
10.29-23.54,22.93-23.54,22.93,10.56,22.93,23.54S304.91,645.3,292.27,645.3Zm0-43.65c-10.8,0-19.59,9-19.59,20.11s8.79,20.11,19.59,20.11,19.59-9,19.59-20.11S303.07,601.65,292.27,601.65Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M324.16,667.12a12.63,12.63,0,1,1,12.3-12.63A12.48,12.48,0,0,1,324.16,667.12Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.09,9.09,0,0,0,324.16,645.3Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-M
mode:overlay"><path d="M600.5,667.12a12.63,12.63,0,1,1,12.3-12.63A12.48,12.48,0,0,1,600.5,667.12Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.08,9.08,0,0,0,600.5,645.3Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M664.28,710.76a12.63,12.63,0,1,1,12.3-12.62A12.47,12.47,0,0,1,664.28,710.76Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,664.28,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M611M
.13,732.59c-12.64,0-22.92-10.56-22.92-23.54s10.28-23.54,22.92-23.54,22.93,10.56,22.93,23.54S623.77,732.59,611.13,732.59Zm0-43.65c-10.8,0-19.58,9-19.58,20.11s8.78,20.11,19.58,20.11,19.59-9,19.59-20.11S621.94,688.94,611.13,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M706.79,645.3a12.63,12.63,0,1,1,12.3-12.63A12.49,12.49,0,0,1,706.79,645.3Zm0-21.83a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,706.79,623.47Z" transform="translate(0.28)" style="fill:#aeaM
4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M473,579.83a12.63,12.63,0,1,1,12.3-12.63A12.49,12.49,0,0,1,473,579.83ZM473,558a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,473,558Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M430.45,536.18a12.63,12.63,0,1,1,12.29-12.63A12.48,12.48,0,0,1,430.45,536.18Zm0-21.82a9.2,9.2,0,1,0,8.95,9.19A9.09,9.09,0,0,0,430.45,514.36Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.M
52;mix-blend-mode:overlay"><path d="M579.25,558a12.63,12.63,0,1,1,12.3-12.62A12.48,12.48,0,0,1,579.25,558Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,579.25,536.18Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M558,601.65A12.63,12.63,0,1,1,570.29,589,12.48,12.48,0,0,1,558,601.65Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.09,9.09,0,0,0,558,579.83Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M4M
94.22,649.82a17.15,17.15,0,1,1,16.7-17.15A17,17,0,0,1,494.22,649.82Zm0-30.87a13.72,13.72,0,1,0,13.36,13.72A13.56,13.56,0,0,0,494.22,619Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M536.73,710.76A12.63,12.63,0,1,1,549,698.14,12.48,12.48,0,0,1,536.73,710.76Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,536.73,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M558,758.93a17.15,17.15M
,0,1,1,16.7-17.15A16.95,16.95,0,0,1,558,758.93Zm0-30.86a13.72,13.72,0,1,0,13.36,13.71A13.55,13.55,0,0,0,558,728.07Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M366.67,710.76A12.63,12.63,0,1,1,379,698.14,12.48,12.48,0,0,1,366.67,710.76Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,366.67,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><rect x="164.72" y="490.82" width="680.24" height="21.82" transform="translate(1009.97 1003.46) rotaM
te(-180)" style="fill:#aea4b3;opacity:0.52;mix-blend-mode:overlay" /><path d="M845.81,507.17C845.81,314.33,693.53,158,505.69,158S165.57,314.33,165.57,507.17" transform="translate(0.28)" style="fill:#f5b659" /><path d="M824.55,507.17c0-180.79-142.76-327.35-318.86-327.35S186.82,326.38,186.82,507.17" transform="translate(0.28)" style="fill:#ecdea0" /><path d="M782,507.17c0-156.69-123.73-283.7-276.35-283.7s-276.35,127-276.35,283.7" transform="translate(0.28)" style="fill:#e18d27" /><polygon points="504.29 223.47 507.63M
 223.47 507.63 487.06 229.62 487.06 229.62 483.63 504.29 483.63 504.29 223.47" style="fill:#ecdea0" /><polygon points="315.76 309.48 513.15 489.61 250.35 399.68 251.4 396.43 498.77 481.07 313.54 312.04 315.76 309.48" style="fill:#ecdea0" /><polygon points="401.19 244.58 507.49 484.63 504.44 486.05 398.15 246 401.19 244.58" style="fill:#ecdea0" /><polygon points="504.29 223.47 507.63 223.47 507.63 483.63 782.31 483.63 782.31 487.06 504.29 487.06 504.29 223.47" style="fill:#ecdea0" /><polygon points="696.17 309.48 69M
8.39 312.04 513.15 481.07 760.53 396.43 761.58 399.68 498.77 489.61 696.17 309.48" style="fill:#ecdea0" /><polygon points="610.73 244.58 613.77 246 507.49 486.05 504.44 484.63 610.73 244.58" style="fill:#ecdea0" /><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M346.26,396.34A12.63,12.63,0,1,1,334,409,12.48,12.48,0,0,1,346.26,396.34Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,346.26,418.16Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M367.M
51,418.16a12.63,12.63,0,1,1-12.29,12.63A12.48,12.48,0,0,1,367.51,418.16Zm0,21.82a9.2,9.2,0,1,0-8.95-9.19A9.08,9.08,0,0,0,367.51,440Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M271.85,418.16c12.65,0,22.93,10.56,22.93,23.54s-10.28,23.54-22.93,23.54-22.92-10.56-22.92-23.54S259.21,418.16,271.85,418.16Zm0,43.65c10.81,0,19.59-9,19.59-20.11s-8.78-20.11-19.59-20.11-19.58,9-19.58,20.11S261.05,461.81,271.85,461.81Z" transform="translate(0.28)" style="fill:M
#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M325,461.81a12.63,12.63,0,1,1-12.3,12.62A12.48,12.48,0,0,1,325,461.81Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,325,483.63Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M527,265.4c12.64,0,22.92,10.56,22.92,23.54S539.59,312.48,527,312.48,504,301.92,504,288.94,514.3,265.4,527,265.4Zm0,43.65c10.8,0,19.58-9,19.58-20.11s-8.78-20.11-19.58-20.11-19.59,9-19.59,20.11S516.15,309.05,527,M
309.05Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M558.83,309.05a12.63,12.63,0,1,1-12.3,12.62A12.47,12.47,0,0,1,558.83,309.05Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,558.83,330.87Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M622.61,396.34A12.63,12.63,0,1,1,610.31,409,12.47,12.47,0,0,1,622.61,396.34Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,622.61,418.16Z" transform="tranM
slate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M686.38,440a12.63,12.63,0,1,1-12.3,12.63A12.49,12.49,0,0,1,686.38,440Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,686.38,461.81Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M750.15,440a12.63,12.63,0,1,1-12.3,12.63A12.49,12.49,0,0,1,750.15,440Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,750.15,461.81Z" transform="translate(0.28)" style="fill:#aea4b3" />M
</g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M718.26,352.69c12.65,0,22.93,10.56,22.93,23.54s-10.28,23.54-22.93,23.54-22.92-10.56-22.92-23.54S705.62,352.69,718.26,352.69Zm0,43.65c10.81,0,19.59-9,19.59-20.11s-8.78-20.11-19.59-20.11-19.58,9-19.58,20.11S707.46,396.34,718.26,396.34Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M686.38,330.87a12.63,12.63,0,1,1-12.3,12.62A12.48,12.48,0,0,1,686.38,330.87Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09M
,0,0,0,686.38,352.69Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M410,330.87a12.63,12.63,0,1,1-12.3,12.62A12.48,12.48,0,0,1,410,330.87Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,410,352.69Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M346.26,287.22A12.63,12.63,0,1,1,334,299.85,12.49,12.49,0,0,1,346.26,287.22Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,346.26,309.05Z" transform=M
"translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M399.4,265.4c12.64,0,22.93,10.56,22.93,23.54S412,312.48,399.4,312.48s-22.93-10.56-22.93-23.54S386.76,265.4,399.4,265.4Zm0,43.65c10.8,0,19.59-9,19.59-20.11s-8.79-20.11-19.59-20.11-19.59,9-19.59,20.11S388.6,309.05,399.4,309.05Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M303.74,352.69a12.63,12.63,0,1,1-12.3,12.63A12.48,12.48,0,0,1,303.74,352.69Zm0,21M
.82a9.2,9.2,0,1,0-9-9.19A9.09,9.09,0,0,0,303.74,374.51Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M537.58,418.16a12.63,12.63,0,1,1-12.3,12.63A12.47,12.47,0,0,1,537.58,418.16Zm0,21.82a9.2,9.2,0,1,0-9-9.19A9.08,9.08,0,0,0,537.58,440Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M580.09,461.81a12.63,12.63,0,1,1-12.3,12.62A12.48,12.48,0,0,1,580.09,461.81Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9M
.09,9.09,0,0,0,580.09,483.63Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M431.29,440A12.63,12.63,0,1,1,419,452.61,12.49,12.49,0,0,1,431.29,440Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,431.29,461.81Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M452.54,396.34A12.63,12.63,0,1,1,440.25,409,12.47,12.47,0,0,1,452.54,396.34Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,452.54,418.16Z"M
 transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M516.32,348.17a17.15,17.15,0,1,1-16.7,17.15A16.95,16.95,0,0,1,516.32,348.17Zm0,30.86A13.72,13.72,0,1,0,503,365.32,13.55,13.55,0,0,0,516.32,379Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M473.8,287.22a12.63,12.63,0,1,1-12.3,12.63A12.49,12.49,0,0,1,473.8,287.22Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,473.8,309.05Z" transform="translaM
te(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M452.54,239.06a17.15,17.15,0,1,1-16.7,17.14A17,17,0,0,1,452.54,239.06Zm0,30.86a13.72,13.72,0,1,0-13.36-13.72A13.56,13.56,0,0,0,452.54,269.92Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M643.86,287.22a12.63,12.63,0,1,1-12.3,12.63A12.49,12.49,0,0,1,643.86,287.22Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,643.86,309.05Z" transform="translate(0.28)" style="fM
ill:#aea4b3" /></g><rect x="165.84" y="485.34" width="680.24" height="21.82" style="fill:#aea4b3;opacity:0.52;mix-blend-mode:overlay" /></g><g id="Face-Accessory-1"><circle cx="516.52" cy="942.46" r="62.02" style="fill:#f96020" /><circle cx="516.52" cy="942.46" r="54.28" style="fill:#d74816" /><rect x="487.05" y="879.79" width="35.52" height="96.79" transform="translate(214.46 1954.46) rotate(-135)" style="fill:#ffa520" /><circle cx="510.95" cy="942.07" r="66.36" style="fill:#f96020" /><circle cx="510.94" cy="942.0M
7" r="58.08" style="fill:#d74816" /><g id="_04CbBX.tif" data-name="04CbBX.tif"><path d="M499.36,875.6h5.23a5.28,5.28,0,0,0,1.13.08c1.51.13,3,.28,4.52.52a52.15,52.15,0,0,1,10.43,2.72,53.73,53.73,0,0,1,32.17,33.55,52.41,52.41,0,0,1,2.21,10c.15,1.22.26,2.45.31,3.67a1.63,1.63,0,0,0,.08.82v4.31a1.52,1.52,0,0,0-.08.82,46.85,46.85,0,0,1-.52,5.14,52,52,0,0,1-5.39,16.51,53.57,53.57,0,0,1-43.89,28.75,50.62,50.62,0,0,1-8-.07,52.07,52.07,0,0,1-10.21-1.83,53.13,53.13,0,0,1-29.73-21.46,53,53,0,0,1-9.05-25.57,17,17,0,0,0-.16-1.88M
c0-.61,0-1.22,0-1.83,0-1.1,0-2.2,0-3.3a.77.77,0,0,0,.07-.4,53.09,53.09,0,0,1,5.25-20.37,53.67,53.67,0,0,1,35.15-28.6,54.71,54.71,0,0,1,9.34-1.48A8.57,8.57,0,0,0,499.36,875.6Zm-42,53.5a44.61,44.61,0,1,0,44.59-44.62A44.59,44.59,0,0,0,457.33,929.1Z" transform="translate(9.03 13)" style="fill:#ff9317" /><path d="M515.36,927.51a21.52,21.52,0,0,1,5.48,1.69,11.83,11.83,0,0,1,5.27,4.7,12,12,0,0,1,1.52,4.64,17.76,17.76,0,0,1-.27,6.21,10.87,10.87,0,0,1-6.8,8,25.21,25.21,0,0,1-5.77,1.53c-1.34.21-2.68.35-4,.44-.47,0-.47,0-.47.M
51v7.94c0,.5,0,.51-.51.51H504c-.56,0-.53,0-.53-.53v-7.68c0-.64.05-.57-.58-.57h-5.8c-.46,0-.46,0-.47.48v7.73c0,.59,0,.57-.54.57h-5.74c-.55,0-.55,0-.55-.57,0-2.51,0-5,0-7.53,0-.14,0-.27,0-.41s-.06-.29-.26-.27H476.43c-.24,0-.34-.06-.34-.31,0-1.9,0-3.79,0-5.69,0-.27.11-.35.36-.35,1.18,0,2.36,0,3.54,0a10.18,10.18,0,0,0,2.13-.27,1.92,1.92,0,0,0,1.55-1.57,11.89,11.89,0,0,0,.29-2.85V921.52c0-2.47,0-4.95,0-7.43a13.56,13.56,0,0,0-.27-2.69,2,2,0,0,0-1.71-1.68,13.39,13.39,0,0,0-2.75-.24h-2.66c-.47,0-.47,0-.47-.49,0-1.76,0-3.51M
,0-5.27,0-.6-.06-.56.54-.57h12.55c.57,0,.57,0,.58-.54v-7.89c0-.2.09-.28.28-.26h6c.61,0,.56-.06.56.54,0,2.51,0,5,0,7.53,0,.7-.05.62.64.62H503c.46,0,.46,0,.47-.49v-7.94c0-.2.07-.28.27-.26h6c.59,0,.57-.09.57.58v7.84c0,.39,0,.39.39.42a32.44,32.44,0,0,1,6.11,1,17.64,17.64,0,0,1,3.2,1.2,9.17,9.17,0,0,1,5,6.06,14.22,14.22,0,0,1,.12,7.24,10.31,10.31,0,0,1-4.17,6,18.31,18.31,0,0,1-5.34,2.53C515.55,927.36,515.43,927.34,515.36,927.51Zm-18.76,12.4c0,2.77,0,5.53,0,8.3,0,.44,0,.45.44.45h3a44,44,0,0,0,6.39-.31,15,15,0,0,0,3.66-.9M
3,6.31,6.31,0,0,0,3.8-4.16,12,12,0,0,0,.26-6,6.32,6.32,0,0,0-2.8-4.24A9.11,9.11,0,0,0,508.7,932a23.93,23.93,0,0,0-4.61-.65c-2.39-.14-4.78,0-7.17-.08-.26,0-.34.1-.32.33s0,.24,0,.36Zm0-22.76v4.25c0,1.05,0,2.09,0,3.13,0,.25,0,.37.34.37a68.58,68.58,0,0,0,7.72-.23,14.47,14.47,0,0,0,3.67-.89,5.57,5.57,0,0,0,3.45-4A11.75,11.75,0,0,0,512,915a5.49,5.49,0,0,0-3.83-4.58,18.25,18.25,0,0,0-5-.88c-2-.1-4,0-6,0h-.21c-.17,0-.25.08-.24.25s0,.27,0,.41Z" transform="translate(9.03 13)" style="fill:#ff9317" /></g><circle cx="459.8" cy=M
"882.7" r="13.97" style="fill:#ff9317" /><circle cx="438.84" cy="861.74" r="13.97" style="fill:#ff9317" /><circle cx="417.89" cy="840.79" r="13.97" style="fill:#ff9317" /><circle cx="396.93" cy="819.83" r="13.97" style="fill:#ff9317" /><circle cx="564.57" cy="882.7" r="13.97" style="fill:#f96020" /><circle cx="585.53" cy="861.74" r="13.97" style="fill:#f96020" /><circle cx="606.48" cy="840.79" r="13.97" style="fill:#f96020" /><circle cx="627.44" cy="819.83" r="13.97" style="fill:#f96020" /></g><g id="Earrings-1"><cM
ircle cx="141.68" cy="475.44" r="61.24" style="fill:#f26227" /><circle cx="141.68" cy="475.44" r="53.6" style="fill:#d74b27" /><g><path d="M134.36,420.84h4.82a6.06,6.06,0,0,0,1,.07c1.4.12,2.79.26,4.18.48A48.47,48.47,0,0,1,154,423.9a49.56,49.56,0,0,1,29.69,31,47.44,47.44,0,0,1,2,9.2c.13,1.13.24,2.25.28,3.39a1.48,1.48,0,0,0,.07.75v4a1.37,1.37,0,0,0-.07.75,42.22,42.22,0,0,1-.48,4.75,47.88,47.88,0,0,1-5,15.23,49.3,49.3,0,0,1-47.87,26.48,47.84,47.84,0,0,1-9.43-1.7,49.07,49.07,0,0,1-27.44-19.8,49.09,49.09,0,0,1-8.35-23.6M
,12.49,12.49,0,0,0-.15-1.73c0-.57,0-1.13,0-1.69,0-1,0-2,0-3.05a.57.57,0,0,0,.07-.36,47.07,47.07,0,0,1,.76-6.38,48.23,48.23,0,0,1,4.09-12.43,49.32,49.32,0,0,1,41.06-27.75A9.08,9.08,0,0,0,134.36,420.84ZM95.57,470.21A41.17,41.17,0,1,0,136.72,429,41.12,41.12,0,0,0,95.57,470.21Z" transform="translate(4.96 5.26)" style="fill:#f79421" /><path d="M149.13,468.75a19.6,19.6,0,0,1,5.05,1.56,10.88,10.88,0,0,1,4.87,4.33,11.08,11.08,0,0,1,1.4,4.28,16.24,16.24,0,0,1-.25,5.73,10.06,10.06,0,0,1-6.28,7.4,23.28,23.28,0,0,1-5.33,1.41c-M
1.23.19-2.46.33-3.71.4-.43,0-.44,0-.44.48v7.33c0,.46,0,.46-.47.46h-5.35c-.52,0-.49,0-.49-.48v-7.09c0-.59.05-.53-.54-.53h-5.34c-.43,0-.43,0-.43.44,0,2.38,0,4.76,0,7.14,0,.55.05.52-.5.52H126c-.5,0-.51,0-.51-.52v-7.33c0-.17-.06-.27-.24-.25s-.26,0-.38,0H113.19c-.21,0-.31,0-.31-.29q0-2.62,0-5.25c0-.25.1-.32.34-.31h3.26a9.33,9.33,0,0,0,2-.26,1.76,1.76,0,0,0,1.43-1.45,11,11,0,0,0,.26-2.63q0-10.31,0-20.61c0-2.29,0-4.57,0-6.86a11.52,11.52,0,0,0-.24-2.48,1.88,1.88,0,0,0-1.58-1.55,12.77,12.77,0,0,0-2.54-.23c-.82,0-1.64,0-2.46M
,0-.43,0-.43,0-.43-.45v-4.87c0-.56,0-.52.5-.52H125c.52,0,.52,0,.52-.51v-6.9c0-.12,0-.25,0-.38s.09-.25.26-.24h5.54c.56,0,.51-.06.51.5,0,2.32,0,4.63,0,6.95,0,.65,0,.58.58.58h5.3c.43,0,.43,0,.43-.46v-7c0-.11,0-.22,0-.33s.07-.26.25-.25h5.54c.55,0,.52-.08.52.54V446c0,.36,0,.35.37.38a30.6,30.6,0,0,1,5.63.91,16.49,16.49,0,0,1,3,1.11,8.5,8.5,0,0,1,4.65,5.6,13.15,13.15,0,0,1,.11,6.68,9.54,9.54,0,0,1-3.85,5.55,17,17,0,0,1-4.93,2.34C149.3,468.61,149.19,468.58,149.13,468.75Zm-17.31,11.44c0,2.55,0,5.1,0,7.66,0,.41,0,.41.41.41H1M
35a40.14,40.14,0,0,0,5.9-.28,14.22,14.22,0,0,0,3.38-.86,5.83,5.83,0,0,0,3.5-3.84,11,11,0,0,0,.24-5.51,5.78,5.78,0,0,0-2.58-3.91,8.31,8.31,0,0,0-2.49-1,21.66,21.66,0,0,0-4.25-.6c-2.2-.13-4.41,0-6.62-.07-.23,0-.31.09-.29.3s0,.22,0,.33Q131.81,476.5,131.82,480.19Zm0-21v3.92q0,1.44,0,2.88c0,.23.05.35.31.34a62.82,62.82,0,0,0,7.13-.2,13.67,13.67,0,0,0,3.39-.83,5.13,5.13,0,0,0,3.18-3.67,10.6,10.6,0,0,0,.15-4.45,5,5,0,0,0-3.52-4.22,16.7,16.7,0,0,0-4.64-.82c-1.86-.09-3.72,0-5.58,0H132a.2.2,0,0,0-.22.23v.38Q131.81,456,131.81,M
459.19Z" transform="translate(4.96 5.26)" style="fill:#f79421" /></g><circle cx="897.68" cy="478.42" r="61.24" style="fill:#f26227" /><circle cx="897.68" cy="478.42" r="53.6" style="fill:#d74b27" /><g><path d="M890.36,423.81h4.82a5.2,5.2,0,0,0,1,.07c1.4.12,2.79.27,4.18.48a48.5,48.5,0,0,1,9.62,2.52,49.52,49.52,0,0,1,29.69,31,47.6,47.6,0,0,1,2,9.2c.13,1.13.24,2.26.28,3.39a1.52,1.52,0,0,0,.07.76v4a1.4,1.4,0,0,0-.07.76,41.81,41.81,0,0,1-.48,4.74,47.88,47.88,0,0,1-5,15.23,49.44,49.44,0,0,1-40.51,26.54,47.59,47.59,0,0,1-M
7.36-.06,48.57,48.57,0,0,1-9.43-1.69,49.12,49.12,0,0,1-27.44-19.8,49.17,49.17,0,0,1-8.35-23.6,12.63,12.63,0,0,0-.15-1.74c0-.56,0-1.12,0-1.69,0-1,0-2,0-3a.62.62,0,0,0,.07-.37,47.11,47.11,0,0,1,.76-6.37,48.1,48.1,0,0,1,4.09-12.43,49.49,49.49,0,0,1,32.44-26.4,50.07,50.07,0,0,1,8.62-1.36A7.27,7.27,0,0,0,890.36,423.81Zm-38.79,49.37A41.17,41.17,0,1,0,892.72,432,41.14,41.14,0,0,0,851.57,473.18Z" transform="translate(4.96 5.26)" style="fill:#f79421" /><path d="M905.13,471.72a19.6,19.6,0,0,1,5,1.56,10.85,10.85,0,0,1,4.87,4.M
34,11,11,0,0,1,1.4,4.28,16.25,16.25,0,0,1-.25,5.73,10,10,0,0,1-6.28,7.39,23.28,23.28,0,0,1-5.33,1.41c-1.23.19-2.46.33-3.71.41-.43,0-.44,0-.44.47v7.33c0,.46,0,.47-.47.47h-5.35c-.52,0-.49,0-.49-.49v-7.09c0-.59,0-.53-.54-.53h-5.34c-.43,0-.43,0-.43.45,0,2.38,0,4.76,0,7.14,0,.54.05.52-.5.52H882c-.5,0-.51,0-.51-.53v-7.33c0-.17-.06-.26-.24-.25H869.19c-.21,0-.31-.05-.31-.28q0-2.62,0-5.25c0-.26.1-.32.34-.32h3.26a9.33,9.33,0,0,0,2-.26,1.76,1.76,0,0,0,1.43-1.45,11,11,0,0,0,.26-2.62q0-10.32,0-20.62c0-2.28,0-4.57,0-6.85a11.55,1M
1.55,0,0,0-.24-2.49,1.88,1.88,0,0,0-1.58-1.55,12.77,12.77,0,0,0-2.54-.23h-2.46c-.43,0-.43,0-.43-.45v-4.87c0-.55,0-.52.5-.52H881c.52,0,.52,0,.52-.5v-6.91c0-.12,0-.25,0-.37s.09-.26.26-.25h5.54c.56,0,.51-.05.51.5,0,2.32,0,4.64,0,6.95,0,.65-.05.58.58.58h5.3c.43,0,.43,0,.43-.45v-7c0-.11,0-.22,0-.33s.07-.26.25-.25h5.54c.55,0,.52-.07.52.55V449c0,.36,0,.36.37.38a30.62,30.62,0,0,1,5.63.92,16.45,16.45,0,0,1,3,1.1,8.5,8.5,0,0,1,4.65,5.6,13.19,13.19,0,0,1,.11,6.69,9.49,9.49,0,0,1-3.85,5.54,16.79,16.79,0,0,1-4.93,2.34C905.3,471M
.58,905.19,471.56,905.13,471.72Zm-17.31,11.44c0,2.55,0,5.11,0,7.66,0,.41,0,.41.41.41H891a40.14,40.14,0,0,0,5.9-.29,14.2,14.2,0,0,0,3.38-.85,5.85,5.85,0,0,0,3.5-3.85,11,11,0,0,0,.24-5.51,5.78,5.78,0,0,0-2.58-3.91,8.31,8.31,0,0,0-2.49-1,23.27,23.27,0,0,0-4.25-.6c-2.2-.13-4.41,0-6.62-.07-.23,0-.31.09-.29.31s0,.22,0,.33C887.81,478.25,887.81,480.7,887.82,483.16Zm0-21v3.92c0,1,0,1.92,0,2.89,0,.22.05.34.31.33a62.82,62.82,0,0,0,7.13-.2,13.67,13.67,0,0,0,3.39-.83,5.11,5.11,0,0,0,3.18-3.66,10.65,10.65,0,0,0,.15-4.46,5,5,0,0,M
0-3.52-4.22,16.68,16.68,0,0,0-4.64-.81c-1.86-.1-3.72,0-5.58-.05H888c-.15,0-.23.07-.22.23v.38Q887.8,458.92,887.81,462.16Z" transform="translate(4.96 5.26)" style="fill:#f79421" /></g></g><g id="Ears-6"><path d="M305.64,230v64A22.69,22.69,0,0,1,283,316.61H262.15a97.69,97.69,0,0,0-37.57,7.51h0a87.1,87.1,0,0,1-112.14-43L108,271.88a86.58,86.58,0,0,1,44.06-116.81h0A86.61,86.61,0,0,1,208.5,151l89.26,23.81H187.46a39.39,39.39,0,0,0-39.39,39.39h0a39.4,39.4,0,0,0,39.39,39.39h4.85A39.42,39.42,0,0,0,212.58,248l40.76-24.46a42.8,M
42.8,0,0,1,52.3,6.44Z" transform="translate(0.34)" style="fill:#542f5f" /><path d="M722.64,230.16v64a22.68,22.68,0,0,0,22.68,22.68h20.81a97.64,97.64,0,0,1,37.56,7.51h0a87.11,87.11,0,0,0,112.15-42.95l4.42-9.29a86.58,86.58,0,0,0-44.07-116.81h0a86.58,86.58,0,0,0-56.41-4.07L730.51,175h110.3A39.39,39.39,0,0,1,880.2,214.4h0a39.38,39.38,0,0,1-39.39,39.39H836a39.42,39.42,0,0,1-20.27-5.61l-40.77-24.46a42.8,42.8,0,0,0-52.29,6.44Z" transform="translate(0.34)" style="fill:#111c0d" /></g><g id="Mouth-1"><path d="M504.57,545.25HM
236.78c-25.78,0-40.38,29.55-24.72,50l35.83,46.85a64.57,64.57,0,0,0,51.31,25.36H504.57" transform="translate(0.28 0)" style="fill:#883a62" /><path d="M483,545.25H775.4c25.78,0,40.38,29.55,24.72,50l-35.83,46.85A64.57,64.57,0,0,1,713,667.49H483" transform="translate(0.28 0)" style="fill:#883a62" /><rect x="267.55" y="570.35" width="474.59" height="64.72" style="fill:#542f5f" /><rect x="505.9" y="556.65" width="247.44" height="37.12" style="fill:#172027" /><path d="M712.79,556.31h0a15.47,15.47,0,0,1,15.47,15.47v21.65a0M
,0,0,0,1,0,0H697.33a0,0,0,0,1,0,0V571.78A15.47,15.47,0,0,1,712.79,556.31Z" style="fill:#f489ae" /><rect x="505.56" y="624.36" width="204.14" height="24.74" style="fill:#172027" /><rect x="654.03" y="624.36" width="30.93" height="24.74" style="fill:#f489ae" /><path d="M691.21,594.11v55.34h37.12A52.45,52.45,0,0,0,709.23,609Z" transform="translate(0.28 0)" style="fill:#f489ae" /><path d="M740.7,575.21v61.86l13.35-11.13a66,66,0,0,0,23.77-50.73h0a18.56,18.56,0,0,0-18.56-18.56h0A18.56,18.56,0,0,0,740.7,575.21Z" transformM
="translate(0.28 0)" style="fill:#f489ae" /><rect x="257.84" y="556.31" width="247.44" height="37.12" transform="translate(763.4 1149.74) rotate(-180)" style="fill:#172027" /><path d="M282.93,556h30.93a0,0,0,0,1,0,0v21.65a15.47,15.47,0,0,1-15.47,15.47h0a15.47,15.47,0,0,1-15.47-15.47V556a0,0,0,0,1,0,0Z" transform="translate(597.06 1149.05) rotate(-180)" style="fill:#f9c1c0" /><rect x="301.49" y="624.01" width="204.14" height="24.74" transform="translate(807.39 1272.77) rotate(-180)" style="fill:#172027" /><rect x="3M
26.23" y="624.01" width="30.93" height="24.74" transform="translate(683.67 1272.77) rotate(-180)" style="fill:#f9c1c0" /><path d="M319.7,593.77V649.1H282.58a52.47,52.47,0,0,1,19.1-40.48Z" transform="translate(0.28 0)" style="fill:#f9c1c0" /><path d="M270.21,574.87v61.86L256.86,625.6a66,66,0,0,1-23.77-50.73h0a18.56,18.56,0,0,1,18.56-18.56h0A18.56,18.56,0,0,1,270.21,574.87Z" transform="translate(0.28 0)" style="fill:#f9c1c0" /><path d="M329.67,556H360.6a0,0,0,0,1,0,0v21.65a15.47,15.47,0,0,1-15.47,15.47h0a15.47,15.47,M
0,0,1-15.47-15.47V556A0,0,0,0,1,329.67,556Z" transform="translate(690.54 1149.05) rotate(-180)" style="fill:#f9c1c0" /><rect x="372.97" y="624.01" width="30.93" height="24.74" transform="translate(777.15 1272.77) rotate(-180)" style="fill:#f9c1c0" /><path d="M375.14,556h30.93a0,0,0,0,1,0,0v21.65a15.47,15.47,0,0,1-15.47,15.47h0a15.47,15.47,0,0,1-15.47-15.47V556a0,0,0,0,1,0,0Z" transform="translate(781.48 1149.05) rotate(-180)" style="fill:#f9c1c0" /><rect x="418.44" y="624.01" width="30.93" height="24.74" transform=M
"translate(868.09 1272.77) rotate(-180)" style="fill:#f9c1c0" /><path d="M423.15,556h30.93a0,0,0,0,1,0,0v21.65a15.47,15.47,0,0,1-15.47,15.47h0a15.47,15.47,0,0,1-15.47-15.47V556A0,0,0,0,1,423.15,556Z" transform="translate(877.5 1149.05) rotate(-180)" style="fill:#f9c1c0" /><rect x="466.45" y="624.01" width="30.93" height="24.74" transform="translate(964.1 1272.77) rotate(-180)" style="fill:#f9c1c0" /><path d="M473.64,556h30.93a0,0,0,0,1,0,0v21.65a15.47,15.47,0,0,1-15.47,15.47h0a15.47,15.47,0,0,1-15.47-15.47V556A0,0,M
0,0,1,473.64,556Z" transform="translate(978.48 1149.05) rotate(-180)" style="fill:#f9c1c0" /><rect x="513.19" y="624.7" width="30.93" height="24.74" transform="translate(1057.58 1274.15) rotate(-180)" style="fill:#f489ae" /><rect x="559.93" y="624.7" width="30.93" height="24.74" transform="translate(1151.06 1274.15) rotate(-180)" style="fill:#f489ae" /><rect x="605.4" y="624.7" width="30.93" height="24.74" transform="translate(1242 1274.15) rotate(-180)" style="fill:#f489ae" /><rect x="653.41" y="624.7" width="30.9M
3" height="24.74" transform="translate(1338.02 1274.15) rotate(-180)" style="fill:#f489ae" /><path d="M509.43,556h30.93a0,0,0,0,1,0,0v21.65a15.47,15.47,0,0,1-15.47,15.47h0a15.47,15.47,0,0,1-15.47-15.47V556a0,0,0,0,1,0,0Z" transform="translate(1050.07 1149.05) rotate(-180)" style="fill:#f489ae" /><path d="M554.9,556h30.93a0,0,0,0,1,0,0v21.65a15.47,15.47,0,0,1-15.47,15.47h0a15.47,15.47,0,0,1-15.47-15.47V556A0,0,0,0,1,554.9,556Z" transform="translate(1141.02 1149.05) rotate(-180)" style="fill:#f489ae" /><path d="M602.M
91,556h30.93a0,0,0,0,1,0,0v21.65a15.47,15.47,0,0,1-15.47,15.47h0a15.47,15.47,0,0,1-15.47-15.47V556A0,0,0,0,1,602.91,556Z" transform="translate(1237.03 1149.05) rotate(-180)" style="fill:#f489ae" /><path d="M653.41556h30.93a0,0,0,0,1,0,0v21.65a15.47,15.47,0,0,1-15.47,15.47h0a15.47,15.47,0,0,1-15.47-15.47V556a0,0,0,0,1,0,0Z" transform="translate(1338.02 1149.05) rotate(-180)" style="fill:#f489ae" /></g><g id="Eyebrows-1">undefined</g><g id="Glasses-4">undefined</g><g id="Eyes-3"><rect x="568.09" y="366.84" width="201M
.78" height="108.65" rx="51.21" transform="translate(-105 257.04) rotate(-19.91)" style="fill:#3d2f39" /><circle cx="645.54" cy="433.1" r="46.56" style="fill:#eb6447" /><rect x="639.33" y="390.29" width="15.52" height="77.61" rx="7.32" transform="translate(-109.01 250.06) rotate(-19.91)" style="fill:#3d2f39" /><rect x="241.28" y="368.37" width="201.78" height="108.65" rx="51.21" transform="translate(518.36 940.65) rotate(-160.09)" style="fill:#80191b" /><circle cx="362.51" cy="434.62" r="46.56" style="fill:#eb6447"M
 /><rect x="356.3" y="391.82" width="15.52" height="77.61" rx="7.32" transform="translate(558.13 963.49) rotate(-160.09)" style="fill:#3d2f39" /></g><g id="Nose-2"><circle cx="478.44" cy="516.44" r="9.88" style="fill:#303636" /><path d="M503,519.73h-3.65a24.52,24.52,0,0,0-49,0H446.7a28.17,28.17,0,0,1,56.34,0Z" transform="translate(0.28 0)" style="fill:#efe1da" /><circle cx="535.24" cy="515.88" r="9.88" style="fill:#303636" /><path d="M510.08,519.17h3.66a24.52,24.52,0,0,1,49,0h3.66a28.18,28.18,0,0,0-56.35,0Z" transfMG
orm="translate(0.28 0)" style="fill:#efe1da" /></g><g id="Hat-5"><path d="M704.39,126H507.13l12.77,10.22A138.53,138.53,0,0,0,704.39,126Z" transform="translate(0.28)" style="fill:#ffa520" /><path d="M703.55,126H506.29l12.77-10.22A138.53,138.53,0,0,1,703.55,126Z" transform="translate(0.28)" style="fill:#b98d22" /></g></g></svg>h!
c/Foundry USA Pool #dropgold/
SjLPs:ETH.USDC-E3606EB48:0x834bf675dAf52B5D6fD953a57c83e824521E5ab6:21579472667:ss:0
JjH=:BNB.BUSD-BD1:bnb1kcx0e9l8a0d0ckvfmd7pf4l4y9qspk9ye285pp:224477524:te:0
c/Foundry USA Pool #dropgold/
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
<svg viewBox="0 0 1287 1287" xmlns="http://www.w3.org/2000/svg"><g transform="translate(664.886 1117.481)"><path d="M165.818 104.54c-11.243 45.096-56.917 72.54-102.017 61.294-45.082-11.243-72.527-56.92-61.279-102.012 11.238-45.1 56.912-72.547 102-61.305 45.097 11.243 72.54 56.925 61.296 102.023z" fill="#F7931A"/><path d="M121.27 72.185c1.676-11.201-6.852-17.223-18.514-21.24l3.783-15.172-9.236-2.302-3.682 14.773a386.353 386.353 0 0 0-7.4-1.741l3.709-14.87-9.23-2.303-3.786 15.168c-2.01-.458-3.983-.91-5.898-1.386l.01-M
.047-12.736-3.18-2.457 9.864s6.852 1.57 6.708 1.667c3.74.934 4.416 3.41 4.303 5.372L56.48 98.353c-.458 1.137-1.618 2.841-4.233 2.194.093.134-6.713-1.676-6.713-1.676l-4.585 10.573 12.02 2.996c2.235.56 4.426 1.147 6.583 1.699l-3.822 15.347 9.226 2.301 3.785-15.183a351.26 351.26 0 0 0 7.36 1.91l-3.772 15.112 9.236 2.302 3.822-15.318c15.749 2.98 27.592 1.778 32.577-12.466 4.016-11.47-.2-18.085-8.487-22.399 6.035-1.392 10.58-5.361 11.793-13.56zm-21.102 29.59c-2.854 11.47-22.165 5.27-28.426 3.715l5.072-20.332c6.26 1.563 M
26.337 4.656 23.354 16.618zm2.857-29.756c-2.604 10.433-18.677 5.132-23.89 3.833l4.597-18.44c5.214 1.299 22.005 3.724 19.293 14.607z" fill="#FFF"/></g><path d="M203.138 300.399v-69.033H79.068v-47.384h100.653v-69.034H79.068V69.607h124.07V.573L9.638.982v299.417h193.5zm105.171 0V.165h-69.43v300.234h69.43zm110.512 0v-174.83l98.598 174.83H592.6V.573h-69.43v175.239L424.984 1.39h-75.591v299.009h69.43zm-288.81 328.056c15.611-.273 30.332-3.472 44.163-9.6 13.832-6.127 25.882-14.365 36.153-24.713 10.27-10.348 18.35-22.466 24.2M
39-36.355 5.888-13.888 8.696-28.593 8.422-44.116v-185.45h-69.43V514.08c0 6.263-1.095 12.118-3.286 17.564-2.191 5.447-5.341 10.213-9.45 14.297-4.108 4.085-8.9 7.353-14.378 9.804-5.478 2.45-11.23 3.676-17.255 3.676-12.325 0-23.006-4.22-32.044-12.663-9.038-8.986-13.558-19.47-13.558-31.453V328.22h-69.43v187.494c.275 15.522 3.356 30.091 9.245 43.707 5.888 13.616 14.31 25.87 25.265 36.764 10.682 10.348 22.87 18.313 36.564 23.896 13.694 5.582 28.21 8.374 43.547 8.374h1.233zm223.9 0v-174.83l98.598 174.83h75.18V328.629H458.M
26v175.239l-98.187-174.422h-75.592v299.009h69.43zm271.966 0c20.541-1.09 39.576-5.65 57.105-13.684 17.528-8.034 32.797-18.723 45.807-32.066 13.01-13.344 23.212-28.798 30.606-46.363 7.395-17.565 11.093-36.423 11.093-56.575 0-20.424-3.766-39.623-11.298-57.596s-17.802-33.768-30.812-47.384c-13.01-13.616-28.347-24.645-46.012-33.087-17.666-8.442-36.495-13.207-56.489-14.297v-.408h-69.43v301.46h69.43zm0-69.442V396.437c10.682 1.09 20.541 4.017 29.58 8.782 9.038 4.766 16.98 10.893 23.827 18.382 6.848 7.489 12.188 16.067 16.02M
3 25.734 3.834 9.668 5.751 19.812 5.751 30.432 0 10.348-1.917 20.152-5.751 29.41-3.835 9.26-9.107 17.361-15.817 24.306-6.71 6.944-14.653 12.663-23.828 17.156-9.175 4.493-19.103 7.284-29.785 8.374zM240.934 956.51v-69.033h-124.48l126.123-232.835-225.954-.408v69.442h109.69L.19 956.51h240.744zm179.12 0 34.509-150.321 39.85 150.321h68.608l89.149-301.868h-72.716l-48.888 166.252-44.37-166.252H418l-38.206 167.07-55.873-167.07h-73.127L351.035 956.51h69.019zm293.74 0 12.325-36.354h94.9l11.914 36.354h73.127l-97.366-299.826h-6M
5.732L640.256 956.51h73.538zm85.04-105.388h-48.888l25.06-72.71 23.829 72.71zM996.032 956.51V781.68l98.598 174.83h75.181V656.684h-69.43v175.24L1002.194 657.5h-75.592v299.01h69.43zm-755.097 328.056v-69.033h-124.48l126.123-232.835-225.954-.409v69.442h109.69L.19 1284.566h240.744zm112.155 0V984.332h-69.43v300.234h69.43zm168.85.409c7.942 0 15.953-.613 24.033-1.838 8.08-1.226 15.953-3.2 23.622-5.923v7.352h69.84V1116.68H509.203v69.033h60.391v15.114c-7.943 5.72-16.57 9.804-25.882 12.255-9.312 2.45-18.693 3.336-28.142 2.655-M
9.449-.68-18.624-2.996-27.525-6.944-8.901-3.949-16.912-9.463-24.033-16.544-7.943-7.897-13.968-16.884-18.076-26.96-4.109-10.076-6.163-20.288-6.163-30.636 0-10.348 2.054-20.56 6.163-30.636 4.108-10.076 10.133-19.062 18.076-26.96 7.943-7.897 16.98-13.82 27.114-17.769 10.134-3.948 20.405-5.923 30.812-5.923 10.408 0 20.679 1.975 30.812 5.923 10.134 3.949 19.172 9.872 27.115 17.77l49.299-49.019c-14.79-14.705-31.497-25.734-50.121-33.087-18.624-7.352-37.659-11.029-57.105-11.029-19.445 0-38.48 3.677-57.104 11.03-18.625 7.35M
2-35.331 18.381-50.121 33.086-14.79 14.706-25.814 31.317-33.072 49.835-7.258 18.518-10.887 37.444-10.887 56.78 0 19.334 3.63 38.192 10.887 56.574 7.258 18.382 18.282 34.925 33.072 49.63 14.79 14.706 31.496 25.735 50.12 33.088 18.625 7.352 37.66 11.029 57.105 11.029z"/></svg>
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
779NSsssu777Sssu777Ssssssu7Su7Sssu7
5sE4SE4SE4SE4SE4SE4SE4SE4S
YYYYYYY[++++++++++xuP.
MjK=:BNB.BUSD-BD1:bnb1z2kyzy0aapxpu59wxd7gm6pgdwaetl2nxgfk7y:585682793830:t:30
4j2DC-L5:xvy+CDsUGhuDNIBjfx9Ga0czIayXMNvLfgIC1yT+ki0=
Bj@=:BNB.BNB:bnb1gjrduftzncf80xp947ehmpp3ldse9gf4ajcmr8:330621:te:0
CjA=:BNB.BNB:bnb1lp2c45aa6zdqdevtdjy5eg89t4zfw4tjlke8tj:2894238:te:0
MjK=:BNB.BUSD-BD1:bnb1nxx047muxr57qhrgxh3q8nnalfzzjcn2zp9j3q:184696061056:te:0
FjDOUT:94458AD0A3EE8ED38F11CE5C794E4F3A438B4EB144D031DF292B9DC5994F7080
6j4ion:2.QmYY7sjXV23CpAdCatTFRbQABJq6X6iheEAWd6oGaqUx2E
IjG=:THOR.RUNE:thor104ep0k5pjeame62zuahfjxlqfh323uenx08k0e:5055581576:t:30HO
CjA=:BNB.BNB:bnb1r5atp9qhf3ye7ant26ujurv0xamklx0t2seyud:3157523:te:0
FjDOUT:8375162D8627AFD60BA3D79A966F9BC36C0AA80B903689463D1637A4C3F60C19
FjDOUT:ED27E52140C8D63CB28E0C6A552E861F42A921AD210111953B356596B81A1C60
GjE=:BNB.BTCB-1DE:bnb14aaca79pjxk739wvgshj4xpw2lshht6mp35as3:136669:te:0
FjDOUT:71C04475D3E773ABF5D8DC3345DC3966E2EB0D2581C94743FB42115F277E7309
FjDOUT:DB0A69453C456B94E445304B0868D0F9979ACA77184BA612EFACCADB95B9AC5F
FjDOUT:88639A08BFDEFA527B9D5C87E35FDEE0860DBCF56E1030F92A925C235F8FC917
FjDOUT:C0A54E71C08D00B9025287FA51D7F6A32A5A33EA25BAD1BF6D2CDA60F2FA31CF
Bj@=:ETH.ETH:0x2dc0601A0465f924CDFdf3Bd8f0d9bD13bc461c0:632131:te:0
FjDOUT:ACBA1F4263EB038B4B84A44EA8E0C4CB7A7BCF6AB4D5C1F8F25F01154833BF87
CjA=:ETH.ETH:0x57b558E7068FA48Abe1d5CE686d0204CAa8b5d0d:4599891:te:0
c/Foundry USA Pool #dropgold/
EjC=:ETH.ETH:0x209053265e81db305151f9ec4f3b1ddb6cd6a109:140246830:t:30
FjDOUT:7143897A0C0056E702E689D73B87CE32FA01E5DC6115BF45FE3CB12B4385D066
FjDOUT:72FA33EC1B338AECBE3B217B285119CD5ACF09795C80AB02100F1F3B866CB068
9j7+:BTC/BTC::bc1q3f787hr38pmal87yxtpq8tng09q60ljjqqd759:0
IjGREFUND:F70F4F2F24AC5D7AF736C6C5DAE30679EA42ED811269EA451B01EB9E83C3C219
%j#Voglio Apple Watch Ultra in titanio
DjB=:ETH.ETH:0xf1Aa42bcD5e0381f765D223bE36B951F2705fcbc:44511314:te:0
FjDOUT:7DE1612E88A9000A24ACBB3220ECD0FF8FF46B54F701EBA6F7F73248254A81EA
IjGREFUND:82181A63D05B693E7C3835536FE95FB2B57FC85FD3E85EB8DFCC0EC7E6D42D46
9j7+:BTC/BTC::bc1q3f787hr38pmal87yxtpq8tng09q60ljjqqd759:0
FjDOUT:1DEB996AFF135B4A76AB5066A9CB16650E2410B00BA00AEB85C36CF6DCDD26D7
FjDOUT:35D76ED1C5A0DC4896C094632211ACF685DC111DC30910E003BC732D72CE0A4F
c/Foundry USA Pool #dropgold/
IjGREFUND:779A24D38D48B64BFD74D927B5BF0EAABC83C31A00AC3ED12BB44E539C0229C4
FjDOUT:2E77AB172488F5E91560654EC822E4FBEC601AA6C50417C476B6310E607BFD15
FjDOUT:C6C381E5A06848D05B0ED6FB50F1B90B56A16C8A7E2CB4FD514752CC18DB7906
FjDOUT:5B999C63D1BB7CA12DADC47C10D0AA1AEFC4A963EE57674C6DEC8A84F46E35BD
FjDOUT:B11EBD2B75450CA79BAC6BCA4136A6BD6AB3CD44DAA564FCFEA8FEB06BB97DEE
FjDOUT:441928A2460851F1F22C07CE6BD4693784B6E7F2158FBAF6E04F231AE21822B1
FjDOUT:A16F258CDEFA98E20DB8C4BC138EFC8B1F29460DD5D3130ED889D8BBC67D5447
FjDOUT:D914E0688C17425B824AB8753D36B2973312357B201ECAE49FBE36FF4899DFB4
Aj?=:BNB.BNB:bnb1d5ewawcrmclzce38uacd6r9xmsjd28yyuykwnn:14775:te:0
CjA=:BNB.BNB:bnb18d42fg2uvw4vd66p664x9l7ftcv3y3hqw9rgf7:7696858:te:0
Copyright Apple Inc., 2018
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz

c/Foundry USA Pool #dropgold/
6j4ion:2.Qmbsm8fynSG5bKoGa79f3x2zbQymNYnciGT5kY2KxMmJ7od
FjDOUT:16447E99F86951EA191448A60136FF7B7B86500CEEDD933B7A4A39FF94C47C93
EjCs:BCH.BCH:qqqmr73y9gp73c80dctmhtrn648x580y7g50zay2d2:704464616:ss:0
FjDOUT:0326D38CA45714706B3F22569647A6775061CED89CC4D98E419FC21ABFF4473E
FjDOUT:353DE24E89CC21EDA1F7E5E221FDED0BDF550ACD83950BE861B0D8277C171F01
HjF=:BNB.ETH-1C9:bnb1qzgyz7rxf2qgyk3v4rxsh64aetw25s45u2l7h3:13873802:te:0
*j(Inscriptions are an attack on OP_RETURNs
Created with GIMPd.e
c/Foundry USA Pool #dropgold/
FjD=:THOR.RUNE:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n:494191304313
EjCs:RUNE:thor17c0svnvxklf3yydzdfdml22djamzhkkcp9lph3:52535926643:ss:0
TUUUUUUUUUUUUUUUUUUUUUUUUUUUU
text/plain;charset=utf-8
# Merged Python Files
logger = logging.getLogger(__name__)
from counterpartylib.lib import config
from counterpartylib.lib import script
def address_scriptpubkey(address):
        bech32 = bitcoin.bech32.CBech32Data(address)
        return b''.join([b'\x00\x14', bech32.to_bytes()])
    except Exception as e:
        bs58 = bitcoin.base58.decode(address)[1:-4]
        return b''.join([b'\x76\xa9\x14', bs58, b'\x88\xac'])
    Converts a base58 bitcoin address into a 21 byte bytes object
    from .util import enabled # Here to account for test mock changes
    if enabled('segwit_support'):
            bech32 = bitcoin.bech32.CBech32Data(address)
            witver = (0x80 + bech32.witver).to_bytes(1, byteorder='big') # mark the first byte for segwit
            witprog = bech32.to_bytes()
            if len(witprog) > 20:
                raise Exception('p2wsh still not supported for sending')
       return b''.join([witver, witprog])
        except Exception as ne:
                script.validate(address) #This will check if the address is valid
                short_address_bytes = bitcoin.base58.decode(address)[:-4]
                return short_address_bytes
            except bitcoin.base58.InvalidBase58Error as e:
                raise e
            except Exception as e:
                raise Exception(('The address {} is not a valid bitcoin address ({})').format(address,'testnet' M
if config.TESTNET or config.REGTEST else 'mainnet'))
            short_address_bytes = bitcoin.base58.decode(address)[:-4]
            return short_address_bytes
        except bitcoin.base58.InvalidBase58Error as e:
# retuns both the message type id and the remainder of the message data
def unpack(short_address_bytes):
    Converts a 21 byte prefix and public key hash into a full base58 bitcoin address
    from .util import enabled # Here to account for tM
    if enabled('segwit_support') and short_address_bytes[0] >= 0x80 and short_address_bytes[0] <= 0x8F:
        # we have a segwit address here
        witver = short_address_bytes[0] - 0x80
        witprog = short_address_bytes[1:]
        return str(bitcoin.bech32.CBech32Data.from_bytes(witver, witprog))
        check = bitcoin.core.Hash(short_address_bytes)[0:4]
        return bitcoin.base58.encode(short_address_bytes + check)
se connections are read
only, so SQL injection attacks can
logger = logging.getLogger(__name__)
from logging import handlers as logging_handlers
from flask_httpauth import HTTPBasicAuth
from jsonrpc import dispatcher
from jsonrpc.exceptioM
ns import JSONRPCDispatchException
from xmltodict import unparse as serialize_to_xml
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
from counterpartylib.lib import util
from counterpartylib.lib import check
from counterpartylib.lib import backend
from counterpartylib.lib import database
from counterpartylib.lib import transaction
from counterpartylib.lib import blocks
from counterpartylib.lib import script
from counterpartylib.lib import message_type
rtylib.lib.messages import send
from counterpartylib.lib.messages.versions import enhanced_send
from counterpartylib.lib.messages import order
from counterpartylib.lib.messages import btcpay
from counterpartylib.lib.messages import issuance
from counterpartylib.lib.messages import broadcast
from counterpartylib.lib.messages import bet
from counterpartylib.lib.messages import dividend
from counterpartylib.lib.messages import burn
from counterpartylib.lib.messages import destroy
from counterpartylib.lib.messages impoM
from counterpartylib.lib.messages import rps
from counterpartylib.lib.messages import rpsresolve
from counterpartylib.lib.messages import sweep
from counterpartylib.lib.messages import dispenser
API_TABLES = ['assets', 'balances', 'credits', 'debits', 'bets', 'bet_matches',
              'broadcasts', 'btcpays', 'burns', 'cancels', 'destructions',
              'dividends', 'issuances', 'orders', 'order_matches', 'sends',
              'bet_expirations', 'order_expirations', 'bet_match_expirations',
          'order_match_expirations', 'bet_match_resolutions', 'rps',
              'rpsresolves', 'rps_matches', 'rps_expirations', 'rps_match_expirations',
              'mempool', 'sweeps', 'dispensers', 'dispenses','transactions']
API_TRANSACTIONS = ['bet', 'broadcast', 'btcpay', 'burn', 'cancel', 'destroy',
                    'dividend', 'issuance', 'order', 'send',
                    'rps', 'rpsresolve', 'sweep', 'dispenser']
COMMONS_ARGS = ['encoding', 'fee_per_kb', 'regular_dust_size',
ultisig_dust_size', 'op_return_value', 'pubkey',
                'allow_unconfirmed_inputs', 'fee', 'fee_provided',
                'estimate_fee_per_kb', 'estimate_fee_per_kb_nblocks', 'estimate_fee_per_kb_conf_target', 'estimate_fee_per_kb_mode',
                'unspent_tx_hash', 'custom_inputs', 'dust_return_pubkey', 'disable_utxo_locks', 'extended_tx_info',
                'p2sh_source_multisig_pubkeys', 'p2sh_source_multisig_pubkeys_required', 'p2sh_pretx_txid']
API_MAX_LOG_SIZE = 10 * 1024 * 1024 #max log sM
ize of 20 MB before rotation (make configurable later)
API_MAX_LOG_COUNT = 10
JSON_RPC_ERROR_API_COMPOSE = -32001 #code to use for error composing transaction result
current_api_status_code = None #is updated by the APIStatusPoller
current_api_status_response_json = None #is updated by the APIStatusPoller
class APIError(Exception):
class BackendError(Exception):
def check_backend_state():
    """Checks blocktime of last block to see if {} Core is running behind.""".format(config.BTC_NAME)
block_count = backend.getblockcount()
    block_hash = backend.getblockhash(block_count)
    cblock = backend.getblock(block_hash)
    time_behind = time.time() - cblock.nTime   # TODO: Block times are not very reliable.
    if time_behind > 60 * 60 * 2:   # Two hours.
        raise BackendError('Bitcoind is running about {} hours behind.'.format(round(time_behind / 3600)))
    # check backend index
    blocks_behind = backend.getindexblocksbehind()
    if blocks_behind > 5:
        raise BackendError('Indexd is rM
unning {} blocks behind.'.format(blocks_behind))
    logger.debug('Backend state check passed.')
class DatabaseError(Exception):
def check_database_state(db, blockcount):
    """Checks {} database to see if is caught up with backend.""".format(config.XCP_NAME)
    if util.CURRENT_BLOCK_INDEX + 1 < blockcount:
        raise DatabaseError('{} database is behind backend.'.format(config.XCP_NAME))
    logger.debug('Database state check passed.')
# TODO: ALL queries EVERYWHERE should be done withM
def db_query(db, statement, bindings=(), callback=None, **callback_args):
    """Allow direct access to the database in a parametrized manner."""
    cursor = db.cursor()
    forbidden_words = ['pragma', 'attach', 'database', 'begin', 'transaction']
    for word in forbidden_words:
        #This will find if the forbidden word is in the statement as a whole word. For example, "transactions" will be allowed because the "s" at the end
        if re.search(r"\b"+word+"\b", statement.lowM
            raise APIError("Forbidden word in query: '{}'.".format(word))
    if hasattr(callback, '__call__'):
        cursor.execute(statement, bindings)
        for row in cursor:
            callback(row, **callback_args)
        results = None
        results = list(cursor.execute(statement, bindings))
def get_rows(db, table, filters=None, filterop='AND', order_by=None, order_dir=None, start_block=None, end_block=None,
              status=None, limit=10M
00, offset=0, show_expired=True):
    """SELECT * FROM wrapper. Filters results based on a filter data structure (as used by the API)."""
    if filters == None:
        filters = []
    def value_to_marker(value):
        # if value is an array place holder is (?,?,?,..)
        if isinstance(value, list):
            return '''({})'''.format(','.join(['?' for e in range(0, len(value))]))
            return '''?'''
    # TODO: Document that op can be anything that SQLite3 accepts.
 or table.lower() not in API_TABLES:
        raise APIError('Unknown table')
    if filterop and filterop.upper() not in ['OR', 'AND']:
        raise APIError('Invalid filter operator (OR, AND)')
    if order_dir and order_dir.upper() not in ['ASC', 'DESC']:
        raise APIError('Invalid order direction (ASC, DESC)')
    if not isinstance(limit, int):
        raise APIError('Invalid limit')
    elif config.API_LIMIT_ROWS != 0 and limit > config.API_LIMIT_ROWS:
        raise APIError('Limit should be lower or equaM
l to %i' % config.API_LIMIT_ROWS)
    elif config.API_LIMIT_ROWS != 0 and limit == 0:
        raise APIError('Limit should be greater than 0')
    if not isinstance(offset, int):
        raise APIError('Invalid offset')
    # TODO: accept an object:  {'field1':'ASC', 'field2': 'DESC'}
    if order_by and not re.compile('^[a-z0-9_]+$').match(order_by):
        raise APIError('Invalid order_by, must be a field name')
    if isinstance(filters, dict): #single filter entry, convert to a one entry list
    elif not isinstance(filters, list):
        filters = []
    # TODO: Document this! (Each filter can be an ordered list.)
    new_filters = []
    for filter_ in filters:
        if type(filter_) in (list, tuple) and len(filter_) in [3, 4]:
            new_filter = {'field': filter_[0], 'op': filter_[1], 'value':  filter_[2]}
            if len(filter_) == 4:
                new_filter['case_sensitive'] = filter_[3]
            new_filters.append(new_filter)
        elif type(filter_) == dict:
         new_filters.append(filter_)
            raise APIError('Unknown filter type')
    filters = new_filters
    # validate filter(s)
    for filter_ in filters:
        for field in ['field', 'op', 'value']: #should have all fields
            if field not in filter_:
                raise APIError("A specified filter is missing the '%s' field" % field)
        if not isinstance(filter_['value'], (str, int, float, list)):
            raise APIError("Invalid value for the field '%s'" % filter_['fM
        if isinstance(filter_['value'], list) and filter_['op'].upper() not in ['IN', 'NOT IN']:
            raise APIError("Invalid value for the field '%s'" % filter_['field'])
        if filter_['op'].upper() not in ['=', '==', '!=', '>', '<', '>=', '<=', 'IN', 'LIKE', 'NOT IN', 'NOT LIKE']:
            raise APIError("Invalid operator for the field '%s'" % filter_['field'])
        if 'case_sensitive' in filter_ and not isinstance(filter_['case_sensitive'], bool):
            raise APIError("case_sensitM
ive must be a boolean")
    # special case for memo and memo_hex field searches
    if table == 'sends':
        adjust_get_sends_memo_filters(filters)
    statement = '''SELECT * FROM {}'''.format(table)
    for filter_ in filters:
        case_sensitive = False if 'case_sensitive' not in filter_ else filter_['case_sensitive']
        if filter_['op'] == 'LIKE' and case_sensitive == False:
            filter_['field'] = '''UPPER({})'''.format(filter_M
            filter_['value'] = filter_['value'].upper()
        marker = value_to_marker(filter_['value'])
        conditions.append('''{} {} {}'''.format(filter_['field'], filter_['op'], marker))
        if isinstance(filter_['value'], list):
            bindings += filter_['value']
            bindings.append(filter_['value'])
    more_conditions = []
    if table not in ['balances', 'order_matches', 'bet_matches']:
        if start_block != None:
            more_conditM
ions.append('''block_index >= ?''')
            bindings.append(start_block)
        if end_block != None:
            more_conditions.append('''block_index <= ?''')
            bindings.append(end_block)
    elif table in ['order_matches', 'bet_matches']:
        if start_block != None:
            more_conditions.append('''tx0_block_index >= ?''')
            bindings.append(start_block)
        if end_block != None:
            more_conditions.append('''tx1_block_index <= ?''')
            bindings.append(end_blM
    if isinstance(status, list) and len(status) > 0:
        more_conditions.append('''status IN {}'''.format(value_to_marker(status)))
        bindings += status
    elif isinstance(status, str) and status != '':
        more_conditions.append('''status == ?''')
        bindings.append(status)
    # legacy filters
    if not show_expired and table == 'orders':
        #Ignore BTC orders one block early.
        expire_index = util.CURRENT_BLOCK_INDEX + 1
        more_conditions.append('''((giveM
_asset == ? AND expire_index > ?) OR give_asset != ?)''')
        bindings += [config.BTC, expire_index, config.BTC]
    if (len(conditions) + len(more_conditions)) > 0:
        statement += ''' WHERE'''
        all_conditions = []
        if len(conditions) > 0:
            all_conditions.append('''({})'''.format(''' {} '''.format(filterop.upper()).join(conditions)))
        if len(more_conditions) > 0:
            all_conditions.append('''({})'''.format(''' AND '''.join(more_conditions)))
        statement += ''M
' {}'''.format(''' AND '''.join(all_conditions))
    if order_by != None:
        statement += ''' ORDER BY {}'''.format(order_by)
        if order_dir != None:
            statement += ''' {}'''.format(order_dir.upper())
    if limit and limit > 0:
        statement += ''' LIMIT {}'''.format(limit)
            statement += ''' OFFSET {}'''.format(offset)
    query_result = db_query(db, statement, tuple(bindings))
    if table == 'balances':
        return adjusM
t_get_balances_results(query_result, db)
    if table == 'destructions':
        return adjust_get_destructions_results(query_result)
    if table == 'sends':
        # for sends, handle the memo field properly
        return adjust_get_sends_results(query_result)
    if table == 'transactions':
        # for transactions, handle the data field properly
        return adjust_get_transactions_results(query_result)
    return query_result
def adjust_get_balances_results(query_result, db):
    for balances_row in list(query_result):
        asset = balances_row['asset']
        if not asset in assets:
            assets[asset] = util.is_divisible(db, asset)
        balances_row['divisible'] = assets[asset]
        filtered_results.append(balances_row)
    return filtered_results
def adjust_get_destructions_results(query_result):
    filtered_results = []
    for destruction_row in list(query_result):
        if type(destruction_row['tag']) == bytes:
estruction_row['tag'] = destruction_row['tag'].decode('utf-8', 'ignore')
        filtered_results.append(destruction_row)
    return filtered_results
def adjust_get_sends_memo_filters(filters):
    """Convert memo to a byte string.  If memo_hex is supplied, attempt to decode it and use that instead."""
    for filter_ in filters:
        if filter_['field'] == 'memo':
            filter_['value'] = bytes(filter_['value'], 'utf-8')
        if filter_['field'] == 'memo_hex':
            # search the indexed memo fM
ield with a byte string
            filter_['field'] = 'memo'
                filter_['value'] = bytes.fromhex(filter_['value'])
            except ValueError as e:
                raise APIError("Invalid memo_hex value")
def adjust_get_sends_results(query_result):
    """Format the memo_hex field.  Try and decode the memo from a utf-8 uncoded string. Invalid utf-8 strings return an empty memo."""
    filtered_results = []
    for send_row in list(query_result):
            if send_roM
                send_row['memo_hex'] = None
                send_row['memo'] = None
                if type(send_row['memo']) == str:
                    send_row['memo'] = bytes(send_row['memo'], 'utf-8')

                send_row['memo_hex'] = binascii.hexlify(send_row['memo']).decode('utf8')
                send_row['memo'] = send_row['memo'].decode('utf-8')
        except UnicodeDecodeError:
            send_row['memo'] = ''
        filtered_results.appenM
    return filtered_results
def adjust_get_transactions_results(query_result):
    """Format the data field.  Try and decode the data from a utf-8 uncoded string. Invalid utf-8 strings return an empty data."""
    filtered_results = []
    for transaction_row in list(query_result):
        transaction_row['data'] = transaction_row['data'].hex()
        filtered_results.append(transaction_row)
    return filtered_results
def compose_transaction(db, name, params,
                        encoding='auto',M
                        fee_per_kb=None,
                        estimate_fee_per_kb=None, estimate_fee_per_kb_conf_target=config.ESTIMATE_FEE_CONF_TARGET, estimate_fee_per_kb_mode=config.ESTIMATE_FEE_MODE,
                        regular_dust_size=config.DEFAULT_REGULAR_DUST_SIZE,
                        multisig_dust_size=config.DEFAULT_MULTISIG_DUST_SIZE,
                        op_return_value=config.DEFAULT_OP_RETURN_VALUE,
                        pubkey=None,
                        allow_unconfirmed_inputs=M
                        fee=None,
                        fee_provided=0,
                        unspent_tx_hash=None, custom_inputs=None, dust_return_pubkey=None, disable_utxo_locks=False, extended_tx_info=False,
                        p2sh_source_multisig_pubkeys=None, p2sh_source_multisig_pubkeys_required=None,
                        p2sh_pretx_txid=None, old_style_api=True, segwit=False):
    """Create and return a transaction."""
    # Get provided pubkeys.
    if type(pubkey) == str:
ed_pubkeys = [pubkey]
    elif type(pubkey) == list:
        provided_pubkeys = pubkey
    elif pubkey == None:
        provided_pubkeys = []
        assert False
    # Get additional pubkeys from `source` and `destination` params.
    # Convert `source` and `destination` to pubkeyhash form.
    for address_name in ['source', 'destination']:
        if address_name in params:
            address = params[address_name]
            if isinstance(address, list):
                #pkhshs = []
#for addr in address:
                #    provided_pubkeys += script.extract_pubkeys(addr)
                #    pkhshs.append(script.make_pubkeyhash(addr))
                #params[address_name] = pkhshs
                pass
                provided_pubkeys += script.extract_pubkeys(address)
                params[address_name] = script.make_pubkeyhash(address)
    # Check validity of collected pubkeys.
    for pubkey in provided_pubkeys:
        if not script.is_fully_valid(binascii.unhexlify(puM
            raise script.AddressError('invalid public key: {}'.format(pubkey))
    compose_method = sys.modules['counterpartylib.lib.messages.{}'.format(name)].compose
    compose_params = inspect.getargspec(compose_method)[0]
    missing_params = [p for p in compose_params if p not in params and p != 'db']
    for param in missing_params:
        params[param] = None
    # dont override fee_per_kb if specified
    if fee_per_kb is not None:
        estimate_fee_per_kb = False
 = config.DEFAULT_FEE_PER_KB
    if 'extended_tx_info' in params:
      extended_tx_info = params['extended_tx_info']
      del params['extended_tx_info']
    if 'old_style_api' in params:
        old_style_api = params['old_style_api']
        del params['old_style_api']
    if 'segwit' in params:
        segwit = params['segwit']
        del params['segwit']
    tx_info = compose_method(db, **params)
    return transaction.construct(db, tx_info, encoding=encoding,
                                        fee_pM
                                        estimate_fee_per_kb=estimate_fee_per_kb, estimate_fee_per_kb_conf_target=estimate_fee_per_kb_conf_target,
                                        regular_dust_size=regular_dust_size,
                                        multisig_dust_size=multisig_dust_size,
                                        op_return_value=op_return_value,
                                        provided_pubkeys=provided_pubkeys,
                                        allow_unconfM
irmed_inputs=allow_unconfirmed_inputs,
                                        exact_fee=fee,
                                        fee_provided=fee_provided,
                                        unspent_tx_hash=unspent_tx_hash, custom_inputs=custom_inputs,
                                        dust_return_pubkey=dust_return_pubkey,
                                        disable_utxo_locks=disable_utxo_locks,
                                        extended_tx_info=extended_tx_info,
                        M
                p2sh_source_multisig_pubkeys=p2sh_source_multisig_pubkeys, p2sh_source_multisig_pubkeys_required=p2sh_source_multisig_pubkeys_required,
                                        p2sh_pretx_txid=p2sh_pretx_txid,
                                        old_style_api=old_style_api,
                                        segwit=segwit)
def conditional_decorator(decorator, condition):
    """Checks the condition and if True applies specified decorator."""
    def gen_decorator(f):
        if not conditioM
            return f
        return decorator(f)
    return gen_decorator
def init_api_access_log(app):
    """Initialize API logger."""
    loggers = (logging.getLogger('werkzeug'), app.logger)
    # Disable console logging...
    for l in loggers:
        l.setLevel(logging.INFO)
        l.propagate = False
    # Log to file, if configured...
    if config.API_LOG:
        handler = logging_handlers.RotatingFileHandler(config.API_LOG, 'a', API_MAX_LOG_SIZE, API_MAX_LOG_COUNT)
        for l in loggers:
       l.addHandler(handler)
class APIStatusPoller(threading.Thread):
    """Perform regular checks on the state of the backend and the database."""
    def __init__(self):
        self.last_database_check = 0
        threading.Thread.__init__(self)
        self.stop_event = threading.Event()
        self.stop_event.set()
        logger.debug('Starting API Status Poller.')
        global current_api_status_code, current_api_status_response_json
        db = database.get_conM
nection(read_only=True, integrity_check=False)
        while self.stop_event.is_set() != True:
                # Check that backend is running, communicable, and caught up with the blockchain.
                # Check that the database has caught up with bitcoind.
                if time.time() - self.last_database_check > 10 * 60: # Ten minutes since last check.
                    if not config.FORCE:
                        code = 11
                        logger.debug('Checking backend state.'M
                        check_backend_state()
                        code = 12
                        logger.debug('Checking database state.')
                        check_database_state(db, backend.getblockcount())
                        self.last_database_check = time.time()
            except (BackendError, DatabaseError) as e:
                exception_name = e.__class__.__name__
                exception_text = str(e)
                logger.debug("API Status Poller: %s", exception_text)
sonrpc_response = jsonrpc.exceptions.JSONRPCServerError(message=exception_name, data=exception_text)
                current_api_status_code = code
                current_api_status_response_json = jsonrpc_response.json.encode()
                current_api_status_code = None
                current_api_status_response_json = None
            time.sleep(config.BACKEND_POLL_INTERVAL)
class APIServer(threading.Thread):
    """Handle JSON-RPC API calls."""
    def __init__(self, db=None):
        self.is_ready = False
        threading.Thread.__init__(self)
        self.stop_event = threading.Event()
        self.stop_event.set()
        logger.info('Starting API Server.')
        self.db = self.db or database.get_connection(read_only=True, integrity_check=False)
        app = flask.Flask(__name__)
        auth = HTTPBasicAuth()
        @auth.get_password
        def get_pw(username):
            if username == config.RPC_USER:M
                return config.RPC_PASSWORD
            return None
        ######################
        # Generate dynamically get_{table} methods
        def generate_get_method(table):
            def get_method(**kwargs):
                try:
                    return get_rows(self.db, table=table, **kwargs)
                except TypeError as e:          #TODO: generalise for all API methods
                    raise APIError(str(e))
            return get_method
        for table in APM
            new_method = generate_get_method(table)
            new_method.__name__ = 'get_{}'.format(table)
            dispatcher.add_method(new_method)
        @dispatcher.add_method
        def sql(query, bindings=None):
            if bindings == None:
                bindings = []
            return db_query(self.db, query, tuple(bindings))
        ######################
        #WRITE/ACTION API
        # Generate dynamically create_{transaction} methods
        def generate_create_method(tx):
            def split_params(**kwargs):
                transaction_args = {}
                common_args = {}
                private_key_wif = None
                for key in kwargs:
                    if key in COMMONS_ARGS:
                        common_args[key] = kwargs[key]
                    elif key == 'privkey':
                        private_key_wif = kwargs[key]
                    else:
                        transaction_args[key] = kwargs[key]
                return transaction_args, common_argsM
            def create_method(**kwargs):
                try:
                    transaction_args, common_args, private_key_wif = split_params(**kwargs)
                    return compose_transaction(self.db, name=tx, params=transaction_args, **common_args)
                except (TypeError, script.AddressError, exceptions.ComposeError, exceptions.TransactionError, exceptions.BalanceError) as error:
                    # TypeError happens when unexpected keyword arguments are passed in
           error_msg = "Error composing {} transaction via API: {}".format(tx, str(error))
                    logging.warning(error_msg)
                    logging.warning(traceback.format_exc())
                    raise JSONRPCDispatchException(code=JSON_RPC_ERROR_API_COMPOSE, message=error_msg)
            return create_method
        for tx in API_TRANSACTIONS:
            create_method = generate_create_method(tx)
            create_method.__name__ = 'create_{}'.format(tx)
            dispatcher.add_methodM
        @dispatcher.add_method
        def get_messages(block_index):
            if not isinstance(block_index, int):
                raise APIError("block_index must be an integer.")
            cursor = self.db.cursor()
            cursor.execute('select * from messages where block_index = ? order by message_index asc', (block_index,))
            messages = cursor.fetchall()
            cursor.close()
            return messages
        @dispatcher.add_method
        def get_messages_by_indexM
            """Get specific messages from the feed, based on the message_index.
            @param message_index: A single index, or a list of one or more message indexes to retrieve.
            if not isinstance(message_indexes, list):
                message_indexes = [message_indexes,]
            for idx in message_indexes:  #make sure the data is clean
                if not isinstance(idx, int):
                    raise APIError("All items in message_indexes are not integM
            cursor = self.db.cursor()
            cursor.execute('SELECT * FROM messages WHERE message_index IN (%s) ORDER BY message_index ASC'
                % (','.join([str(x) for x in message_indexes]),))
            messages = cursor.fetchall()
            cursor.close()
            return messages
        @dispatcher.add_method
        def get_supply(asset):
            if asset == 'BTC':
                return  backend.get_btc_supply(normalize=False)
            elif asset == 'XCP':
 return util.xcp_supply(self.db)
                asset = util.resolve_subasset_longname(self.db, asset)
                return util.asset_supply(self.db, asset)
        @dispatcher.add_method
        def get_xcp_supply():
            logger.warning("Deprecated method: `get_xcp_supply`")
            return util.xcp_supply(self.db)
        @dispatcher.add_method
        def get_asset_info(assets=None, asset=None):
            if asset is not None:
                assets = [asset]
        if not isinstance(assets, list):
                raise APIError("assets must be a list of asset names, even if it just contains one entry")
            assetsInfo = []
            for asset in assets:
                asset = util.resolve_subasset_longname(self.db, asset)
                # BTC and XCP.
                if asset in [config.BTC, config.XCP]:
                    if asset == config.BTC:
                        supply = backend.get_btc_supply(normalize=False)
                    else:
             supply = util.xcp_supply(self.db)
                    assetsInfo.append({
                        'asset': asset,
                        'asset_longname': None,
                        'owner': None,
                        'divisible': True,
                        'locked': False,
                        'supply': supply,
                        'description': '',
                        'issuer': None
                    })
                    continue
                # User
            cursor = self.db.cursor()
                issuances = list(cursor.execute('''SELECT * FROM issuances WHERE (status = ? AND asset = ?) ORDER BY block_index ASC''', ('valid', asset)))
                cursor.close()
                if not issuances:
                    continue #asset not found, most likely
                else:
                    last_issuance = issuances[-1]
                locked = False
                for e in issuances:
                    if e['locked']: locked = True
   assetsInfo.append({
                    'asset': asset,
                    'asset_longname': last_issuance['asset_longname'],
                    'owner': last_issuance['issuer'],
                    'divisible': bool(last_issuance['divisible']),
                    'locked': locked,
                    'supply': util.asset_supply(self.db, asset),
                    'description': last_issuance['description'],
                    'issuer': last_issuance['issuer']})
            return assetsInfo
        def get_block_info(block_index):
            assert isinstance(block_index, int)
            cursor = self.db.cursor()
            cursor.execute('''SELECT * FROM blocks WHERE block_index = ?''', (block_index,))
            blocks = list(cursor)
            if len(blocks) == 1:
                block = blocks[0]
            elif len(blocks) == 0:
                raise exceptions.DatabaseError('No blocks found.')
                assert False
            cursor.close()
        @dispatcher.add_method
        def fee_per_kb(conf_target=config.ESTIMATE_FEE_CONF_TARGET, mode=config.ESTIMATE_FEE_MODE):
            return backend.fee_per_kb(conf_target, mode)
        @dispatcher.add_method
        def get_blocks(block_indexes, min_message_index=None):
            """fetches block info and messages for the specified block indexes
            @param min_message_index: Retrieve blocks from the message feed on or after this specific message index
              (useful M
since blocks may appear in the message feed more than once, if a reorg occurred). Note that
              if this parameter is not specified, the messages for the first block will be returned.
            if not isinstance(block_indexes, (list, tuple)):
                raise APIError("block_indexes must be a list of integers.")
            if len(block_indexes) >= 250:
                raise APIError("can only specify up to 250 indexes at a time.")
            block_indexes_str = ','.join([str(x) foM
r x in block_indexes])
            cursor = self.db.cursor()
            # The blocks table gets rolled back from undolog, so min_message_index doesn't matter for this query
            cursor.execute('SELECT * FROM blocks WHERE block_index IN (%s) ORDER BY block_index ASC'
                % (block_indexes_str,))
            blocks = cursor.fetchall()
            cursor.execute('SELECT * FROM messages WHERE block_index IN (%s) ORDER BY message_index ASC'
                % (block_indexes_str,))
            messageM
s = collections.deque(cursor.fetchall())
            # Discard any messages less than min_message_index
            if min_message_index:
                while len(messages) and messages[0]['message_index'] < min_message_index:
                    messages.popleft()
            # Packages messages into their appropriate block in the data structure to be returned
            for block in blocks:
                block['_messages'] = []
                while len(messages) and messages[0]['block_index'] == block['bloM
                    block['_messages'].append(messages.popleft())
            #NOTE: if len(messages), then we're only returning the messages for the first set of blocks before the reorg
            cursor.close()
            return blocks
        @dispatcher.add_method
        def get_running_info():
            latestBlockIndex = backend.getblockcount()
                check_database_state(self.db, latestBlockIndex)
            except DatabaseError:
                caught_up = FalsM
                caught_up = True
                cursor = self.db.cursor()
                blocks = list(cursor.execute('''SELECT * FROM blocks WHERE block_index = ?''', (util.CURRENT_BLOCK_INDEX, )))
                assert len(blocks) == 1
                last_block = blocks[0]
                cursor.close()
                last_block = None
                last_message = util.last_message(self.db)
                last_M
                indexd_blocks_behind = backend.getindexblocksbehind()
                indexd_blocks_behind = latestBlockIndex if latestBlockIndex > 0 else 999999
            indexd_caught_up = indexd_blocks_behind <= 1
            server_ready = caught_up and indexd_caught_up
            return {
                'server_ready': server_ready,
                'db_caught_up': caught_up,
                'bitcoin_block_count': latestBlockIndex,
                'lastM
_block': last_block,
                'indexd_caught_up': indexd_caught_up,
                'indexd_blocks_behind': indexd_blocks_behind,
                'last_message_index': last_message['message_index'] if last_message else -1,
                'api_limit_rows': config.API_LIMIT_ROWS,
                'running_testnet': config.TESTNET,
                'running_regtest': config.REGTEST,
                'running_testcoin': config.TESTCOIN,
                'version_major': config.VERSION_MAJOR,
                'versioM
n_minor': config.VERSION_MINOR,
                'version_revision': config.VERSION_REVISION
        @dispatcher.add_method
        def get_element_counts():
            counts = {}
            cursor = self.db.cursor()
            for element in ['transactions', 'blocks', 'debits', 'credits', 'balances', 'sends', 'orders',
                'order_matches', 'btcpays', 'issuances', 'broadcasts', 'bets', 'bet_matches', 'dividends',
                'burns', 'cancels', 'order_expirations', 'bet_expirationsM
', 'order_match_expirations',
                'bet_match_expirations', 'messages', 'destructions']:
                cursor.execute("SELECT COUNT(*) AS count FROM %s" % element)
                count_list = cursor.fetchall()
                assert len(count_list) == 1
                counts[element] = count_list[0]['count']
            cursor.close()
            return counts
        @dispatcher.add_method
        def get_asset_names(longnames=False):
            cursor = self.db.cursor()
            if longnames:
                names = []
                for row in cursor.execute("SELECT asset, asset_longname FROM issuances WHERE status = 'valid' GROUP BY asset ORDER BY asset ASC"):
                    names.append({'asset': row['asset'], 'asset_longname': row['asset_longname']})
                names = [row['asset'] for row in cursor.execute("SELECT DISTINCT asset FROM issuances WHERE status = 'valid' ORDER BY asset ASC")]
            cursor.close()
            return names
        @dispatcher.add_methoM
        def get_asset_longnames():
            return get_asset_names(longnames=True)
        @dispatcher.add_method
        def get_holder_count(asset):
            asset = util.resolve_subasset_longname(self.db, asset)
            holders = util.holders(self.db, asset, True)
            addresses = []
            for holder in holders:
                addresses.append(holder['address'])
            return {asset: len(set(addresses))}
        @dispatcher.add_method
        def get_holders(asset):
sset = util.resolve_subasset_longname(self.db, asset)
            holders = util.holders(self.db, asset, True)
            return holders
        @dispatcher.add_method
        def search_raw_transactions(address, unconfirmed=True):
            return backend.search_raw_transactions(address, unconfirmed=unconfirmed)
        @dispatcher.add_method
        def get_unspent_txouts(address, unconfirmed=False, unspent_tx_hash=None, order_by=None):
            results = backend.get_unspent_txouts(address, unconfirmed=unM
confirmed, unspent_tx_hash=unspent_tx_hash)
            if order_by is None:
                return results
                order_key = order_by
                reverse = False
                if order_key.startswith('-'):
                    order_key = order_key[1:]
                    reverse = True
                return sorted(results, key=lambda x: x[order_key], reverse=reverse)
        @dispatcher.add_method
        def getrawtransaction(tx_hash, verbose=False, skip_missing=False):
      return backend.getrawtransaction(tx_hash, verbose=verbose, skip_missing=skip_missing)
        @dispatcher.add_method
        def getrawtransaction_batch(txhash_list, verbose=False, skip_missing=False):
            return backend.getrawtransaction_batch(txhash_list, verbose=verbose, skip_missing=skip_missing)
        @dispatcher.add_method
        def get_tx_info(tx_hex, block_index=None):
            # block_index mandatory for transactions before block 335000
            source, destination, btc_amount, feM
e, data, extra = blocks.get_tx_info(tx_hex, block_index=block_index)
            return source, destination, btc_amount, fee, util.hexlify(data) if data else ''
        @dispatcher.add_method
        def unpack(data_hex):
            data = binascii.unhexlify(data_hex)
            message_type_id, message = message_type.unpack(data)
            # TODO: Enabled only for `send`.
            if message_type_id == send.ID:
                unpack_method = send.unpack
            elif message_type_id == enhanced_send.IM
                unpack_method = enhanced_send.unpack
                raise APIError('unsupported message type')
            unpacked = unpack_method(self.db, message, util.CURRENT_BLOCK_INDEX)
            return message_type_id, unpacked
        @dispatcher.add_method
        # TODO: Rename this method.
        def search_pubkey(pubkeyhash, provided_pubkeys=None):
            return backend.pubkeyhash_to_pubkey(pubkeyhash, provided_pubkeys=provided_pubkeys)
        @dispatcher.add_method
    def get_dispenser_info(tx_hash=None, tx_index=None):
            cursor = self.db.cursor()
            if tx_hash is None and tx_index is None:
                raise APIError("You must provided a tx hash or a tx index")
            if tx_hash is not None:
                cursor.execute('SELECT d.*, a.asset_longname FROM dispensers d LEFT JOIN assets a ON a.asset_name = d.asset WHERE tx_hash=:tx_hash', {"tx_hash":tx_hash})
                cursor.execute('SELECT d.*, a.M
asset_longname FROM dispensers d LEFT JOIN assets a ON a.asset_name = d.asset WHERE tx_index=:tx_index', {"tx_index":tx_index})
            dispensers = cursor.fetchall()
            if len(dispensers) == 1:
                dispenser = dispensers[0]
                oracle_price = ""
                satoshi_price = ""
                fiat_price = ""
                oracle_price_last_updated = ""
                oracle_fiat_label = ""
                if dispenser["oracle_addM
                    fiat_price = util.satoshirate_to_fiat(dispenser["satoshirate"])
                    oracle_price, oracle_fee, oracle_fiat_label, oracle_price_last_updated = util.get_oracle_last_price(self.db, dispenser["oracle_address"], util.CURRENT_BLOCK_INDEX)

                    if (oracle_price > 0):
                        satoshi_price = math.ceil((fiat_price/oracle_price) * config.UNIT)
                    else:
                        raise APIError("Last oracle priM
                return {
                    "tx_index": dispenser["tx_index"],
                    "tx_hash": dispenser["tx_hash"],
                    "block_index": dispenser["block_index"],
                    "source": dispenser["source"],
                    "asset": dispenser["asset"],
                    "give_quantity": dispenser["give_quantity"],
                    "escrow_quantity": dispenser["escrow_quantity"],
                    "mainchainrate": dispenser["satoshirate"],M
                    "fiat_price": fiat_price,
                    "fiat_unit": oracle_fiat_label,
                    "oracle_price": oracle_price,
                    "satoshi_price": satoshi_price,
                    "status": dispenser["status"],
                    "give_remaining": dispenser["give_remaining"],
                    "oracle_address": dispenser["oracle_address"],
                    "oracle_price_last_updated": oracle_price_last_updated,
                    "asset_longname": dispenser["asset_lonM
            return {}
        def _set_cors_headers(response):
            if not config.RPC_NO_ALLOW_CORS:
                response.headers['Access-Control-Allow-Origin'] = '*'
                response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
                response.headers['Access-Control-Allow-Headers'] = 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'
('/healthz', methods=['GET'])
        def handle_healthz():
            msg, code = 'Healthy', 200
                latestBlockIndex = backend.getblockcount()
                check_database_state(self.db, latestBlockIndex)
            except DatabaseError:
                msg, code = 'Unhealthy', 503
            return flask.Response(msg, code, mimetype='text/plain')
        @app.route('/', defaults={'args_path': ''}, methods=['GET', 'POST', 'OPTIONS'])
        @app.route('/<path:args_path>',  methM
ods=['GET', 'POST', 'OPTIONS'])
        # Only require authentication if RPC_PASSWORD is set.
        @conditional_decorator(auth.login_required, hasattr(config, 'RPC_PASSWORD'))
        def handle_root(args_path):
            """Handle all paths, decide where to forward the query."""
            if args_path == '' or args_path.startswith('api/') or args_path.startswith('API/') or \
               args_path.startswith('rpc/') or args_path.startswith('RPC/'):
                if flask.request.method == 'POST':
              # Need to get those here because it might not be available in this aux function.
                    request_json = flask.request.get_data().decode('utf-8')
                    response = handle_rpc_post(request_json)
                    return response
                elif flask.request.method == 'OPTIONS':
                    response = handle_rpc_options()
                    return response
                else:
                    error = 'Invalid method.'
                    return flask.ResponsM
e(error, 405, mimetype='application/json')
            elif args_path.startswith('rest/') or args_path.startswith('REST/'):
                if flask.request.method == 'GET' or flask.request.method == 'POST':
                    # Pass the URL path without /REST/ part and Flask request object.
                    rest_path = args_path.split('/', 1)[1]
                    response = handle_rest(rest_path, flask.request)
                    return response
                else:
                    error = 'Invalid metM
                    return flask.Response(error, 405, mimetype='application/json')
                # Not found
                return flask.Response(None, 404, mimetype='application/json')
        ######################
        # JSON-RPC API
        ######################
        def handle_rpc_options():
            response = flask.Response('', 204)
            _set_cors_headers(response)
            return response
        def handle_rpc_post(request_json):
            """Handle /API/ M
POST route. Call relevant get_rows/create_transaction wrapper."""
            # Check for valid request format.
                request_data = json.loads(request_json)
                assert 'id' in request_data and request_data['jsonrpc'] == "2.0" and request_data['method']
                # params may be omitted
                obj_error = jsonrpc.exceptions.JSONRPCInvalidRequest(data="Invalid JSON-RPC 2.0 request format")
                return flask.Response(obj_error.json.eM
ncode(), 400, mimetype='application/json')
            # Only arguments passed as a `dict` are supported.
            if request_data.get('params', None) and not isinstance(request_data['params'], dict):
                obj_error = jsonrpc.exceptions.JSONRPCInvalidRequest(
                    data='Arguments must be passed as a JSON object (list of unnamed arguments not supported)')
                return flask.Response(obj_error.json.encode(), 400, mimetype='application/json')
            # Return an error if thM
e API Status Poller checks fail.
            if not config.FORCE and current_api_status_code:
                return flask.Response(current_api_status_response_json, 503, mimetype='application/json')
            # Answer request normally.
            # NOTE: `UnboundLocalError: local variable 'output' referenced before assignment` means the method doesn
            jsonrpc_response = jsonrpc.JSONRPCResponseManager.handle(request_json, dispatcher)
            response = flask.Response(jsonrpc_rM
esponse.json.encode(), 200, mimetype='application/json')
            _set_cors_headers(response)
            return response
        ######################
        # HTTP REST API
        ######################
        def handle_rest(path_args, flask_request):
            """Handle /REST/ route. Query the database using get_rows or create transaction using compose_transaction."""
            url_action = flask_request.path.split('/')[-1]
            if url_action == 'compose':
                compose = True
       elif url_action == 'get':
                compose = False
                error = 'Invalid action "%s".' % url_action
                return flask.Response(error, 400, mimetype='application/json')
            # Get all arguments passed via URL.
            url_args = path_args.split('/')
                query_type = url_args.pop(0).lower()
            except IndexError:
                error = 'No query_type provided.'
                return flask.Response(error, 400, mimeM
type='application/json')
            # Check if message type or table name are valid.
            if (compose and query_type not in API_TRANSACTIONS) or \
               (not compose and query_type not in API_TABLES):
                error = 'No such query type in supported queries: "%s".' % query_type
                return flask.Response(error, 400, mimetype='application/json')
            # Parse the additional arguments.
            extra_args = flask_request.args.items()
            query_data = {}
                common_args = {}
                transaction_args = {}
                for (key, value) in extra_args:
                    # Determine value type.
                    try:
                        value = int(value)
                    except ValueError:
                        try:
                            value = float(value)
                        except ValueError:
                            pass
                    # Split keys into common and transaction-specific arguments. M
Discard the privkey.
                    if key in COMMONS_ARGS:
                        common_args[key] = value
                    elif key == 'privkey':
                        pass
                    else:
                        transaction_args[key] = value
                # Must have some additional transaction arguments.
                if not len(transaction_args):
                    error = 'No transaction arguments provided.'
                    return flask.Response(error, 400, mimetype='applicationM
                # Compose the transaction.
                try:
                    query_data = compose_transaction(self.db, name=query_type, params=transaction_args, **common_args)
                except (script.AddressError, exceptions.ComposeError, exceptions.TransactionError, exceptions.BalanceError) as error:
                    error_msg = logging.warning("{} -- error composing {} transaction via API: {}".format(
                        str(error.__class__.__name__), query_type, str(error)))
             return flask.Response(error_msg, 400, mimetype='application/json')
                # Need to de-generate extra_args to pass it through.
                query_args = dict([item for item in extra_args])
                operator = query_args.pop('op', 'AND')
                # Put the data into specific dictionary format.
                data_filter = [{'field': key, 'op': '==', 'value': value} for (key, value) in query_args.items()]
                # Run the query.
                try:
                    query_data = get_rows(self.db, table=query_type, filters=data_filter, filterop=operator)
                except APIError as error:
                    return flask.Response(str(error), 400, mimetype='application/json')
            # See which encoding to choose from.
            file_format = flask_request.headers['Accept']
            # JSON as default.
            if file_format == 'application/json' or file_format == '*/*':
                response_data = json.dumps(query_data)
lif file_format == 'application/xml':
                # Add document root for XML. Note when xmltodict encounters a list, it produces separate tags for every item.
                # Hence we end up with multiple query_type roots. To combat this we put it in a separate item dict.
                response_data = serialize_to_xml({query_type: {'item': query_data}})
                error = 'Invalid file format: "%s".' % file_format
                return flask.Response(error, 400, mimetype='applicatioM
            response = flask.Response(response_data, 200, mimetype=file_format)
            return response
        # Init the HTTP Server.
        init_api_access_log(app)
        # Run app server (blocking)
        self.is_ready = True
        app.run(host=config.RPC_HOST, port=config.RPC_PORT, threaded=True)
        self.db.close()
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
from Crypto.Cipher import ARC4
def init_arc4(seed):
isinstance(seed, str):
        seed = binascii.unhexlify(seed)
    return ARC4.new(seed)
Initialise database.
Sieve blockchain for Counterparty transactions, and add them to the database.
logger = logging.getLogger(__name__)
import bitcoin as bitcoinlib
from bitcoin.core.script import CScriptInvaliM
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
from counterpartylib.lib import util
from counterpartylib.lib import check
from counterpartylib.lib import script
from counterpartylib.lib import backend
from counterpartylib.lib import log
from counterpartylib.lib import database
from counterpartylib.lib import message_type
from counterpartylib.lib import arc4
from counterpartylib.lib.transaction_helper import p2sh_encoding
from .messages import (send, order, btcpay, issuancM
e, broadcast, bet, dividend, burn, cancel, rps, rpsresolve, destroy, sweep, dispenser)
from .messages.versions import enhanced_send, mpma
from .kickstart.blocks_parser import BlockchainParser, ChainstateParser
from .kickstart.utils import ib2h
from .exceptions import DecodeError, BTCOnlyError
# Order matters for FOREIGN KEY constraints.
TABLES = ['credits', 'debits', 'messages'] + \
         ['bet_match_resolutions', 'order_match_expirations', 'order_matches',
         'order_expirations', 'orders', 'bet_match_eM
xpirations', 'bet_matches',
         'bet_expirations', 'bets', 'broadcasts', 'btcpays', 'burns',
         'cancels', 'dividends', 'issuances', 'sends',
         'rps_match_expirations', 'rps_expirations', 'rpsresolves',
         'rps_matches', 'rps',
         'destructions', 'assets', 'addresses', 'sweeps', 'dispensers', 'dispenses']
# Compose list of tables tracked by undolog
UNDOLOG_TABLES = copy.copy(TABLES)
UNDOLOG_TABLES.remove('messages')
UNDOLOG_TABLES += ['balances']
CURR_DIR = os.path.dirname(os.path.reaM
with open(CURR_DIR + '/../mainnet_burns.csv', 'r') as f:
    mainnet_burns_reader = csv.DictReader(f)
    MAINNET_BURNS = {}
    for line in mainnet_burns_reader:
        MAINNET_BURNS[line['tx_hash']] = line
def parse_tx(db, tx):
    """Parse the transaction, return True for success."""
    cursor = db.cursor()
            # Only one source and one destination allowed for now.
            if len(tx['source'].split('-')) > 1:
                return
            if tx['desM
                if len(tx['destination'].split('-')) > 1:
                    return
            # Burns.
            if tx['destination'] == config.UNSPENDABLE:
                burn.parse(db, tx, MAINNET_BURNS)
                return
            if len(tx['data']) > 1:
                try:
                    message_type_id, message = message_type.unpack(tx['data'], tx['block_index'])
                except struct.error:    # Deterministically raised.
                    message_type_id = None
               message = None
                message_type_id = None
                message = None
            # Protocol change.
            rps_enabled = tx['block_index'] >= 308500 or config.TESTNET or config.REGTEST
            if message_type_id == send.ID:
                send.parse(db, tx, message)
            elif message_type_id == enhanced_send.ID and util.enabled('enhanced_sends', block_index=tx['block_index']):
                enhanced_send.parse(db, tx, message)
            elif meM
ssage_type_id == mpma.ID and util.enabled('mpma_sends', block_index=tx['block_index']):
                mpma.parse(db, tx, message)
            elif message_type_id == order.ID:
                order.parse(db, tx, message)
            elif message_type_id == btcpay.ID:
                btcpay.parse(db, tx, message)
            elif message_type_id == issuance.ID:
                issuance.parse(db, tx, message, message_type_id)
            elif message_type_id == issuance.SUBASSET_ID and util.enabled('subassets', bloM
ck_index=tx['block_index']):
                issuance.parse(db, tx, message, message_type_id)
            elif message_type_id == broadcast.ID:
                broadcast.parse(db, tx, message)
            elif message_type_id == bet.ID:
                bet.parse(db, tx, message)
            elif message_type_id == dividend.ID:
                dividend.parse(db, tx, message)
            elif message_type_id == cancel.ID:
                cancel.parse(db, tx, message)
            elif message_type_id == rps.ID and rpsM
                rps.parse(db, tx, message)
            elif message_type_id == rpsresolve.ID and rps_enabled:
                rpsresolve.parse(db, tx, message)
            elif message_type_id == destroy.ID and util.enabled('destroy_reactivated', block_index=tx['block_index']):
                destroy.parse(db, tx, message)
            elif message_type_id == sweep.ID and util.enabled('sweep_send', block_index=tx['block_index']):
                sweep.parse(db, tx, message)
            elif message_type_iM
d == dispenser.ID and util.enabled('dispensers', block_index=tx['block_index']):
                dispenser.parse(db, tx, message)
            elif message_type_id == dispenser.DISPENSE_ID and util.enabled('dispensers', block_index=tx['block_index']):
                dispenser.dispense(db, tx)
                cursor.execute('''UPDATE transactions \
                                           SET supported=? \
                                           WHERE tx_hash=?''',
                            M
            (False, tx['tx_hash']))
                if tx['block_index'] != config.MEMPOOL_BLOCK_INDEX:
                    logger.info('Unsupported transaction: hash {}; data {}'.format(tx['tx_hash'], tx['data']))
                cursor.close()
                return False
            # NOTE: for debugging (check asset conservation after every `N` transactions).
            # if not tx['tx_index'] % N:
            #     check.asset_conservation(db)
            return True
    except Exception as e:
 exceptions.ParseTransactionError("%s" % e)
        cursor.close()
def parse_block(db, block_index, block_time,
                previous_ledger_hash=None, ledger_hash=None,
                previous_txlist_hash=None, txlist_hash=None,
                previous_messages_hash=None):
    """Parse the block, return hash of new ledger, txlist and messages.
    The unused arguments `ledger_hash` and `txlist_hash` are for the test suite.
    undolog_cursor = db.cursor()
    #remove the row tracer andM
 exec tracer on this cursor, so we don't utilize them with undolog operations...
    undolog_cursor.setexectrace(None)
    undolog_cursor.setrowtrace(None)
    util.BLOCK_LEDGER = []
    database.BLOCK_MESSAGES = []
    assert block_index == util.CURRENT_BLOCK_INDEX
    # Remove undolog records for any block older than we should be tracking
    undolog_oldest_block_index = block_index - config.UNDOLOG_MAX_PAST_BLOCKS
    first_undo_index = list(undolog_cursor.execute('''SELECT first_undo_index FROM undolog_blockM
 WHERE block_index == ?''',
        (undolog_oldest_block_index,)))
    if len(first_undo_index) == 1 and first_undo_index[0] is not None:
        undolog_cursor.execute('''DELETE FROM undolog WHERE undo_index < ?''', (first_undo_index[0][0],))
    undolog_cursor.execute('''DELETE FROM undolog_block WHERE block_index < ?''',
        (undolog_oldest_block_index,))
    # Set undolog barrier for this block
    if block_index != config.BLOCK_FIRST:
        undolog_cursor.execute('''INSERT OR REPLACE INTO undolog_blockM
(block_index, first_undo_index)
            SELECT ?, seq+1 FROM SQLITE_SEQUENCE WHERE name='undolog' ''', (block_index,))
        undolog_cursor.execute('''INSERT OR REPLACE INTO undolog_block(block_index, first_undo_index)
            VALUES(?,?)''', (block_index, 1,))
    undolog_cursor.close()
    # Expire orders, bets and rps.
    order.expire(db, block_index)
    bet.expire(db, block_index, block_time)
    rps.expire(db, block_index)
    # Parse transactions, sorting them by type.
    cursor.execute('''SELECT * FROM transactions \
                      WHERE block_index=? ORDER BY tx_index''',
                   (block_index,))
    for tx in list(cursor):
            parse_tx(db, tx)
            txlist.append('{}{}{}{}{}{}'.format(tx['tx_hash'], tx['source'], tx['destination'],
                                                tx['btc_amount'], tx['fee'],
                                                binascii.hexlify(tx['data']).decode('UTF-8')))
 except exceptions.ParseTransactionError as e:
            logger.warn('ParseTransactionError for tx %s: %s' % (tx['tx_hash'], e))
    # Calculate consensus hashes.
    new_txlist_hash, found_txlist_hash = check.consensus_hash(db, 'txlist_hash', previous_txlist_hash, txlist)
    new_ledger_hash, found_ledger_hash = check.consensus_hash(db, 'ledger_hash', previous_ledger_hash, util.BLOCK_LEDGER)
    new_messages_hash, found_messages_hash = check.consensus_haM
sh(db, 'messages_hash', previous_messages_hash, database.BLOCK_MESSAGES)
    return new_ledger_hash, new_txlist_hash, new_messages_hash, found_messages_hash
    """Initialise data, create and populate the database."""
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS blocks(
                      block_index INTEGER UNIQUE,
                      block_hash TEXT UNIQUE,
                      block_time INTEGER,
                      previous_block_hash TEXM
                      difficulty INTEGER,
                      PRIMARY KEY (block_index, block_hash))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON blocks (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      index_hash_idx ON blocks (block_index, block_hash)
                   ''')
t do `ALTER TABLE IF COLUMN NOT EXISTS`.
    columns = [column['name'] for column M
in cursor.execute('''PRAGMA table_info(blocks)''')]
    if 'ledger_hash' not in columns:
        cursor.execute('''ALTER TABLE blocks ADD COLUMN ledger_hash TEXT''')
    if 'txlist_hash' not in columns:
        cursor.execute('''ALTER TABLE blocks ADD COLUMN txlist_hash TEXT''')
    if 'messages_hash' not in columns:
        cursor.execute('''ALTER TABLE blocks ADD COLUMN messages_hash TEXT''')
    if 'previous_block_hash' not in columns:
        cursor.execute('''ALTER TABLE blocks ADD COLUMN previous_block_hash TM
    if 'difficulty' not in columns:
        cursor.execute('''ALTER TABLE blocks ADD COLUMN difficulty TEXT''')
    # Check that first block in DB is BLOCK_FIRST.
    cursor.execute('''SELECT * from blocks ORDER BY block_index''')
    blocks = list(cursor)
        if blocks[0]['block_index'] != config.BLOCK_FIRST:
            raise exceptions.DatabaseError('First block in database is not block {}.'.format(config.BLOCK_FIRST))
    cursor.execute('''CREATE TABLE IF NOTM
 EXISTS transactions(
                      tx_index INTEGER UNIQUE,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      block_hash TEXT,
                      block_time INTEGER,
                      source TEXT,
                      destination TEXT,
                      btc_amount INTEGER,
                      fee INTEGER,
                      data BLOB,
                      supported BOOL DEFAULT 1,
                      FOREIGN KEY (block_index, bloM
ck_hash) REFERENCES blocks(block_index, block_hash),
                      PRIMARY KEY (tx_index, tx_hash, block_index))
                    ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON transactions (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx_index_idx ON transactions (tx_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx_hash_idx ON transactionsM
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      index_index_idx ON transactions (block_index, tx_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      index_hash_index_idx ON transactions (tx_index, tx_hash, block_index)
                   ''')
    # Purge database of blocks, transactions from before BLOCK_FIRST.
    cursor.execute('''DELETE FROM blocks WHERE block_index < ?''', (config.BLOCK_FIRST,))
or.execute('''DELETE FROM transactions WHERE block_index < ?''', (config.BLOCK_FIRST,))
    # (Valid) debits
    cursor.execute('''CREATE TABLE IF NOT EXISTS debits(
                      block_index INTEGER,
                      address TEXT,
                      asset TEXT,
                      quantity INTEGER,
                      action TEXT,
                      event TEXT,
                      FOREIGN KEY (block_index) REFERENCES blocks(block_index))
                   ''')
    cursor.execute('''CREAM
TE INDEX IF NOT EXISTS
                      address_idx ON debits (address)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      asset_idx ON debits (asset)
                   ''')
    # (Valid) credits
    cursor.execute('''CREATE TABLE IF NOT EXISTS credits(
                      block_index INTEGER,
                      address TEXT,
                      asset TEXT,
                      quantity INTEGER,
                      calling_function TEXT,
                      FOREIGN KEY (block_index) REFERENCES blocks(block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      address_idx ON credits (address)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      asset_idx ON credits (asset)
                   ''')
    cursor.execute('''CREATE TABLE IF NOT EXISTS balances(
                      address TEXT,
                      asset TEXT,
                    quantity INTEGER)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      address_asset_idx ON balances (address, asset)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      address_idx ON balances (address)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      asset_idx ON balances (asset)
                   ''')
    # TODO: Store more asset info here?!
sor.execute('''CREATE TABLE IF NOT EXISTS assets(
                      asset_id TEXT UNIQUE,
                      asset_name TEXT UNIQUE,
                      block_index INTEGER,
                      asset_longname TEXT)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      name_idx ON assets (asset_name)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      id_idx ON assets (asset_id)
                   ''')
    # Add asset_lonM
gname for sub-assets
t do `ALTER TABLE IF COLUMN NOT EXISTS`.
    columns = [column['name'] for column in cursor.execute('''PRAGMA table_info(assets)''')]
    if 'asset_longname' not in columns:
        cursor.execute('''ALTER TABLE assets ADD COLUMN asset_longname TEXT''')
    cursor.execute('''CREATE UNIQUE INDEX IF NOT EXISTS asset_longname_idx ON assets(asset_longname)''')
    cursor.execute('''SELECT * FROM assets WHERE asset_name = ?''', ('BTC',))
    if not list(cursor):
execute('''INSERT INTO assets VALUES (?,?,?,?)''', ('0', 'BTC', None, None))
        cursor.execute('''INSERT INTO assets VALUES (?,?,?,?)''', ('1', 'XCP', None, None))
    # Leaving this here because in the future this could work for other things besides broadcast
    cursor.execute('''CREATE TABLE IF NOT EXISTS addresses(
                      address TEXT UNIQUE,
                      options INTEGER,
                      block_index INTEGER)
                   ''')
    cursor.execute('''CREATEM
 INDEX IF NOT EXISTS
                      addresses_idx ON addresses (address)
                   ''')
    send.initialise(db)
    destroy.initialise(db)
    order.initialise(db)
    btcpay.initialise(db)
    issuance.initialise(db)
    broadcast.initialise(db)
    bet.initialise(db)
    dividend.initialise(db)
    burn.initialise(db)
    cancel.initialise(db)
    rps.initialise(db)
    rpsresolve.initialise(db)
    sweep.initialise(db)
    dispenser.initialise(db)
ecute('''CREATE TABLE IF NOT EXISTS messages(
                      message_index INTEGER PRIMARY KEY,
                      block_index INTEGER,
                      command TEXT,
                      category TEXT,
                      bindings TEXT,
                      timestamp INTEGER)
                  ''')
                      # TODO: FOREIGN KEY (block_index) REFERENCES blocks(block_index) DEFERRABLE INITIALLY DEFERRED)
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_indexM
_idx ON messages (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_message_index_idx ON messages (block_index, message_index)
                   ''')
    # Create undolog tables
    cursor.execute('''CREATE TABLE IF NOT EXISTS undolog(
                        undo_index INTEGER PRIMARY KEY AUTOINCREMENT,
                        sql TEXT)
                   ''')
    cursor.execute('''CREATE TABLE IF NOT EXISTS undolog_block(
                    M
    block_index INTEGER PRIMARY KEY,
                        first_undo_index INTEGER)
                   ''')
    # Create undolog triggers for all tables in TABLES list, plus the 'balances' table
    for table in UNDOLOG_TABLES:
        columns = [column['name'] for column in cursor.execute('''PRAGMA table_info({})'''.format(table))]
        cursor.execute('''CREATE TRIGGER IF NOT EXISTS _{}_insert AFTER INSERT ON {} BEGIN
                            INSERT INTO undolog VALUES(NULL, 'DELETE FROM {} WHERE rowid='|M
                            END;
                       '''.format(table, table, table))
        columns_parts = ["{}='||quote(old.{})||'".format(c, c) for c in columns]
        cursor.execute('''CREATE TRIGGER IF NOT EXISTS _{}_update AFTER UPDATE ON {} BEGIN
                            INSERT INTO undolog VALUES(NULL, 'UPDATE {} SET {} WHERE rowid='||old.rowid);
                            END;
                       '''.format(table, table, table, ','.join(columns_parts)))
        columns_parts = M
["'||quote(old.{})||'".format(c) for c in columns]
        cursor.execute('''CREATE TRIGGER IF NOT EXISTS _{}_delete BEFORE DELETE ON {} BEGIN
                            INSERT INTO undolog VALUES(NULL, 'INSERT INTO {}(rowid,{}) VALUES('||old.rowid||',{})');
                            END;
                       '''.format(table, table, table, ','.join(columns), ','.join(columns_parts)))
    # Drop undolog tables on messages table if they exist (fix for adding them in 9.52.0)
    for trigger_type in ('insert', 'uM
        cursor.execute("DROP TRIGGER IF EXISTS _messages_{}".format(trigger_type))
    # Mempool messages
    # NOTE: `status`, 'block_index` are removed from bindings.
    cursor.execute('''DROP TABLE IF EXISTS mempool''')
    cursor.execute('''CREATE TABLE mempool(
                      tx_hash TEXT,
                      command TEXT,
                      category TEXT,
                      bindings TEXT,
                      timestamp INTEGER)
                  ''')
ef get_tx_info(tx_hex, block_parser=None, block_index=None, db=None):
    """Get the transaction info. Returns normalized None data for DecodeError and BTCOnlyError."""
        return _get_tx_info(tx_hex, block_parser, block_index)
    except DecodeError as e:
        return b'', None, None, None, None, None
    except BTCOnlyError as e:
        # NOTE: For debugging, logger.debug('Could not decode: ' + str(e))
        if util.enabled('dispensers', block_index):
                return b'',M
 None, None, None, None, _get_swap_tx(e.decodedTx, block_parser, block_index, db=db)
            except: # (DecodeError, backend.indexd.BackendRPCError) as e:
                return b'', None, None, None, None, None
            return b'', None, None, None, None, None
def _get_swap_tx(decoded_tx, block_parser=None, block_index=None, db=None):
    def get_pubkeyhash(scriptpubkey):
        asm = script.get_asm(scriptpubkey)
        if len(asm) > 0:
            if asm[0] == "OP_DUP":
      if len(asm) != 5 or asm[1] != 'OP_HASH160' or asm[3] != 'OP_EQUALVERIFY' or asm[4] != 'OP_CHECKSIG':
                    return False
                else:
                    return {"pubkeyhash":asm[2],"address_version":config.ADDRESSVERSION}
            elif (asm[0] == "OP_HASH160") and util.enabled('p2sh_dispensers_support'):
                if len(asm) != 3 or asm[-1] != 'OP_EQUAL':
                    return False
                else:
                    return {"pubkeyhash":asm[1M
],"address_version":config.P2SH_ADDRESSVERSION}
        return False
    def get_address(scriptpubkey):
        if util.enabled('correct_segwit_txids') and scriptpubkey.is_witness_v0_keyhash():
            pubkey = scriptpubkey[2:]
            address = str(bitcoinlib.bech32.CBech32Data.from_bytes(0, pubkey))
            return address
            pubkeyhashdict = get_pubkeyhash(scriptpubkey)
            if not pubkeyhashdict:
                return False
            pubkeyhash = pubM
keyhashdict["pubkeyhash"]
            address_version = pubkeyhashdict["address_version"]
            pubkeyhash = binascii.hexlify(pubkeyhash).decode('utf-8')
            address = script.base58_check_encode(pubkeyhash, address_version)
            # Test decoding of address.
            if address != config.UNSPENDABLE and binascii.unhexlify(bytes(pubkeyhash, 'utf-8')) != script.base58_check_decode(address, address_version):
                return False
            return address
   check_sources = db == None # If we didn't get passed a database cursor, assume we have to check for dispenser
    for vout in decoded_tx.vout:
        address = get_address(vout.scriptPubKey)
        destination = None
        btc_amount = None
            destination = address
            btc_amount = vout.nValue
        elif util.enabled('hotfix_dispensers_with_non_p2pkh'):
            asm = script.get_asm(vout.scriptPubKey)
            if asm[-1] == 'OP_CHECKSIG':
                destinatiM
on, new_data = decode_checksig(asm, decoded_tx)
            elif asm[-1] == 'OP_CHECKMULTISIG':
                destination, new_data = decode_checkmultisig(asm, decoded_tx)
            elif asm[0] == 'OP_HASH160' and asm[-1] == 'OP_EQUAL' and len(asm) == 3:
                destination, new_data = decode_scripthash(asm)
            elif asm[0] == 'OP_RETURN':
                pass #Just ignore.
            elif util.enabled('segwit_support') and asm[0] == 0:
                # Segwit output
                destinatioM
n, new_data = decode_p2w(vout.scriptPubKey)
                logger.error('unrecognised scriptPubkey. Just ignore this: ' + str(asm))
            if destination and not new_data:
                amount = vout.nValue
                logger.error('cannot parse destination address or new_data found: ' + str(asm))
        if db != None and dispenser.is_dispensable(db, destination, btc_amount):
            check_sources = True
            outputs.append((destination, btc_amount))
  # Collect all (unique) source addresses.
    #   if we haven't found them yet
    if check_sources:
        for vin in decoded_tx.vin[:]:                   # Loop through inputs.
            if block_parser:
                vin_tx = block_parser.read_raw_transaction(ib2h(vin.prevout.hash))
                vin_ctx = backend.deserialize(vin_tx['__data__'])
                vin_tx = backend.getrawtransaction(ib2h(vin.prevout.hash)) # TODO: Biggest penalty on parsing is here
        vin_ctx = backend.deserialize(vin_tx)
            vout = vin_ctx.vout[vin.prevout.n]
            asm = script.get_asm(vout.scriptPubKey)
            if asm[-1] == 'OP_CHECKSIG':
                new_source, new_data = decode_checksig(asm, decoded_tx)
                if new_data or not new_source:
                    raise DecodeError('data in source')
            elif asm[-1] == 'OP_CHECKMULTISIG':
                new_source, new_data = decode_checkmultisig(asm, decoded_tx)
                if new_data or noM
                    raise DecodeError('data in source')
            elif asm[0] == 'OP_HASH160' and asm[-1] == 'OP_EQUAL' and len(asm) == 3:
                new_source, new_data = decode_scripthash(asm)
                if new_data or not new_source:
                    raise DecodeError('data in source')
            elif util.enabled('segwit_support') and asm[0] == 0:
                # Segwit output
                # Get the full transaction data for this input transaction.
                new_source,M
 new_data = decode_p2w(vout.scriptPubKey)
                raise DecodeError('unrecognised source type')
            # old; append to sources, results in invalid addresses
            # new; first found source is source, the rest can be anything (to fund the TX for example)
            if not (util.enabled('first_input_is_source') and len(sources)):
                # Collect unique sources.
                if new_source not in sources:
                    sources.append(new_source)
def _get_tx_info(tx_hex, block_parser=None, block_index=None, p2sh_is_segwit=False):
    """Get the transaction info. Calls one of two subfunctions depending on signature type."""
    if not block_index:
        block_index = util.CURRENT_BLOCK_INDEX
    if util.enabled('p2sh_addresses', block_index=block_index):   # Protocol change.
        return  get_tx_info3(tx_hex, block_parser=block_parser, p2sh_is_segwit=p2sh_is_segwit)
    elif util.enabled('multisig_addresses', block_index=block_index):   M
        return get_tx_info2(tx_hex, block_parser=block_parser)
        return get_tx_info1(tx_hex, block_index, block_parser=block_parser)
def get_tx_info1(tx_hex, block_index, block_parser=None):
    """Get singlesig transaction info.
    The destination, if it exists, always comes before the data output; the
    change, if it exists, always comes after.
    ctx = backend.deserialize(tx_hex)
    def get_pubkeyhash(scriptpubkey):
        asm = script.get_asm(scriptpubkey)
    if len(asm) != 5 or asm[0] != 'OP_DUP' or asm[1] != 'OP_HASH160' or asm[3] != 'OP_EQUALVERIFY' or asm[4] != 'OP_CHECKSIG':
            return False
        return asm[2]
    def get_address(scriptpubkey):
        pubkeyhash = get_pubkeyhash(scriptpubkey)
        if not pubkeyhash:
            return False
        pubkeyhash = binascii.hexlify(pubkeyhash).decode('utf-8')
        address = script.base58_check_encode(pubkeyhash, config.ADDRESSVERSION)
        # Test decoding of address.
        if address != confM
ig.UNSPENDABLE and binascii.unhexlify(bytes(pubkeyhash, 'utf-8')) != script.base58_check_decode(address, config.ADDRESSVERSION):
            return False
        return address
    # Fee is the input values minus output values.
    # Get destination output and data output.
    destination, btc_amount, data = None, None, b''
    pubkeyhash_encoding = False
    for vout in ctx.vout:
        fee -= vout.nValue
        # Sum data chunks to get data. (Can mix OP_RETURN and multi-sig.)
        asm = scripM
t.get_asm(vout.scriptPubKey)
        if len(asm) == 2 and asm[0] == 'OP_RETURN':                                             # OP_RETURN
            if type(asm[1]) != bytes:
                continue
            data_chunk = asm[1]
            data += data_chunk
        elif len(asm) == 5 and asm[0] == 1 and asm[3] == 2 and asm[4] == 'OP_CHECKMULTISIG':    # Multi-sig
            if type(asm[2]) != bytes:
                continue
            data_pubkey = asm[2]
            data_chunk_length = data_pubkey[0]  # No M
            data_chunk = data_pubkey[1:data_chunk_length + 1]
            data += data_chunk
        elif len(asm) == 5 and (block_index >= 293000 or config.TESTNET or config.REGTEST):    # Protocol change.
            # Be strict.
            pubkeyhash = get_pubkeyhash(vout.scriptPubKey)
            if not pubkeyhash:
                continue
            if ctx.is_coinbase():
                raise DecodeError('coinbase transaction')
            obj1 = arc4.init_arc4(ctx.vin[0].prevout.hash[::-1]M
            data_pubkey = obj1.decrypt(pubkeyhash)
            if data_pubkey[1:9] == config.PREFIX or pubkeyhash_encoding:
                pubkeyhash_encoding = True
                data_chunk_length = data_pubkey[0]  # No ord() necessary.
                data_chunk = data_pubkey[1:data_chunk_length + 1]
                if data_chunk[-8:] == config.PREFIX:
                    data += data_chunk[:-8]
                    break
                else:
                    data += data_chunk
        # Destination is tM
he first output before the data.
        if not destination and not btc_amount and not data:
            address = get_address(vout.scriptPubKey)
            if address:
                destination = address
                btc_amount = vout.nValue
    # Check for, and strip away, prefix (except for burns).
    if destination == config.UNSPENDABLE:
    elif data[:len(config.PREFIX)] == config.PREFIX:
        data = data[len(config.PREFIX):]
        raise DecodeError('no prefix')
look for source if data were found or destination is UNSPENDABLE, for speed.
    if not data and destination != config.UNSPENDABLE:
        raise BTCOnlyError('no data and not unspendable')
    # Collect all possible source addresses; ignore coinbase transactions and anything but the simplest Pay
    source_list = []
    for vin in ctx.vin[:]:                                               # Loop through input transactions.
        if vin.prevout.is_null():
            raise DecodeError('cM
oinbase transaction')
         # Get the full transaction data for this input transaction.
        if block_parser:
            vin_tx = block_parser.read_raw_transaction(ib2h(vin.prevout.hash))
            vin_ctx = backend.deserialize(vin_tx['__data__'])
            vin_tx = backend.getrawtransaction(ib2h(vin.prevout.hash))
            vin_ctx = backend.deserialize(vin_tx)
        vout = vin_ctx.vout[vin.prevout.n]
        fee += vout.nValue
        address = get_address(vout.scriptPubKey)
            raise DecodeError('invalid scriptpubkey')
            source_list.append(address)
    # Require that all possible source addresses be the same.
    if all(x == source_list[0] for x in source_list):
        source = source_list[0]
        source = None
    return source, destination, btc_amount, fee, data, None
def get_tx_info3(tx_hex, block_parser=None, p2sh_is_segwit=False):
    return get_tx_info2(tx_hex, block_parser=block_parser, p2sh_support=True, p2sh_is_M
segwit=p2sh_is_segwit)
def arc4_decrypt(cyphertext, ctx):
obfuscate. Initialise key once per attempt.'''
    key = arc4.init_arc4(ctx.vin[0].prevout.hash[::-1])
    return key.decrypt(cyphertext)
def get_opreturn(asm):
    if len(asm) == 2 and asm[0] == 'OP_RETURN':
        pubkeyhash = asm[1]
        if type(pubkeyhash) == bytes:
            return pubkeyhash
    raise DecodeError('invalid OP_RETURN')
def decode_opreturn(asm, ctx):
    chunk = get_opreturn(asm)
    chunk = arc4_decrypt(chunk, ctx)
   if chunk[:len(config.PREFIX)] == config.PREFIX:             # Data
        destination, data = None, chunk[len(config.PREFIX):]
        raise DecodeError('unrecognised OP_RETURN output')
    return destination, data
def decode_checksig(asm, ctx):
    pubkeyhash = script.get_checksig(asm)
    chunk = arc4_decrypt(pubkeyhash, ctx)
    if chunk[1:len(config.PREFIX) + 1] == config.PREFIX:        # Data
        # Padding byte in each output (instead of just in the last one) so that encoding methods may beM
s just not very much data.
        chunk_length = chunk[0]
        chunk = chunk[1:chunk_length + 1]
        destination, data = None, chunk[len(config.PREFIX):]
    else:                                                       # Destination
        pubkeyhash = binascii.hexlify(pubkeyhash).decode('utf-8')
        destination, data = script.base58_check_encode(pubkeyhash, config.ADDRESSVERSION), None
    return destination, data
def decode_scripthash(asm):
    destination = script.base58_check_enM
code(binascii.hexlify(asm[1]).decode('utf-8'), config.P2SH_ADDRESSVERSION)
    return destination, None
def decode_checkmultisig(asm, ctx):
    pubkeys, signatures_required = script.get_checkmultisig(asm)
    for pubkey in pubkeys[:-1]:     # (No data in last pubkey.)
        chunk += pubkey[1:-1]       # Skip sign byte and nonce byte.
    chunk = arc4_decrypt(chunk, ctx)
    if chunk[1:len(config.PREFIX) + 1] == config.PREFIX:        # Data
        # Padding byte in each output (instead of just iM
n the last one) so that encoding methods may be mixed. Also, it
s just not very much data.
        chunk_length = chunk[0]
        chunk = chunk[1:chunk_length + 1]
        destination, data = None, chunk[len(config.PREFIX):]
    else:                                                       # Destination
        pubkeyhashes = [script.pubkey_to_pubkeyhash(pubkey) for pubkey in pubkeys]
        destination, data = script.construct_array(signatures_required, pubkeyhashes, len(pubkeyhashes)), None
    return destinatM
def decode_p2w(script_pubkey):
        bech32 = bitcoinlib.bech32.CBech32Data.from_bytes(0, script_pubkey[2:22])
        return str(bech32), None
    except TypeError as e:
        raise DecodeError('bech32 decoding error')
def get_tx_info2(tx_hex, block_parser=None, p2sh_support=False, p2sh_is_segwit=False):
    """Get multisig transaction info.
    The destinations, if they exists, always comes before the data output; the
    change, if it exists, always comes after.
    ctx = backend.deserialize(tx_hex)
    # Ignore coinbase transactions.
    if ctx.is_coinbase():
        raise DecodeError('coinbase transaction')
    # Get destinations and data outputs.
    destinations, btc_amount, fee, data = [], 0, 0, b''
    for vout in ctx.vout:
        # Fee is the input values minus output values.
        output_value = vout.nValue
        fee -= output_value
        # Ignore transactions with invalid script.
            asm = script.get_asm(vout.scriptPM
        except CScriptInvalidError as e:
            raise DecodeError(e)
        if asm[0] == 'OP_RETURN':
            new_destination, new_data = decode_opreturn(asm, ctx)
        elif asm[-1] == 'OP_CHECKSIG':
            new_destination, new_data = decode_checksig(asm, ctx)
        elif asm[-1] == 'OP_CHECKMULTISIG':
                new_destination, new_data = decode_checkmultisig(asm, ctx)
                raise DecodeError('unrecognised output type')
sh_support and asm[0] == 'OP_HASH160' and asm[-1] == 'OP_EQUAL' and len(asm) == 3:
            new_destination, new_data = decode_scripthash(asm)
        elif util.enabled('segwit_support') and asm[0] == 0:
            # Segwit Vout, second param is redeemScript
            #redeemScript = asm[1]
            new_destination, new_data = decode_p2w(vout.scriptPubKey)
            raise DecodeError('unrecognised output type')
        assert not (new_destination and new_data)
        assert new_destinationM
 != None or new_data != None  # `decode_*()` should never return `None, None`.
        if util.enabled('null_data_check'):
            if new_data == []:
                raise DecodeError('new destination is `None`')
        # All destinations come before all data.
        if not data and not new_data and destinations != [config.UNSPENDABLE,]:
            destinations.append(new_destination)
            btc_amount += output_value
            if new_destination:     # Change.
                break
          else:                   # Data.
                data += new_data
    # source can be determined by parsing the p2sh_data transaction
    #   or from the first spent output
    # P2SH encoding signalling
    p2sh_encoding_source = None
    if util.enabled('p2sh_encoding') and data == b'P2SH':
        for vin in ctx.vin:
            if util.enabled("prevout_segwit_fix"):
                vin_tx = backend.getrawtransaction(ib2h(vin.prevout.hash))
                vin_ctx =M
 backend.deserialize(vin_tx)
                prevout_is_segwit = vin_ctx.has_witness()
                prevout_is_segwit = p2sh_is_segwit
            # Ignore transactions with invalid script.
                asm = script.get_asm(vin.scriptSig)
            except CScriptInvalidError as e:
                raise DecodeError(e)
            new_source, new_destination, new_data = p2sh_encoding.decode_p2sh_input(asm, p2sh_is_segwit=prevout_is_segwit)
s could be a p2sh source address with no encoded data
            if new_data is None:
              continue;
            if new_source is not None:
                if p2sh_encoding_source is not None and new_source != p2sh_encoding_source:
                    # this p2sh data input has a bad source address
                    raise DecodeError('inconsistent p2sh inputs')
                p2sh_encoding_source = new_source
            assert not new_destination
            data += new_data
    # Only look for soM
urce if data were found or destination is `UNSPENDABLE`,
    if not data and destinations != [config.UNSPENDABLE,]:
        raise BTCOnlyError('no data and not unspendable', ctx)
    # Collect all (unique) source addresses.
    #   if we haven't found them yet
    for vin in ctx.vin[:]:                   # Loop through inputs.
        # Get the full transaction data for this input transaction.
        if block_parser:
            vin_tx = block_parser.read_raw_transaction(ib2h(vin.prevout.hash))
           vin_ctx = backend.deserialize(vin_tx['__data__'])
            vin_tx = backend.getrawtransaction(ib2h(vin.prevout.hash))
            vin_ctx = backend.deserialize(vin_tx)
        vout = vin_ctx.vout[vin.prevout.n]
        fee += vout.nValue
        asm = script.get_asm(vout.scriptPubKey)
        if asm[-1] == 'OP_CHECKSIG':
            new_source, new_data = decode_checksig(asm, ctx)
            if new_data or not new_source:
                raise DecodeError('data in source')
 asm[-1] == 'OP_CHECKMULTISIG':
            new_source, new_data = decode_checkmultisig(asm, ctx)
            if new_data or not new_source:
                raise DecodeError('data in source')
        elif p2sh_support and asm[0] == 'OP_HASH160' and asm[-1] == 'OP_EQUAL' and len(asm) == 3:
            new_source, new_data = decode_scripthash(asm)
            if new_data or not new_source:
                raise DecodeError('data in source')
        elif util.enabled('segwit_support') and asm[0] == 0:
            new_source, new_data = decode_p2w(vout.scriptPubKey)
            raise DecodeError('unrecognised source type')
        # old; append to sources, results in invalid addresses
        # new; first found source is source, the rest can be anything (to fund the TX for example)
        if not (util.enabled('first_input_is_source') and len(sources)):
            # Collect unique sources.
            if new_source not in sources:
                sources.append(new_source)
the source from the p2sh data source
    if p2sh_encoding_source is not None:
        sources = p2sh_encoding_source
        sources = '-'.join(sources)
    destinations = '-'.join(destinations)
    return sources, destinations, btc_amount, round(fee), data, None
def reinitialise(db, block_index=None):
    """Drop all predefined tables and initialise the database once again."""
    cursor = db.cursor()
    # Delete all of the results of parsing (including the undolog)
    for table in TABLES + ['balancM
es', 'undolog', 'undolog_block']:
        cursor.execute('''DROP TABLE IF EXISTS {}'''.format(table))
    # Create missing tables
    # clean consensus hashes if first block hash doesn't match with checkpoint.
    if config.TESTNET:
        checkpoints = check.CHECKPOINTS_TESTNET
    elif config.REGTEST:
        checkpoints = check.CHECKPOINTS_REGTEST
        checkpoints = check.CHECKPOINTS_MAINNET
    columns = [column['name'] for column in cursor.execute('''PRAGMA table_info(blocksM
    for field in ['ledger_hash', 'txlist_hash']:
        if field in columns:
            sql = '''SELECT {} FROM blocks  WHERE block_index = ?'''.format(field)
            first_block = list(cursor.execute(sql, (config.BLOCK_FIRST,)))
            if first_block:
                first_hash = first_block[0][field]
                if first_hash != checkpoints[config.BLOCK_FIRST][field]:
                    logger.info('First hash changed. Cleaning {}.'.format(field))
                    cursor.execute('''UPDATM
E blocks SET {} = NULL'''.format(field))
    # For rollbacks, just delete new blocks and then reparse what
        cursor.execute('''DELETE FROM transactions WHERE block_index > ?''', (block_index,))
        cursor.execute('''DELETE FROM blocks WHERE block_index > ?''', (block_index,))
    elif config.TESTNET or config.REGTEST:  # block_index NOT specified and we are running testnet
        # just blow away the consensus hashes with a full testnet reparse, as we could activate
 # new features retroactively, which could otherwise lead to ConsensusError exceptions being raised.
        logger.info("Testnet/regtest full reparse detected: Clearing all consensus hashes before performing reparse.")
        cursor.execute('''UPDATE blocks SET ledger_hash = NULL, txlist_hash = NULL, messages_hash = NULL''')
def reparse(db, block_index=None, quiet=False):
    """Reparse all transactions (atomically). If block_index is set, rollback
    to the end of that block.
f reparse_from_undolog(db, block_index, quiet):
        """speedy reparse method that utilizes the undolog.
        if fails, fallback to the full reparse method"""
        if not block_index:
            return False # Can't reparse from undolog
        undolog_cursor = db.cursor()
        undolog_cursor.setexectrace(None)
        undolog_cursor.setrowtrace(None)
        def get_block_index_for_undo_index(undo_indexes, undo_index):
            for block_index, first_undo_index in undo_indexes.items(): #in order
                if undo_index < first_undo_index:
                    return block_index - 1
                return next(reversed(undo_indexes)) #the last inserted block_index
            # Check if we can reparse from the undolog
            results = list(undolog_cursor.execute(
                '''SELECT block_index, first_undo_index FROM undolog_block WHERE block_index >= ? ORDER BY block_index ASC''', (block_index,)))
            undo_indexes = collections.OrderedDict()
       for result in results:
                undo_indexes[result[0]] = result[1]
            undo_start_block_index = block_index + 1
            if undo_start_block_index not in undo_indexes:
                if block_index in undo_indexes:
                    # Edge case, should only happen if we're "rolling back" to latest block (e.g. via cmd line)
                    return True #skip undo
                else:
                    return False # Undolog doesn't go that far back, full reparse required...
        # Grab the undolog...
            undolog = list(undolog_cursor.execute(
                '''SELECT undo_index, sql FROM undolog WHERE undo_index >= ? ORDER BY undo_index DESC''',
                (undo_indexes[undo_start_block_index],)))
            # Replay the undolog backwards, from the last entry to first_undo_index...
            for entry in undolog:
                logger.info("Undolog: Block {} (undo_index {}): {}".format(
                    get_block_index_for_undo_index(undo_indexes, entry[0]), eM
                undolog_cursor.execute(entry[1])
            # Trim back tx and blocks
            undolog_cursor.execute('''DELETE FROM transactions WHERE block_index > ?''', (block_index,))
            undolog_cursor.execute('''DELETE FROM blocks WHERE block_index > ?''', (block_index,))
            # As well as undolog entries...
            undolog_cursor.execute('''DELETE FROM undolog WHERE undo_index >= ?''', (undo_indexes[undo_start_block_index],))
            undolog_cursor.execute('''DM
ELETE FROM undolog_block WHERE block_index >= ?''', (undo_start_block_index,))
        undolog_cursor.close()
        logger.info('Rolling back transactions to block {}.'.format(block_index))
        logger.info('Reparsing all transactions.')
    check.software_version()
    reparse_start = time.time()
    # Reparse from the undolog if possible
    reparsed = reparse_from_undolog(db, block_index, quiet)
    cursor = db.cursor()
    if not reparsed:
            logger.info("Could not roll back from undolog. Performing full reparse instead...")
            root_logger = logging.getLogger()
            root_level = logger.getEffectiveLevel()
            reinitialise(db, block_index)
            # Reparse all blocks, transactions.
            if quiet:
                root_logger.setLevel(logging.WARNING)
            previous_ledger_hash, previous_txlist_hash, previous_messages_hash = None, None, None
  cursor.execute('''SELECT * FROM blocks ORDER BY block_index''')
            for block in cursor.fetchall():
                util.CURRENT_BLOCK_INDEX = block['block_index']
                previous_ledger_hash, previous_txlist_hash, previous_messages_hash, previous_found_messages_hash = parse_block(
                                                                         db, block['block_index'], block['block_time'],
                                                                         previous_ledger_hash=prevM
                                                                         previous_txlist_hash=previous_txlist_hash,
                                                                         previous_messages_hash=previous_messages_hash)
                if quiet and block['block_index'] % 10 == 0:  # every 10 blocks print status
                    root_logger.setLevel(logging.INFO)
                logger.info('Block (re-parse): %s (hashes: L:%s / TX:%s / M:%s%s)' % (
                    block['blocM
k_index'], previous_ledger_hash[-5:], previous_txlist_hash[-5:], previous_messages_hash[-5:],
                    (' [overwrote %s]' % previous_found_messages_hash) if previous_found_messages_hash and previous_found_messages_hash != previous_messages_hash else ''))
                if quiet and block['block_index'] % 10 == 0:
                    root_logger.setLevel(logging.WARNING)
            root_logger.setLevel(root_level)
        # Check for conservation of assets.
.asset_conservation(db)
        # Update database version number.
        database.update_version(db)
    reparse_end = time.time()
    logger.info("Reparse took {:.3f} minutes.".format((reparse_end - reparse_start) / 60.0))
    # on full reparse - vacuum the DB afterwards for better subsequent performance (especially on non-SSDs)
    if not block_index:
        database.vacuum(db)
def list_tx(db, block_hash, block_index, block_time, tx_hash, tx_index, tx_hex=None):
    assert type(tx_hash) =M
    cursor = db.cursor()
    # Edge case: confirmed tx_hash also in mempool
    cursor.execute('''SELECT * FROM transactions WHERE tx_hash = ?''', (tx_hash,))
    transactions = list(cursor)
    if transactions:
        return tx_index
    # Get the important details about each transaction.
    if tx_hex is None:
        tx_hex = backend.getrawtransaction(tx_hash) # TODO: This is the call that is stalling the process the most
    source, destination, btc_amount, fee, data, decoded_tx = get_tx_info(tx_hex, M
    if not source and decoded_tx and util.enabled('dispensers', block_index):
        outputs = decoded_tx[1]
        for out in outputs:
            if out[0] != decoded_tx[0][0] and dispenser.is_dispensable(db, out[0], out[1]):
                source = decoded_tx[0][0]
                destination = out[0]
                btc_amount = out[1]
                fee = 0
                data = struct.pack(config.SHORT_TXTYPE_FORMAT, dispenser.DISPENSE_ID)
                data += b'\x00'
                break # PM
revent inspection of further dispenses (only first one is valid)
    if block_hash == None:
        block_hash = config.MEMPOOL_BLOCK_HASH
        block_index = config.MEMPOOL_BLOCK_INDEX
        assert block_index == util.CURRENT_BLOCK_INDEX
    if source and (data or destination == config.UNSPENDABLE or decoded_tx):
        logger.debug('Saving transaction: {}'.format(tx_hash))
        cursor.execute('''INSERT INTO transactions(
                            tx_index,
                            block_index,
                            block_hash,
                            block_time,
                            source,
                            destination,
                            btc_amount,
                            fee,
                            data) VALUES(?,?,?,?,?,?,?,?,?,?)''',
                            (tx_index,
                             tx_hash,
                             block_index,
                             block_hash,
                          block_time,
                             source,
                             destination,
                             btc_amount,
                             fee,
                             data)
                      )
        cursor.close()
        return tx_index + 1
        logger.getChild('list_tx.skip').debug('Skipping transaction: {}'.format(tx_hash))
def kickstart(db, bitcoind_dir):
    if bitcoind_dir is None:
        if platform.system() == 'DM
            bitcoind_dir = os.path.expanduser('~/Library/Application Support/Bitcoin/')
        elif platform.system() == 'Windows':
            bitcoind_dir = os.path.join(os.environ['APPDATA'], 'Bitcoin')
            bitcoind_dir = os.path.expanduser('~/.bitcoin')
    if not os.path.isdir(bitcoind_dir):
        raise Exception('Bitcoin Core data directory not found at {}. Use --bitcoind-dir parameter.'.format(bitcoind_dir))
    cursor = db.cursor()
    logger.warning('''Warning:
hat bitcoind is stopped.
- You must reindex bitcoind after the initialization is complete (restart with `-reindex=1`)
- The initialization may take a while.''')
    if input('Proceed with the initialization? (y/N) : ') != 'y':
    if config.TESTNET:
        first_hash = config.BLOCK_FIRST_TESTNET_HASH
    elif config.REGTEST:
        first_hash = config.BLOCK_FIRST_REGTEST_HASH
        first_hash = config.BLOCK_FIRST_MAINNET_HASH
    start_time_total = time.time()
    # Get hash of last M
    chain_parser = ChainstateParser(os.path.join(bitcoind_dir, 'chainstate'))
    last_hash = chain_parser.get_last_block_hash()
    chain_parser.close()
    # Start block parser.
    block_parser = BlockchainParser(os.path.join(bitcoind_dir, 'blocks'), os.path.join(bitcoind_dir, 'blocks/index'))
    current_hash = last_hash
        # Prepare SQLite database. # TODO: Be more specific!
        logger.info('Preparing database.')
        start_time = time.time()
nitialise(db, block_index=config.BLOCK_FIRST - 1)
        logger.info('Prepared database in {:.3f}s'.format(time.time() - start_time))
        # Get blocks and transactions, moving backwards in time.
        while current_hash != None:
            start_time = time.time()
            transactions = []
            # Get `tx_info`s for transactions in this block.
            block = block_parser.read_raw_block(current_hash)
            for tx in block['transactions']:
                source, destination, btc_amountM
, fee, data = get_tx_info(tx['__data__'], block_parser=block_parser, block_index=block['block_index'])
                if source and (data or destination == config.UNSPENDABLE):
                    transactions.append((
                        tx['tx_hash'], block['block_index'], block['block_hash'], block['block_time'],
                        source, destination, btc_amount, fee, data
                    ))
                    logger.info('Valid transaction: {}'.format(tx['tx_hash']))
            # Insert block M
and transactions into database.
            cursor.execute('''INSERT INTO blocks(
                                    block_index,
                                    block_hash,
                                    block_time) VALUES(?,?,?)''',
                                    (block['block_index'],
                                    block['block_hash'],
                                    block['block_time']))
            if len(transactions):
                transactions = list(reversed(transactions))
         tx_chunks = [transactions[i:i+90] for i in range(0, len(transactions), 90)]
                for tx_chunk in tx_chunks:
                    sql = '''INSERT INTO transactions
                                (tx_index, tx_hash, block_index, block_hash, block_time, source, destination, btc_amount, fee, data)
                             VALUES '''
                    bindings = ()
                    bindings_place = []
                    # negative tx_index from -1 and inverse order for fast reordering   # TM
ODO: Can this be clearer?
                    for tx in tx_chunk:
                        bindings += (-(tx_index + 1),) + tx
                        bindings_place.append('''(?,?,?,?,?,?,?,?,?,?)''')
                        tx_index += 1
                    sql += ', '.join(bindings_place)
                    cursor.execute(sql, bindings)
            logger.info('Block {} ({}): {}/{} saved in {:.3f}s'.format(
                          block['block_index'], block['block_hash'],
                          len(transaM
ctions), len(block['transactions']),
                          time.time() - start_time))
            # Get hash of next block.
            current_hash = block['hash_prev'] if current_hash != first_hash else None
        block_parser.close()
        # Reorder all transactions in database.
        logger.info('Reordering transactions.')
        start_time = time.time()
        cursor.execute('''UPDATE transactions SET tx_index = tx_index + ?''', (tx_index,))
        logger.info('Reordered transactions in {:.3f}sM
.'.format(time.time() - start_time))
    # Parse all transactions in database.
    logger.info('Total duration: {:.3f}s'.format(time.time() - start_time_total))
def last_db_index(db):
    cursor = db.cursor()
        blocks = list(cursor.execute('''SELECT * FROM blocks WHERE block_index = (SELECT MAX(block_index) from blocks)'''))
            return blocks[0]['block_index']
        except IndexError:
            return 0
    except apsw.SQLError:
def get_next_tx_index(db):
    """Return index of next transaction."""
    cursor = db.cursor()
    txes = list(cursor.execute('''SELECT * FROM transactions WHERE tx_index = (SELECT MAX(tx_index) from transactions)'''))
        assert len(txes) == 1
        tx_index = txes[0]['tx_index'] + 1
        tx_index = 0
class MempoolError(Exception):
    # Check software version.
    check.software_version()
    # Get index of last block.
    if util.CURRENT_BLOCK_INDEX == 0:
        logger.warning('New database.')
        block_index = config.BLOCK_FIRST
        block_index = util.CURRENT_BLOCK_INDEX + 1
        # Check database version.
            check.database_version(db)
        except check.DatabaseVersionError as e:
            logger.info(str(e))
            # no need to reparse or rollback a new database
            if block_index != config.BLOCK_FIRST:
      reparse(db, block_index=e.reparse_block_index, quiet=False)
            else: #version update was included in reparse(), so don't do it twice
                database.update_version(db)
    logger.info('Resuming parsing.')
    # Get index of last transaction.
    tx_index = get_next_tx_index(db)
    not_supported = {}   # No false positives. Use a dict to allow for O(1) lookups
    not_supported_sorted = collections.deque()
    # ^ Entries in form of (block_index, tx_hash), oldest first. Allows for easy reM
moval of past, unncessary entries
    cursor = db.cursor()
    # a reorg can happen without the block count increasing, or even for that
    # matter, with the block count decreasing. This should only delay
    # processing of the new blocks a bit.
        start_time = time.time()
        # Get block count.
        # If the backend is unreachable and `config.FORCE` is set, just sleep
        # and try again repeatedly.
            block_count = backend.getblockcount()
onnectionRefusedError, http.client.CannotSendRequest, backend.addrindexrs.BackendRPCError) as e:
            if config.FORCE:
                time.sleep(config.BACKEND_POLL_INTERVAL)
                continue
                raise e
        # Get new blocks.
        if block_index <= block_count:
            current_index = block_index
            # Backwards check for incorrect blocks due to chain reorganisation, and stop when a common parent is found.
            if block_count - block_index < M
100: # Undolog only saves last 100 blocks, if there's a reorg deeper than that manual reparse should be done
                requires_rollback = False
                while True:
                    if current_index == config.BLOCK_FIRST:
                        break
                    logger.debug('Checking that block {} is not an orphan.'.format(current_index))
                    # Backend parent hash.
                    current_hash = backend.getblockhash(current_index)
                    current_cblock = M
backend.getblock(current_hash)
                    backend_parent = bitcoinlib.core.b2lx(current_cblock.hashPrevBlock)
                    # DB parent hash.
                    blocks = list(cursor.execute('''SELECT * FROM blocks
                                                    WHERE block_index = ?''', (current_index - 1,)))
                    if len(blocks) != 1:  # For empty DB.
                        break
                    db_parent = blocks[0]['block_hash']
                    # Compare.
        assert type(db_parent) == str
                    assert type(backend_parent) == str
                    if db_parent == backend_parent:
                        break
                    else:
                        current_index -= 1
                        requires_rollback = True
                # Rollback for reorganisation.
                if requires_rollback:
                    # Record reorganisation.
                    logger.warning('Blockchain reorganisation at block {}.'.format(current_indexM
                    log.message(db, block_index, 'reorg', None, {'block_index': current_index})
                    # Rollback the DB.
                    reparse(db, block_index=current_index-1, quiet=True)
                    block_index = current_index
                    tx_index = get_next_tx_index(db)
                    continue
            # Check version. (Don
t add any blocks to the database while
            # running an out
            check.software_version()
 Get and parse transactions in this block (atomically).
            block_hash = backend.getblockhash(current_index)
            block = backend.getblock(block_hash)
            previous_block_hash = bitcoinlib.core.b2lx(block.hashPrevBlock)
            block_time = block.nTime
            txhash_list, raw_transactions = backend.get_tx_list(block)
            with db:
                util.CURRENT_BLOCK_INDEX = block_index
                # List the block.
                cursor.execute('''INSERT INTO blocks(
                                block_index,
                                    block_hash,
                                    block_time,
                                    previous_block_hash,
                                    difficulty) VALUES(?,?,?,?,?)''',
                                    (block_index,
                                    block_hash,
                                    block_time,
                                    previous_block_hash,
                                    block.difficuM
                              )
                # List the transactions in the block.
                for tx_hash in txhash_list:
                    tx_hex = raw_transactions[tx_hash]
                    tx_index = list_tx(db, block_hash, block_index, block_time, tx_hash, tx_index, tx_hex)
                # Parse the transactions in the block.
                new_ledger_hash, new_txlist_hash, new_messages_hash, found_messages_hash = parse_block(db, block_index, block_time)
            # When newly caught uM
p, check for conservation of assets.
            if block_index == block_count:
                if config.CHECK_ASSET_CONSERVATION:
                    check.asset_conservation(db)
            # Remove any non
supported transactions older than ten blocks.
            while len(not_supported_sorted) and not_supported_sorted[0][0] <= block_index - 10:
                tx_h = not_supported_sorted.popleft()[1]
                del not_supported[tx_h]
            logger.info('Block: %s (%ss, hashes: L:%s / TX:%s / M:%M
                str(block_index), "{:.2f}".format(time.time() - start_time, 3),
                new_ledger_hash[-5:], new_txlist_hash[-5:], new_messages_hash[-5:],
                (' [overwrote %s]' % found_messages_hash) if found_messages_hash and found_messages_hash != new_messages_hash else ''))
            # Increment block index.
            block_count = backend.getblockcount()
            block_index += 1
            # TODO: add zeromq support here to await TXs and Blocks instead ofM
            # Get old mempool.
            old_mempool = list(cursor.execute('''SELECT * FROM mempool'''))
            old_mempool_hashes = [message['tx_hash'] for message in old_mempool]
            if backend.MEMPOOL_CACHE_INITIALIZED is False:
                backend.init_mempool_cache()
                logger.info("Ready for queries.")
            # Fake values for fake block.
            curr_time = int(time.time())
            mempool_tx_index = tx_index
            xcp_mempool = []
         raw_mempool = backend.getrawmempool()
            # this is a quick fix to make counterparty usable on high mempool situations
            # however, this makes the mempool unreliable on counterparty, a better, larger
            # fix must be done by changing this whole function into a zmq driven loop
            if len(raw_mempool) > config.MEMPOOL_TXCOUNT_UPDATE_LIMIT:
                continue
            # For each transaction in Bitcoin Core mempool, if it
            # a fake block,M
 a fake transaction, capture the generated messages,
            # and then save those messages.
            # Every transaction in mempool is parsed independently. (DB is rolled back after each one.)
            # We first filter out which transactions we've already parsed before so we can batch fetch their raw data
            parse_txs = []
            for tx_hash in raw_mempool:
                # If already in mempool, copy to new one.
                if tx_hash in old_mempool_hashes:
                    for meM
ssage in old_mempool:
                        if message['tx_hash'] == tx_hash:
                            xcp_mempool.append((tx_hash, message))
                # If not a supported XCP transaction, skip.
                elif tx_hash in not_supported:
                    pass
                # Else: list, parse and save it.
                else:
                    parse_txs.append(tx_hash)
            # fetch raw for all transactions that need to be parsed
            # Sometimes the transactions can
ound: `{'code': -5, 'message': 'No information available about transaction'}`
            #  - is txindex enabled in Bitcoind?
            #  - or was there a block found while batch feting the raw txs
            #  - or was there a double spend for w/e reason accepted into the mempool (replace-by-fee?)
                raw_transactions = backend.getrawtransaction_batch(parse_txs)
            except Exception as e:
                logger.warning('Failed to fetch raw for mempool TXs, restarting loopM
                continue  # restart the follow loop
            for tx_hash in parse_txs:
                try:
                    with db:
                        # List the fake block.
                        cursor.execute('''INSERT INTO blocks(
                                            block_index,
                                            block_hash,
                                            block_time) VALUES(?,?,?)''',
                                       (config.MEMPOOL_BLOCK_INDEX,
                                       config.MEMPOOL_BLOCK_HASH,
                                        curr_time)
                                      )
                        tx_hex = raw_transactions[tx_hash]
                        if tx_hex is None:
                          logger.debug('tx_hash %s not found in backend.  Not adding to mempool.', (tx_hash, ))
                          raise MempoolError
                        mempool_tx_index = list_tx(db, None, block_index, curr_time, tx_hash, tx_index=M
mempool_tx_index, tx_hex=tx_hex)
                        # Parse transaction.
                        cursor.execute('''SELECT * FROM transactions WHERE tx_hash = ?''', (tx_hash,))
                        transactions = list(cursor)
                        if transactions:
                            assert len(transactions) == 1
                            transaction = transactions[0]
                            supported = parse_tx(db, transaction)
                            if not supported:
               not_supported[tx_hash] = ''
                                not_supported_sorted.append((block_index, tx_hash))
                        else:
                            # If a transaction hasn
                            # table `transactions`, then it
                            # Counterparty transaction.
                            not_supported[tx_hash] = ''
                            not_supported_sorted.append((block_index, tx_hash))
                           M
                        # Save transaction and side
                        cursor.execute('''SELECT * FROM messages WHERE block_index = ?''', (config.MEMPOOL_BLOCK_INDEX,))
                        for message in list(cursor):
                            xcp_mempool.append((tx_hash, message))
                        # Rollback.
                        raise MempoolError
                except exceptions.ParseTransactionError as e:
                    logger.warn('ParseTranM
sactionError for tx %s: %s' % (tx_hash, e))
                except MempoolError:
                    pass
write mempool messages to database.
            with db:
                cursor.execute('''DELETE FROM mempool''')
                for message in xcp_mempool:
                    tx_hash, new_message = message
                    new_message['tx_hash'] = tx_hash
                    cursor.execute('''INSERT INTO mempool VALUES(:tx_hash, :command, :category, :bindings, :timestamp)''', new_messM
            elapsed_time = time.time() - start_time
            sleep_time = config.BACKEND_POLL_INTERVAL - elapsed_time if elapsed_time <= config.BACKEND_POLL_INTERVAL else 0
            logger.getChild('mempool').debug('Refresh mempool: %s XCP txs seen, out of %s total entries (took %ss, next refresh in %ss)' % (
                len(xcp_mempool), len(raw_mempool),
                "{:.2f}".format(elapsed_time, 3),
                "{:.2f}".format(sleep_time, 3)))
            db.wal_checkpM
oint(mode=apsw.SQLITE_CHECKPOINT_PASSIVE)
            time.sleep(sleep_time)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
logger = logging.getLogger(__name__)
from counterpartylib.lib import config
from counterpartylib.lib import util
from counterpartylib.lib import exceptions
from counterpartylib.lib import backend
from counterpartylib.lib import database
CONSENSUS_HASH_SEED = M
'We can only see a short distance ahead, but we can see plenty there that needs to be done.'
CONSENSUS_HASH_VERSION_MAINNET = 2
CHECKPOINTS_MAINNET = {
    config.BLOCK_FIRST_MAINNET: {'ledger_hash': '766ff0a9039521e3628a79fa669477ade241fc4c0ae541c3eae97f34b547b0b7', 'txlist_hash': '766ff0a9039521e3628a79fa669477ade241fc4c0ae541c3eae97f34b547b0b7'},
    280000: {'ledger_hash': '265719e2770d5a6994f6fe49839069183cd842ee14f56c2b870e56641e8a8725', 'txlist_hash': 'a59b33b4633649db4f14586af47e258ed9b8884dbb7aa308fb1f49aM
    290000: {'ledger_hash': '4612ed7034474b4ff1727eb0e216d533ebe7ac755fb015e0f9a170c063f3e84c', 'txlist_hash': 'c15423c849fd360d38cbd6c6c3ea37a07fece723da92353f3056facc2676d9e7'},
    300000: {'ledger_hash': '9a3dd4949780404d61e5ca1929f94a43f08eb0fa19ccb4b5d6a61cafd7943199', 'txlist_hash': 'efa02dbdcc4158a598e3b476ece5ba9cc8d26f3abc8ac3777ac6dde0f0afc7e6'},
    310000: {'ledger_hash': '45e43d5cc77ea01129df01d7f55b0c89b2d4e18cd3d626fd92f30bfb37a85f4d', 'txlist_hash': '83cdcf75833d828ded09979b601fde87e2fM
db0f5eb1cc6ab5d2042b7ec85f90e'},
    320000: {'ledger_hash': '91c1d33626669e8098bc762b1a9e3f616884e4d1cadda4881062c92b0d3d3e98', 'txlist_hash': '761793042d8e7c80e14a16c15bb9d40e237c468a87c207a59730b616bdfde7d4'},
    330000: {'ledger_hash': 'dd56aa97e5ca15841407f383ce1d7814536a594d7cfffcb4cf60bee8b362065a', 'txlist_hash': '3c45b4377a99e020550a198daa45c378c488a72ba199b53deb90b320d55a897b'},
    334000: {'ledger_hash': '24c4fa4097106031267439eb9fbe8ce2a18560169c67726652b608908c1ca9bb', 'txlist_hash': '764ca9e8d3b9546M
d1c4ff441a39594548989f60daefc6f28e046996e76a273bf'},
    335000: {'ledger_hash': 'e57c9d606a615e7e09bf99148596dd28e64b25cd8b081e226d535a64c1ed08d1', 'txlist_hash': '437d9507185b5e193627edf4998aad2264755af8d13dd3948ce119b32dd50ce2'},
    336000: {'ledger_hash': '1329ff5b80d034b64f6ea3481b7c7176437a8837b2a7cb7b8a265fdd1397572d', 'txlist_hash': '33eb8cacd4c750f8132d81e8e43ca13bd565f1734d7d182346364847414da52f'},
    337000: {'ledger_hash': '607e6a93e8d97cefea9bd55384898ee90c8477ded8a46017f2294feedbc83409', 'txlist_hasM
h': '20b535a55abcc902ca70c19dd648cbe5149af8b4a4157b94f41b71fc422d428e'},
    338000: {'ledger_hash': 'f043914c71e4b711abb1c1002767b9a4e7d605e249facaaf7a2046b0e9741204', 'txlist_hash': 'fa2c3f7f76345278271ed5ec391d582858e10b1f154d9b44e5a1f4896400ee46'},
    339000: {'ledger_hash': '49f7240bc90ebc2f242dd599c7d2c427b9d2ac844992131e6e862b638ae4393a', 'txlist_hash': 'c1e3b497c054dcf67ddd0dc223e8b8a6e09a1a05bacb9fef5c03e48bd01e64e7'},
    340000: {'ledger_hash': '255760e2abfb79fdd76b65759f1590f582c1747f3eeccc4b2ae37d23e3M
0e0729', 'txlist_hash': '8502004bb63e699b243ac8af072d704c69b817905e74787c2031af971e8cd87c'},
    341000: {'ledger_hash': '1369cba3909e564d2e725879a8b2cd987df075db121d1d421c8ce16b65f4bf04', 'txlist_hash': 'd217d0bed190cb27f58fcb96b255f8006bc4b9ed739e1bb08507201c49c426c8'},
    342000: {'ledger_hash': '9e7e9b8620717189ccea697ff2f84fe71bc4ae8d991481ff235164d72a9e6e4f', 'txlist_hash': 'adf75d023760101b2b337f6359dd811b12521c83837eb3f7db3bbfd0b095aa54'},
    343000: {'ledger_hash': 'aa47312ebe94b35504bec6c74713e404e5f368M
54e0836839344d13debe50558c', 'txlist_hash': '6bdbbc96364b3c92cea132fe66a0925f9445a249f7062326bdcc4ad4711f0c01'},
    344000: {'ledger_hash': '40187263aa96d1362bf7b19c8ba0fff7f0c0f3eb132a40fc90601b5926c7e6e3', 'txlist_hash': '98da8efe705c4b54275bfd25f816a7e7a4ff1f67647e17d7a0aaa2a3fef8bda0'},
    345000: {'ledger_hash': 'e4a1e1be4beea63d9740ca166b75bb4e3ffa2af33e1fe282e5b09c4952a7448c', 'txlist_hash': '777f163eaa5ad79dcb738871d4318a0699defec469d8afe91ab6277ff8d3e8b8'},
    350000: {'ledger_hash': '6a67e9f2e9d07e7bb3M
277cf9c24f84c857ed1b8fff4a37e589cd56ade276dd95', 'txlist_hash': '96bcbdbce74b782a845d4fda699846d2d3744044c2870a413c018642b8c7c3bf'},
    355000: {'ledger_hash': 'a84b17992217c7845e133a8597dac84eba1ee8c48bcc7f74bcf512837120f463', 'txlist_hash': '210d96b42644432b9e1a3433a29af9acb3bad212b67a7ae1dbc011a11b04bc24'},
    360000: {'ledger_hash': 'ddca07ea43b336b703fb8ebab6c0dc30582eb360d6f0eb0446e1fe58b53dee0a', 'txlist_hash': '31d0ff3e3782cf9464081829c5595b3de5ac477290dc069d98672f3f552767f8'},
    365000: {'ledger_hash':M
 '2d55b126cca3eca15c07b5da683988f9e01d7346d2ca430e940fd7c07ce84fd7', 'txlist_hash': '7988a823cc1e3234953cc87d261d3c1fede8493d0a31b103357eb23cc7dc2eda'},
    366000: {'ledger_hash': '64ce274df2784f9ca88a8d7071613ec6527e506ec31cd434eca64c6a3345a6b7', 'txlist_hash': '0d4374da6100e279b24f4ba4a2d6afbfc4fb0fc2d312330a515806e8c5f49404'},
    370000: {'ledger_hash': 'fabb2a2e91fad3fe7734169d554cca396c1030243044cef42fcf65717cf0fa61', 'txlist_hash': '41d1732868c9ac25951ace5ca9f311a15d5eca9bf8d548e0d988c050bd2aff87'},
000: {'ledger_hash': 'a7ac4e2948cea0c426c8fc201cf57d9c313027ea7bff2b32a25ed28d3dbaa581', 'txlist_hash': '96118a7aa2ca753488755b7419a0f44a7fbc371bc58dcc7ab083c70fc14ef8b3'},
    380000: {'ledger_hash': '70453ba04c1c0198c4771e7964cffa25f9456c2f71456a8b05dfe935d5fcdc88', 'txlist_hash': '8bf2070103cca6f0bde507b7d20b0ba0630da6349beb560fa64c926d08dbcaef'},
    385000: {'ledger_hash': '93eb0a6e820bee197e7591edbc5ead7bfa38f32c88aabf4785f080fd6ae96c4c', 'txlist_hash': '1f8f17fd5766382a8c10a2a0e995a7d5a5d1bcd5fc0220d1e2691b2M
    390000: {'ledger_hash': '7d42b98eecbc910a67a5f4ac8dc7d6d9b6995ebc5bdf53663b414965fe7d2c5e', 'txlist_hash': 'b50efc4a4241bf3ec33a38c3b5f34756a9f305fe5fa9a80f7f9b70d5d7b2a780'},
    395000: {'ledger_hash': '89f9ac390b35e69dd75d6c34854ba501dce2f662fc707aee63cad5822c7660f2', 'txlist_hash': '2151dd2f0aa14685f3d041727a689d5d242578072a049123b317724fc4f1100c'},
    400000: {'ledger_hash': 'eb681a305125e04b6f044b36045e23ee248ce4eb68433cea2b36d15e7e74d5f1', 'txlist_hash': 'b48e9501e8d6f1f1b4127d868860885d3dbM
76698c2c31a567777257df101cf61'},
    405000: {'ledger_hash': '3725055b37a8958ade6ca1c277cf50fee6036b4a92befb8da2f7c32f0b210881', 'txlist_hash': '871b2adfd246e3fe69f0fe9098e3251045ed6e9712c4cf90ea8dfdd1eb330ed6'},
    410000: {'ledger_hash': '1fa9a34f233695ebd7ebb08703bf8d99812fa099f297efc5d307d1ebef902ffd', 'txlist_hash': 'ee3bd84c728a37e2bbe061c1539c9ee6d71db18733b1ed53ee8d320481f55030'},
    415000: {'ledger_hash': '6772a8a1c784db14c0bf111e415919c9da4e5ca142be0b9e323c82c1b13c74e0', 'txlist_hash': 'cfb81785cd48e9bM
a0e54fee4d62f49b347489da82139fd5e1555ae0bc11a33d5'},
    420000: {'ledger_hash': '42167117e16943f44bb8117aa0a39bed2d863a454cd694d0bc5006a7aab23b06', 'txlist_hash': 'a1139870bef8eb9bbe60856029a4f01fce5432eb7aeacd088ba2e033757b86e3'},
CONSENSUS_HASH_VERSION_TESTNET = 7
CHECKPOINTS_TESTNET = {
    config.BLOCK_FIRST_TESTNET: {'ledger_hash': '63f0fef31d02da85fa779e9a0e1b585b1a6a4e59e14564249e288e074e91c223', 'txlist_hash': '63f0fef31d02da85fa779e9a0e1b585b1a6a4e59e14564249e288e074e91c223'},
    316000: {'ledger_hashM
': 'f645e6877da416b8b91670ac927df686c5ea6fc1158c150ae49d594222ed504c', 'txlist_hash': '3e29bcbf3873326097024cc26e9296f0164f552dd79c2ee7cfc344e6d64fa87d'},
    319000: {'ledger_hash': '384ca28ac56976bc24a6ab7572b41bc61474e6b87fdee814135701d6a8f5c8a2', 'txlist_hash': '6c05c98418a6daa6de82dd59e000d3f3f5407c5432d4ab7d76047873a38e4d4b'},
    322000: {'ledger_hash': 'f4015c37eb4f31ac42083fd0389cde4868acb5353d3f3abfe2f3a88aba8cae72', 'txlist_hash': '18f278154e9bc3bbcc39da905ab4ad3023742ab7723b55b0fd1c58c36cd3e9bf'},
25000: {'ledger_hash': 'd7f70a927f5aeed38e559ddc0bc4697601477ea43cde928ad228fefc195b02da', 'txlist_hash': '1a60e38664b39e0f501b3e5a60c6fc0bd4ed311b74872922c2dde4cb2267fd3e'},
    329000: {'ledger_hash': '96637b4400cbe084c2c4f139f59b5bc16770815e96306423aaeb2b2677a9a657', 'txlist_hash': '79d577d8fbba0ad6ae67829dfa5824f758286ccd429d65b7d1d42989134d5b57'},
    350000: {'ledger_hash': 'cae8fec787bba3d5c968a8f4b6fb22a54c96d5acbeadd0425f6b20c3a8813ea3', 'txlist_hash': '097df9c3079df4d96f59518df72492dfd7a79716462e3a4a30d62M
    400000: {'ledger_hash': '94abfd9c00c8462c155f64011e71af141b7d524e17de5aeda26b7469fe79b5f0', 'txlist_hash': 'a9fc42b69f80ec69f3f98e8a3cd81f4f946544fd0561a62a0891254c16970a87'},
    450000: {'ledger_hash': '09eb9f2aa605ce77225362b4b556284acdd9f6d3bc273372dfae4a5be9e9b035', 'txlist_hash': '05af651c1de49d0728834991e50000fbf2286d7928961b71917f682a0f2b7171'},
    500000: {'ledger_hash': '85f3bca8c88246ddfa1a5ec327e71f0696c182ed2a5fedf3712cd2e87e2661ac', 'txlist_hash': '663b34955116a96501e0c1c27f27d24baM
d7d45995913367553c5cfe4b8b9d0a9'},
    550000: {'ledger_hash': 'c143026133af2d83bc49ef205b4623194466ca3e7c79f95da2ad565359ccb5ad', 'txlist_hash': '097b8bca7a243e0b9bdf089f34de15bd2dcd4727fb4e88aae7bfd96302250326'},
    600000: {'ledger_hash': '82caf720967d0e43a1c49a6c75f255d9056ed1bffe3f96d962478faccdaba8ff', 'txlist_hash': '0d99f42184233426d70102d5ac3c80aaecf804d441a8a0d0ef26038d333ab7a7'},
    650000: {'ledger_hash': 'bef100ae7d5027a8b3f32416c4f26e1f16b21cee2a986c57be1466a3ba338051', 'txlist_hash': '409ed86e4274bM
511193d187df92e433c734dcc890bf93496e7a7dee770e7035e'},
    700000: {'ledger_hash': 'afe5e9c3f3a8c6f19c4f9feaf09df051c28202c6bae64f3563a09ffea9e79a6e', 'txlist_hash': '4f9765158855d24950c7e076615b0ad5b72738d4d579decfd3b93c998edf4fcb'},
    750000: {'ledger_hash': 'e7c7969a6156facb193b77ef71b5e3fac49c6998e5a94ec3b90292be10ece9cc', 'txlist_hash': '6e511790656d3ffec0c912d697e5d1c2a4e401a1606203c77ab5a5855891bc2c'},
    800000: {'ledger_hash': '42a7c679e51e5e8d38df26b67673b4850e8e6f72723aa19673b3219fcc02b77b', 'txlist_hM
ash': '885ae1e6c21f5fb3645231aaa6bb6910fc21a0ae0ca5dbe9a4011f3b5295b3e7'},
    850000: {'ledger_hash': '35b2a2ab4a8bfbc321d4545292887b4ccaea73415c7674f795aefa6e240890eb', 'txlist_hash': '72d5cfe1e729a22da9eacd4d7752c881c43a191904556b65a0fae82b770dcdf3'},
    900000: {'ledger_hash': 'a5552b4998d2e5a516b9310d6592e7368771c1ad3b6e6330f6bc0baa3db31643', 'txlist_hash': '5a2e9fbd9b52ee32b8e8bfff993ed92dc22510aa7448277a704176cf01e55b04'},
    950000: {'ledger_hash': '5a5e78b55ac294690229abff7ff8f74f390f3a47dc4d08a0bac40e2eM
89a5bed2', 'txlist_hash': 'f4fa9838fb38d3e5beffb760fae022dcc59c61c506dd28ac83ee48ba814d04b2'},
    1000000: {'ledger_hash': 'eafca6700b9fd8f3992f8a18316e9ad59480ef74a4e7737793c101878aba8e1a', 'txlist_hash': '03deb626e031f30acd394bf49c35e11a487cb11e55dff5ba9a3f6d04b460c7de'},
    1050000: {'ledger_hash': '8012ebaf4c6638173e88ecd3e7bb2242ab88a9bdf877fc32c42dbcd7d2d3bab1', 'txlist_hash': '896274fdba957961083b07b80634126bc9f0434b67d723ed1fa83157ce5cd9a7'},
    1100000: {'ledger_hash': '76357f917235daa180c904cdf5c44366eM
ef3e33539b7b0ba6a38f89582e82d22', 'txlist_hash': '36ecfd4b07f23176cd6960bc0adef97472c13793e53ac3df0eea0dd2e718a570'},
    1150000: {'ledger_hash': '5924f004bfdc3be449401c764808ebced542d2e06ba30c5984830292d1a926aa', 'txlist_hash': '9ff139dacf4b04293074e962153b972d25fa16d862dae05f7f3acc15e83c4fe8'},
    1200000: {'ledger_hash': 'a3d009bd2e0b838c185b8866233d7b4edaff87e5ec4cc4719578d1a8f9f8fe34', 'txlist_hash': '11dcf3a0ab714f05004a4e6c77fe425eb2a6427e4c98b7032412ab29363ffbb2'},
    1250000: {'ledger_hash': '37244453b4M
eac67d1dbfc0f60116cac90dab7b814d756653ad3d9a072fbac61a', 'txlist_hash': 'c01ed3113f8fd3a6b54f5cefafd842ebf7c314ce82922e36236414d820c5277a'},
    1300000: {'ledger_hash': 'a83c1cd582604130fd46f1304560caf0f4e3300f3ce7c3a89824b8901f13027f', 'txlist_hash': '67e663b75a80940941b8370ada4985be583edaa7ba454d49db9a864a7bb7979c'},
    1350000: {'ledger_hash': 'f96e6aff578896a4568fb69f72aa0a8b52eb9ebffefca4bd7368790341cd821d', 'txlist_hash': '83e7d31217af274b13889bd8b9f8f61afcd7996c2c8913e9b53b1d575f54b7c1'},
dger_hash': '85a23f6fee9ce9c80fa335729312183ff014920bbf297095ac77c4105fb67e17', 'txlist_hash': 'eee762f34a3f82e6332c58e0c256757d97ca308719323af78bf5924f08463e12'},
CONSENSUS_HASH_VERSION_REGTEST = 1
CHECKPOINTS_REGTEST = {
    config.BLOCK_FIRST_REGTEST: {'ledger_hash': '33cf0669a0d309d7e6b1bf79494613b69262b58c0ea03c9c221d955eb4c84fe5', 'txlist_hash': '33cf0669a0d309d7e6b1bf79494613b69262b58c0ea03c9c221d955eb4c84fe5'},
class ConsensusError(Exception):
def consensus_hash(db, field, previous_consensusM
    cursor = db.cursor()
    block_index = util.CURRENT_BLOCK_INDEX
    # Initialise previous hash on first block.
    if block_index <= config.BLOCK_FIRST:
        assert not previous_consensus_hash
        previous_consensus_hash = util.dhash_string(CONSENSUS_HASH_SEED)
    # Get previous hash.
    if not previous_consensus_hash:
            previous_consensus_hash = list(cursor.execute('''SELECT * FROM blocks WHERE block_index = ?''', (block_index - 1,)))[0][field]
            previous_consensus_hash = None
        if not previous_consensus_hash:
            raise ConsensusError('Empty previous {} for block {}. Please launch a `reparse`.'.format(field, block_index))
    # Calculate current hash.
    if config.TESTNET:
        consensus_hash_version = CONSENSUS_HASH_VERSION_TESTNET
    elif config.REGTEST:
        consensus_hash_version = CONSENSUS_HASH_VERSION_REGTEST
        consensus_hash_version = CONSENSUS_HASH_VERSION_MAINNET
    calculated_hash =M
 util.dhash_string(previous_consensus_hash + '{}{}'.format(consensus_hash_version, ''.join(content)))
    # Verify hash (if already in database) or save hash (if not).
    # NOTE: do not enforce this for messages_hashes, those are more informational (for now at least)
    found_hash = list(cursor.execute('''SELECT * FROM blocks WHERE block_index = ?''', (block_index,)))[0][field] or None
    if found_hash and field != 'messages_hash':
        # Check against existing value.
        if calculated_hash != found_hashM
            raise ConsensusError('Inconsistent {} for block {} (calculated {}, vs {} in database).'.format(
                field, block_index, calculated_hash, found_hash))
        # Save new hash.
        cursor.execute('''UPDATE blocks SET {} = ? WHERE block_index = ?'''.format(field), (calculated_hash, block_index))
    # Check against checkpoints.
    if config.TESTNET:
        checkpoints = CHECKPOINTS_TESTNET
    elif config.REGTEST:
        checkpoints = CHECKPOINTS_REGTEST
eckpoints = CHECKPOINTS_MAINNET
    if field != 'messages_hash' and block_index in checkpoints and checkpoints[block_index][field] != calculated_hash:
        raise ConsensusError('Incorrect {} hash for block {}.  Calculated {} but expected {}'.format(field, block_index, calculated_hash, checkpoints[block_index][field],))
    return calculated_hash, found_hash
class SanityError(Exception):
def asset_conservation(db):
    logger.debug('Checking for conservation of assets.')
    supplies = util.supplies(M
    held = util.held(db)
    for asset in supplies.keys():
        asset_issued = supplies[asset]
        asset_held = held[asset] if asset in held and held[asset] != None else 0
        if asset_issued != asset_held:
            raise SanityError('{} {} issued
 {} {} held'.format(util.value_out(db, asset_issued, asset), asset, util.value_out(db, asset_held, asset), asset))
        logger.debug('{} has been conserved ({} {} both issued and held)'.format(asset, util.value_out(db, asset_issued, asset), asset))M
class VersionError(Exception):
class VersionUpdateRequiredError(VersionError):
def check_change(protocol_change, change_name):
    # Check client version.
    if config.VERSION_MAJOR < protocol_change['minimum_version_major']:
        passed = False
    elif config.VERSION_MAJOR == protocol_change['minimum_version_major']:
        if config.VERSION_MINOR < protocol_change['minimum_version_minor']:
            passed = False
        elif config.VERSION_MINOR == protocol_changeM
['minimum_version_minor']:
            if config.VERSION_REVISION < protocol_change['minimum_version_revision']:
                passed = False
        explanation = 'Your version of {} is v{}, but, as of block {}, the minimum version is v{}.{}.{}. Reason:
. Please upgrade to the latest version and restart the server.'.format(
            config.APP_NAME, config.VERSION_STRING, protocol_change['block_index'], protocol_change['minimum_version_major'], protocol_change['minimum_version_minoM
            protocol_change['minimum_version_revision'], change_name)
        if util.CURRENT_BLOCK_INDEX >= protocol_change['block_index']:
            raise VersionUpdateRequiredError(explanation)
            warnings.warn(explanation)
def software_version():
    if config.FORCE:
    logger.debug('Checking version.')
        host = 'https://counterpartyxcp.github.io/counterparty-lib/counterpartylib/protocol_changes.json'
        response = requests.get(host, headers={'M
cache-control': 'no-cache'})
        versions = json.loads(response.text)
    except (requests.exceptions.ConnectionError, ConnectionRefusedError, ValueError) as e:
        logger.warning('Unable to check version! ' + str(sys.exc_info()[1]))
    for change_name in versions:
        protocol_change = versions[change_name]
            check_change(protocol_change, change_name)
        except VersionUpdateRequiredError as e:
            logger.error("Version Update Required", exc_info=sys.M
            sys.exit(config.EXITCODE_UPDATE_REQUIRED)
    logger.debug('Version check passed.')
class DatabaseVersionError(Exception):
    def __init__(self, message, reparse_block_index):
        super(DatabaseVersionError, self).__init__(message)
        self.reparse_block_index = reparse_block_index
def database_version(db):
    if config.FORCE:
    logger.debug('Checking database version.')
    version_major, version_minor = database.version(db)
    if version_major != config.VERM
        # Rollback database if major version has changed.
        raise DatabaseVersionError('Client major version number mismatch ({}
 {}).'.format(version_major, config.VERSION_MAJOR), config.BLOCK_FIRST)
    elif version_minor != config.VERSION_MINOR:
        # Reparse all transactions if minor version has changed.
        raise DatabaseVersionError('Client minor version number mismatch ({}
 {}).'.format(version_minor, config.VERSION_MINOR), None)
# vim: tabstop=8 expandtab shiftwidth=4 softtaM
"""Variables prefixed with `DEFAULT` should be able to be overridden by
configuration file and command
UNIT = 100000000        # The same across assets.
VERSION_REVISION = 1
VERSION_STRING = str(VERSION_MAJOR) + '.' + str(VERSION_MINOR) + '.' + str(VERSION_REVISION)
# Counterparty protocol
TXTYPE_FORMAT = '>I'
SHORT_TXTYPE_FORMAT = 'B'
TWO_WEEKS = 2 * 7 * 24 * 3600
MAX_EXPIRATION = 4 * 2016   # TM
MEMPOOL_BLOCK_HASH = 'mempool'
MEMPOOL_BLOCK_INDEX = 9999999
OP_RETURN_MAX_SIZE = 80  # bytes
# Currency agnosticism
BTC_NAME = 'Bitcoin'
XCP_NAME = 'Counterparty'
APP_NAME = XCP_NAME.lower()
DEFAULT_RPC_PORT_REGTEST = 24000
DEFAULT_RPC_PORT_TESTNET = 14000
DEFAULT_RPC_PORT = 4000
DEFAULT_BACKEND_PORT_REGTEST = 28332
DEFAULT_BACKEND_PORT_TESTNET = 18332
DEFAULT_BACKEND_PORT = 8332
DEFAULT_INDEXD_PORT_REGTEST = 28432
DEXD_PORT_TESTNET = 18432
DEFAULT_INDEXD_PORT = 8432
UNSPENDABLE_REGTEST = 'mvCounterpartyXXXXXXXXXXXXXXW24Hef'
UNSPENDABLE_TESTNET = 'mvCounterpartyXXXXXXXXXXXXXXW24Hef'
UNSPENDABLE_MAINNET = '1CounterpartyXXXXXXXXXXXXXXXUWLpVr'
ADDRESSVERSION_TESTNET = b'\x6f'
P2SH_ADDRESSVERSION_TESTNET = b'\xc4'
PRIVATEKEY_VERSION_TESTNET = b'\xef'
ADDRESSVERSION_MAINNET = b'\x00'
P2SH_ADDRESSVERSION_MAINNET = b'\x05'
PRIVATEKEY_VERSION_MAINNET = b'\x80'
ADDRESSVERSION_REGTEST = b'\x6f'
P2SH_ADDRESSVERSION_REGTEST = b'\xc4'
RIVATEKEY_VERSION_REGTEST = b'\xef'
MAGIC_BYTES_TESTNET = b'\xfa\xbf\xb5\xda'   # For bip-0010
MAGIC_BYTES_MAINNET = b'\xf9\xbe\xb4\xd9'   # For bip-0010
MAGIC_BYTES_REGTEST = b'\xda\xb5\xbf\xfa'
BLOCK_FIRST_TESTNET_TESTCOIN = 310000
BURN_START_TESTNET_TESTCOIN = 310000
BURN_END_TESTNET_TESTCOIN = 4017708     # Fifty years, at ten minutes per block.
BLOCK_FIRST_TESTNET = 310000
BLOCK_FIRST_TESTNET_HASH = '000000001f605ec6ee8d2c0d21bf3d3ded0a31ca837acc98893876213828989d'
BURN_START_TESTNET = 310000
T = 4017708              # Fifty years, at ten minutes per block.
BLOCK_FIRST_MAINNET_TESTCOIN = 278270
BURN_START_MAINNET_TESTCOIN = 278310
BURN_END_MAINNET_TESTCOIN = 2500000     # A long time.
BLOCK_FIRST_MAINNET = 278270
BLOCK_FIRST_MAINNET_HASH = '00000000000000017bac9a8e85660ad348050c789922d5f8fe544d473368be1a'
BURN_START_MAINNET = 278310
BURN_END_MAINNET = 283810
BLOCK_FIRST_REGTEST = 0
BLOCK_FIRST_REGTEST_HASH = '0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206'
BURN_START_REGTEST = 101
URN_END_REGTEST = 150000000
BLOCK_FIRST_REGTEST_TESTCOIN = 0
BURN_START_REGTEST_TESTCOIN = 101
BURN_END_REGTEST_TESTCOIN = 150
# NOTE: If the DUST_SIZE constants are changed, they MUST also be changed in counterblockd/lib/config.py as well
DEFAULT_REGULAR_DUST_SIZE = 546          # TODO: Revisit when dust size is adjusted in bitcoin core
DEFAULT_MULTISIG_DUST_SIZE = 7800        # <https://bitcointalk.org/index.php?topic=528023.msg7469941#msg7469941>
DEFAULT_OP_RETURN_VALUE = 0
KB_ESTIMATE_SMART = 1024
DEFAULT_FEE_PER_KB = 25000               # sane/low default, also used as minimum when estimated fee is used
ESTIMATE_FEE_PER_KB = True               # when True will use `estimatesmartfee` from bitcoind instead of DEFAULT_FEE_PER_KB
ESTIMATE_FEE_CONF_TARGET = 3
ESTIMATE_FEE_MODE = 'CONSERVATIVE'
DEFAULT_FEE_FRACTION_REQUIRED = .009   # 0.90%
DEFAULT_FEE_FRACTION_PROVIDED = .01    # 1.00%
DEFAULT_REQUESTS_TIMEOUT = 20   # 20 seconds
DEFAULT_RPC_BATCH_SIZE = 20     # A 1 MB M
block can hold about 4200 transactions.
EXITCODE_UPDATE_REQUIRED = 5
DEFAULT_CHECK_ASSET_CONSERVATION = True
BACKEND_RAW_TRANSACTIONS_CACHE_SIZE = 20000
BACKEND_RPC_BATCH_NUM_WORKERS = 6
UNDOLOG_MAX_PAST_BLOCKS = 100 #the number of past blocks that we store undolog history
DEFAULT_UTXO_LOCKS_MAX_ADDRESSES = 1000
DEFAULT_UTXO_LOCKS_MAX_AGE = 3.0 #in seconds
ADDRESS_OPTION_REQUIRE_MEMO = 1
ADDRESS_OPTION_MAX_VALUE = ADDRESS_OPTION_REQUIRE_MEMO # Or list of all the address options
API_LIMIT_ROWS = 1000
MEMPOOL_TXCOUNT_UPDATE_LIMIT=60000
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
logger = logging.getLogger(__name__)
from counterpartylib.lib import config
from counterpartylib.lib import util
from counterpartylib.lib import exceptions
from counterpartylib.lib import log
def rowtracer(cursor, sql):
    """Converts fetched SQL data intM
    for index, (name, type_) in enumerate(cursor.getdescription()):
        dictionary[name] = sql[index]
    return dictionary
def exectracer(cursor, sql, bindings):
    # This means that all changes to database must use a very simple syntax.
    # TODO: Need sanity checks here.
    sql = sql.lower()
    if sql.startswith('create trigger') or sql.startswith('drop trigger'):
        #CREATE TRIGGER stmts may include an "insert" or "update" as part of them
    array = sql.split('(')[0].split(' ')
    command = array[0]
    if 'insert' in sql:
        category = array[2]
    elif 'update' in sql:
        category = array[1]
        #CREATE TABLE, etc
    db = cursor.getconnection()
    dictionary = {'command': command, 'category': category, 'bindings': bindings}
        'blocks', 'transactions',
        'balances', 'messages', 'mempool', 'assets',
        'new_sends', 'new_issuances' # interim table fM
    skip_tables_block_messages = copy.copy(skip_tables)
    if command == 'update':
        # List message manually.
        skip_tables += ['orders', 'bets', 'rps', 'order_matches', 'bet_matches', 'rps_matches']
    # Record alteration in database.
    if category not in skip_tables:
        log.message(db, bindings['block_index'], command, category, bindings)
    # Record alteration in computation of message feed hash for the block
    if category not in skip_tables_block_messages:
    # don't include asset_longname as part of the messages hash
        #   until subassets are enabled
        if category == 'issuances' and not util.enabled('subassets'):
            if isinstance(bindings, dict) and 'asset_longname' in bindings: del bindings['asset_longname']
        # don't include memo as part of the messages hash
        #   until enhanced_sends are enabled
        if category == 'sends' and not util.enabled('enhanced_sends'):
            if isinstance(bindings, dict) and 'memo' in bindingsM
: del bindings['memo']
        sorted_bindings = sorted(bindings.items()) if isinstance(bindings, dict) else [bindings,]
        BLOCK_MESSAGES.append('{}{}{}'.format(command, category, sorted_bindings))
class DatabaseIntegrityError(exceptions.DatabaseError):
def get_connection(read_only=True, foreign_keys=True, integrity_check=True):
    """Connects to the SQLite database, returning a db `Connection` object"""
    logger.debug('Creating connection to `{}`.'.format(config.DATABASE))
        db = apsw.Connection(config.DATABASE, flags=apsw.SQLITE_OPEN_READONLY)
        db = apsw.Connection(config.DATABASE)
    cursor = db.cursor()
    # For integrity, security.
    if foreign_keys and not read_only:
        logger.info('Checking database foreign keys...')
        cursor.execute('''PRAGMA foreign_keys = ON''')
        cursor.execute('''PRAGMA defer_foreign_keys = ON''')
        rows = list(cursor.execute('''PRAGMA foreign_key_check'''))
                logger.debug('Foreign Key Error: {}'.format(row))
            raise exceptions.DatabaseError('Foreign key check failed.')
        # So that writers don
        cursor.execute('''PRAGMA journal_mode = WAL''')
        logger.info('Foreign key check completed.')
    # Make case sensitive the `LIKE` operator.
    # For insensitive queries use 'UPPER(fieldname) LIKE value.upper()''
    cursor.execute('''PRAGMA case_sensitive_like = ON''')
    if integrity_check:
 logger.info('Checking database integrity...')
        integral = False
        for i in range(10): # DUPE
                cursor.execute('''PRAGMA integrity_check''')
                rows = cursor.fetchall()
                if not (len(rows) == 1 and rows[0][0] == 'ok'):
                    raise exceptions.DatabaseError('Integrity check failed.')
                integral = True
                break
            except DatabaseIntegrityError:
                time.sleep(1)
                continue
        if not integral:
            raise exceptions.DatabaseError('Could not perform integrity check.')
        logger.info('Integrity check completed.')
    db.setrowtrace(rowtracer)
    db.setexectrace(exectracer)
    cursor = db.cursor()
    user_version = cursor.execute('PRAGMA user_version').fetchall()[0]['user_version']
    # manage old user_version
    if user_version == config.VERSION_MINOR:
        version_minor = user_version
        version_major = cM
        user_version = (config.VERSION_MAJOR * 1000) + version_minor
        cursor.execute('PRAGMA user_version = {}'.format(user_version))
        version_minor = user_version % 1000
        version_major = user_version // 1000
    return version_major, version_minor
def update_version(db):
    cursor = db.cursor()
    user_version = (config.VERSION_MAJOR * 1000) + config.VERSION_MINOR
    cursor.execute('PRAGMA user_version = {}'.format(user_version)) # Syntax?!
    logger.info('DaM
tabase version number updated.')
    logger.info('Starting database VACUUM. This may take awhile...')
    cursor = db.cursor()
    cursor.execute('VACUUM')
    logger.info('Database VACUUM completed.')
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
class DatabaseError(Exception):
class TransactionError(Exception):
class ParseTransactionError(Exception):
class AssetError (Exception):
class AssetIDError(AssetError):
class MessageError(Exception):
class ComposeError(MessageError):
class UnpackError(MessageError):
class ValidateError(MessageError):
class DecodeError(MessageError):
class PushDataDecodeError(DecodeError):
class BTCOnlyError(MessageError):
    def __init__(self, msg, decodedTx=None):
        super(BTCOnlyError, self).__init__(msg)
        self.decodedTx = decodedTx
class BalanceError(ExceM
class EncodingError(Exception):
class OptionsError(Exception):
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
logger = logging.getLogger(__name__)
from datetime import datetime
from dateutil.tz import tzlocal
from colorlog import ColoredFormatter
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
m counterpartylib.lib import util
class ModuleLoggingFilter(logging.Filter):
    module level logging filter (NodeJS-style), ie:
        filters="*,-counterpartylib.lib,counterpartylib.lib.api"
         - counterpartycli.server
         - counterpartylib.lib.api
        but will not log:
         - counterpartylib.lib
         - counterpartylib.lib.backend.indexd
    def __init__(self, filters):
        self.filters = str(filters).split(",")
        self.catchall = "*" in selfM
        if self.catchall:
            self.filters.remove("*")
    def filter(self, record):
        Determine if specified record should be logged or not
        result = None
        for filter in self.filters:
            if filter[:1] == "-":
                if result is None and ModuleLoggingFilter.ismatch(record, filter[1:]):
                    result = False
                if ModuleLoggingFilter.ismatch(record, filter):
                    result = True
        if result is None:
            return self.catchall
        return result
    def ismatch(cls, record, name):
        Determine if the specified record matches the name, in the same way as original logging.Filter does, ie:
            'counterpartylib.lib' will match 'counterpartylib.lib.check'
        nlen = len(name)
        if nlen == 0:
            return True
        elif name == record.name:
            return True
        elif record.name.find(name, 0, nlenM
            return False
        return record.name[nlen] == "."
def set_logger(logger):
    global ROOT_LOGGER
    if ROOT_LOGGER is None:
        ROOT_LOGGER = logger
LOGGING_SETUP = False
LOGGING_TOFILE_SETUP = False
def set_up(logger, verbose=False, logfile=None, console_logfilter=None):
    global LOGGING_SETUP
    global LOGGING_TOFILE_SETUP
    def set_up_file_logging():
        assert logfile
        max_log_size = 20 * 1024 * 1024 # 20 MB
        if os.name == 'nt':
    from counterpartylib.lib import util_windows
            fileh = util_windows.SanitizedRotatingFileHandler(logfile, maxBytes=max_log_size, backupCount=5)
            fileh = logging.handlers.RotatingFileHandler(logfile, maxBytes=max_log_size, backupCount=5)
        fileh.setLevel(logging.DEBUG)
        LOGFORMAT = '%(asctime)s [%(levelname)s] %(message)s'
        formatter = logging.Formatter(LOGFORMAT, '%Y-%m-%d-T%H:%M:%S%z')
        fileh.setFormatter(formatter)
        logger.addHandler(fileh)
    if LOGGING_SETUP:
        if logfile and not LOGGING_TOFILE_SETUP:
             set_up_file_logging()
             LOGGING_TOFILE_SETUP = True
        logger.getChild('log.set_up').debug('logging already setup')
    LOGGING_SETUP = True
    log_level = logging.DEBUG if verbose else logging.INFO
    logger.setLevel(log_level)
    # Console Logging
    console = logging.StreamHandler()
    console.setLevel(log_level)
    # only add [%(name)s] to LOGFORMAT if we're using console_logfilter
GFORMAT = '%(log_color)s[%(asctime)s][%(levelname)s]' + ('' if console_logfilter is None else '[%(name)s]') + ' %(message)s%(reset)s'
    LOGCOLORS = {'WARNING': 'yellow', 'ERROR': 'red', 'CRITICAL': 'red'}
    formatter = ColoredFormatter(LOGFORMAT, "%Y-%m-%d %H:%M:%S", log_colors=LOGCOLORS)
    console.setFormatter(formatter)
    logger.addHandler(console)
    if console_logfilter:
        console.addFilter(ModuleLoggingFilter(console_logfilter))
        set_up_file_logging()
        LOGGING_TOFILE_SETUP = True
    # Quieten noisy libraries.
    requests_log = logging.getLogger("requests")
    requests_log.setLevel(log_level)
    requests_log.propagate = False
    urllib3_log = logging.getLogger('urllib3')
    urllib3_log.setLevel(log_level)
    urllib3_log.propagate = False
    # Disable InsecureRequestWarning
    requests.packages.urllib3.disable_warnings()
    return int(time.time())
def isodt (epoch_time):
        return datetime.froM
mtimestamp(epoch_time, tzlocal()).isoformat()
        return '<datetime>'
def message(db, block_index, command, category, bindings, tx_hash=None):
    cursor = db.cursor()
    # Get last message index.
    messages = list(cursor.execute('''SELECT * FROM messages
                                      WHERE message_index = (SELECT MAX(message_index) from messages)'''))
        assert len(messages) == 1
        message_index = messages[0]['message_index'] + 1
    # Not to be misleading
    if block_index == config.MEMPOOL_BLOCK_INDEX:
            del bindings['status']
            del bindings['block_index']
            del bindings['tx_index']
        except KeyError:
    # Handle binary data.
    for item in sorted(bindings.items()):
        if type(item[1]) == bytes:
            items.append((item[0], binascii.hexlify(item[1]).decode('ascii')))
            items.append(item)
_string = json.dumps(collections.OrderedDict(items))
    cursor.execute('insert into messages values(:message_index, :block_index, :command, :category, :bindings, :timestamp)',
                   (message_index, block_index, command, category, bindings_string, curr_time()))
    # Log only real transactions.
    if block_index != config.MEMPOOL_BLOCK_INDEX:
        log(db, command, category, bindings)
def log (db, command, category, bindings):
    cursor = db.cursor()
    for element in bindM
            str(bindings[element])
        except KeyError:
            bindings[element] = '<Error>'
    def output (quantity, asset):
            if asset not in ('fraction', 'leverage'):
                return str(util.value_out(db, quantity, asset)) + ' ' + asset
                return str(util.value_out(db, quantity, asset))
        except exceptions.AssetError:
            return '<AssetError>'
        except decimal.DivisionByZero:
      return '<DivisionByZero>'
        except TypeError:
            return '<None>'
    if command == 'update':
        if category == 'order':
            logger.debug('Database: set status of order {} to {}.'.format(bindings['tx_hash'], bindings['status']))
        elif category == 'bet':
            logger.debug('Database: set status of bet {} to {}.'.format(bindings['tx_hash'], bindings['status']))
        elif category == 'order_matches':
            logger.debug('Database: set status of order_match {} to {M
}.'.format(bindings['order_match_id'], bindings['status']))
        elif category == 'bet_matches':
            logger.debug('Database: set status of bet_match {} to {}.'.format(bindings['bet_match_id'], bindings['status']))
        elif category == 'dispensers':
            escrow_quantity = ''
            divisible = get_asset_info(cursor, bindings['asset'])['divisible']
            if divisible:
                if "escrow_quantity" in bindings:
                    escrow_quantity = "{:.8f}".format(bM
indings["escrow_quantity"]/config.UNIT)
            if ("action" in bindings) and bindings["action"] == 'refill dispenser':
                logger.info("Dispenser: {} refilled a dispenser with {} {}".format(bindings["source"],escrow_quantity,bindings["asset"]))
            elif "prev_status" in bindings: #There was a dispense
                if bindings["prev_status"] == 0:
                    if bindings["status"] == 10:
                        logger.info("Dispenser: {} closed dispenser M
for {} (dispenser empty)".format(bindings["source"],bindings["asset"]))
            elif bindings["status"] == 10: #Address closed the dispenser
                logger.info("Dispenser: {} closed dispenser for {} (operator closed)".format(bindings["source"],bindings["asset"]))
        # TODO: elif category == 'balances':
            # logger.debug('Database: set balance of {} in {} to {}.'.format(bindings['address'], bindings['asset'], output(bindings['quantity'], bindings['asset']).split(' ')[0]))
        if category == 'credits':
            logger.debug('Credit: {} to {} #{}# <{}>'.format(output(bindings['quantity'], bindings['asset']), bindings['address'], bindings['action'], bindings['event']))
        elif category == 'debits':
            logger.debug('Debit: {} from {} #{}# <{}>'.format(output(bindings['quantity'], bindings['asset']), bindings['address'], bindings['action'], bindings['event']))
        elif category == 'sends':
            logger.info('Send: {} from {} to {} ({}) [{}]M
'.format(output(bindings['quantity'], bindings['asset']), bindings['source'], bindings['destination'], bindings['tx_hash'], bindings['status']))
        elif category == 'orders':
            logger.info('Order: {} ordered {} for {} in {} blocks, with a provided fee of {:.8f} {} and a required fee of {:.8f} {} ({}) [{}]'.format(bindings['source'], output(bindings['give_quantity'], bindings['give_asset']), output(bindings['get_quantity'], bindings['get_asset']), bindings['expiration'], bindings['fee_provided'] / coM
nfig.UNIT, config.BTC, bindings['fee_required'] / config.UNIT, config.BTC, bindings['tx_hash'], bindings['status']))
        elif category == 'order_matches':
            logger.info('Order Match: {} for {} ({}) [{}]'.format(output(bindings['forward_quantity'], bindings['forward_asset']), output(bindings['backward_quantity'], bindings['backward_asset']), bindings['id'], bindings['status']))
        elif category == 'btcpays':
            logger.info('{} Payment: {} paid {} to {} for order match {} ({}) [{}]'.formM
at(config.BTC, bindings['source'], output(bindings['btc_amount'], config.BTC), bindings['destination'], bindings['order_match_id'], bindings['tx_hash'], bindings['status']))
        elif category == 'issuances':
            if (get_asset_issuances_quantity(cursor, bindings["asset"]) == 0) or (bindings['quantity'] > 0): #This is the first issuance or the creation of more supply, so we have to log the creation of the token
                if bindings['divisible']:
                    divisibility = 'divisible'
               unit = config.UNIT
                else:
                    divisibility = 'indivisible'
                    unit = 1
                try:
                    quantity = util.value_out(cursor, bindings['quantity'], None, divisible=bindings['divisible'])
                except Exception as e:
                    quantity = '?'
                if 'asset_longname' in bindings and bindings['asset_longname'] is not None:
                    logger.info('Subasset Issuance: {} created {} of {}M
 subasset {} as numeric asset {} ({}) [{}]'.format(bindings['source'], quantity, divisibility, bindings['asset_longname'], bindings['asset'], bindings['tx_hash'], bindings['status']))
                else:
                    logger.info('Issuance: {} created {} of {} asset {} ({}) [{}]'.format(bindings['source'], quantity, divisibility, bindings['asset'], bindings['tx_hash'], bindings['status']))
            if bindings['locked']:
                lock_issuance = get_lock_issuance(cursor, bindings["assM
                if (lock_issuance == None) or (lock_issuance['tx_hash'] == bindings['tx_hash']):
                    logger.info('Issuance: {} locked asset {} ({}) [{}]'.format(bindings['source'], bindings['asset'], bindings['tx_hash'], bindings['status']))
            if bindings['transfer']:
                logger.info('Issuance: {} transfered asset {} to {} ({}) [{}]'.format(bindings['source'], bindings['asset'], bindings['issuer'], bindings['tx_hash'], bindings['status']))
        elif category == 'broadcasts':
            if bindings['locked']:
                logger.info('Broadcast: {} locked his feed ({}) [{}]'.format(bindings['source'], bindings['tx_hash'], bindings['status']))
                logger.info('Broadcast: ' + bindings['source'] + ' at ' + isodt(bindings['timestamp']) + ' with a fee of {}%'.format(output(D(bindings['fee_fraction_int'] / 1e8), 'fraction')) + ' (' + bindings['tx_hash'] + ')' + ' [{}]'.format(bindings['status']))
 category == 'bets':
            logger.info('Bet: {} against {}, by {}, on {}'.format(output(bindings['wager_quantity'], config.XCP), output(bindings['counterwager_quantity'], config.XCP), bindings['source'], bindings['feed_address']))
        elif category == 'bet_matches':
            placeholder = ''
            if bindings['target_value'] >= 0:    # Only non
negative values are valid.
                placeholder = ' that ' + str(output(bindings['target_value'], 'value'))
            if bindings['leverage']:M
                placeholder += ', leveraged {}x'.format(output(bindings['leverage'] / 5040, 'leverage'))
            logger.info('Bet Match: {} for {} against {} for {} on {} at {}{} ({}) [{}]'.format(util.BET_TYPE_NAME[bindings['tx0_bet_type']], output(bindings['forward_quantity'], config.XCP), util.BET_TYPE_NAME[bindings['tx1_bet_type']], output(bindings['backward_quantity'], config.XCP), bindings['feed_address'], isodt(bindings['deadline']), placeholder, bindings['id'], bindings['status']))
        elif categoM
            logger.info('Dividend: {} paid {} per unit of {} ({}) [{}]'.format(bindings['source'], output(bindings['quantity_per_unit'], bindings['dividend_asset']), bindings['asset'], bindings['tx_hash'], bindings['status']))
        elif category == 'burns':
            logger.info('Burn: {} burned {} for {} ({}) [{}]'.format(bindings['source'], output(bindings['burned'], config.BTC), output(bindings['earned'], config.XCP), bindings['tx_hash'], bindings['status']))
        elif category == 'cM
            logger.info('Cancel: {} ({}) [{}]'.format(bindings['offer_hash'], bindings['tx_hash'], bindings['status']))
        elif category == 'rps':
            log_message = 'RPS: {} opens game with {} possible moves and a wager of {}'.format(bindings['source'], bindings['possible_moves'], output(bindings['wager'], 'XCP'))
            logger.info(log_message)
        elif category == 'rps_matches':
            log_message = 'RPS Match: {} is playing a {}-moves game with {} with a wager of {} ({}) [{}M
]'.format(bindings['tx0_address'], bindings['possible_moves'], bindings['tx1_address'], output(bindings['wager'], 'XCP'), bindings['id'], bindings['status'])
            logger.info(log_message)
        elif category == 'rpsresolves':
            if bindings['status'] == 'valid':
                rps_matches = list(cursor.execute('''SELECT * FROM rps_matches WHERE id = ?''', (bindings['rps_match_id'],)))
                assert len(rps_matches) == 1
                rps_match = rps_matches[0]
                log_mesM
sage = 'RPS Resolved: {} is playing {} on a {}-moves game with {} with a wager of {} ({}) [{}]'.format(rps_match['tx0_address'], bindings['move'], rps_match['possible_moves'], rps_match['tx1_address'], output(rps_match['wager'], 'XCP'), rps_match['id'], rps_match['status'])
                log_message = 'RPS Resolved: {} [{}]'.format(bindings['tx_hash'], bindings['status'])
            logger.info(log_message)
        elif category == 'order_expirations':
            logger.info('Expired order: {M
}'.format(bindings['order_hash']))
        elif category == 'order_match_expirations':
            logger.info('Expired Order Match awaiting payment: {}'.format(bindings['order_match_id']))
        elif category == 'bet_expirations':
            logger.info('Expired bet: {}'.format(bindings['bet_hash']))
        elif category == 'bet_match_expirations':
            logger.info('Expired Bet Match: {}'.format(bindings['bet_match_id']))
        elif category == 'bet_match_resolutions':
   cfd_type_id = util.BET_TYPE_ID['BullCFD'] + util.BET_TYPE_ID['BearCFD']
            equal_type_id = util.BET_TYPE_ID['Equal'] + util.BET_TYPE_ID['NotEqual']
            if bindings['bet_match_type_id'] == cfd_type_id:
                if bindings['settled']:
                    logger.info('Bet Match Settled: {} credited to the bull, {} credited to the bear, and {} credited to the feed address ({})'.format(output(bindings['bull_credit'], config.XCP), output(bindings['bear_credit'], config.XCP), output(bindings['M
fee'], config.XCP), bindings['bet_match_id']))
                else:
                    logger.info('Bet Match Force
Liquidated: {} credited to the bull, {} credited to the bear, and {} credited to the feed address ({})'.format(output(bindings['bull_credit'], config.XCP), output(bindings['bear_credit'], config.XCP), output(bindings['fee'], config.XCP), bindings['bet_match_id']))
            elif bindings['bet_match_type_id'] == equal_type_id:
                logger.info('Bet Match Settled: {} won the pot of {};M
 {} credited to the feed address ({})'.format(bindings['winner'], output(bindings['escrow_less_fee'], config.XCP), output(bindings['fee'], config.XCP), bindings['bet_match_id']))
        elif category == 'rps_expirations':
            logger.info('Expired RPS: {}'.format(bindings['rps_hash']))
        elif category == 'rps_match_expirations':
            logger.info('Expired RPS Match: {}'.format(bindings['rps_match_id']))
        elif category == 'destructions':
            asset_info = get_asset_info(cursor, bM
            quantity = bindings['quantity']
            if asset_info['divisible']:
                quantity = "{:.8f}".format(quantity/config.UNIT)
            logger.info('Destruction: {} destroyed {} {} with tag
({}) [{}]'.format(bindings['source'], quantity, bindings['asset'], bindings['tag'], bindings['tx_hash'], bindings['status']))
        elif category == 'dispensers':
            each_price = bindings['satoshirate']
            currency = config.BTC
            dispenser_label =M
            escrow_quantity = bindings['escrow_quantity']
            give_quantity = bindings['give_quantity']
            if (bindings['oracle_address'] != None) and util.enabled('oracle_dispensers'):
                each_price = "{:.2f}".format(each_price/100.0)
                oracle_last_price, oracle_fee, currency, oracle_last_updated = util.get_oracle_last_price(db, bindings['oracle_address'], bindings['block_index'])
                dispenser_label = 'oracle dispenser using {}'.forM
mat(bindings['oracle_address'])
                each_price = "{:.8f}".format(each_price/config.UNIT)
            divisible = get_asset_info(cursor, bindings['asset'])['divisible']
            if divisible:
                escrow_quantity = "{:.8f}".format(escrow_quantity/config.UNIT)
                give_quantity = "{:.8f}".format(give_quantity/config.UNIT)
            if bindings['status'] == 0:
                logger.info('Dispenser: {} opened a {} for aM
sset {} with {} balance, giving {} {} for each {} {}'.format(bindings['source'], dispenser_label, bindings['asset'], escrow_quantity, give_quantity, bindings['asset'], each_price, currency))
            elif bindings['status'] == 1:
                logger.info('Dispenser: {} (empty address) opened a {} for asset {} with {} balance, giving {} {} for each {} {}'.format(bindings['source'], dispenser_label, bindings['asset'], escrow_quantity, give_quantity, bindings['asset'], each_price, currency))
            elif binM
dings['status'] == 10:
                logger.info('Dispenser: {} closed a {} for asset {}'.format(bindings['source'], dispenser_label, bindings['asset']))
        elif category == 'dispenses':
            cursor.execute('SELECT * FROM dispensers WHERE tx_hash=:tx_hash', {
                'tx_hash': bindings['dispenser_tx_hash']
            dispensers = cursor.fetchall()
            dispenser = dispensers[0]
            if (dispenser["oracle_address"] != None) and util.enabled('oracle_dispeM
                tx_btc_amount = get_tx_info(cursor, bindings['tx_hash'])/config.UNIT
                oracle_last_price, oracle_fee, oracle_fiat_label, oracle_last_price_updated = util.get_oracle_last_price(db, dispenser["oracle_address"], bindings['block_index'])
                fiatpaid = round(tx_btc_amount*oracle_last_price,2)
                logger.info('Dispense: {} from {} to {} for {:.8f} {} ({} {}) ({})'.format(output(bindings['dispense_quantity'], bindings['asset']), bindings['souM
rce'], bindings['destination'], tx_btc_amount, config.BTC, fiatpaid, oracle_fiat_label, bindings['tx_hash']))
                logger.info('Dispense: {} from {} to {} ({})'.format(output(bindings['dispense_quantity'], bindings['asset']), bindings['source'], bindings['destination'], bindings['tx_hash']))
def get_lock_issuance(cursor, asset):
    cursor.execute('''SELECT * FROM issuances \
        WHERE (status = ? AND asset = ? AND locked = ?)
        ORDER BY tx_index ASC''', (M
'valid', asset, True))
    issuances = cursor.fetchall()
    if len(issuances) > 0:
        return issuances[0]
def get_asset_issuances_quantity(cursor, asset):
    cursor.execute('''SELECT COUNT(*) AS issuances_count FROM issuances \
        WHERE (status = ? AND asset = ?)
        ORDER BY tx_index DESC''', ('valid', asset))
    issuances = cursor.fetchall()
    return issuances[0]['issuances_count']
def get_asset_info(cursor, asset):
    if asset == config.BTC or asset == config.XCPM
        return {'divisible':True}
    cursor.execute('''SELECT * FROM issuances \
        WHERE (status = ? AND asset = ?)
        ORDER BY tx_index DESC''', ('valid', asset))
    issuances = cursor.fetchall()
    return issuances[0]
def get_tx_info(cursor, tx_hash):
    cursor.execute('SELECT * FROM transactions WHERE tx_hash=:tx_hash', {
        'tx_hash': tx_hash
    transactions = cursor.fetchall()
    transaction = transactions[0]
    return transaction["btc_amount"]
# vim: tabstop=8 expanM
dtab shiftwidth=4 softtabstop=4
#### message_type.py
logger = logging.getLogger(__name__)
from counterpartylib.lib import config
from counterpartylib.lib import util
def pack(message_type_id, block_index=None):
    # pack message ID into 1 byte if not zero
    if util.enabled('short_tx_type_id', block_index) and message_type_id > 0 and message_type_id < 256:
        return struct.pack(config.SHORT_TXTYPE_FORMAT, message_type_id)
    # pack into 4 bytes
truct.pack(config.TXTYPE_FORMAT, message_type_id)
# retuns both the message type id and the remainder of the message data
def unpack(packed_data, block_index=None):
    message_type_id = None
    message_remainder = None
    if len(packed_data) > 1:
        # try to read 1 byte first
        if util.enabled('short_tx_type_id', block_index):
            message_type_id = struct.unpack(config.SHORT_TXTYPE_FORMAT, packed_data[:1])[0]
            if message_type_id > 0:
                message_remainder = packed_dataM
                return (message_type_id, message_remainder)
    # First message byte was 0.  We will read 4 bytes
    if len(packed_data) > 4:
        message_type_id = struct.unpack(config.TXTYPE_FORMAT, packed_data[:4])[0]
        message_remainder = packed_data[4:]
    return (message_type_id, message_remainder)
None of the functions/objects in this module need be passed `db`.
Naming convention: a `pub` is either a pubkey or a pubkeyhash
from bitcoin.core.key import CPubKey
from bitcoin.bech32 import CBech32Data
from counterpartylib.lib import util
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
b58_digits = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
class InputError (Exception):
class AddressError(Exception):
class MultiSigAddressError(AddressError):
class VersionByteError (AddressError):
class Base58Error (AddressError):
class Base58ChecksumError (Base58Error):
def validate(address, allow_p2sh=True):
    """Make sure the address is valid.
    May throw `AddressError`.
    # Get array of pubkeyhashes to check.
    if is_multisig(address):
        pubkeyhashes = pubkeyhash_array(address)
        pubkeyhashes = [address]
    # Check validity by attempting to decode.
    for pubkeyhash in pubkeyhashes:
            if util.enabled('segwit_support'):
                if not is_bech32(pubkeyhasM
                    base58_check_decode(pubkeyhash, config.ADDRESSVERSION)
                base58_check_decode(pubkeyhash, config.ADDRESSVERSION)
        except VersionByteError as e:
            if not allow_p2sh:
                raise e
            base58_check_decode(pubkeyhash, config.P2SH_ADDRESSVERSION)
        except Base58Error as e:
            if not util.enabled('segwit_support') or not is_bech32(pubkeyhash):
                raise e
def base58_encode(binary):
    """Encode the adM
endian bytes to integer
    n = int('0x0' + util.hexlify(binary), 16)
    # Divide that integer into base58
        n, r = divmod(n, 58)
        res.append(b58_digits[r])
    res = ''.join(res[::-1])
def base58_check_encode(original, version):
    """Check if base58 encoding is valid."""
    b = binascii.unhexlify(bytes(original, 'utf-8'))
    binary = d + util.dhash(d)[:4]
    res = base58_encode(binary)
    # Encode leading zeros as base58 zeros
        if c == czero:
            pad += 1
    address = b58_digits[0] * pad + res
    if original != util.hexlify(base58_check_decode(address, version)):
        raise AddressError('encoded address does not decode properly')
def base58_decode(s):
    # Convert the string to an integer
        if c not in b58_digits:
 Base58Error('Not a valid Base58 character:
        digit = b58_digits.index(c)
    # Convert the integer to bytes
    res = binascii.unhexlify(h.encode('utf8'))
    # Add padding back.
    for c in s[:-1]:
        if c == b58_digits[0]:
            pad += 1
    k = b'\x00' * pad + res
def base58_check_decode_parts(s):
    """Decode from base58 and return partM
    k = base58_decode(s)
    addrbyte, data, chk0 = k[0:1], k[1:-4], k[-4:]
    return addrbyte, data, chk0
def base58_check_decode(s, version):
    """Decode from base58 and return data part."""
    addrbyte, data, chk0 = base58_check_decode_parts(s)
    if addrbyte != version:
        raise VersionByteError('incorrect version byte')
    chk1 = util.dhash(addrbyte + data)[:4]
    if chk0 != chk1:
        raise Base58ChecksumError('Checksum mismatch: 0x{}
 0x{}'.format(util.hexlify(chk0), util.hexlM
def is_multisig(address):
    """Check if the address is multi
    array = address.split('_')
    return len(array) > 1
def is_p2sh(address):
    if is_multisig(address):
        return False
        base58_check_decode(address, config.P2SH_ADDRESSVERSION)
    except (VersionByteError, Base58Error):
        return False
def is_bech32(address):
        b32data = CBech32Data(address)
def is_fully_valid(pubkey_bin):
    """Check if the public key is valid."""
    cpubkey = CPubKey(pubkey_bin)
    return cpubkey.is_fullyvalid
def make_canonical(address):
    """Return canonical version of the address."""
    if is_multisig(address):
        signatures_required, pubkeyhashes, signatures_possible = extract_array(address)
            [base58_check_decode(pubkeyhash, config.ADDRESSVERSION) for pubkeyhash in pubkeyhashes]
        except Base58Error:
            raise MultiSigAddreM
signature address must use PubKeyHashes, not public keys.')
        return construct_array(signatures_required, pubkeyhashes, signatures_possible)
        return address
def test_array(signatures_required, pubs, signatures_possible):
    """Check if multi
signature data is valid."""
        signatures_required, signatures_possible = int(signatures_required), int(signatures_possible)
    except (ValueError, TypeError):
        raise MultiSigAddressError('Signature values not inM
    if signatures_required < 1 or signatures_required > 3:
        raise MultiSigAddressError('Invalid signatures_required.')
    if signatures_possible < 2 or signatures_possible > 3:
        raise MultiSigAddressError('Invalid signatures_possible.')
    for pubkey in pubs:
        if '_' in pubkey:
            raise MultiSigAddressError('Invalid characters in pubkeys/pubkeyhashes.')
    if signatures_possible != len(pubs):
        raise InputError('Incorrect number of pubkeys/pubkeyhashes in multi
def construct_array(signatures_required, pubs, signatures_possible):
    """Create a multi
signature address."""
    test_array(signatures_required, pubs, signatures_possible)
    address = '_'.join([str(signatures_required)] + sorted(pubs) + [str(signatures_possible)])
def extract_array(address):
    """Extract data from multi
signature address."""
    assert is_multisig(address)
    array = address.split('_')
    signatures_required, pubs, signatures_possible = array[0],M
 sorted(array[1:-1]), array[-1]
    test_array(signatures_required, pubs, signatures_possible)
    return int(signatures_required), pubs, int(signatures_possible)
def pubkeyhash_array(address):
    """Return PubKeyHashes from an address."""
    signatures_required, pubs, signatures_possible = extract_array(address)
    if not all([is_pubkeyhash(pub) for pub in pubs]):
        raise MultiSigAddressError('Invalid PubKeyHashes. Multi
signature address must use PubKeyHashes, not public keys.')
    pubkeyhashes = pubM
    return pubkeyhashes
    x = hashlib.sha256(x).digest()
    m = hashlib.new('ripemd160')
    return m.digest()
def pubkey_to_pubkeyhash(pubkey):
    """Convert public key to PubKeyHash."""
    pubkeyhash = hash160(pubkey)
    pubkey = base58_check_encode(binascii.hexlify(pubkeyhash).decode('utf-8'), config.ADDRESSVERSION)
def pubkey_to_p2whash(pubkey):
    """Convert public key to PayToWitness."""
    pubkeyhash = hash160(pubkey)
    pubkey = CBech32Data.froM
m_bytes(0, pubkeyhash)
    return str(pubkey)
def bech32_to_scripthash(address):
    bech32 = CBech32Data(address)
    return bytes(bech32)
def get_asm(scriptpubkey):
    # TODO: When is an exception thrown here? Can this `try` block be tighter? Can it be replaced by a conditional?
        # TODO: This should be `for element in scriptpubkey`.
        for op in scriptpubkey:
            if type(op) == bitcoinlib.core.script.CScriptOp:
                # TODO: `op = element`
 asm.append(str(op))
                # TODO: `data = element` (?)
                asm.append(op)
    except bitcoinlib.core.script.CScriptTruncatedPushDataError:
        raise exceptions.PushDataDecodeError('invalid pushdata due to truncation')
        raise exceptions.DecodeError('empty output')
def get_checksig(asm):
    if len(asm) == 5 and asm[0] == 'OP_DUP' and asm[1] == 'OP_HASH160' and asm[3] == 'OP_EQUALVERIFY' and asm[4] == 'OP_CHECKSIG':
        if type(pubkeyhash) == bytes:
            return pubkeyhash
    raise exceptions.DecodeError('invalid OP_CHECKSIG')
def get_checkmultisig(asm):
    if len(asm) == 5 and asm[3] == 2 and asm[4] == 'OP_CHECKMULTISIG':
        pubkeys, signatures_required = asm[1:3], asm[0]
        if all([type(pubkey) == bytes for pubkey in pubkeys]):
            return pubkeys, signatures_required
    if len(asm) == 6 and asm[4] == 3 and asm[5] == 'OP_CHECKMULTISIG':
s, signatures_required = asm[1:4], asm[0]
        if all([type(pubkey) == bytes for pubkey in pubkeys]):
            return pubkeys, signatures_required
    raise exceptions.DecodeError('invalid OP_CHECKMULTISIG')
def scriptpubkey_to_address(scriptpubkey):
    asm = get_asm(scriptpubkey)
    if asm[-1] == 'OP_CHECKSIG':
            checksig = get_checksig(asm)
        except exceptions.DecodeError:  # coinbase
            return None
        return base58_check_encode(binascii.hexlify(checksig).decoM
de('utf-8'), config.ADDRESSVERSION)
    elif asm[-1] == 'OP_CHECKMULTISIG':
        pubkeys, signatures_required = get_checkmultisig(asm)
        pubkeyhashes = [pubkey_to_pubkeyhash(pubkey) for pubkey in pubkeys]
        return construct_array(signatures_required, pubkeyhashes, len(pubkeyhashes))
    elif len(asm) == 3 and asm[0] == 'OP_HASH160' and asm[2] == 'OP_EQUAL':
        return base58_check_encode(binascii.hexlify(asm[1]).decode('utf-8'), config.P2SH_ADDRESSVERSION)
# TODO: Use `pythonM
-bitcointools` instead. (Get rid of `pycoin` dependency.)
from pycoin.encoding import wif_to_tuple_of_secret_exponent_compressed, public_pair_to_sec, EncodingError
from pycoin.ecdsa import generator_secp256k1, public_pair_for_secret_exponent
class AltcoinSupportError (Exception): pass
def private_key_to_public_key(private_key_wif):
    """Convert private key to public key."""
    if config.TESTNET:
        allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_TESTNET]
    elif config.REGTEST:
        allowable_wif_pM
refixes = [config.PRIVATEKEY_VERSION_REGTEST]
        allowable_wif_prefixes = [config.PRIVATEKEY_VERSION_MAINNET]
        secret_exponent, compressed = wif_to_tuple_of_secret_exponent_compressed(
                private_key_wif, allowable_wif_prefixes=allowable_wif_prefixes)
    except EncodingError:
        raise AltcoinSupportError('pycoin: unsupported WIF prefix')
    public_pair = public_pair_for_secret_exponent(generator_secp256k1, secret_exponent)
    public_key = public_pair_to_sec(publicM
_pair, compressed=compressed)
    public_key_hex = binascii.hexlify(public_key).decode('utf-8')
    return public_key_hex
def is_pubkeyhash(monosig_address):
    """Check if PubKeyHash is valid P2PKH address. """
    assert not is_multisig(monosig_address)
        base58_check_decode(monosig_address, config.ADDRESSVERSION)
    except (Base58Error, VersionByteError):
        return False
def make_pubkeyhash(address):
    """Create a new PubKeyHash."""
    if is_multisig(address):
   signatures_required, pubs, signatures_possible = extract_array(address)
        pubkeyhashes = []
        for pub in pubs:
            if is_pubkeyhash(pub):
                pubkeyhash = pub
                pubkeyhash = pubkey_to_pubkeyhash(binascii.unhexlify(bytes(pub, 'utf-8')))
            pubkeyhashes.append(pubkeyhash)
        pubkeyhash_address = construct_array(signatures_required, pubkeyhashes, signatures_possible)
        if util.enabled('segwit_support') and is_bech32(addresM
            pubkeyhash_address = address # Some bech32 addresses are valid base58 data
        elif is_pubkeyhash(address):
            pubkeyhash_address = address
        elif is_p2sh(address):
            pubkeyhash_address = address
            pubkeyhash_address = pubkey_to_pubkeyhash(binascii.unhexlify(bytes(address, 'utf-8')))
    return pubkeyhash_address
def extract_pubkeys(pub):
    """Assume pubkey if not pubkeyhash. (Check validity later.)"""
    if is_multisig(pub):
        _, pubs, _ = extract_array(pub)
        for pub in pubs:
            if not is_pubkeyhash(pub):
                pubkeys.append(pub)
    elif is_p2sh(pub):
    elif util.enabled('segwit_support') and is_bech32(pub):
        if not is_pubkeyhash(pub):
            pubkeys.append(pub)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
#### transaction.py
Construct and serialize the Bitcoin transactions that are Counterparty transactions.
This module contains no consensus
logger = logging.getLogger(__name__)
import bitcoin as bitcoinlib
from bitcoin.core.script import CScript
from bitcoin.core import x, CTransaction
from bitcoin.core import b2lx
from counterpartylib.lib import blocks
from counterpartylib.lib import config
from counterpartylib.lib import excM
from counterpartylib.lib import util
from counterpartylib.lib import script
from counterpartylib.lib import backend
from counterpartylib.lib import arc4
from counterpartylib.lib.transaction_helper import serializer, p2sh_encoding
OP_PUSHDATA1 = b'\x4c'
OP_HASH160 = b'\xa9'
OP_EQUALVERIFY = b'\x88'
OP_CHECKSIG = b'\xac'
OP_CHECKMULTISIG = b'\xae'
 is None or DictCache per address
# set higher than the max number of UTXOs we should expect to
# manage in an aging cache for any one source address, at any one period
UTXO_LOCKS_PER_ADDRESS_MAXSIZE = 5000
# UTXO_P2SH_ENCODING_LOCKS is TTLCache for UTXOs that are used for chaining p2sh encoding
#  instead of a simple (txid, vout) key we use [(vin.prevout.hash, vin.prevout.n) for vin tx1.vin]
UTXO_P2SH_ENCODING_LOCKS = None
# we cache the make_outkey_vin to avoid having to fetch raw txs too oftenM
UTXO_P2SH_ENCODING_LOCKS_CACHE = None
    global UTXO_LOCKS, UTXO_P2SH_ENCODING_LOCKS, UTXO_P2SH_ENCODING_LOCKS_CACHE
    if config.UTXO_LOCKS_MAX_ADDRESSES > 0:  # initialize if configured
        UTXO_LOCKS = util.DictCache(size=config.UTXO_LOCKS_MAX_ADDRESSES)
    UTXO_P2SH_ENCODING_LOCKS = cachetools.TTLCache(10000, 180)
    UTXO_P2SH_ENCODING_LOCKS_CACHE = cachetools.TTLCache(1000, 600)
def print_coin(coin):
    return 'amount: {:.8f}; txid: {}; vout: {}; confirmations: {}'.format(coinM
['amount'], coin['txid'], coin['vout'], coin.get('confirmations', '?')) # simplify and make deterministic
    """ Yield successive n
sized chunks from l.
    for i in range(0, len(l), n):
        yield l[i:i+n]
def make_outkey(output):
    return '{}{}'.format(output['txid'], output['vout'])
def make_outkey_vin_txid(txid, vout):
    global UTXO_P2SH_ENCODING_LOCKS_CACHE
    if (txid, vout) not in UTXO_P2SH_ENCODING_LOCKS_CACHE:
        txhex = backend.getrawtransaction(txid, verboM
        UTXO_P2SH_ENCODING_LOCKS_CACHE[(txid, vout)] = make_outkey_vin(txhex, vout)
    return UTXO_P2SH_ENCODING_LOCKS_CACHE[(txid, vout)]
def make_outkey_vin(txhex, vout):
    txbin = binascii.unhexlify(txhex) if isinstance(txhex, str) else txhex
    assert isinstance(vout, int)
    tx = bitcoinlib.core.CTransaction.deserialize(txbin)
    outkey = [(vin.prevout.hash, vin.prevout.n) for vin in tx.vin]
    outkey = hashlib.sha256(("%s%s" % (outkey, vout)).encode('ascii')).digest()
def get_dust_return_pubkey(source, provided_pubkeys, encoding):
    """Return the pubkey to which dust from data outputs will be sent.
    This pubkey is used in multi-sig data outputs (as the only real pubkey) to
    make those the outputs spendable. It is derived from the source address, so
    that the dust is spendable by the creator of the transaction.
    # Get hex dust return pubkey.
    if script.is_multisig(source):
        a, self_pubkeys, b = script.extract_array(backend.multisig_pubkeyhashes_tM
o_pubkeys(source, provided_pubkeys))
        dust_return_pubkey_hex = self_pubkeys[0]
        dust_return_pubkey_hex = backend.pubkeyhash_to_pubkey(source, provided_pubkeys)
    # Convert hex public key into the (binary) dust return pubkey.
        dust_return_pubkey = binascii.unhexlify(dust_return_pubkey_hex)
    except binascii.Error:
        raise script.InputError('Invalid private key.')
    return dust_return_pubkey
def construct_coin_selection(encoding, data_array, source, allow_unconfM
irmed_inputs, unspent_tx_hash, custom_inputs,
                             fee_per_kb, estimate_fee_per_kb, estimate_fee_per_kb_nblocks, exact_fee, size_for_fee, fee_provided, destination_btc_out, data_btc_out,
                             regular_dust_size, disable_utxo_locks):
    global UTXO_LOCKS, UTXO_P2SH_ENCODING_LOCKS
    # Array of UTXOs, as retrieved by listunspent function from bitcoind
    if custom_inputs:
        use_inputs = unspent = custom_inputs
        if unspent_tx_hash is not None:
            unspent = backend.get_unspent_txouts(source, unconfirmed=allow_unconfirmed_inputs, unspent_tx_hash=unspent_tx_hash)
            unspent = backend.get_unspent_txouts(source, unconfirmed=allow_unconfirmed_inputs)
        filter_unspents_utxo_locks = []
        if UTXO_LOCKS is not None and source in UTXO_LOCKS:
            filter_unspents_utxo_locks = UTXO_LOCKS[source].keys()
        filter_unspents_p2sh_locks = UTXO_P2SH_ENCODING_LOCKS.keys()
        # filter out any locked UTXOs to prevM
ent creating transactions that spend the same UTXO when they're created at the same time
        filtered_unspent = []
        for output in unspent:
            if make_outkey(output) not in filter_unspents_utxo_locks and make_outkey_vin_txid(output['txid'], output['vout']) not in filter_unspents_p2sh_locks:
                filtered_unspent.append(output)
        unspent = filtered_unspent
        unspent = backend.sort_unspent_txouts(unspent)
        logger.debug('Sorted candidate UTXOs: {}'.format([print_coin(cM
oin) for coin in unspent]))
        use_inputs = unspent
    # use backend estimated fee_per_kb
    if estimate_fee_per_kb:
        estimated_fee_per_kb = backend.fee_per_kb(estimate_fee_per_kb_nblocks, config.ESTIMATE_FEE_MODE)
        if estimated_fee_per_kb is not None:
            fee_per_kb = max(estimated_fee_per_kb, fee_per_kb)  # never drop below the default fee_per_kb
    logger.debug('Fee/KB {:.8f}'.format(fee_per_kb / config.UNIT))
    change_quantity = 0
    final_fee = fee_per_kb
    desired_input_count = 1
    if encoding == 'multisig' and data_array and util.enabled('bytespersigop'):
        desired_input_count = len(data_array) * 2
    # pop inputs until we can pay for the fee
    for coin in use_inputs:
        logger.debug('New input: {}'.format(print_coin(coin)))
        inputs.append(coin)
        btc_in += round(coin['amount'] * config.UNIT)
        # If exact fee is specified, use that. Otherwise, calculate size of tx
        # and base M
fee on that (plus provide a minimum fee for selling BTC).
        size = 181 * len(inputs) + size_for_fee + 10
        if exact_fee:
            final_fee = exact_fee
            necessary_fee = int(size / 1000 * fee_per_kb)
            final_fee = max(fee_provided, necessary_fee)
            logger.getChild('p2shdebug').debug('final_fee inputs: %d size: %d final_fee %s' % (len(inputs), size, final_fee))
        # Check if good.
        btc_out = destination_btc_out + data_btc_out
        change_quanM
tity = btc_in - (btc_out + final_fee)
        logger.debug('Size: {} Fee: {:.8f} Change quantity: {:.8f} BTC'.format(size, final_fee / config.UNIT, change_quantity / config.UNIT))
        # If change is necessary, must not be a dust output.
        if change_quantity == 0 or change_quantity >= regular_dust_size:
            sufficient_funds = True
            if len(inputs) >= desired_input_count:
                break
    if not sufficient_funds:
        # Approximate needed change, fee by with most recently calcM
        # quantities.
        btc_out = destination_btc_out + data_btc_out
        total_btc_out = btc_out + max(change_quantity, 0) + final_fee
        raise exceptions.BalanceError('Insufficient {} at address {}. (Need approximately {} {}.) To spend unconfirmed coins, use the flag `--unconfirmed`. (Unconfirmed coins cannot be spent from multi
sig addresses.)'.format(config.BTC, source, total_btc_out / config.UNIT, config.BTC))
    # Lock the source's inputs (UTXOs) chosen for this transaction
O_LOCKS is not None and not disable_utxo_locks:
        if source not in UTXO_LOCKS:
            UTXO_LOCKS[source] = cachetools.TTLCache(
                UTXO_LOCKS_PER_ADDRESS_MAXSIZE, config.UTXO_LOCKS_MAX_AGE)
        for input in inputs:
            UTXO_LOCKS[source][make_outkey(input)] = input
        logger.debug("UTXO locks: Potentials ({}): {}, Used: {}, locked UTXOs: {}".format(
            len(unspent), [make_outkey(coin) for coin in unspent],
            [make_outkey(input) for input in inputs], listM
(UTXO_LOCKS[source].keys())))
    # ensure inputs have scriptPubKey
    #   this is not provided by indexd
    inputs = backend.ensure_script_pub_key_for_inputs(inputs)
    return inputs, change_quantity, btc_in, final_fee
def select_any_coin_from_source(source, allow_unconfirmed_inputs=True, disable_utxo_locks=False):
    ''' Get the first (biggest) input from the source address '''
    global UTXO_LOCKS
    # Array of UTXOs, as retrieved by listunspent function from bitcoind
    unspent = backend.get_unspent_M
txouts(source, unconfirmed=allow_unconfirmed_inputs)
    filter_unspents_utxo_locks = []
    if UTXO_LOCKS is not None and source in UTXO_LOCKS:
        filter_unspents_utxo_locks = UTXO_LOCKS[source].keys()
    # filter out any locked UTXOs to prevent creating transactions that spend the same UTXO when they're created at the same time
    filtered_unspent = []
    for output in unspent:
        if make_outkey(output) not in filter_unspents_utxo_locks:
            filtered_unspent.append(output)
    unspent = backend.sort_unspent_txouts(unspent)
    # use the first input
    input = unspent[0]
    if input is None:
    # Lock the source's inputs (UTXOs) chosen for this transaction
    if UTXO_LOCKS is not None and not disable_utxo_locks:
        if source not in UTXO_LOCKS:
            UTXO_LOCKS[source] = cachetools.TTLCache(
                UTXO_LOCKS_PER_ADDRESS_MAXSIZE, config.UTXO_LOCKS_MAX_AGE)
        UTXO_LOCKS[source][make_outkey(input)] = input
def return_result(tx_hexes, old_style_api):
        tx_hexes = list(filter(None, tx_hexes))  # filter out None
        if old_style_api:
            if len(tx_hexes) != 1:
                raise Exception("Can't do 2 TXs with old_style_api")
            return tx_hexes[0]
            if len(tx_hexes) == 1:
                return tx_hexes[0]
                return tx_hexes
def construct (db, tx_info, encoding='auto',
               fee_per_kb=config.DEFAULT_FEE_PER_M
               estimate_fee_per_kb=None, estimate_fee_per_kb_conf_target=config.ESTIMATE_FEE_CONF_TARGET,
               estimate_fee_per_kb_mode=config.ESTIMATE_FEE_MODE, estimate_fee_per_kb_nblocks=config.ESTIMATE_FEE_CONF_TARGET,
               regular_dust_size=config.DEFAULT_REGULAR_DUST_SIZE,
               multisig_dust_size=config.DEFAULT_MULTISIG_DUST_SIZE,
               op_return_value=config.DEFAULT_OP_RETURN_VALUE,
               exact_fee=None, fee_provided=0, provided_pubkeys=None, dust_return_puM
               allow_unconfirmed_inputs=False, unspent_tx_hash=None, custom_inputs=None, disable_utxo_locks=False, extended_tx_info=False,
               old_style_api=None, segwit=False,
               p2sh_source_multisig_pubkeys=None, p2sh_source_multisig_pubkeys_required=None, p2sh_pretx_txid=None,):
    if estimate_fee_per_kb is None:
        estimate_fee_per_kb = config.ESTIMATE_FEE_PER_KB
    global UTXO_LOCKS, UTXO_P2SH_ENCODING_LOCKS
    # lazy assign from config, because when set as default M
it's evaluated before it's configured
    if old_style_api is None:
        old_style_api = config.OLD_STYLE_API
    (source, destination_outputs, data) = tx_info
    if dust_return_pubkey:
        dust_return_pubkey = binascii.unhexlify(dust_return_pubkey)
    if p2sh_source_multisig_pubkeys:
        p2sh_source_multisig_pubkeys = [binascii.unhexlify(p) for p in p2sh_source_multisig_pubkeys]
        # If public key is necessary for construction of (unsigned)
        # transaction, use the public M
key provided, or find it from the
        # blockchain.
        script.validate(source)
    source_is_p2sh = script.is_p2sh(source)
    # Normalize source
    if script.is_multisig(source):
        source_address = backend.multisig_pubkeyhashes_to_pubkeys(source, provided_pubkeys)
        source_address = source
    # Sanity checks.
    if exact_fee and not isinstance(exact_fee, int):
        raise exceptions.TransactionError('Exact fees must be in satoshis.')
    if not isinstance(fee_pM
        raise exceptions.TransactionError('Fee provided must be in satoshis.')
    '''Determine encoding method'''
        desired_encoding = encoding
        # Data encoding methods (choose and validate).
        if desired_encoding == 'auto':
            if len(data) + len(config.PREFIX) <= config.OP_RETURN_MAX_SIZE:
                encoding = 'opreturn'
                encoding = 'p2sh' if not old_style_api and util.enabled('p2sh_encoding') else 'multisig'  # p2sh M
is not possible with old_style_api
        elif desired_encoding == 'p2sh' and not util.enabled('p2sh_encoding'):
            raise exceptions.TransactionError('P2SH encoding not enabled yet')
        elif encoding not in ('pubkeyhash', 'multisig', 'opreturn', 'p2sh'):
            raise exceptions.TransactionError('Unknown encoding
        encoding = None
    '''Destinations'''
    # Destination outputs.
        # Replace multi
sig addresses with multi
        # destination output isn
t a dust output. Set null values to dust size.
    destination_outputs_new = []
    if encoding != 'p2sh':
        for (address, value) in destination_outputs:
            # Value.
            if script.is_multisig(address):
                dust_size = multisig_dust_size
                dust_size = regular_dust_size
            if value == None:
                value = dust_size
            elif value < dust_size:
                raise exceptions.TrM
ansactionError('Destination output is dust.')
            # Address.
            script.validate(address)
            if script.is_multisig(address):
                destination_outputs_new.append((backend.multisig_pubkeyhashes_to_pubkeys(address, provided_pubkeys), value))
                destination_outputs_new.append((address, value))
    destination_outputs = destination_outputs_new
    destination_btc_out = sum([value for address, value in destination_outputs])
        # @TODO: p2sh encoding require signable dust key
        if encoding == 'multisig':
            # dust_return_pubkey should be set or explicitly set to False to use the default configured for the node
            #  the default for the node is optional so could fail
            if (source_is_p2sh and dust_return_pubkey is None) or (dust_return_pubkey is False and config.P2SH_DUST_RETURN_PUBKEY is None):
                raise exceptions.TransactionError("Can't use multisig encoding when source is P2SH and M
no dust_return_pubkey is provided.")
            elif dust_return_pubkey is False:
                dust_return_pubkey = binascii.unhexlify(config.P2SH_DUST_RETURN_PUBKEY)
        if not dust_return_pubkey:
            if encoding == 'multisig' or encoding == 'p2sh' and not source_is_p2sh:
                dust_return_pubkey = get_dust_return_pubkey(source, provided_pubkeys, encoding)
                dust_return_pubkey = None
        # Divide data into chunks.
        if encoding == 'pubkeyhash':
            # Prefix is also a suffix here.
            chunk_size = 20 - 1 - 8
        elif encoding == 'multisig':
            # Two pubkeys, minus length byte, minus prefix, minus two nonces,
            # minus two sign bytes.
            chunk_size = (33 * 2) - 1 - 8 - 2 - 2
        elif encoding == 'p2sh':
            pubkeylength = -1
            if dust_return_pubkey is not None:
                pubkeylength = len(dust_return_pubkey)
            chunk_size = p2sh_encoding.maximum_data_chunk_size(pubkeylengM
        elif encoding == 'opreturn':
            chunk_size = config.OP_RETURN_MAX_SIZE
            if len(data) + len(config.PREFIX) > chunk_size:
                raise exceptions.TransactionError('One `OP_RETURN` output per transaction.')
        data_array = list(chunks(data, chunk_size))
        # Data outputs.
        if encoding == 'multisig':
            data_value = multisig_dust_size
        elif encoding == 'p2sh':
            data_value = 0   # this will be calculated later
        elif encoding == M
            data_value = op_return_value
            data_value = regular_dust_size
        data_output = (data_array, data_value)
        data_value = 0
        data_array = []
        data_output = None
        dust_return_pubkey = None
    data_btc_out = data_value * len(data_array)
    logger.getChild('p2shdebug').debug('data_btc_out=%s (data_value=%d len(data_array)=%d)' % (data_btc_out, data_value, len(data_array)))
    # Calculate collective size of outputs, for fee calculation.
    p2pkhsize = 25 + 9
    if encoding == 'multisig':
        data_output_size = 81       # 71 for the data
    elif encoding == 'opreturn':
        # prefix + data + 10 bytes script overhead
        data_output_size = len(config.PREFIX) + 10
        if data is not None:
            data_output_size = data_output_size + len(data)
        data_output_size = p2pkhsize   # Pay
PubKeyHash (25 for the dM
    outputs_size = (p2pkhsize * len(destination_outputs)) + (len(data_array) * data_output_size)
    if encoding == 'p2sh':
        # calculate all the p2sh outputs
        size_for_fee, datatx_necessary_fee, data_value, data_btc_out = p2sh_encoding.calculate_outputs(destination_outputs, data_array, fee_per_kb, exact_fee)
        # replace the data value
        data_output = (data_array, data_value)
        sum_data_output_size = len(data_array) * data_output_size
        size_for_fee = ((25 + 9) M
* len(destination_outputs)) + sum_data_output_size
    if not (encoding == 'p2sh' and p2sh_pretx_txid):
        inputs, change_quantity, n_btc_in, n_final_fee = construct_coin_selection(
            encoding, data_array,
            source, allow_unconfirmed_inputs, unspent_tx_hash, custom_inputs,
            fee_per_kb, estimate_fee_per_kb, estimate_fee_per_kb_nblocks,
            exact_fee, size_for_fee, fee_provided, destination_btc_out, data_btc_out,
            regular_dust_size, disable_utxo_locks
        btc_in = n_btc_in
        final_fee = n_final_fee
        # when encoding is P2SH and the pretx txid is passed we can skip coinselection
        inputs, change_quantity = None, None
    if change_quantity:
        change_output = (source_address, change_quantity)
        change_output = None
    unsigned_pretx_hex = None
    unsigned_tx_hex = None
    pretx_txid = None
    if encoding == 'p2sh':
        assert not (segwit and p2sh_pretx_txid)  # shouldn't do old stylM
e with segwit enabled
        if p2sh_pretx_txid:
            pretx_txid = p2sh_pretx_txid if isinstance(p2sh_pretx_txid, bytes) else binascii.unhexlify(p2sh_pretx_txid)
            unsigned_pretx = None
            destination_value_sum = sum([value for (destination, value) in destination_outputs])
            source_value = destination_value_sum
            if change_output:
                # add the difference between source and destination to the change
                change_value = change_outpM
ut[1] + (destination_value_sum - source_value)
                change_output = (change_output[0], change_value)
            unsigned_pretx = serializer.serialise_p2sh_pretx(inputs,
                                                             source=source_address,
                                                             source_value=source_value,
                                                             data_output=data_output,
                                                             change_output=changM
                                                             pubkey=dust_return_pubkey,
                                                             multisig_pubkeys=p2sh_source_multisig_pubkeys,
                                                             multisig_pubkeys_required=p2sh_source_multisig_pubkeys_required)
            unsigned_pretx_hex = binascii.hexlify(unsigned_pretx).decode('utf-8')
        # with segwit we already know the txid and can return both
            #pretx_M
txid = hashlib.sha256(unsigned_pretx).digest()  # this should be segwit txid
            ptx = CTransaction.stream_deserialize(io.BytesIO(unsigned_pretx)) # could be a non-segwit tx anyways
            txid_ba = bytearray(ptx.GetTxid())
            txid_ba.reverse()
            pretx_txid = bytes(txid_ba) # gonna leave the malleability problem to upstream
            logger.getChild('p2shdebug').debug('pretx_txid %s' % pretx_txid)
            print('pretx txid:', binascii.hexlify(pretx_txid))
        if unsigned_pM
            # we set a long lock on this, don't want other TXs to spend from it
            UTXO_P2SH_ENCODING_LOCKS[make_outkey_vin(unsigned_pretx, 0)] = True
        # only generate the data TX if we have the pretx txId
        if pretx_txid:
            source_input = None
            if script.is_p2sh(source):
                source_input = select_any_coin_from_source(source)
                if not source_input:
                    raise exceptions.TransactionError('Unable to select source input for p2shM
            unsigned_datatx = serializer.serialise_p2sh_datatx(pretx_txid,
                                                               source=source_address,
                                                               source_input=source_input,
                                                               destination_outputs=destination_outputs,
                                                               data_output=data_output,
                                                          M
     pubkey=dust_return_pubkey,
                                                               multisig_pubkeys=p2sh_source_multisig_pubkeys,
                                                               multisig_pubkeys_required=p2sh_source_multisig_pubkeys_required)
            unsigned_datatx_hex = binascii.hexlify(unsigned_datatx).decode('utf-8')
            # let the rest of the code work it's magic on the data tx
            unsigned_tx_hex = unsigned_datatx_hex
            # we're just gonna M
return the pretx, it doesn't require any of the further checks
            logger.warn('old_style_api = %s' % old_style_api)
            return return_result([unsigned_pretx_hex], old_style_api=old_style_api)
        # Serialise inputs and outputs.
        unsigned_tx = serializer.serialise(encoding, inputs, destination_outputs,
                                data_output, change_output,
                                dust_return_pubkey=dust_return_pubkey)
        unsigned_tx_hex = binascii.hexlify(unsiM
gned_tx).decode('utf-8')
    '''Sanity Check'''
    # Desired transaction info.
    (desired_source, desired_destination_outputs, desired_data) = tx_info
    desired_source = script.make_canonical(desired_source)
    desired_destination = script.make_canonical(desired_destination_outputs[0][0]) if desired_destination_outputs else ''
    # NOTE: Include change in destinations for BTC transactions.
    # if change_output and not desired_data and desired_destination != config.UNSPENDABLE:
    #    if desired_destinM
    #        desired_destination = desired_source
    #        desired_destination += '-{}'.format(desired_source)
    if desired_data == None:
        desired_data = b''
    # Parsed transaction info.
        if pretx_txid and unsigned_pretx:
            backend.cache_pretx(pretx_txid, unsigned_pretx)
        parsed_source, parsed_destination, x, y, parsed_data, extra = blocks._get_tx_info(unsigned_tx_hex, p2sh_is_segwit=script.is_bech32(desired_source))
 encoding == 'p2sh':
            # make_canonical can't determine the address, so we blindly change the desired to the parsed
            desired_source = parsed_source
        if pretx_txid and unsigned_pretx:
            backend.clear_pretx(pretx_txid)
    except exceptions.BTCOnlyError:
        if extended_tx_info:
            return {
                'btc_in': btc_in,
                'btc_out': destination_btc_out + data_btc_out,
                'btc_change': change_quanM
                'btc_fee': final_fee,
                'tx_hex': unsigned_tx_hex,
        logger.getChild('p2shdebug').debug('BTC-ONLY')
        return return_result([unsigned_pretx_hex, unsigned_tx_hex], old_style_api=old_style_api)
    desired_source = script.make_canonical(desired_source)
    # Check desired info against parsed info.
    desired = (desired_source, desired_destination, desired_data)
    parsed = (parsed_source, parsed_destination, parsed_data)
    if desired != parsed:
 # Unlock (revert) UTXO locks
        if UTXO_LOCKS is not None and inputs:
            for input in inputs:
                UTXO_LOCKS[source].pop(make_outkey(input), None)
        raise exceptions.TransactionError('Constructed transaction does not parse correctly: {}
 {}'.format(desired, parsed))
    if extended_tx_info:
            'btc_in': btc_in,
            'btc_out': destination_btc_out + data_btc_out,
            'btc_change': change_quantity,
            'btc_fee': final_fee,
     'tx_hex': unsigned_tx_hex,
    return return_result([unsigned_pretx_hex, unsigned_tx_hex], old_style_api=old_style_api)
def normalize_custom_inputs(raw_custom_inputs):
    custom_inputs = []
    for custom_input in raw_custom_inputs:
        if 'value' not in custom_input:
            custom_input['value'] = int(custom_input['amount'] * config.UNIT)
        custom_inputs.append(custom_input)
    return custom_inputs
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
logger = logging.getLogger(__name__)
from datetime import datetime
from dateutil.tz import tzlocal
from operator import itemgetter
import bitcoin as bitcoinlib
from counterpartylib.lib import exceptions
from counterpartylib.lib.exceptions import DecodeEM
from counterpartylib.lib import config
B26_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
# subasset contain only characters a-zA-Z0-9.-_@!
SUBASSET_DIGITS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_@!'
SUBASSET_REVERSE = {'a':1,'b':2,'c':3,'d':4,'e':5,'f':6,'g':7,'h':8,'i':9,'j':10,'k':11,'l':12,'m':13,'n':14,
                    'o':15,'p':16,'q':17,'r':18,'s':19,'t':20,'u':21,'v':22,'w':23,'x':24,'y':25,'z':26,
                    'A':27,'B':28,'C':29,'D':30,'E':31,'F':M
32,'G':33,'H':34,'I':35,'J':36,'K':37,'L':38,'M':39,
                    'N':40,'O':41,'P':42,'Q':43,'R':44,'S':45,'T':46,'U':47,'V':48,'W':49,'X':50,'Y':51,'Z':52,
                    '0':53,'1':54,'2':55,'3':56,'4':57,'5':58,'6':59,'7':60,'8':61,'9':62,'.':63,'-':64,'_':65,'@':66,'!':67}
# Obsolete in Python
3.4, with enum module.
BET_TYPE_NAME = {0: 'BullCFD', 1: 'BearCFD', 2: 'Equal', 3: 'NotEqual'}
BET_TYPE_ID = {'BullCFD': 0, 'BearCFD': 1, 'Equal': 2, 'NotEqual': 3}
json_dump = lambda x: json.dumps(x, sortM
_keys=True, indent=4)
json_print = lambda x: print(json_dump(x))
CURRENT_BLOCK_INDEX = None
CURR_DIR = os.path.dirname(os.path.realpath(__file__))
with open(CURR_DIR + '/../protocol_changes.json') as f:
    PROTOCOL_CHANGES = json.load(f)
class RPCError (Exception): pass
# TODO: Move to `util_test.py`.
t timeout properly. (If server hangs, then unhangs, no result.)
def api(method, params):
    """Poll API via JSON-RPC."""
    headers = {'content-type': 'application/json'}M
        "method": method,
        "params": params,
        "jsonrpc": "2.0",
    response = requests.post(config.RPC, data=json.dumps(payload), headers=headers)
    if response == None:
        raise RPCError('Cannot communicate with {} server.'.format(config.XCP_NAME))
    elif response.status_code != 200:
        if response.status_code == 500:
            raise RPCError('Malformed API call.')
            raise RPCError(str(response.status_code) + ' ' + respM
    response_json = response.json()
    if 'error' not in response_json.keys() or response_json['error'] == None:
            return response_json['result']
        except KeyError:
            raise RPCError(response_json)
        raise RPCError('{} ({})'.format(response_json['error']['message'], response_json['error']['code']))
    return [l[i:i + n] for i in range(0, len(l), n)]
    return [x for x in z]
    # Had to do it this way to support python 3.4, if we start
    # using the 3.5 runtime this can be replaced by:
    #  (first_elem, *t)
    l.insert(0, first_elem)
    it = itertools.groupby(l, itemgetter(0))
    for key, subiter in it:
       yield key, sum(item[1] for item in subiter)
def date_passed(date):
    """Check if the date has already passed."""
    return date <= int(time.time())
def price (numerator, denominator):
eturn price as Fraction or Decimal."""
    if CURRENT_BLOCK_INDEX >= 294500 or config.TESTNET or config.REGTEST: # Protocol change.
        return fractions.Fraction(numerator, denominator)
        numerator = D(numerator)
        denominator = D(denominator)
        return D(numerator / denominator)
def last_message(db):
    """Return latest message from the db."""
    cursor = db.cursor()
    messages = list(cursor.execute('''SELECT * FROM messages WHERE message_index = (SELECT MAX(message_index) from M
        assert len(messages) == 1
        last_message = messages[0]
        raise exceptions.DatabaseError('No messages found.')
    return last_message
def generate_asset_id(asset_name, block_index):
    """Create asset_id from asset_name."""
    if asset_name == config.BTC: return 0
    elif asset_name == config.XCP: return 1
    if len(asset_name) < 4:
        raise exceptions.AssetNameError('too short')
    # Numeric asset names.
umeric_asset_names'):  # Protocol change.
        if asset_name[0] == 'A':
            # Must be numeric.
                asset_id = int(asset_name[1:])
            except ValueError:
                raise exceptions.AssetNameError('non
numeric asset name starts with
            # Number must be in range.
            if not (26**12 + 1 <= asset_id <= 2**64 - 1):
                raise exceptions.AssetNameError('numeric asset name not in range')
            return asset_id
len(asset_name) >= 13:
            raise exceptions.AssetNameError('long asset names must be numeric')
    if asset_name[0] == 'A': raise exceptions.AssetNameError('non
numeric asset name starts with
    # Convert the Base 26 string to an integer.
    for c in asset_name:
        if c not in B26_DIGITS:
            raise exceptions.AssetNameError('invalid character:', c)
        digit = B26_DIGITS.index(c)
    if asset_id < 26**3:
raise exceptions.AssetNameError('too short')
def generate_asset_name (asset_id, block_index):
    """Create asset_name from asset_id."""
    if asset_id == 0: return config.BTC
    elif asset_id == 1: return config.XCP
    if asset_id < 26**3:
        raise exceptions.AssetIDError('too low')
    if enabled('numeric_asset_names'):  # Protocol change.
        if asset_id <= 2**64 - 1:
            if 26**12 + 1 <= asset_id:
                asset_name = 'A' + str(asset_id)
                returnM
            raise exceptions.AssetIDError('too high')
    # Divide that integer into Base 26 string.
        n, r = divmod (n, 26)
        res.append(B26_DIGITS[r])
    asset_name = ''.join(res[::-1])
    return asset_name + checksum.compute(asset_name)
    return asset_name
def get_asset_id (db, asset_name, block_index):
    """Return asset_id from asset_name."""
    if not enabled('hotfix_numeric_assets'):
generate_asset_id(asset_name, block_index)
    cursor = db.cursor()
    cursor.execute('''SELECT * FROM assets WHERE asset_name = ?''', (asset_name,))
    assets = list(cursor)
    if len(assets) == 1:
        return int(assets[0]['asset_id'])
        raise exceptions.AssetError('No such asset: {}'.format(asset_name))
def get_asset_name (db, asset_id, block_index):
    """Return asset_name from asset_id."""
    if not enabled('hotfix_numeric_assets'):
        return generate_asset_name(asset_id, block_inM
    cursor = db.cursor()
    cursor.execute('''SELECT * FROM assets WHERE asset_id = ?''', (str(asset_id),))
    assets = list(cursor)
    if len(assets) == 1:
        return assets[0]['asset_name']
    elif not assets:
        return 0    # Strange, I know
# If asset_name is an existing subasset (PARENT.child) then return the corresponding numeric asset name (A12345)
#   If asset_name is not an existing subasset, then return the unmodified asset_name
def resolve_subasset_longname(db, asset_name):
nabled('subassets'):
        subasset_longname = None
            subasset_parent, subasset_longname = parse_subasset_from_asset_name(asset_name)
        except Exception as e:
            logger.warn("Invalid subasset {}".format(asset_name))
            subasset_longname = None
        if subasset_longname is not None:
            cursor = db.cursor()
            cursor.execute('''SELECT asset_name FROM assets WHERE asset_longname = ?''', (subasset_longname,))
            assets = list(cursor)
      cursor.close()
            if len(assets) == 1:
                return assets[0]['asset_name']
    return asset_name
# checks and validates subassets (PARENT.SUBASSET)
#   throws exceptions for assset or subasset names with invalid syntax
#   returns (None, None) if the asset is not a subasset name
def parse_subasset_from_asset_name(asset):
    subasset_parent = None
    subasset_child = None
    subasset_longname = None
    chunks = asset.split('.', 1)
    if (len(chunks) == 2):
        subasset_parent = M
        subasset_child = chunks[1]
        subasset_longname = asset
        # validate parent asset
        validate_subasset_parent_name(subasset_parent)
        # validate child asset
        validate_subasset_longname(subasset_longname, subasset_child)
    return (subasset_parent, subasset_longname)
# throws exceptions for invalid subasset names
def validate_subasset_longname(subasset_longname, subasset_child=None):
    if subasset_child is None:
        chunks = subasset_longname.split('.', 1)
      if (len(chunks) == 2):
            subasset_child = chunks[1]
            subasset_child = ''
    if len(subasset_child) < 1:
        raise exceptions.AssetNameError('subasset name too short')
    if len(subasset_longname) > 250:
        raise exceptions.AssetNameError('subasset name too long')
    # can't start with period, can't have consecutive periods, can't contain anything not in SUBASSET_DIGITS
    previous_digit = '.'
    for c in subasset_child:
        if c not in SUBASSET_DIGITS:
          raise exceptions.AssetNameError('subasset name contains invalid character:', c)
        if c == '.' and previous_digit == '.':
            raise exceptions.AssetNameError('subasset name contains consecutive periods')
        previous_digit = c
    if previous_digit == '.':
        raise exceptions.AssetNameError('subasset name ends with a period')
# throws exceptions for invalid subasset names
def validate_subasset_parent_name(asset_name):
    if asset_name == config.BTC:
xceptions.AssetNameError('parent asset cannot be {}'.format(config.BTC))
    if asset_name == config.XCP:
        raise exceptions.AssetNameError('parent asset cannot be {}'.format(config.XCP))
    if len(asset_name) < 4:
        raise exceptions.AssetNameError('parent asset name too short')
    if len(asset_name) >= 13:
        raise exceptions.AssetNameError('parent asset name too long')
    if asset_name[0] == 'A':
        raise exceptions.AssetNameError('parent asset name starts with
        if c not in B26_DIGITS:
            raise exceptions.AssetNameError('parent asset name contains invalid character:', c)
def compact_subasset_longname(string):
    """Compacts a subasset name string into an array of bytes to save space using a base68 encoding scheme.
    Assumes all characters provided belong to SUBASSET_DIGITS.
    for i, c in enumerate(string[::-1]):
        name_int += (68 ** i) * SUBASSET_REVERSE[c]
    return name_int.to_bytes((name_int.M
bit_length() + 7) // 8, byteorder='big')
def expand_subasset_longname(raw_bytes):
    """Expands an array of bytes into a subasset name string."""
    integer = int.from_bytes(raw_bytes, byteorder='big')
    if integer == 0:
    while integer != 0:
        ret = SUBASSET_DIGITS[integer % 68 - 1] + ret
        integer //= 68
def generate_random_asset ():
    return 'A' + str(random.randint(26**12 + 1, 2**64 - 1))
def parse_options_from_string(string):
ions integer from string, if exists."""
    string_list = string.split(" ")
    if len(string_list) == 2:
            options = int(string_list.pop())
            raise exceptions.OptionsError('options not an integer')
        return options
        return False
def validate_address_options(options):
    """Ensure the options are all valid and in range."""
    if (options > config.MAX_INT) or (options < 0):
        raise exceptions.OptionsError('options integer overflow')
 elif options > config.ADDRESS_OPTION_MAX_VALUE:
        raise exceptions.OptionsError('options out of range')
    elif not active_options(config.ADDRESS_OPTION_MAX_VALUE, options):
        raise exceptions.OptionsError('options not possible')
def active_options(config, options):
    """Checks if options active in some given config."""
    return config & options == options
class DebitError (Exception): pass
def debit (db, address, asset, quantity, action=None, event=None):
    """Debit given address by quantity M
    block_index = CURRENT_BLOCK_INDEX
    if type(quantity) != int:
        raise DebitError('Quantity must be an integer.')
    if quantity < 0:
        raise DebitError('Negative quantity.')
    if quantity > config.MAX_INT:
        raise DebitError('Quantity can\'t be higher than MAX_INT.')
    if asset == config.BTC:
        raise DebitError('Cannot debit bitcoins.')
    debit_cursor = db.cursor()
    # Contracts can only hold XCP balances.
    if enabled('contracts_only_xcp_balances'): # ProtocM
        if len(address) == 40:
            assert asset == config.XCP
    if asset == config.BTC:
        raise exceptions.BalanceError('Cannot debit bitcoins from a {} address!'.format(config.XCP_NAME))
    debit_cursor.execute('''SELECT * FROM balances \
                            WHERE (address = ? AND asset = ?)''', (address, asset))
    balances = debit_cursor.fetchall()
    if not len(balances) == 1:
        old_balance = 0
        old_balance = balances[0]['quantity']
        raise DebitError('Insufficient funds.')
    balance = round(old_balance - quantity)
    balance = min(balance, config.MAX_INT)
    assert balance >= 0
        'quantity': balance,
        'address': address,
        'asset': asset
    sql='update balances set quantity = :quantity where (address = :address and asset = :asset)'
    debit_cursor.execute(sql, bindings)
        'block_index': block_index,
        'address': address,
       'asset': asset,
        'quantity': quantity,
        'action': action,
        'event': event
    sql='insert into debits values(:block_index, :address, :asset, :quantity, :action, :event)'
    debit_cursor.execute(sql, bindings)
    debit_cursor.close()
    BLOCK_LEDGER.append('{}{}{}{}'.format(block_index, address, asset, quantity))
class CreditError (Exception): pass
def credit (db, address, asset, quantity, action=None, event=None):
    """Credit given address by quantity of asset."""
index = CURRENT_BLOCK_INDEX
    if type(quantity) != int:
        raise CreditError('Quantity must be an integer.')
    if quantity < 0:
        raise CreditError('Negative quantity.')
    if quantity > config.MAX_INT:
        raise CreditError('Quantity can\'t be higher than MAX_INT.')
    if asset == config.BTC:
        raise CreditError('Cannot debit bitcoins.')
    credit_cursor = db.cursor()
    # Contracts can only hold XCP balances.
    if enabled('contracts_only_xcp_balances'): # Protocol change.
 if len(address) == 40:
            assert asset == config.XCP
    credit_cursor.execute('''SELECT * FROM balances \
                             WHERE (address = ? AND asset = ?)''', (address, asset))
    balances = credit_cursor.fetchall()
    if len(balances) == 0:
        assert balances == []
        #update balances table with new balance
        bindings = {
            'address': address,
            'asset': asset,
            'quantity': quantity,
        sql='insert into balances values(:addrM
ess, :asset, :quantity)'
        credit_cursor.execute(sql, bindings)
    elif len(balances) > 1:
        assert False
        old_balance = balances[0]['quantity']
        assert type(old_balance) == int
        balance = round(old_balance + quantity)
        balance = min(balance, config.MAX_INT)
        bindings = {
            'quantity': balance,
            'address': address,
            'asset': asset
        sql='update balances set quantity = :quantity where (address = :address and asM
        credit_cursor.execute(sql, bindings)
    # Record credit.
        'block_index': block_index,
        'address': address,
        'asset': asset,
        'quantity': quantity,
        'action': action,
        'event': event
    sql='insert into credits values(:block_index, :address, :asset, :quantity, :action, :event)'
    credit_cursor.execute(sql, bindings)
    credit_cursor.close()
    BLOCK_LEDGER.append('{}{}{}{}'.format(block_index, address, asset, quantity))
class QuantityError(Exception): pass
def is_divisible(db, asset):
    """Check if the asset is divisible."""
    if asset in (config.BTC, config.XCP):
        cursor = db.cursor()
        cursor.execute('''SELECT * FROM issuances \
                          WHERE (status = ? AND asset = ?) ORDER BY tx_index DESC''', ('valid', asset))
        issuances = cursor.fetchall()
        if not issuances: raise exceptions.AssetError('No such asset: {}'.format(asset))
        return issuances[M
def value_input(quantity, asset, divisible):
    if asset == 'leverage':
        return round(quantity)
    if asset in ('value', 'fraction', 'price', 'odds'):
        return float(quantity)  # TODO: Float?!
        quantity = D(quantity) * config.UNIT
        if quantity == quantity.to_integral():
            return int(quantity)
            raise QuantityError('Divisible assets have only eight decimal places of precision.')
        quantity = D(quantityM
        if quantity != round(quantity):
            raise QuantityError('Fractional quantities of indivisible assets.')
        return round(quantity)
def value_in(db, quantity, asset, divisible=None):
    if asset not in ['leverage', 'value', 'fraction', 'price', 'odds'] and divisible == None:
        divisible = is_divisible(db, asset)
    return value_input(quantity, asset, divisible)
def value_output(quantity, asset, divisible):
    def norm(num, places):
        """Round only if necessary."""
= round(num, places)
        fmt = '{:.' + str(places) + 'f}'
        num = fmt.format(num)
        return num.rstrip('0')+'0' if num.rstrip('0')[-1] == '.' else num.rstrip('0')
    if asset == 'fraction':
        return str(norm(D(quantity) * D(100), 6)) + '%'
    if asset in ('leverage', 'value', 'price', 'odds'):
        return norm(quantity, 6)
        quantity = D(quantity) / D(config.UNIT)
        if quantity == quantity.to_integral():
            return str(quantity) + '.0'  # For divisiM
ble assets, display the decimal point.
            return norm(quantity, 8)
        quantity = D(quantity)
        if quantity != round(quantity):
            raise QuantityError('Fractional quantities of indivisible assets.')
        return round(quantity)
def value_out(db, quantity, asset, divisible=None):
    if asset not in ['leverage', 'value', 'fraction', 'price', 'odds'] and divisible == None:
        divisible = is_divisible(db, asset)
    return value_output(quantity, asset, divisiM
def holders(db, asset, exclude_empty_holders=False):
    """Return holders of the asset."""
    cursor = db.cursor()
    if exclude_empty_holders:
        cursor.execute('''SELECT * FROM balances \
                          WHERE asset = ? AND quantity > ?''', (asset, 0))
        cursor.execute('''SELECT * FROM balances \
                          WHERE asset = ?''', (asset, ))
    for balance in list(cursor):
        holders.append({'address': balaM
nce['address'], 'address_quantity': balance['quantity'], 'escrow': None})
    # Funds escrowed in orders. (Protocol change.)
    cursor.execute('''SELECT * FROM orders \
                      WHERE give_asset = ? AND status = ?''', (asset, 'open'))
    for order in list(cursor):
        holders.append({'address': order['source'], 'address_quantity': order['give_remaining'], 'escrow': order['tx_hash']})
    # Funds escrowed in pending order matches. (Protocol change.)
    cursor.execute('''SELECT * FROM order_matcheM
                      WHERE (forward_asset = ? AND status = ?)''', (asset, 'pending'))
    for order_match in list(cursor):
        holders.append({'address': order_match['tx0_address'], 'address_quantity': order_match['forward_quantity'], 'escrow': order_match['id']})
    cursor.execute('''SELECT * FROM order_matches \
                      WHERE (backward_asset = ? AND status = ?)''', (asset, 'pending'))
    for order_match in list(cursor):
        holders.append({'address': order_match['tx1_address'], 'addreM
ss_quantity': order_match['backward_quantity'], 'escrow': order_match['id']})
    # Bets and RPS (and bet/rps matches) only escrow XCP.
    if asset == config.XCP:
        cursor.execute('''SELECT * FROM bets \
                          WHERE status = ?''', ('open',))
        for bet in list(cursor):
            holders.append({'address': bet['source'], 'address_quantity': bet['wager_remaining'], 'escrow': bet['tx_hash']})
        cursor.execute('''SELECT * FROM bet_matches \
                          WHERE statusM
 = ?''', ('pending',))
        for bet_match in list(cursor):
            holders.append({'address': bet_match['tx0_address'], 'address_quantity': bet_match['forward_quantity'], 'escrow': bet_match['id']})
            holders.append({'address': bet_match['tx1_address'], 'address_quantity': bet_match['backward_quantity'], 'escrow': bet_match['id']})
        cursor.execute('''SELECT * FROM rps \
                          WHERE status = ?''', ('open',))
        for rps in list(cursor):
            holders.append({'adM
dress': rps['source'], 'address_quantity': rps['wager'], 'escrow': rps['tx_hash']})
        cursor.execute('''SELECT * FROM rps_matches \
                          WHERE status IN (?, ?, ?)''', ('pending', 'pending and resolved', 'resolved and pending'))
        for rps_match in list(cursor):
            holders.append({'address': rps_match['tx0_address'], 'address_quantity': rps_match['wager'], 'escrow': rps_match['id']})
            holders.append({'address': rps_match['tx1_address'], 'address_quantity': rps_matcM
h['wager'], 'escrow': rps_match['id']})
    if enabled('dispensers_in_holders'):
        # Funds escrowed in dispensers.
        cursor.execute('''SELECT * FROM dispensers \
                          WHERE asset = ? AND status = ?''', (asset, 0))
        for dispenser in list(cursor):
            holders.append({'address': dispenser['source'], 'address_quantity': dispenser['give_remaining'], 'escrow': None})
def xcp_created (db):
    """Return number of XCP created thus faM
    cursor = db.cursor()
    cursor.execute('''SELECT SUM(earned) AS total FROM burns \
                      WHERE (status = ?)''', ('valid',))
    total = list(cursor)[0]['total'] or 0
def xcp_destroyed (db):
    """Return number of XCP destroyed thus far."""
    cursor = db.cursor()
    cursor.execute('''SELECT SUM(quantity) AS total FROM destructions \
                      WHERE (status = ? AND asset = ?)''', ('valid', config.XCP))
al = list(cursor)[0]['total'] or 0
    # Subtract issuance fees.
    cursor.execute('''SELECT SUM(fee_paid) AS total FROM issuances\
                      WHERE status = ?''', ('valid',))
    issuance_fee_total = list(cursor)[0]['total'] or 0
    # Subtract dividend fees.
    cursor.execute('''SELECT SUM(fee_paid) AS total FROM dividends\
                      WHERE status = ?''', ('valid',))
    dividend_fee_total = list(cursor)[0]['total'] or 0
    # Subtract sweep fees.
    cursor.execute('''SELECT SUM(fee_paid)M
 AS total FROM sweeps\
                      WHERE status = ?''', ('valid',))
    sweeps_fee_total = list(cursor)[0]['total'] or 0
    return destroyed_total + issuance_fee_total + dividend_fee_total + sweeps_fee_total
def xcp_supply (db):
    """Return the XCP supply."""
    return xcp_created(db) - xcp_destroyed(db)
    """Return creations."""
    cursor = db.cursor()
    creations = {config.XCP: xcp_created(db)}
    cursor.execute('''SELECT asset, SUM(quantity) AS createdM
                      WHERE status = ? GROUP BY asset''', ('valid',))
    for issuance in cursor:
        asset = issuance['asset']
        created = issuance['created']
        creations[asset] = created
    return creations
def destructions (db):
    """Return destructions."""
    cursor = db.cursor()
    destructions = {config.XCP: xcp_destroyed(db)}
    cursor.execute('''SELECT asset, SUM(quantity) AS destroyed FROM destructions \
                      WHERE (status = ? AM
ND asset != ?) GROUP BY asset''', ('valid', config.XCP))
    for destruction in cursor:
        asset = destruction['asset']
        destroyed = destruction['destroyed']
        destructions[asset] = destroyed
    return destructions
def asset_issued_total (db, asset):
    """Return asset total issued."""
    cursor = db.cursor()
    cursor.execute('''SELECT SUM(quantity) AS total FROM issuances \
                      WHERE (status = ? AND asset = ?)''', ('valid', asset))
    issued_total = lM
ist(cursor)[0]['total'] or 0
    return issued_total
def asset_destroyed_total (db, asset):
    """Return asset total destroyed."""
    cursor = db.cursor()
    cursor.execute('''SELECT SUM(quantity) AS total FROM destructions \
                      WHERE (status = ? AND asset = ?)''', ('valid', asset))
    destroyed_total = list(cursor)[0]['total'] or 0
    return destroyed_total
def asset_supply (db, asset):
    """Return asset supply."""
    return asset_issued_total(db, M
asset) - asset_destroyed_total(db, asset)
    """Return supplies."""
    d1 = creations(db)
    d2 = destructions(db)
    return {key: d1[key] - d2.get(key, 0) for key in d1.keys()}
def held (db): #TODO: Rename ?
        "SELECT asset, SUM(quantity) AS total FROM balances GROUP BY asset",
        "SELECT give_asset AS asset, SUM(give_remaining) AS total FROM orders WHERE status = 'open' GROUP BY asset",
        "SELECT give_asset AS asset, SUM(give_remaining) AS total FROM orderM
s WHERE status = 'filled' and give_asset = 'XCP' and get_asset = 'BTC' GROUP BY asset",
        "SELECT forward_asset AS asset, SUM(forward_quantity) AS total FROM order_matches WHERE status = 'pending' GROUP BY asset",
        "SELECT backward_asset AS asset, SUM(backward_quantity) AS total FROM order_matches WHERE status = 'pending' GROUP BY asset",
        "SELECT 'XCP' AS asset, SUM(wager_remaining) AS total FROM bets WHERE status = 'open'",
        "SELECT 'XCP' AS asset, SUM(forward_quantity) AS total FROM beM
t_matches WHERE status = 'pending'",
        "SELECT 'XCP' AS asset, SUM(backward_quantity) AS total FROM bet_matches WHERE status = 'pending'",
        "SELECT 'XCP' AS asset, SUM(wager) AS total FROM rps WHERE status = 'open'",
        "SELECT 'XCP' AS asset, SUM(wager * 2) AS total FROM rps_matches WHERE status IN ('pending', 'pending and resolved', 'resolved and pending')",
        "SELECT asset, SUM(give_remaining) AS total FROM dispensers WHERE status=0 OR status=1 GROUP BY asset",
    sql = "SELECT asM
set, SUM(total) AS total FROM (" + " UNION ALL ".join(queries) + ") GROUP BY asset;"
    cursor = db.cursor()
    cursor.execute(sql)
    for row in cursor:
        asset = row['asset']
        total = row['total']
        held[asset] = total
class GetURLError (Exception): pass
def get_url(url, abort_on_error=False, is_json=True, fetch_timeout=5):
    """Fetch URL using requests.get."""
        r = requests.get(url, timeout=fetch_timeout)
        raise GetURLError("Got get_url request error: %s" % e)
        if r.status_code != 200 and abort_on_error:
            raise GetURLError("Bad status code returned: '%s'. result body: '%s'." % (r.status_code, r.text))
        result = json.loads(r.text) if is_json else r.text
    if not isinstance(text, bytes):
        text = bytes(str(text), 'utf-8')
    return hashlib.sha256(hashlib.sha256(text).digest()).digest()
def dhash_string(text):
rn binascii.hexlify(dhash(text)).decode()
def get_balance (db, address, asset):
    """Get balance of contract or address."""
    cursor = db.cursor()
    balances = list(cursor.execute('''SELECT * FROM balances WHERE (address = ? AND asset = ?)''', (address, asset)))
    if not balances: return 0
    else: return balances[0]['quantity']
# Why on Earth does `binascii.hexlify()` return bytes?!
    """Return the hexadecimal representation of the binary data. Decode from ASCII to M
    return binascii.hexlify(x).decode('ascii')
def unhexlify(hex_string):
    return binascii.unhexlify(bytes(hex_string, 'utf-8'))
### Protocol Changes ###
def enabled(change_name, block_index=None):
    """Return True if protocol change is enabled."""
    if config.REGTEST:
        return True # All changes are always enabled on REGTEST
    if config.TESTNET:
        index_name = 'testnet_block_index'
        index_name = 'block_index'
    enable_block_index = PROTOCOL_CHANGES[change_name][M
    if not block_index:
        block_index = CURRENT_BLOCK_INDEX
    if block_index >= enable_block_index:
        return False
def get_value_by_block_index(change_name, block_index=None):
    if not block_index:
        block_index = CURRENT_BLOCK_INDEX
    if config.REGTEST:
        max_block_index_testnet = -1
        for key, value in PROTOCOL_CHANGES[change_name]["testnet"]:
            if int(key) > int(max_block_index):
                max_block_index = keyM
        return PROTOCOL_CHANGES[change_name]["testnet"][max_block_index]["value"]
    if config.TESTNET:
        index_name = 'testnet'
        index_name = 'mainnet'
    max_block_index = -1
    for key in PROTOCOL_CHANGES[change_name][index_name]:
        if int(key) > int(max_block_index) and block_index >= int(key):
            max_block_index = key
    return PROTOCOL_CHANGES[change_name][index_name][max_block_index]["value"]
def transfer(db, source, destinatM
ion, asset, quantity, action, event):
    """Transfer quantity of asset from source to destination."""
    debit(db, source, asset, quantity, action=action, event=event)
    credit(db, destination, asset, quantity, action=action, event=event)
def make_id(hash_1, hash_2):
    return hash_1 + ID_SEPARATOR + hash_2
def parse_id(match_id):
    assert match_id[64] == ID_SEPARATOR
    return match_id[:64], match_id[65:] # UTF-8 encoding means that the indices are doubled.
ance(v, dict) or isinstance(v, DictCache):
        for dk, dv in v.items():
            s += sizeof(dk)
            s += sizeof(dv)
        return sys.getsizeof(v)
    """Threadsafe FIFO dict cache"""
    def __init__(self, size=100):
        if int(size) < 1 :
            raise AttributeError('size < 1 or not a number')
        self.size = size
        self.dict = collections.OrderedDict()
        self.lock = threading.Lock()
    def __getitem__(self,keyM
        with self.lock:
            return self.dict[key]
    def __setitem__(self,key,value):
        with self.lock:
            while len(self.dict) >= self.size:
                self.dict.popitem(last=False)
            self.dict[key] = value
    def __delitem__(self,key):
        with self.lock:
            del self.dict[key]
    def __len__(self):
        with self.lock:
            return len(self.dict)
    def __contains__(self, key):
        with self.lock:
            return key in self.dict
ef refresh(self, key):
        with self.lock:
            self.dict.move_to_end(key, last=True)
URL_USERNAMEPASS_REGEX = re.compile('.+://(.+)@')
def clean_url_for_log(url):
    m = URL_USERNAMEPASS_REGEX.match(url)
    if m and m.group(1):
        url = url.replace(m.group(1), 'XXXXXXXX')
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
def satoshirate_to_fiat(satoshirate):
    return round(satoshirate/100.0,2)
def get_oracle_last_price(db, oracle_address, block_index):
    cursor.execute('SELECT * FROM broadcasts WHERE source=:source AND status=:status AND block_index<:block_index ORDER by tx_index DESC LIMIT 1', {
        'source': oracle_address,
        'status': 'valid',
        'block_index': block_index
    broadcasts = cursor.fetchall()
    if len(broadcasts) == 0:
        return None, None
    oracle_broadcast = broadcasts[0]
    oracle_label = oracle_broadcast["text"].split("-")
    if len(oracle_label) == 2:
fiat_label = oracle_label[1]
        fiat_label = ""
    return oracle_broadcast['value'], oracle_broadcast['fee_fraction_int'], fiat_label, oracle_broadcast['block_index']
#### util_windows.py
import logging.handlers
logger = logging.getLogger(__name__)
from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int
from ctypes.wintypes import BOOL, HANDLE, DWORD, LPWSTR, LPCWSTR, LPVOID
class SanitizedRotatingFileHanM
dler(logging.handlers.RotatingFileHandler):
    def emit(self, record):
        # If the message doesn't need to be rendered we take a shortcut.
        if record.levelno < self.level:
        # Make sure the message is a string.
        message = record.msg
        #Sanitize and clean up the message
        message = unicodedata.normalize('NFKD', message).encode('ascii', 'ignore').decode()
        # Copy the original record so we don't break other handlers.
        record = copy.copy(record)
     record.msg = message
        # Use the built-in stream handler to handle output.
        logging.handlers.RotatingFileHandler.emit(self, record)
def fix_win32_unicode():
    """Thanks to http://stackoverflow.com/a/3259271 ! (converted to python3)"""
    if sys.platform != "win32":
    original_stderr = sys.stderr
    # If any exception occurs in this code, we'll probably try to print it on stderr,
    # which makes for frustrating debugging if stderr is directed to our wrapper.
ranoid about catching errors and reporting them to original_stderr,
    # so that we can at least see them.
    def _complain(message):
        print(message if isinstance(message, str) else repr(message), file=original_stderr)
    # Work around <http://bugs.python.org/issue6058>.
    codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
    # Make Unicode console output work independently of the current code page.
    # This also fixes <http://bugs.python.org/issue1602>.
t to Michael Kaplan <http://blogs.msdn.com/b/michkap/archive/2010/04/07/9989346.aspx>
    # and TZOmegaTZIOY
    # <http://stackoverflow.com/questions/878972/windows-cmd-encoding-change-causes-python-crash/1432462#1432462>.
        # <http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx>
        # HANDLE WINAPI GetStdHandle(DWORD nStdHandle);
        # returns INVALID_HANDLE_VALUE, NULL, or a valid handle
        # <http://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx>
WORD WINAPI GetFileType(DWORD hFile);
        # <http://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx>
        # BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode);
        GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32))
        STD_OUTPUT_HANDLE = DWORD(-11)
        STD_ERROR_HANDLE = DWORD(-12)
        GetFileType = WINFUNCTYPE(DWORD, DWORD)(("GetFileType", windll.kernel32))
        FILE_TYPE_CHAR = 0x0002
        FILE_TYPE_REMOTE = 0x8000
eMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))(("GetConsoleMode", windll.kernel32))
        INVALID_HANDLE_VALUE = DWORD(-1).value
        def not_a_console(handle):
            if handle == INVALID_HANDLE_VALUE or handle is None:
                return True
            return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR
                    or GetConsoleMode(handle, byref(DWORD())) == 0)
        old_stdout_fileno = None
        old_stderr_fileno = None
        if hasattr(sys.stdout, 'fileno'):
            old_stdout_fileno = sys.stdout.fileno()
        if hasattr(sys.stderr, 'fileno'):
            old_stderr_fileno = sys.stderr.fileno()
        STDOUT_FILENO = 1
        STDERR_FILENO = 2
        real_stdout = (old_stdout_fileno == STDOUT_FILENO)
        real_stderr = (old_stderr_fileno == STDERR_FILENO)
        if real_stdout:
            hStdout = GetStdHandle(STD_OUTPUT_HANDLE)
            if not_a_console(hStdout):
                real_stdout = False
        if real_stderr:
            hStderr = GeM
tStdHandle(STD_ERROR_HANDLE)
            if not_a_console(hStderr):
                real_stderr = False
        if real_stdout or real_stderr:
            # BOOL WINAPI WriteConsoleW(HANDLE hOutput, LPWSTR lpBuffer, DWORD nChars,
            #                           LPDWORD lpCharsWritten, LPVOID lpReserved);
            WriteConsoleW = WINFUNCTYPE(BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID)(("WriteConsoleW", windll.kernel32))
            class UnicodeOutput:
                def __init__(self, hConsoM
le, stream, fileno, name):
                    self._hConsole = hConsole
                    self._stream = stream
                    self._fileno = fileno
                    self.closed = False
                    self.softspace = False
                    self.mode = 'w'
                    self.encoding = 'utf-8'
                    self.name = name
                    self.errors = ''
                    self.flush()
                def isatty(self):
                    return False
                def closM
                    # don't really close the handle, that would only cause problems
                    self.closed = True
                def fileno(self):
                    return self._fileno
                def flush(self):
                    if self._hConsole is None:
                        try:
                            self._stream.flush()
                        except Exception as e:
                            _complain("%s.flush: %r from %r" % (self.name, e, self._stream))
                def write(self, text):
                    try:
                        if self._hConsole is None:
                            if isinstance(text, str):
                                text = text.encode('utf-8')
                            self._stream.write(text)
                        else:
                            if not isinstance(text, str):
                                text = str(text).decode('utf-8')
                            remaining = len(text)
              while remaining:
                                n = DWORD(0)
                                # There is a shorter-than-documented limitation on the
                                # length of the string passed to WriteConsoleW (see
                                # <http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232>.
                                retval = WriteConsoleW(self._hConsole, text, min(remaining, 10000), byref(n), None)
                                if retval == 0 or n.value == 0:
                              raise IOError("WriteConsoleW returned %r, n.value = %r" % (retval, n.value))
                                remaining -= n.value
                                if not remaining:
                                    break
                                text = text[n.value:]
                    except Exception as e:
                        _complain("%s.write: %r" % (self.name, e))
                        raise
                def writelines(self, lines):
                    try:
                     for line in lines:
                            self.write(line)
                    except Exception as e:
                        _complain("%s.writelines: %r" % (self.name, e))
                        raise
            if real_stdout:
                sys.stdout = UnicodeOutput(hStdout, None, STDOUT_FILENO, '<Unicode console stdout>')
                sys.stdout = UnicodeOutput(None, sys.stdout, old_stdout_fileno, '<Unicode redirected stdout>')
            if real_stderr:
              sys.stderr = UnicodeOutput(hStderr, None, STDERR_FILENO, '<Unicode console stderr>')
                sys.stderr = UnicodeOutput(None, sys.stderr, old_stderr_fileno, '<Unicode redirected stderr>')
    except Exception as e:
        _complain("exception %r while fixing up sys.stdout and sys.stderr" % (e,))
    # While we're at it, let's unmangle the command-line arguments:
    # This works around <http://bugs.python.org/issue2128>.
    GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommM
andLineW", windll.kernel32))
    CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))(("CommandLineToArgvW", windll.shell32))
    argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc))
    argv = [argv_unicode[i].encode('utf-8').decode('utf-8') for i in range(0, argc.value)]
    if not hasattr(sys, 'frozen'):
        # If this is an executable produced by py2exe or bbfreeze, then it will
        # have been invoked directly. Otherwise, unicode_argv[0] is the PM
        # interpreter, so skip that.
        argv = argv[1:]
        # Also skip option arguments to the Python interpreter.
        while len(argv) > 0:
            arg = argv[0]
            if not arg.startswith("-") or arg == "-":
                break
            argv = argv[1:]
            if arg == '-m':
                # sys.argv[0] should really be the absolute path of the module source,
                # but never mind
                break
            if arg == '-c':
                argv[0] = '-c'
                break
#### addrindexrs.py
logger = logging.getLogger(__name__)
from requests.exceptions import Timeout, ReadTimeout, ConnectionError
import concurrent.futures
import bitcoin.wallet
from counterpartylib.lib import config, util, address
SOCKET_TIMEOUT = 5.0
BACKEND_PING_TIME = 30.0
raw_transactions_cache = util.DictCache(size=config.BACKEND_RAW_TRANSACTIONS_CACHE_SIZE)  # used in getrawtransaction_batch()
class BackendRPCError(Exception):
class AddrIndexRsRPCError(Exception):
def rpc_call(payload):
    """Calls to bitcoin core and returns the response"""
    url = config.BACKEND_URL
    for i in range(TRIES):
            response = requests.post(url, data=json.dumps(payloaM
d), headers={'content-type': 'application/json'},
                verify=(not config.BACKEND_SSL_NO_VERIFY), timeout=config.REQUESTS_TIMEOUT)
            if i > 0:
                logger.debug('Successfully connected.')
        except (Timeout, ReadTimeout, ConnectionError):
            logger.debug('Could not connect to backend at `{}`. (Try {}/{})'.format(util.clean_url_for_log(url), i+1, TRIES))
            time.sleep(5)
    if response == None:
        if config.TESTNET:
            network =M
        elif config.REGTEST:
            network = 'regtest'
            network = 'mainnet'
        raise BackendRPCError('Cannot communicate with backend at `{}`. (server is set to run on {}, is backend?)'.format(util.clean_url_for_log(url), network))
    elif response.status_code in (401,):
        raise BackendRPCError('Authorization error connecting to {}: {} {}'.format(util.clean_url_for_log(url), response.status_code, response.reason))
    elif response.status_code not in (200, 500):M
        raise BackendRPCError(str(response.status_code) + ' ' + response.reason)
    # Handle json decode errors
        response_json = response.json()
    except json.decoder.JSONDecodeError as e:
        raise BackendRPCError('Received invalid JSON from backend with a response of {}'.format(str(response.status_code) + ' ' + response.reason))
    # Batch query returns a list
    if isinstance(response_json, list):
        return response_json
    if 'error' not in response_json.keys() or response_jsonM
        return response_json['result']
    elif response_json['error']['code'] == -5:   # RPC_INVALID_ADDRESS_OR_KEY
        raise BackendRPCError('{} Is `txindex` enabled in {} Core?'.format(response_json['error'], config.BTC_NAME))
    elif response_json['error']['code'] in [-28, -8, -2]:
Block height out of range
The network does not appear to fully agree!
        logger.debug('Backend not ready. Sleeping for ten seconds.')
coin Core takes more than `sys.getrecursionlimit() * 10 = 9970`
        # seconds to start, this
ll hit the maximum recursion depth limit.
        time.sleep(10)
        return rpc_call(payload)
        raise BackendRPCError('Error connecting to {}: {}'.format(util.clean_url_for_log(url), response_json['error']))
def rpc(method, params):
        "method": method,
        "params": params,
        "jsonrpc": "2.0",
    return rpc_call(payload)
def rpc_batch(requesM
    responses = collections.deque()
    def make_call(chunk):
        #send a list of requests to bitcoind to be executed
        #note that this is list executed serially, in the same thread in bitcoind
        #e.g. see: https://github.com/bitcoin/bitcoin/blob/master/src/rpcserver.cpp#L939
        responses.extend(rpc_call(chunk))
    chunks = util.chunkify(request_list, config.RPC_BATCH_SIZE)
    with concurrent.futures.ThreadPoolExecutor(max_workers=config.BACKEND_RPC_BATCH_NUM_WORKERS) as executor:
        for chunk in chunks:
            executor.submit(make_call, chunk)
    return list(responses)
def extract_addresses(txhash_list):
    logger.debug('extract_addresses, txs: %d' % (len(txhash_list), ))
    tx_hashes_tx = getrawtransaction_batch(txhash_list, verbose=True)
    return extract_addresses_from_txlist(tx_hashes_tx, getrawtransaction_batch)
def extract_addresses_from_txlist(tx_hashes_tx, _getrawtransaction_batch):
    helper for extract_addresses, seperated so we can pass in a mocked _getrM
awtransaction_batch for test purposes
    logger.debug('extract_addresses_from_txlist, txs: %d' % (len(tx_hashes_tx.keys()), ))
    tx_hashes_addresses = {}
    tx_inputs_hashes = set()  # use set to avoid duplicates
    for tx_hash, tx in tx_hashes_tx.items():
        tx_hashes_addresses[tx_hash] = set()
        for vout in tx['vout']:
            if 'addresses' in vout['scriptPubKey']:
                tx_hashes_addresses[tx_hash].update(tuple(vout['scriptPubKey']['addresses']))
        tx_inputs_hashesM
.update([vin['txid'] for vin in tx['vin']])
    logger.debug('extract_addresses, input TXs: %d' % (len(tx_inputs_hashes), ))
    # chunk txs to avoid huge memory spikes
    for tx_inputs_hashes_chunk in util.chunkify(list(tx_inputs_hashes), config.BACKEND_RAW_TRANSACTIONS_CACHE_SIZE):
        raw_transactions = _getrawtransaction_batch(tx_inputs_hashes_chunk, verbose=True)
        for tx_hash, tx in tx_hashes_tx.items():
            for vin in tx['vin']:
                vin_tx = raw_transactions.get(vin['txid'], M
                if not vin_tx:
                    continue
                vout = vin_tx['vout'][vin['vout']]
                if 'addresses' in vout['scriptPubKey']:
                    tx_hashes_addresses[tx_hash].update(tuple(vout['scriptPubKey']['addresses']))
    return tx_hashes_addresses, tx_hashes_tx
def getblockcount():
    return rpc('getblockcount', [])
def getblockhash(blockcount):
    return rpc('getblockhash', [blockcount])
def getblock(block_hash):
    return rpc('getblock', [block_hash, M
def getrawtransaction(tx_hash, verbose=False, skip_missing=False):
    return getrawtransaction_batch([tx_hash], verbose=verbose, skip_missing=skip_missing)[tx_hash]
def getrawmempool():
    return rpc('getrawmempool', [])
def fee_per_kb(conf_target, mode, nblocks=None):
    :param conf_target:
    :return: fee_per_kb in satoshis, or None when unable to determine
    if nblocks is None and conf_target is None:
        conf_target = nblocks
    feeperkb = rpc('estimatesmaM
rtfee', [conf_target, mode])
    if 'errors' in feeperkb and feeperkb['errors'][0] == 'Insufficient data or no feerate found':
    return int(max(feeperkb['feerate'] * config.UNIT, config.DEFAULT_FEE_PER_KB_ESTIMATE_SMART))
def sendrawtransaction(tx_hex):
    return rpc('sendrawtransaction', [tx_hex])
GETRAWTRANSACTION_MAX_RETRIES=2
monotonic_call_id = 0
def getrawtransaction_batch(txhash_list, verbose=False, skip_missing=False, _retry=0):
    _logger = logger.getChild("getrawtransaction_batM
    if len(txhash_list) > config.BACKEND_RAW_TRANSACTIONS_CACHE_SIZE:
        #don't try to load in more than BACKEND_RAW_TRANSACTIONS_CACHE_SIZE entries in a single call
        txhash_list_chunks = util.chunkify(txhash_list, config.BACKEND_RAW_TRANSACTIONS_CACHE_SIZE)
        for txhash_list_chunk in txhash_list_chunks:
            txes.update(getrawtransaction_batch(txhash_list_chunk, verbose=verbose, skip_missing=skip_missing))
    tx_hash_call_id = {}
    noncached_txhashes = set()
    txhash_list = set(txhash_list)
    # payload for transactions not in cache
    for tx_hash in txhash_list:
        if tx_hash not in raw_transactions_cache:
            #call_id = binascii.hexlify(os.urandom(5)).decode('utf8') # Don't drain urandom
            global monotonic_call_id
            monotonic_call_id = monotonic_call_id + 1
            call_id = "{}".format(monotonic_call_id)
            payload.append({
                "method": 'getrawtransaction',
     "params": [tx_hash, 1],
                "jsonrpc": "2.0",
                "id": call_id
            noncached_txhashes.add(tx_hash)
            tx_hash_call_id[call_id] = tx_hash
    #refresh any/all cache entries that already exist in the cache,
    # so they're not inadvertently removed by another thread before we can consult them
    #(this assumes that the size of the working set for any given workload doesn't exceed the max size of the cache)
    for tx_hash in txhash_list.difference(noncacM
        raw_transactions_cache.refresh(tx_hash)
    _logger.debug("getrawtransaction_batch: txhash_list size: {} / raw_transactions_cache size: {} / # getrawtransaction calls: {}".format(
        len(txhash_list), len(raw_transactions_cache), len(payload)))
    # populate cache
    if len(payload) > 0:
        batch_responses = rpc_batch(payload)
        for response in batch_responses:
            if 'error' not in response or response['error'] is None:
                tx_hex = response['result']
                tx_hash = tx_hash_call_id[response['id']]
                raw_transactions_cache[tx_hash] = tx_hex
            elif skip_missing and 'error' in response and response['error']['code'] == -5:
                raw_transactions_cache[tx_hash] = None
                logging.debug('Missing TX with no raw info skipped (txhash: {}): {}'.format(
                    tx_hash_call_id.get(response.get('id', '??'), '??'), response['error']))
                #TODO: this seems to happen for bogus tM
ransactions? Maybe handle it more gracefully than just erroring out?
                raise BackendRPCError('{} (txhash:: {})'.format(response['error'], tx_hash_call_id.get(response.get('id', '??'), '??')))
    # get transactions from cache
    for tx_hash in txhash_list:
            if verbose:
                result[tx_hash] = raw_transactions_cache[tx_hash]
                result[tx_hash] = raw_transactions_cache[tx_hash]['hex'] if raw_transactions_cache[tx_hash] isM
        except KeyError as e: #shows up most likely due to finickyness with addrindex not always returning results that we need...
            print("Key error in addrindexrs still exists!!!!!")
            _logger.warning("tx missing in rawtx cache: {} -- txhash_list size: {}, hash: {} / raw_transactions_cache size: {} / # rpc_batch calls: {} / txhash in noncached_txhashes: {} / txhash in txhash_list: {} -- list {}".format(
                e, len(txhash_list), hashlib.md5(json.dumps(list(txhashM
_list)).encode()).hexdigest(), len(raw_transactions_cache), len(payload),
                tx_hash in noncached_txhashes, tx_hash in txhash_list, list(txhash_list.difference(noncached_txhashes)) ))
            if  _retry < GETRAWTRANSACTION_MAX_RETRIES: #try again
                time.sleep(0.05 * (_retry + 1)) # Wait a bit, hitting the index non-stop may cause it to just break down... TODO: Better handling
                r = getrawtransaction_batch([tx_hash], verbose=verbose, skip_missing=skip_missing, _retry=_retM
                result[tx_hash] = r[tx_hash]
                raise #already tried again, give up
class AddrIndexRsThread (threading.Thread):
    def __init__(self, host, port):
        threading.Thread.__init__(self)
        self.host = host
        self.port = port
        self.sock = None
        self.lastId = 0
        self.message_to_send = None
        self.message_result = None
        self.is_killed = False
        logging.debug('AddrIndexRs thM
        self.send({"kill": True})
    def connect(self):
        self.lastId = 0
            logging.info('AddrIndexRs connecting...')
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.settimeout(SOCKET_TIMEOUT)
                self.sock.connect((self.host, self.port))
                logging.info('Error connecting to AddrIndexRs! Retrying in a few seconds')
                time.sleep(5.0)
                logging.info('Connected to AddrIndexRs!')
                break
        self.locker = threading.Condition()
        self.locker.acquire()
        self.connect()
        while self.locker.wait():
            if not(self.is_killed) and self.message_to_send != None:
                msg = self.message_to_send
                self.message_to_send = None
                retry_count = 15
                while retry_count > 0:
                    has_sent = False
      while not(has_sent) and msg:
                        try:
                            logging.debug('AddrIndexRs sending')
                            self.sock.send(msg)
                            has_sent = True
                        except Exception as e:
                            #try:
                            logging.debug('AddrIndexRs error:' + e)
                            self.connect()
                            #except Exception as e2:
                            #logging.debug('AddrIndexRM
s fatal error:' + e2)
                    self.message_to_send = None
                    data = b""
                    parsed = False
                    while not(parsed):
                        try:
                            data = data + self.sock.recv(READ_BUF_SIZE)
                            self.message_result = json.loads(data.decode('utf-8'))
                            retry_count = 0
                            parsed = True
                            logging.debug('AddrIndexRs Recv complete!')
                      except socket.timeout:
                            logging.debug('AddrIndexRs Recv timeout error sending: '+str(msg))
                            if retry_count <= 0:
                                self.connect()
                            self.message_result = None
                            retry_count -= -1
                        except socket.error as e:
                            logging.debug('AddrIndexRs Recv error:' + str(e)+' with msg '+str(msg))
                            self.M
                        except Exception as e:
                            logging.debug('AddrIndexRs Recv error:' + str(e)+' with msg '+str(msg))
                            if retry_count <= 0:
                                raise e
                            self.message_result = None
                            retry_count -= 1
                        finally:
                            self.locker.notify()
                self.locker.notify()
        self.sock.close()
ging.debug('AddrIndexRs socket closed normally')
    def send(self, msg):
        self.locker.acquire()
        if not("kill" in msg):
            msg["id"] = self.lastId
            self.lastId += 1
            self.message_to_send = (json.dumps(msg) + "\n").encode('utf8')
        self.locker.notify()
        self.locker.wait()
        self.locker.release()
        return self.message_result
def ensure_addrindexrs_connected():
    max_backoff = 5000
le _backend == None:
            _backend = AddrIndexRsThread(config.INDEXD_CONNECT, config.INDEXD_PORT)
            _backend.daemon = True
            _backend.start()
            _backend.send({
                "method": "server.version",
                "params": []
        except Exception as e:
            logger.debug(e)
            time.sleep(backoff)
            backoff = min(backoff * 1.5, max_backoff)
def _script_pubkey_to_hash(spk):
    return hashlib.sha256(spk).digest()[::M
def _address_to_hash(addr):
    script_pubkey = bitcoin.wallet.CBitcoinAddress(addr).to_scriptPubKey()
    return _script_pubkey_to_hash(script_pubkey)
# Returns an array of UTXOS from an address in the following format
#   "txId": utxo_txid_hex,
#   "confirmations": num
# [{"txId":"a0d12eb3716e2e70fd00525486ace0da2947f82d818b7be0285f16ff672cf237","vout":5,"height":647484,"value":30455293,"confirmations":2}]
def unpack_outpoint(outpoint):
    txid, vout = outpoint.split(':')
    return (txid, int(vout))
def unpack_vout(outpoint, tx, block_count):
    vout = tx["vout"][outpoint[1]]
    if "confirmations" in tx and tx["confirmations"] > 0:
        height = block_count - tx["confirmations"] + 1
        tx["confirmations"] = 0
        "txId": tx["txid"],
        "vout": outpoint[1],
        "height": height,
        "value": int(round(vout["value"] * config.UNIT)),
"confirmations": tx["confirmations"]
def get_unspent_txouts(source):
    ensure_addrindexrs_connected()
    block_count = getblockcount()
    result = _backend.send({
        "method": "blockchain.scripthash.get_utxos",
        "params": [_address_to_hash(source)]
    if not(result is None) and "result" in result:
        result = result["result"]
        result = [unpack_outpoint(x) for x in result]
        # each item on the result array is like
        # {"tx_hash": hex_encoded_hash}
h = getrawtransaction_batch([x[0] for x in result], verbose=True, skip_missing=True)
        batch = [unpack_vout(outpoint, batch[outpoint[0]], block_count) for outpoint in result if outpoint[0] in batch]
        batch = [x for x in batch if x is not None]
        return batch
# Returns transactions in the following format
#  "blockhash": hexstring,
#  "blocktime": num,
#  "confirmations": num,
#  "hash": hexstring,
#  "hex": hexstring,
#  "txid": hexstring,
#      "txinwitness": array of hex_witness_program, // Only if it's a witness-containing tx
#      "txid": hexstring,
#      "sequence": num,
#      "coinbase": X, // contents not important, this is only present if the tx is a coinbase
#      "scriptSig": {
#        "asm": asm_decompiled_program,
#        "hex": hex_program
#       "value": decimal,
#       "scriptPubKey": {
#           "type": string,
#           "reqSigs": num,
#           "hex": hexstring, // the program in hex
#           "asm": string, // the decompiled program
#           "addresses": [ ...list of found addresses on the program ]
def search_raw_transactions(address, unconfirmed=True):
    ensure_addrindexrs_connected()
    hsh = _address_to_hash(address)
    txs = _backend.send({
        "method": "blockchain.scripthash.getM
        "params": [hsh]
    batch = getrawtransaction_batch([x["tx_hash"] for x in txs], verbose=True)
    if not(unconfirmed):
        batch = [x for x in batch if x.height >= 0]
# Returns the number of blocks the backend is behind the node
def getindexblocksbehind():
    # Addrindexrs never "gets behind"
    ensure_addrindexrs_connected()
    if '_backend' in globals():
        _backend.stop()
logger = logging.getLogger(__name__)
from requests.exceptions import Timeout, ReadTimeout, ConnectionError
import concurrent.futures
from counterpartylib.lib import config, util
raw_transactions_cache = util.DictCache(size=config.BACKEND_RAW_TRANSACTIONS_CACHE_SIZE)  # used in getrawtransaction_batch()
class BackendRPCError(Exception):
class IndexdRPCError(Exception):M
def rpc_call(payload):
    """Calls to bitcoin core and returns the response"""
    url = config.BACKEND_URL
    for i in range(TRIES):
            response = requests.post(url, data=json.dumps(payload), headers={'content-type': 'application/json'},
                verify=(not config.BACKEND_SSL_NO_VERIFY), timeout=config.REQUESTS_TIMEOUT)
            if i > 0:
                logger.debug('Successfully connected.')
        except (TimeoM
ut, ReadTimeout, ConnectionError):
            logger.debug('Could not connect to backend at `{}`. (Try {}/{})'.format(util.clean_url_for_log(url), i+1, TRIES))
            time.sleep(5)
    if response == None:
        if config.TESTNET:
            network = 'testnet'
        elif config.REGTEST:
            network = 'regtest'
            network = 'mainnet'
        raise BackendRPCError('Cannot communicate with backend at `{}`. (server is set to run on {}, is backend?)'.format(util.clean_url_for_M
    elif response.status_code in (401,):
        raise BackendRPCError('Authorization error connecting to {}: {} {}'.format(util.clean_url_for_log(url), response.status_code, response.reason))
    elif response.status_code not in (200, 500):
        raise BackendRPCError(str(response.status_code) + ' ' + response.reason)
    # Handle json decode errors
        response_json = response.json()
    except json.decoder.JSONDecodeError as e:
        raise BackendRPCError('Received invalid JM
SON from backend with a response of {}'.format(str(response.status_code) + ' ' + response.reason))
    # Batch query returns a list
    if isinstance(response_json, list):
        return response_json
    if 'error' not in response_json.keys() or response_json['error'] == None:
        return response_json['result']
    elif response_json['error']['code'] == -5:   # RPC_INVALID_ADDRESS_OR_KEY
        raise BackendRPCError('{} Is `txindex` enabled in {} Core?'.format(response_json['error'], config.BTC_NAME))
if response_json['error']['code'] in [-28, -8, -2]:
Block height out of range
The network does not appear to fully agree!
        logger.debug('Backend not ready. Sleeping for ten seconds.')
        # If Bitcoin Core takes more than `sys.getrecursionlimit() * 10 = 9970`
        # seconds to start, this
ll hit the maximum recursion depth limit.
        time.sleep(10)
        return rpc_call(payload)
        raise BackendRPCError('Error connecting to {M
}: {}'.format(util.clean_url_for_log(url), response_json['error']))
def rpc(method, params):
        "method": method,
        "params": params,
        "jsonrpc": "2.0",
    return rpc_call(payload)
def rpc_batch(request_list):
    responses = collections.deque()
    def make_call(chunk):
        #send a list of requests to bitcoind to be executed
        #note that this is list executed serially, in the same thread in bitcoind
        #e.g. see: https://github.com/bitcoinM
/bitcoin/blob/master/src/rpcserver.cpp#L939
        responses.extend(rpc_call(chunk))
    chunks = util.chunkify(request_list, config.RPC_BATCH_SIZE)
    with concurrent.futures.ThreadPoolExecutor(max_workers=config.BACKEND_RPC_BATCH_NUM_WORKERS) as executor:
        for chunk in chunks:
            executor.submit(make_call, chunk)
    return list(responses)
def extract_addresses(txhash_list):
    logger.debug('extract_addresses, txs: %d' % (len(txhash_list), ))
    tx_hashes_tx = getrawtransaction_batch(txhashM
_list, verbose=True)
    return extract_addresses_from_txlist(tx_hashes_tx, getrawtransaction_batch)
def extract_addresses_from_txlist(tx_hashes_tx, _getrawtransaction_batch):
    helper for extract_addresses, seperated so we can pass in a mocked _getrawtransaction_batch for test purposes
    logger.debug('extract_addresses_from_txlist, txs: %d' % (len(tx_hashes_tx.keys()), ))
    tx_hashes_addresses = {}
    tx_inputs_hashes = set()  # use set to avoid duplicates
    for tx_hash, tx in tx_hashM
        tx_hashes_addresses[tx_hash] = set()
        for vout in tx['vout']:
            if 'addresses' in vout['scriptPubKey']:
                tx_hashes_addresses[tx_hash].update(tuple(vout['scriptPubKey']['addresses']))
        tx_inputs_hashes.update([vin['txid'] for vin in tx['vin']])
    logger.debug('extract_addresses, input TXs: %d' % (len(tx_inputs_hashes), ))
    # chunk txs to avoid huge memory spikes
    for tx_inputs_hashes_chunk in util.chunkify(list(tx_inputs_hashes), config.BACKENDM
_RAW_TRANSACTIONS_CACHE_SIZE):
        raw_transactions = _getrawtransaction_batch(tx_inputs_hashes_chunk, verbose=True)
        for tx_hash, tx in tx_hashes_tx.items():
            for vin in tx['vin']:
                vin_tx = raw_transactions.get(vin['txid'], None)
                if not vin_tx:
                    continue
                vout = vin_tx['vout'][vin['vout']]
                if 'addresses' in vout['scriptPubKey']:
                    tx_hashes_addresses[tx_hash].update(tuple(vout['scriptPubKey']M
    return tx_hashes_addresses, tx_hashes_tx
def getblockcount():
    return rpc('getblockcount', [])
def getblockhash(blockcount):
    return rpc('getblockhash', [blockcount])
def getblock(block_hash):
    return rpc('getblock', [block_hash, False])
def getrawtransaction(tx_hash, verbose=False, skip_missing=False):
    return getrawtransaction_batch([tx_hash], verbose=verbose, skip_missing=skip_missing)[tx_hash]
def getrawmempool():
    return rpc('getrawmempool', [])
def fee_per_kb(conf_tarM
get, mode, nblocks=None):
    :param conf_target:
    :return: fee_per_kb in satoshis, or None when unable to determine
    if nblocks is None and conf_target is None:
        conf_target = nblocks
    feeperkb = rpc('estimatesmartfee', [conf_target, mode])
    if 'errors' in feeperkb and feeperkb['errors'][0] == 'Insufficient data or no feerate found':
    return int(max(feeperkb['feerate'] * config.UNIT, config.DEFAULT_FEE_PER_KB_ESTIMATE_SMART))
wtransaction(tx_hex):
    return rpc('sendrawtransaction', [tx_hex])
GETRAWTRANSACTION_MAX_RETRIES=2
def getrawtransaction_batch(txhash_list, verbose=False, skip_missing=False, _retry=0):
    _logger = logger.getChild("getrawtransaction_batch")
    if len(txhash_list) > config.BACKEND_RAW_TRANSACTIONS_CACHE_SIZE:
        #don't try to load in more than BACKEND_RAW_TRANSACTIONS_CACHE_SIZE entries in a single call
        txhash_list_chunks = util.chunkify(txhash_list, config.BACKEND_RAW_TRANSACTIONS_CACHE_SIZE)
        for txhash_list_chunk in txhash_list_chunks:
            txes.update(getrawtransaction_batch(txhash_list_chunk, verbose=verbose, skip_missing=skip_missing))
    tx_hash_call_id = {}
    noncached_txhashes = set()
    txhash_list = set(txhash_list)
    # payload for transactions not in cache
    for tx_hash in txhash_list:
        if tx_hash not in raw_transactions_cache:
            call_id = binascii.hexlify(os.urandom(5)).decode('utf8')
                "method": 'getrawtransaction',
                "params": [tx_hash, 1],
                "jsonrpc": "2.0",
                "id": call_id
            noncached_txhashes.add(tx_hash)
            tx_hash_call_id[call_id] = tx_hash
    #refresh any/all cache entries that already exist in the cache,
    # so they're not inadvertently removed by another thread before we can consult them
    #(this assumes that the size of the working set for any given workload doesn't exceed tM
he max size of the cache)
    for tx_hash in txhash_list.difference(noncached_txhashes):
        raw_transactions_cache.refresh(tx_hash)
    _logger.debug("getrawtransaction_batch: txhash_list size: {} / raw_transactions_cache size: {} / # getrawtransaction calls: {}".format(
        len(txhash_list), len(raw_transactions_cache), len(payload)))
    # populate cache
    if len(payload) > 0:
        batch_responses = rpc_batch(payload)
        for response in batch_responses:
            if 'error' not in response M
or response['error'] is None:
                tx_hex = response['result']
                tx_hash = tx_hash_call_id[response['id']]
                raw_transactions_cache[tx_hash] = tx_hex
            elif skip_missing and 'error' in response and response['error']['code'] == -5:
                raw_transactions_cache[tx_hash] = None
                logging.debug('Missing TX with no raw info skipped (txhash: {}): {}'.format(
                    tx_hash_call_id.get(response.get('id', '??'), '??'), response['error']))M
                #TODO: this seems to happen for bogus transactions? Maybe handle it more gracefully than just erroring out?
                raise BackendRPCError('{} (txhash:: {})'.format(response['error'], tx_hash_call_id.get(response.get('id', '??'), '??')))
    # get transactions from cache
    for tx_hash in txhash_list:
            if verbose:
                result[tx_hash] = raw_transactions_cache[tx_hash]
                result[tx_hash] = raM
w_transactions_cache[tx_hash]['hex'] if raw_transactions_cache[tx_hash] is not None else None
        except KeyError as e: #shows up most likely due to finickyness with addrindex not always returning results that we need...
            _logger.warning("tx missing in rawtx cache: {} -- txhash_list size: {}, hash: {} / raw_transactions_cache size: {} / # rpc_batch calls: {} / txhash in noncached_txhashes: {} / txhash in txhash_list: {} -- list {}".format(
                e, len(txhash_list), hashlib.md5(json.dumps(lM
ist(txhash_list)).encode()).hexdigest(), len(raw_transactions_cache), len(payload),
                tx_hash in noncached_txhashes, tx_hash in txhash_list, list(txhash_list.difference(noncached_txhashes)) ))
            if  _retry < GETRAWTRANSACTION_MAX_RETRIES: #try again
                time.sleep(0.05 * (_retry + 1)) # Wait a bit, hitting the index non-stop may cause it to just break down... TODO: Better handling
                r = getrawtransaction_batch([tx_hash], verbose=verbose, skip_missing=skip_missing, _M
                result[tx_hash] = r[tx_hash]
                raise #already tried again, give up
def get_unspent_txouts(source):
    return indexd_rpc_call('/a/'+source+'/utxos')
def search_raw_transactions(address, unconfirmed=True):
    all_transactions = indexd_rpc_call('/a/'+address+'/txs?verbose=1')
        return all_transactions
    # filter for confirmed transactions only
    confirmed_transactions = list(filter(lambda t: 'confirmaM
tions' in t and t['confirmations'] > 0, all_transactions))
    return confirmed_transactions
def getindexblocksbehind():
    status = indexd_rpc_call('/status')
    if status['ready']:
    if status['blocksBehind']:
        return status['blocksBehind']
    raise IndexdRPCError('Unknown status for indexd')
def indexd_rpc_call(path):
    url = config.INDEXD_URL+path
        response = requests.get(url, headers={'content-type': 'application/json'},
t=config.REQUESTS_TIMEOUT)
    except (Timeout, ReadTimeout, ConnectionError):
        logger.debug('Could not connect to backend at `{}`.'.format(util.clean_url_for_log(url),))
    if response == None:
        if config.TESTNET:
            network = 'testnet'
        elif config.REGTEST:
            network = 'regtest'
            network = 'mainnet'
        raise IndexdRPCError('Cannot communicate with {} indexd server at `{}`.'.format(network, util.clean_url_for_log(url)))
    elif response.statuM
        raise IndexdRPCError('Indexd returned error: {} {} {}'.format(response.status_code, response.reason, response.text))
    elif response.status_code not in (200, 500):
        raise IndexdRPCError("Bad response from {}: {} {}".format(util.clean_url_for_log(url), response.status_code, response.reason))
    # Return result, with error handling.
    response_json = response.json()
    if isinstance(response_json, (list, tuple)) or 'error' not in response_json.keys() or response_json['error'] == NM
        return response_json
        raise IndexdRPCError('{}'.format(response_json['error']))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
logger = logging.getLogger(__name__)
from decimal import Decimal as D
import bitcoin as bitcoinlib
import bitcoin.rpc as bitcoinlib_rpc
from bitcoin.core import CBlock
from counterpartylib.lib import util
from counterpartylib.lib import script
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
from counterpartylib.lib.backend import addrindexrs
MEMPOOL_CACHE_INITIALIZED = False
def sortkeypicker(keynames):
    """http://stackoverflow.com/a/1143719"""
    for i, k in enumerate(keynames):
        if k[:1] == '-':
            keynames[i] = k[1:]
            negate.add(k[1:])
    def getit(adict):
       composite = [adict[k] for k in keynames]
       for i, (k, v) in enumerate(zip(keynamM
           if k in negate:
               composite[i] = -v
       return composite
    mdl = sys.modules['counterpartylib.lib.backend.{}'.format(config.BACKEND_NAME)]
    BACKEND().stop()
def getblockcount():
    return BACKEND().getblockcount()
def getblockhash(blockcount):
    return BACKEND().getblockhash(blockcount)
def getblock(block_hash):
    block_hex = BACKEND().getblock(block_hash)
    return CBlock.deserializM
e(util.unhexlify(block_hex))
def cache_pretx(txid, rawtx):
    PRETX_CACHE[binascii.hexlify(txid).decode('utf8')] = binascii.hexlify(rawtx).decode('utf8')
def clear_pretx(txid):
    del PRETX_CACHE[binascii.hexlify(txid).decode('utf8')]
def getrawtransaction(tx_hash, verbose=False, skip_missing=False):
    if tx_hash in PRETX_CACHE:
        return PRETX_CACHE[tx_hash]
        return BACKEND().getrawtransaction(tx_hash, verbose=verbose, skip_missing=skip_missing)
def getrawtransaction_batch(txhash_listM
, verbose=False, skip_missing=False):
    return BACKEND().getrawtransaction_batch(txhash_list, verbose=verbose, skip_missing=skip_missing)
def sendrawtransaction(tx_hex):
    return BACKEND().sendrawtransaction(tx_hex)
def getrawmempool():
    return BACKEND().getrawmempool()
def getindexblocksbehind():
    return BACKEND().getindexblocksbehind()
def extract_addresses(txhash_list):
    return BACKEND().extract_addresses(txhash_list)
def ensure_script_pub_key_for_inputs(coins):
    txhash_set = set()
        if 'scriptPubKey' not in coin:
            txhash_set.add(coin['txid'])
    if len(txhash_set) > 0:
        txs = BACKEND().getrawtransaction_batch(list(txhash_set), verbose=True, skip_missing=False)
        for coin in coins:
            if 'scriptPubKey' not in coin:
                # get the scriptPubKey
                txid = coin['txid']
                for vout in txs[txid]['vout']:
                    if vout['n'] == coin['vout']:
                        coin['scriptPubKey'] = vout['scM
def fee_per_kb(conf_target, mode, nblocks=None):
    :param conf_target:
    :return: fee_per_kb in satoshis, or None when unable to determine
    return BACKEND().fee_per_kb(conf_target, mode, nblocks=nblocks)
def deserialize(tx_hex):
    return bitcoinlib.core.CTransaction.deserialize(binascii.unhexlify(tx_hex))
    return bitcoinlib.core.CTransaction.serialize(ctx)
def is_valid(address):
        script.valiM
    except script.AddressError:
        return False
def get_txhash_list(block):
    return [bitcoinlib.core.b2lx(ctx.GetHash()) for ctx in block.vtx]
def get_tx_list(block):
    raw_transactions = {}
    tx_hash_list = []
    for ctx in block.vtx:
        if util.enabled('correct_segwit_txids'):
            hsh = ctx.GetTxid()
            hsh = ctx.GetHash()
        tx_hash = bitcoinlib.core.b2lx(hsh)
        raw = ctx.serialize()
        tx_hash_list.append(tx_hM
        raw_transactions[tx_hash] = bitcoinlib.core.b2x(raw)
    return (tx_hash_list, raw_transactions)
def sort_unspent_txouts(unspent, unconfirmed=False):
    # Filter out all dust amounts to avoid bloating the resultant transaction
    unspent = list(filter(lambda x: x['value'] > config.DEFAULT_MULTISIG_DUST_SIZE, unspent))
    # Sort by amount, using the largest UTXOs available
    if config.REGTEST:
        # REGTEST has a lot of coinbase inputs that can't be spent due to maturity
        # this doesn'M
t usually happens on mainnet or testnet because most fednodes aren't mining
        unspent = sorted(unspent, key=lambda x: (x['confirmations'], x['value']), reverse=True)
        unspent = sorted(unspent, key=lambda x: x['value'], reverse=True)
def get_btc_supply(normalize=False):
    """returns the total supply of {} (based on what Bitcoin Core says the current block height is)""".format(config.BTC)
    block_count = getblockcount()
    blocks_remaining = block_count
    while blocks_remaining > 0:
        if blocks_remaining >= 210000:
            blocks_remaining -= 210000
            total_supply += 210000 * reward
            reward /= 2
            total_supply += (blocks_remaining * reward)
            blocks_remaining = 0
    return total_supply if normalize else int(total_supply * config.UNIT)
class MempoolError(Exception):
def get_unspent_txouts(source, unconfirmed=False, unspent_tx_hash=None):
    """returns a list of uM
nspent outputs for a specific address
    @return: A list of dicts, with each entry in the dict having the following keys:
    unspent = BACKEND().get_unspent_txouts(source)
    # filter by unspent_tx_hash
    if unspent_tx_hash is not None:
        unspent = list(filter(lambda x: x['txId'] == unspent_tx_hash, unspent))
    # filter unconfirmed
    if not unconfirmed:
        unspent = [utxo for utxo in unspent if utxo['confirmations'] > 0]
    for utxo in unspent:
        utxo['amount'] = M
float(utxo['value'] / config.UNIT)
        utxo['txid'] = utxo['txId']
        del utxo['txId']
        # do not add scriptPubKey
def search_raw_transactions(address, unconfirmed=True):
    return BACKEND().search_raw_transactions(address, unconfirmed)
class UnknownPubKeyError(Exception):
def pubkeyhash_to_pubkey(pubkeyhash, provided_pubkeys=None):
    # Search provided pubkeys.
    if provided_pubkeys:
        if type(provided_pubkeys) != list:
            provided_pubkeys = [providM
        for pubkey in provided_pubkeys:
            if pubkeyhash == script.pubkey_to_pubkeyhash(util.unhexlify(pubkey)):
                return pubkey
            elif pubkeyhash == script.pubkey_to_p2whash(util.unhexlify(pubkey)):
                return pubkey
    # Search blockchain.
    raw_transactions = search_raw_transactions(pubkeyhash, unconfirmed=True)
    for tx_id in raw_transactions:
        tx = raw_transactions[tx_id]
        for vin in tx['vin']:
            if 'txinwitness' in vin:
             if len(vin['txinwitness']) >= 2:
                    # catch unhexlify errs for when txinwitness[1] isn't a witness program (eg; for P2W)
                    try:
                        pubkey = vin['txinwitness'][1]
                        if pubkeyhash == script.pubkey_to_p2whash(util.unhexlify(pubkey)):
                            return pubkey
                    except binascii.Error:
                        pass
            elif 'coinbase' not in vin:
                scriptsig = vin['scriptSig']M
                asm = scriptsig['asm'].split(' ')
                if len(asm) >= 2:
                    # catch unhexlify errs for when asm[1] isn't a pubkey (eg; for P2SH)
                    try:
                        pubkey = asm[1]
                        if pubkeyhash == script.pubkey_to_pubkeyhash(util.unhexlify(pubkey)):
                            return pubkey
                    except binascii.Error:
                        pass
    raise UnknownPubKeyError('Public key was neither provided nor publisM
hed in blockchain.')
def multisig_pubkeyhashes_to_pubkeys(address, provided_pubkeys=None):
    signatures_required, pubkeyhashes, signatures_possible = script.extract_array(address)
    pubkeys = [pubkeyhash_to_pubkey(pubkeyhash, provided_pubkeys) for pubkeyhash in pubkeyhashes]
    return script.construct_array(signatures_required, pubkeys, signatures_possible)
def init_mempool_cache():
    """prime the mempool cache, so that functioning is faster...
    global MEMPOOL_CACHE_INITIALIZED
g('Initializing mempool cache...')
    start = time.time()
    mempool_txhash_list = getrawmempool()
    #with this function, don't try to load in more than BACKEND_RAW_TRANSACTIONS_CACHE_SIZE entries
    num_tx = min(len(mempool_txhash_list), config.BACKEND_RAW_TRANSACTIONS_CACHE_SIZE)
    mempool_tx = BACKEND().getrawtransaction_batch(mempool_txhash_list[:num_tx], skip_missing=True, verbose=True)
    vin_txhash_list = []
    max_remaining_num_tx = config.BACKEND_RAW_TRANSACTIONS_CACHE_SIZE - num_tx
        for txid in mempool_tx:
            tx = mempool_tx[txid]
            if not(tx is None):
                vin_txhash_list += [vin['txid'] for vin in tx['vin']]
        BACKEND().getrawtransaction_batch(vin_txhash_list[:max_remaining_num_tx], skip_missing=True, verbose=True)
    MEMPOOL_CACHE_INITIALIZED = True
    logger.info('Mempool cache initialized: {:.2f}s for {:,} transactions'.format(time.time() - start, num_tx + min(max_remaining_num_tx, len(vin_txhash_list))))
expandtab shiftwidth=4 softtabstop=4
#### bc_data_stream.py
# Workalike python implementation of Bitcoin's CDataStream class.
from .exceptions import SerializationError
class BCDataStream(object):
  def __init__(self):
    self.input = None
    self.read_cursor = 0
    self.input = None
    self.read_cursor = 0
  def write(self, bytes):  # Initialize with string of bytes
    if self.input is None:
      self.input = bytes
      self.input += bM
  def map_file(self, file, start):  # Initialize with bytes from file
    self.input = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
    self.read_cursor = start
  def seek_file(self, position):
    self.read_cursor = position
  def close_file(self):
    self.input.close()
  def read_string(self):
    # Strings are encoded depending on length:
    # 0 to 252 :  1-byte-length followed by bytes (if any)
    # 253 to 65,535 : byte'253' 2-byte-length followed by bytes
    # 65,536 to 4,294,967,295 : bytM
e '254' 4-byte-length followed by bytes
    # ... and the Bitcoin client is coded to understand:
    # greater than 4,294,967,295 : byte '255' 8-byte-length followed by bytes of string
    # ... but I don't think it actually handles any strings that big.
    if self.input is None:
      raise SerializationError("call write(bytes) before trying to deserialize")
      length = self.read_compact_size()
    except IndexError:
      raise SerializationError("attempt to read past end of buffer")
f.read_bytes(length)
  def write_string(self, string):
    # Length-encoded as with read-string
    self.write_compact_size(len(string))
    self.write(string)
  def read_bytes(self, length):
      result = self.input[self.read_cursor:self.read_cursor+length]
      self.read_cursor += length
    except IndexError:
      raise SerializationError("attempt to read past end of buffer")
  def read_boolean(self): return self.read_bytes(1)[0] != chr(0)
  def read_int16(self):M
 return self._read_num('<h')
  def read_uint16(self): return self._read_num('<H')
  def read_int32(self): return self._read_num('<i')
  def read_uint32(self): return self._read_num('<I')
  def read_int64(self): return self._read_num('<q')
  def read_uint64(self): return self._read_num('<Q')
  def write_boolean(self, val): return self.write(chr(1) if val else chr(0))
  def write_int16(self, val): return self._write_num('<h', val)
  def write_uint16(self, val): return self._write_num('<H', val)
  def write_int32(selM
f, val): return self._write_num('<i', val)
  def write_uint32(self, val): return self._write_num('<I', val)
  def write_int64(self, val): return self._write_num('<q', val)
  def write_uint64(self, val): return self._write_num('<Q', val)
  def read_compact_size(self):
    size = self.input[self.read_cursor]
    self.read_cursor += 1
      size = self._read_num('<H')
    elif size == 254:
      size = self._read_num('<I')
    elif size == 255:
      size = self._read_num('<Q')
def write_compact_size(self, size):
      raise SerializationError("attempt to write size < 0")
    elif size < 253:
       self.write(chr(size))
    elif size < 2**16:
      self.write('\xfd')
      self._write_num('<H', size)
    elif size < 2**32:
      self.write('\xfe')
      self._write_num('<I', size)
    elif size < 2**64:
      self.write('\xff')
      self._write_num('<Q', size)
  def _read_num(self, format):
    (i,) = struct.unpack_from(format, self.input, self.read_cursor)
ad_cursor += struct.calcsize(format)
  def _write_num(self, format, num):
    s = struct.pack(format, num)
  def read_var_int(self):
        cur_byte = self.read_bytes(1)[0]
        n = (n << 7) | (cur_byte & 0x7F)
        if cur_byte & 0x80:
            return n
#### blocks_parser.py
import os, json, time, logging, binascii
logger = logging.getLogger(__name__)
from .bc_data_stream import BCDataStrM
from .utils import b2h, double_hash, ib2h, inverse_hash
def open_leveldb(db_dir):
        import plyvel
        raise Exception("Please install the plyvel package via pip3.")
        return plyvel.DB(db_dir, create_if_missing=False)
    except plyvel._plyvel.IOError as e:
        logger.info(str(e))
        raise Exception("Ensure that bitcoind is stopped.")
class BlockchainParser():
    def __init__(self, blocks_dir, leveldb_dir):
        self.blocks_dir = blocks_dir
self.leveldb_dir = leveldb_dir
        self.file_num = -1
        self.current_file_size = 0
        self.current_block_file = None
        self.data_stream = None
        self.ldb = open_leveldb(self.leveldb_dir)
    def read_tx_in(self, vds):
        tx_in['txid'] = ib2h(vds.read_bytes(32))
        tx_in['vout'] = vds.read_uint32()
        script_sig_size = vds.read_compact_size()
        tx_in['scriptSig'] = b2h(vds.read_bytes(script_sig_size))
        tx_in['sequence'] = vds.read_uint32()
      if tx_in['txid'] == '0000000000000000000000000000000000000000000000000000000000000000':
            tx_in = {
                'coinbase': tx_in['scriptSig'],
                'sequence': tx_in['sequence']
        return tx_in
    def read_tx_out(self, vds):
        tx_out['value'] = vds.read_int64() / 100000000
        script = vds.read_bytes(vds.read_compact_size())
        tx_out['scriptPubKey'] = {
            'hex': b2h(script)
        return tx_out
d_transaction(self, vds):
        transaction = {}
        start_pos = vds.read_cursor
        transaction['version'] = vds.read_int32()
        transaction['vin'] = []
        for i in range(vds.read_compact_size()):
            transaction['vin'].append(self.read_tx_in(vds))
        transaction['vout'] = []
        for i in range(vds.read_compact_size()):
            transaction['vout'].append(self.read_tx_out(vds))
        transaction['lock_time'] = vds.read_uint32()
        data = vds.input[start_pos:vds.reaM
        transaction['tx_hash'] = ib2h(double_hash(data))
        transaction['__data__'] = b2h(data)
        return transaction
    def read_block_header(self, vds):
        block_header = {}
        block_header['magic_bytes'] = vds.read_int32()
        #if block_header['magic_bytes'] != 118034699:
         #   raise Exception('Not a block')
        block_header['block_size'] = vds.read_int32()
        header_start = vds.read_cursor
        block_header['version'] = vds.read_int32()
        block_headerM
['hash_prev'] = ib2h(vds.read_bytes(32))
        block_header['hash_merkle_root'] = ib2h(vds.read_bytes(32))
        block_header['block_time'] = vds.read_uint32()
        block_header['bits'] = vds.read_uint32()
        block_header['nonce'] = vds.read_uint32()
        header_end = vds.read_cursor
        header = vds.input[header_start:header_end]
        block_header['block_hash'] = ib2h(double_hash(header))
        block_header['__header__'] = b2h(header)
        return block_header
    def read_block(self, vdM
        block = self.read_block_header(vds)
        block['transaction_count'] = vds.read_compact_size()
        block['transactions'] = []
        for i in range(block['transaction_count']):
            block['transactions'].append(self.read_transaction(vds))
        return block
    def prepare_data_stream(self, file_num, pos_in_file):
        if self.data_stream is None or file_num != self.file_num:
            self.file_num = file_num
            if self.current_block_file:
                self.current_bloM
            data_file_path = os.path.join(self.blocks_dir, 'blk%05d.dat' % (self.file_num,))
            self.current_block_file = open(data_file_path, "rb")
            self.data_stream = BCDataStream()
            self.data_stream.map_file(self.current_block_file, pos_in_file)
            self.data_stream.seek_file(pos_in_file)
    def read_raw_block(self, block_hash):
        block_hash = binascii.unhexlify(inverse_hash(block_hash))
        block_data = self.ldb.get(bytes('b', 'utfM
        ds = BCDataStream()
        ds.write(block_data)
        version = ds.read_var_int()
        height = ds.read_var_int()
        status = ds.read_var_int()
        tx_count = ds.read_var_int()
        file_num = ds.read_var_int()
        block_pos_in_file = ds.read_var_int() - 8
        block_undo_pos_in_file = ds.read_var_int()
        block_header = ds.read_bytes(80)
        self.prepare_data_stream(file_num, block_pos_in_file)
        block = self.read_block(self.data_stream)
 block['block_index'] = height
        return block
    def read_raw_transaction(self, tx_hash):
        tx_hash = binascii.unhexlify(inverse_hash(tx_hash))
        tx_data = self.ldb.get(bytes('t', 'utf-8') + tx_hash)
        ds = BCDataStream()
        ds.write(tx_data)
        file_num = ds.read_var_int()
        block_pos_in_file = ds.read_var_int()
        tx_pos_in_block = ds.read_var_int()
        tx_pos_in_file = block_pos_in_file + 80 + tx_pos_in_block
        self.prepare_data_stream(file_nuM
        transaction = self.read_transaction(self.data_stream)
        return transaction
    def close(self):
        if self.current_block_file:
            self.current_block_file.close()
        self.ldb.close()
class ChainstateParser():
    def __init__(self, leveldb_dir):
        self.ldb = open_leveldb(leveldb_dir)
    def get_last_block_hash(self):
        block_hash = self.ldb.get(bytes('B', 'utf-8'))
        block_hash = ib2h(block_hash)
        return block_hash
        self.ldb.close()
class SolvingError(Exception): pass
class SerializationError(Exception):
  """ Thrown when there's a problem deserializing or serializing """
import binascii, os, random, json, hashlib
bytes_from_int = chr if bytes == str else lambda x: bytes([x])
    return binascii.hexlify(b).decode('utf-8')
def random_hex(length):
    return binascii.b2a_hex(os.urandom(length))
def double_hash(b):
	return hashlib.sha256(hashliM
b.sha256(b).digest()).digest()
def inverse_hash(hashstring):
	hashstring = hashstring[::-1]
	return ''.join([hashstring[i:i+2][::-1] for i in range(0, len(hashstring), 2)])
	return inverse_hash(b2h(b))
class JsonDecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o,  decimal.Decimal):
            return str(o)
        return super(DecimalEncoder, self).default(o)
#### p2sh_encoding.py
This module contains p2sh data encodingM
import traceback # not needed if not printing exceptions on p2sh decoding
logger = logging.getLogger(__name__)
import bitcoin as bitcoinlib
from bitcoin.core.script import CScript
from counterpartylib.lib import config
from counterpartylib.lib import script
from counterpartylib.lib import exceptions
def maximum_data_chunk_size(pubkeylength):
    if pubkeylength >= 0:
        return bitcoinlib.core.script.MAX_SCRIPT_ELEMENT_SIZE - len(confiM
g.PREFIX) - pubkeylength - 12 #Two bytes are for unique offset. This will work for a little more than 1000 outputs
        return bitcoinlib.core.script.MAX_SCRIPT_ELEMENT_SIZE - len(config.PREFIX) - 44 # Redeemscript size for p2pkh addresses, multisig won't work here
def calculate_outputs(destination_outputs, data_array, fee_per_kb, exact_fee=None):
    datatx_size = 10  # 10 base
    datatx_size += 181  # 181 for source input
    datatx_size += (25 + 9) * len(destination_outputs)  # destination outputsM
    datatx_size += 13  # opreturn that signals P2SH encoding
    datatx_size += len(data_array) * (9 + 181)  # size of p2sh inputs, excl data
    datatx_size += sum([len(data_chunk) for data_chunk in data_array])  # data in scriptSig
    datatx_necessary_fee = int(datatx_size / 1000 * fee_per_kb)
    pretx_output_size = 10  # 10 base
    pretx_output_size += len(data_array) * 29  # size of P2SH output
    size_for_fee = pretx_output_size
    # split the tx fee evenly between all datatx outputs
= math.ceil(datatx_necessary_fee / len(data_array))
    data_value = config.DEFAULT_REGULAR_DUST_SIZE
    # adjust the data output with the new value and recalculate data_btc_out
    data_btc_out = data_value * len(data_array)
        remain_fee = exact_fee - data_value * len(data_array)
        if remain_fee > 0:
            #if the dust isn't enough to reach the exact_fee, data value will be an array with only the last fee bumped
            data_value = [data_value for i in range(len(data_arrM
            data_value[len(data_array)-1] = data_value[len(data_array)-1] + remain_fee
            data_btc_out = exact_fee
    data_output = (data_array, data_value)
    logger.getChild('p2shdebug').debug('datatx size: %d fee: %d' % (datatx_size, datatx_necessary_fee))
    logger.getChild('p2shdebug').debug('pretx output size: %d' % (pretx_output_size, ))
    logger.getChild('p2shdebug').debug('size_for_fee: %d' % (size_for_fee, ))
    return size_for_fee, datatx_necessary_fee, data_value, dM
def decode_p2sh_input(asm, p2sh_is_segwit=False):
    ''' Looks at the scriptSig for the input of the p2sh-encoded data transaction
        [signature] [data] [OP_HASH160 ... OP_EQUAL]
    pubkey, source, redeem_script_is_valid, found_data = decode_data_redeem_script(asm[-1], p2sh_is_segwit)
    if redeem_script_is_valid:
        # this is a signed transaction, so we got {sig[,sig]} {datachunk} {redeemScript}
        datachunk = found_data
        redeemScript = asm[-1] #asm[-2:]
    #print('ASM:', len(asm))
        pubkey, source, redeem_script_is_valid, found_data = decode_data_redeem_script(asm[-1], p2sh_is_segwit)
        if not redeem_script_is_valid or len(asm) != 3:
            return None, None, None
        # this is an unsigned transaction (last is outputScript), so we got [datachunk] [redeemScript] [temporaryOutputScript]
        datachunk, redeemScript, _substituteScript = asm
    data = datachunk
    if data[:len(config.PREFIX)] == config.PREFIX:
        data = data[len(confiM
        if data == b'':
            return source, None, None
        raise exceptions.DecodeError('unrecognised P2SH output')
    return source, None, data
def decode_data_push(arr, pos):
    opcode = bitcoinlib.core.script.CScriptOp(arr[pos])
    if opcode > 0 and opcode < bitcoinlib.core.script.OP_PUSHDATA1:
        pushlen = arr[pos]
    elif opcode == bitcoinlib.core.script.OP_PUSHDATA1:
        pushlen = arr[pos + 1]
elif opcode == bitcoinlib.core.script.OP_PUSHDATA2:
        (pushlen, ) = struct.unpack('<H', arr[pos + 1:pos + 3])
    elif opcode == bitcoinlib.core.script.OP_PUSHDATA4:
        (pushlen, ) = struct.unpack('<L', arr[pos + 1:pos + 5])
    return pos + pushlen, arr[pos:pos + pushlen]
def decode_data_redeem_script(redeemScript, p2sh_is_segwit=False):
    script_len = len(redeemScript)
    found_data = b''
    if script_len == 41 and \
        redeemScript[0] == bitcoinlib.core.scM
        redeemScript[35] == bitcoinlib.core.script.OP_CHECKSIGVERIFY and \
        redeemScript[37] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[38] == bitcoinlib.core.script.OP_DEPTH and \
        redeemScript[39] == bitcoinlib.core.script.OP_0 and \
        redeemScript[40] == bitcoinlib.core.script.OP_EQUAL:
            # - OP_DROP [push] [33-byte pubkey] OP_CHECKSIGVERIFY [n] OP_DROP OP_DEPTH 0 OP_EQUAL
            pubkey = redeemScript[2:35]
            if p2sh_is_segwit:
             source = script.pubkey_to_p2whash(pubkey)
                source = script.pubkey_to_pubkeyhash(pubkey)
            redeem_script_is_valid = True
    elif script_len > 41 and \
        redeemScript[0] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[script_len-4] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[script_len-3] == bitcoinlib.core.script.OP_DEPTH and \
        redeemScript[script_len-2] == bitcoinlib.core.script.OP_0 and \
        redeemScript[scripM
t_len-1] == bitcoinlib.core.script.OP_EQUAL:
            # - OP_DROP {arbitrary multisig script} [n] OP_DROP OP_DEPTH 0 OP_EQUAL
            pubkey = None
            source = None
            redeem_script_is_valid = True
        pubkey = None
        source = None
        redeem_script_is_valid = False
            opcode = bitcoinlib.core.script.CScriptOp(redeemScript[0])
            if opcode > bitcoinlib.core.script.OP_0 and opcode < bitcoinlib.core.script.OP_PUSHDATA1 or \
   opcode in (bitcoinlib.core.script.OP_PUSHDATA1, bitcoinlib.core.script.OP_PUSHDATA2, bitcoinlib.core.script.OP_PUSHDATA4):
                pos = 0
                pos, found_data = decode_data_push(redeemScript, 0)
                if redeemScript[pos] == bitcoinlib.core.script.OP_DROP:
                    pos += 1
                    valid_sig = False
                    opcode = redeemScript[pos]
                    if type(opcode) != type(''):
                        if opcode >= bitcoinlib.core.script.OP_2 M
and opcode <= bitcoinlib.core.script.OP_15:
                            # it's multisig
                            req_sigs = opcode - bitcoinlib.core.script.OP_1 + 1
                            pos += 1
                            pubkey = None
                            num_sigs = 0
                            found_sigs = False
                            while not found_sigs:
                                pos, npubkey = decode_data_push(redeemScript, pos)
                                num_sigs += 1
                          if redeemScript[pos] - bitcoinlib.core.script.OP_1 + 1 == num_sigs:
                                    found_sigs = True
                            pos += 1
                            valid_sig = redeemScript[pos] == bitcoinlib.core.script.OP_CHECKMULTISIGVERIFY
                        else:
                            # it's p2pkh
                            pos, pubkey = decode_data_push(redeemScript, pos)
                            if p2sh_is_segwit:
                              M
  source = script.pubkey_to_p2whash(pubkey)
                            else:
                                source = script.pubkey_to_pubkeyhash(pubkey)
                            valid_sig = redeemScript[pos] == bitcoinlib.core.script.OP_CHECKSIGVERIFY
                        pos += 1
                        if valid_sig:
                            uniqueOffsetLength = 0
                            for i in range(pos+1, len(redeemScript)):
                                if redeemScript[i] == bitcoinlib.corM
                                    uniqueOffsetLength = i-pos-1
                                    break
                            redeem_script_is_valid = redeemScript[pos + 1 + uniqueOffsetLength] == bitcoinlib.core.script.OP_DROP and \
                                redeemScript[pos + 2 + uniqueOffsetLength] == bitcoinlib.core.script.OP_DEPTH and \
                                redeemScript[pos + 3 + uniqueOffsetLength] == 0 and \
                                redeemScript[pos + 4 + uM
niqueOffsetLength] == bitcoinlib.core.script.OP_EQUAL
        except Exception as e:
            pass #traceback.print_exc()
    return pubkey, source, redeem_script_is_valid, found_data
def make_p2sh_encoding_redeemscript(datachunk, n, pubKey=None, multisig_pubkeys=None, multisig_pubkeys_required=None):
    _logger = logger.getChild('p2sh_encoding')
    assert len(datachunk) <= bitcoinlib.core.script.MAX_SCRIPT_ELEMENT_SIZE
    dataDropScript = [datachunk, bitcoinlib.core.script.OP_DROP] # just drop the data chM
    cleanupScript = [n, bitcoinlib.core.script.OP_DROP, bitcoinlib.core.script.OP_DEPTH, 0, bitcoinlib.core.script.OP_EQUAL] # unique offset + prevent scriptSig malleability
    if pubKey is not None:
        # a p2pkh script looks like this: {pubkey} OP_CHECKSIGVERIFY
        verifyOwnerScript = [pubKey, bitcoinlib.core.script.OP_CHECKSIGVERIFY]
    elif multisig_pubkeys_required is not None and multisig_pubkeys:
        # a 2-of-3 multisig looks like this:
        #   2 {pubkey1} {pubkey2} {pubkey3} 3 OP_CHEM
        multisig_pubkeys_required = int(multisig_pubkeys_required)
        if multisig_pubkeys_required < 2 or multisig_pubkeys_required > 15:
            raise exceptions.TransactionError('invalid multisig pubkeys value')
        verifyOwnerScript = [multisig_pubkeys_required]
        for multisig_pubkey in multisig_pubkeys:
            verifyOwnerScript.append(multisig_pubkey)
        verifyOwnerScript = verifyOwnerScript + [len(multisig_pubkeys), bitcoinlib.core.script.OP_CHECKMULTISIGVERIFY]
        raise exceptions.TransactionError('Either pubKey or multisig pubKeys must be provided')
    #redeemScript = CScript(datachunk) + CScript(dataDropScript + verifyOwnerScript + cleanupScript)
    redeemScript = CScript(dataDropScript + verifyOwnerScript + cleanupScript)
    _logger.debug('datachunk %s' % (binascii.hexlify(datachunk)))
    _logger.debug('dataDropScript %s (%s)' % (repr(CScript(dataDropScript)), binascii.hexlify(CScript(dataDropScript))))
    _logger.debug('verifyOwnerScript %s (%s)' %M
 (repr(CScript(verifyOwnerScript)), binascii.hexlify(CScript(verifyOwnerScript))))
    _logger.debug('entire redeemScript %s (%s)' % (repr(redeemScript), binascii.hexlify(redeemScript)))
    #scriptSig = CScript([]) + redeemScript  # PUSH(datachunk) + redeemScript
    scriptSig = CScript([redeemScript])
    outputScript = redeemScript.to_p2sh_scriptPubKey()
    _logger.debug('scriptSig %s (%s)' % (repr(scriptSig), binascii.hexlify(scriptSig)))
    _logger.debug('outputScript %s (%s)' % (repr(outputScript), binascM
ii.hexlify(outputScript)))
    # outputScript looks like OP_HASH160 {{ hash160([redeemScript]) }} OP_EQUALVERIFY
    # redeemScript looks like OP_DROP {{ pubkey }} OP_CHECKSIGVERIFY {{ n }} OP_DROP OP_DEPTH 0 OP_EQUAL
    # scriptSig is {{ datachunk }} OP_DROP {{ pubkey }} OP_CHECKSIGVERIFY {{ n }} OP_DROP OP_DEPTH 0 OP_EQUAL
    return scriptSig, redeemScript, outputScript
def make_standard_p2sh_multisig_script(multisig_pubkeys, multisig_pubkeys_required):
    # a 2-of-3 multisig looks like this:
ey1} {pubkey2} {pubkey3} 3 OP_CHECKMULTISIG
    multisig_pubkeys_required = int(multisig_pubkeys_required)
    multisig_script = [multisig_pubkeys_required]
    for multisig_pubkey in multisig_pubkeys:
        multisig_script.append(multisig_pubkey)
    multisig_script = multisig_script + [len(multisig_pubkeys), bitcoinlib.core.script.OP_CHECKMULTISIG]
    return multisig_script
Construct and serialize the Bitcoin transactions that are Counterparty transactions.
logger = logging.getLogger(__name__)
import bitcoin as bitcoinlib
from bitcoin.core import Hash160
from bitcoin.core.script import CScript
from bitcoin.wallet import P2PKHBitcoinAddress, P2SHBitcoinAddress
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
from counterpartylib.lib import util
ounterpartylib.lib import script
from counterpartylib.lib import backend
from counterpartylib.lib import arc4
from counterpartylib.lib.transaction_helper import p2sh_encoding
from bitcoin.bech32 import CBech32Data
OP_PUSHDATA1 = b'\x4c'
OP_HASH160 = b'\xa9'
OP_EQUALVERIFY = b'\x88'
OP_CHECKSIG = b'\xac'
OP_CHECKMULTISIG = b'\xae'
UTXO_LOCKS_PER_ADDREM
SS_MAXSIZE = 5000  # set higher than the max number of UTXOs we should expect to
                                       # manage in an aging cache for any one source address, at any one period
        return (i).to_bytes(1, byteorder='little')
    elif i <= 0xffff:
        return b'\xfd' + (i).to_bytes(2, byteorder='little')
    elif i <= 0xffffffff:
        return b'\xfe' + (i).to_bytes(4, byteorder='little')
        return b'\xff' + (i).to_bytes(8, byteorder='little')
        return (i).to_bytes(1, byteorder='little')              # Push i bytes.
        return b'\x4c' + (i).to_bytes(1, byteorder='little')    # OP_PUSHDATA1
    elif i <= 0xffff:
        return b'\x4d' + (i).to_bytes(2, byteorder='little')    # OP_PUSHDATA2
        return b'\x4e' + (i).to_bytes(4, byteorder='little')    # OP_PUSHDATA4
def get_script(address):
    if script.is_multisig(address):
        return get_multisig_script(address)
 script.is_bech32(address):
        return get_p2w_script(address)
            return get_monosig_script(address)
        except script.VersionByteError as e:
            return get_p2sh_script(address)
def get_multisig_script(address):
    signatures_required, pubkeys, signatures_possible = script.extract_array(address)
    # Required signatures.
    if signatures_required == 1:
        op_required = OP_1
    elif signatures_required == 2:
    elif signatures_required == 3:
        op_required = OP_3
        raise script.InputError('Required signatures must be 1, 2 or 3.')
    # Required signatures.
    # Note 1-of-1 addresses are not supported (they don't go through extract_array anyway).
    if signatures_possible == 2:
        op_total = OP_2
    elif signatures_possible == 3:
        op_total = OP_3
        raise script.InputError('Total possible signatures must be 2 or 3.')
    # Construct script.
 = op_required                                # Required signatures
    for public_key in pubkeys:
        public_key = binascii.unhexlify(public_key)
        tx_script += op_push(len(public_key))              # Push bytes of public key
        tx_script += public_key                            # Data chunk (fake) public key
    tx_script += op_total                                  # Total signatures
    tx_script += OP_CHECKMULTISIG                          # OP_CHECKMULTISIG
    return (tx_script, None)
et_monosig_script(address):
    # Construct script.
    pubkeyhash = script.base58_check_decode(address, config.ADDRESSVERSION)
    tx_script = OP_DUP                                     # OP_DUP
    tx_script += OP_HASH160                                # OP_HASH160
    tx_script += op_push(20)                               # Push 0x14 bytes
    tx_script += pubkeyhash                                # pubKeyHash
    tx_script += OP_EQUALVERIFY                            # OP_EQUALVERIFY
    tx_script += OP_CHECKSM
IG                               # OP_CHECKSIG
    return (tx_script, None)
def get_p2sh_script(address):
    # Construct script.
    scripthash = script.base58_check_decode(address, config.P2SH_ADDRESSVERSION)
    tx_script = OP_HASH160
    tx_script += op_push(len(scripthash))
    tx_script += scripthash
    tx_script += OP_EQUAL
    return (tx_script, None)
def get_p2w_script(address):
    # Construct script.
    scripthash = bytes(CBech32Data(address))
    if len(scripthash) == 20:
        # P2WPKH encM
        tx_script = OP_0
        tx_script += b'\x14'
        tx_script += scripthash
        witness_script = OP_HASH160
        witness_script += op_push(len(scripthash))
        witness_script += scripthash
        witness_script += OP_EQUAL
        return (tx_script, witness_script)
    elif len(scripthash) == 32:
        # P2WSH encoding
        raise Exception('P2WSH encoding not yet supported')
def make_fully_valid(pubkey_start):
    """Take a too short data pubkey and make it look like a real pubM
    Take an obfuscated chunk of data that is two bytes too short to be a pubkey and
    add a sign byte to its beginning and a nonce byte to its end. Choose these
    bytes so that the resulting sequence of bytes is a fully valid pubkey (i.e. on
    the ECDSA curve). Find the correct bytes by guessing randomly until the check
    passes. (In parsing, these two bytes are ignored.)
    assert type(pubkey_start) == bytes
    assert len(pubkey_start) == 31    # One sign byte and one nonce byte required (fM
    random_bytes = hashlib.sha256(pubkey_start).digest()      # Deterministically generated, for unit tests.
    sign = (random_bytes[0] & 0b1) + 2                  # 0x02 or 0x03
    nonce = initial_nonce = random_bytes[1]
    while not script.is_fully_valid(pubkey):
        # Increment nonce.
        assert nonce != initial_nonce
        # Construct a possibly fully valid public key.
        pubkey = bytes([sign]) + pubkey_start + bytes([nonce % 256])
rt len(pubkey) == 33
def serialise(encoding, inputs, destination_outputs, data_output=None, change_output=None, dust_return_pubkey=None):
    s  = (1).to_bytes(4, byteorder='little')                # Version
    use_segwit = False
    for i in range(len(inputs)):
        txin = inputs[i]
        spk = txin['scriptPubKey']
        if spk[0:2] == '00': # Witness version 0
            datalen = binascii.unhexlify(spk[2:4])[0]
            if datalen == 20 or datalen == 32:
                # 20 is fM
or P2WPKH and 32 is for P2WSH
                if not(use_segwit):
                    s  = (2).to_bytes(4, byteorder='little') # Rewrite version
                    use_segwit = True
                txin['is_segwit'] = True
        s += b'\x00' # marker
        s += b'\x01' # flag
    # Number of inputs.
    s += var_int(int(len(inputs)))
    witness_txins = []
    witness_data = {}
    # List of Inputs.
    for i in range(len(inputs)):
        txin = inputs[i]
        s += binascii.unhexlifM
y(bytes(txin['txid'], 'utf-8'))[::-1]         # TxOutHash
        s += txin['vout'].to_bytes(4, byteorder='little')   # TxOutIndex
        tx_script = binascii.unhexlify(bytes(txin['scriptPubKey'], 'utf-8'))
        s += var_int(int(len(tx_script)))                      # Script length
        s += tx_script                                         # Script
        s += b'\xff' * 4                                    # Sequence
    # Number of outputs.
    n += len(destination_outputs)
    if data_output:M
        data_array, value = data_output
        for data_chunk in data_array: n += 1
        data_array = []
    if change_output: n += 1
    # Destination output.
    for destination, value in destination_outputs:
        s += value.to_bytes(8, byteorder='little')          # Value
        tx_script, witness_script = get_script(destination)
        #if use_segwit and destination in witness_data: # Not deleteing, We will need this for P2WSH
        #    witness_data[destination].appeM
        #    tx_script = witness_script
        #if witness_script:
        #    tx_script = witness_script
        s += var_int(int(len(tx_script)))                      # Script length
        s += tx_script
    for data_chunk in data_array:
        data_array, value = data_output
        s += value.to_bytes(8, byteorder='little')        # Value
        data_chunk = config.PREFIX + data_chunk
        # Initialise encryption key (once per output).
        assert isinstancM
e(inputs[0]['txid'], str)
        key = arc4.init_arc4(binascii.unhexlify(inputs[0]['txid']))  # Arbitrary, easy
        if encoding == 'multisig':
            assert dust_return_pubkey
            # Get data (fake) public key.
            pad_length = (33 * 2) - 1 - 2 - 2 - len(data_chunk)
            assert pad_length >= 0
            data_chunk = bytes([len(data_chunk)]) + data_chunk + (pad_length * b'\x00')
            data_chunk = key.encrypt(data_chunk)
            data_pubkey_1 = maM
ke_fully_valid(data_chunk[:31])
            data_pubkey_2 = make_fully_valid(data_chunk[31:])
            # Construct script.
            tx_script = OP_1                                   # OP_1
            tx_script += op_push(33)                           # Push bytes of data chunk (fake) public key    (1/2)
            tx_script += data_pubkey_1                         # (Fake) public key                  (1/2)
            tx_script += op_push(33)                           # Push bytes of data chunk (fake) pubM
            tx_script += data_pubkey_2                         # (Fake) public key                  (2/2)
            tx_script += op_push(len(dust_return_pubkey))  # Push bytes of source public key
            tx_script += dust_return_pubkey                       # Source public key
            tx_script += OP_3                                  # OP_3
            tx_script += OP_CHECKMULTISIG                      # OP_CHECKMULTISIG
        elif encoding == 'opreturn':
            data_chunk = key.M
            tx_script = OP_RETURN                                  # OP_RETURN
            tx_script += op_push(len(data_chunk))                  # Push bytes of data chunk (NOTE: OP_SMALLDATA?)
            tx_script += data_chunk                                # Data
        elif encoding == 'pubkeyhash':
            pad_length = 20 - 1 - len(data_chunk)
            assert pad_length >= 0
            data_chunk = bytes([len(data_chunk)]) + data_chunk + (pad_length * b'\x00')
            data_chM
unk = key.encrypt(data_chunk)
            # Construct script.
            tx_script = OP_DUP                                     # OP_DUP
            tx_script += OP_HASH160                                # OP_HASH160
            tx_script += op_push(20)                               # Push 0x14 bytes
            tx_script += data_chunk                                # (Fake) pubKeyHash
            tx_script += OP_EQUALVERIFY                            # OP_EQUALVERIFY
            tx_script += OP_CHECKSIG          M
                     # OP_CHECKSIG
            raise exceptions.TransactionError('Unknown encoding
        s += var_int(int(len(tx_script)))                      # Script length
        s += tx_script
    # Change output.
    if change_output:
        change_address, change_value = change_output
        s += change_value.to_bytes(8, byteorder='little')   # Value
        tx_script, witness_script = get_script(change_address)
        #print("Change address!", change_address, "\n", witnessM
_data, "\n", tx_script, "\n", witness_script)
        #if witness_script: #use_segwit and change_address in witness_data:
        #    if not(change_address in witness_data):
        #        witness_data[change_address] = []
        #    witness_data[change_address].append(witness_script)
        #    tx_script = witness_script
        #    use_segwit = True
        s += var_int(int(len(tx_script)))                      # Script length
        s += tx_script
        for i in range(len(inputs))M
            txin = inputs[i]
            if txin['is_segwit']:
                s += b'\x02'
                s += b'\x00\x00'
                s += b'\x00'
    s += (0).to_bytes(4, byteorder='little')                # LockTime
def serialise_p2sh_pretx(inputs, source, source_value, data_output, change_output=None, pubkey=None, multisig_pubkeys=None, multisig_pubkeys_required=None):
    assert data_output  # we don't do this unless there's data
    data_array, data_value = data_outM
    s  = (1).to_bytes(4, byteorder='little')  # Version
    # Number of inputs.
    s += var_int(int(len(inputs)))
    # List of Inputs.
    for i in range(len(inputs)):
        txin = inputs[i]
        s += binascii.unhexlify(bytes(txin['txid'], 'utf-8'))[::-1]  # TxOutHash
        s += txin['vout'].to_bytes(4, byteorder='little')            # TxOutIndex
        tx_script = binascii.unhexlify(bytes(txin['scriptPubKey'], 'utf-8'))
        s += var_int(int(len(tx_script)))  # Script length
ript                     # Script
        s += b'\xff' * 4                   # Sequence
    # Number of outputs.
    n = len(data_array)
    if change_output:
    # encode number of outputs
    # P2SH for data encodeded inputs
    for n, data_chunk in enumerate(data_array):
        data_chunk = config.PREFIX + data_chunk  # prefix the data_chunk
        # get the scripts
        scriptSig, redeemScript, outputScript = p2sh_encoding.make_p2sh_encoding_redeemscript(data_chunk, nM
, pubkey, multisig_pubkeys, multisig_pubkeys_required)
        #if data_value is an array, then every output fee is specified in it
        if type(data_value) == list:
            s += data_value[n].to_bytes(8, byteorder='little')  # Value
            s += data_value.to_bytes(8, byteorder='little')  # Value
        s += var_int(int(len(outputScript)))             # Script length
        s += outputScript                                # Script
    # Change output.
    if change_output:
ge_address, change_value = change_output
        tx_script, witness_script = get_script(change_address)
        s += change_value.to_bytes(8, byteorder='little')  # Value
        s += var_int(int(len(tx_script)))                  # Script length
        s += tx_script                                     # Script
    s += (0).to_bytes(4, byteorder='little')  # LockTime
def serialise_p2sh_datatx(txid, source, source_input, destination_outputs, data_output, pubkey=None, multisig_pubkeys=None, multisiM
g_pubkeys_required=None):
    assert data_output  # we don't do this unless there's data
    txhash = bitcoinlib.core.lx(bitcoinlib.core.b2x(txid))  # reverse txId
    data_array, value = data_output
    s = (1).to_bytes(4, byteorder='little')
    # number of inputs is the length of data_array (+1 if a source_input exists)
    number_of_inputs = len(data_array)
    if source_input is not None:
        number_of_inputs += 1
    s += var_int(number_of_inputs)
    # Handle a source input here for a PM
    if source_input is not None:
        s += binascii.unhexlify(bytes(source_input['txid'], 'utf-8'))[::-1]  # TxOutHash
        s += source_input['vout'].to_bytes(4, byteorder='little')            # TxOutIndex
        # since pubkey is not returned from indexd, add it from bitcoind
        source_inputs = backend.ensure_script_pub_key_for_inputs([source_input])
        source_input = source_inputs[0]
        tx_script = binascii.unhexlify(bytes(source_input['scriptPubKey'], 'utf-8'))
int(int(len(tx_script)))                                    # Script length
        s += tx_script                                                       # Script
        s += b'\xff' * 4                                                     # Sequence
    # list of inputs
    for n, data_chunk in enumerate(data_array):
        data_chunk = config.PREFIX + data_chunk  # prefix the data_chunk
        # get the scripts
        scriptSig, redeemScript, outputScript = p2sh_encoding.make_p2sh_encoding_redeemscript(data_cM
hunk, n, pubkey, multisig_pubkeys, multisig_pubkeys_required)
        #substituteScript = scriptSig + outputScript
        s += txhash                                              # TxOutHash
        s += (n).to_bytes(4, byteorder='little')                 # TxOutIndex (assumes 0-based)
        #s += var_int(len(substituteScript))                      # Script length
        #s += substituteScript                                    # Script
        s += var_int(len(scriptSig))# + len(outputScript))              M
        # Script length
        s += scriptSig                                    # Script
        #s += outputScript                                    # Script
        s += b'\xff' * 4                                         # Sequence
    # number of outputs, always 1 for the opreturn
    n += len(destination_outputs)
    # encode output length
    # destination outputs
    for destination, value in destination_outputs:
        tx_script, witness_script = get_script(destination)M
        s += value.to_bytes(8, byteorder='little')  # Value
        s += var_int(int(len(tx_script)))           # Script length
        s += tx_script                              # Script
    # opreturn to signal P2SH encoding
    key = arc4.init_arc4(txid)
    data_chunk = config.PREFIX + b'P2SH'
    data_chunk = key.encrypt(data_chunk)
    tx_script = OP_RETURN                  # OP_RETURN
    tx_script += op_push(len(data_chunk))  # Push bytes of data chunk
    tx_script += data_chunk                # Data
    s += (0).to_bytes(8, byteorder='little')  # Value
    s += var_int(int(len(tx_script)))         # Script length
    s += tx_script                            # Script
    s += (0).to_bytes(4, byteorder='little')  # LockTime
UUUUUUUUUUUUUUUUUUUUUUUUUUUUU
!22222222222222222222222222222222222222222222222222
text/plain;charset=utf-8
# Merged Python Files
Datastreams are identified by the address that publishes them, and referenced
in transaction outputs.
For CFD leverage, 1x = 5040, 2x = 10080, etc.: 5040 is a superior highly
composite number and a colossally abundant number, and has 1-10, 12 as factors.
All wagers are in XCP.
Expiring a bet match doesn
open the constituent bets. (So all bets may be
logger = logging.getLogger(__name__)
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
from counterpartylib.lib import util
from counterpartylib.lib import log
from counterpartylib.lib import message_type
LENGTH = 2 + 4 + 8 + 8 + 8 + 4 + 4
def initialise (db):
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS bets(
                      tx_index INTEGER UNIQUE,
                      tx_hash TEXT M
                      block_index INTEGER,
                      source TEXT,
                      feed_address TEXT,
                      bet_type INTEGER,
                      deadline INTEGER,
                      wager_quantity INTEGER,
                      wager_remaining INTEGER,
                      counterwager_quantity INTEGER,
                      counterwager_remaining INTEGER,
                      target_value REAL,
                      leverage INTEGER,
                      expirationM
                      expire_index INTEGER,
                      fee_fraction_int INTEGER,
                      status TEXT,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index),
                      PRIMARY KEY (tx_index, tx_hash))
                  ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON bets (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTSM
                      index_hash_idx ON bets (tx_index, tx_hash)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      expire_idx ON bets (status, expire_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      feed_valid_bettype_idx ON bets (feed_address, status, bet_type)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON bets (source)
                   ''')
execute('''CREATE INDEX IF NOT EXISTS
                      status_idx ON bets (status)
                   ''')
    cursor.execute('''CREATE TABLE IF NOT EXISTS bet_matches(
                      id TEXT PRIMARY KEY,
                      tx0_index INTEGER,
                      tx0_hash TEXT,
                      tx0_address TEXT,
                      tx1_index INTEGER,
                      tx1_hash TEXT,
                      tx1_address TEXT,
                      tx0_bet_type INTEGER,
                  tx1_bet_type INTEGER,
                      feed_address TEXT,
                      initial_value INTEGER,
                      deadline INTEGER,
                      target_value REAL,
                      leverage INTEGER,
                      forward_quantity INTEGER,
                      backward_quantity INTEGER,
                      tx0_block_index INTEGER,
                      tx1_block_index INTEGER,
                      block_index INTEGER,
                      tx0_expiration INM
                      tx1_expiration INTEGER,
                      match_expire_index INTEGER,
                      fee_fraction_int INTEGER,
                      status TEXT,
                      FOREIGN KEY (tx0_index, tx0_hash, tx0_block_index) REFERENCES transactions(tx_index, tx_hash, block_index),
                      FOREIGN KEY (tx1_index, tx1_hash, tx1_block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                     match_expire_idx ON bet_matches (status, match_expire_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      valid_feed_idx ON bet_matches (feed_address, status)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      id_idx ON bet_matches (id)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx0_address_idx ON bet_matches (tx0_address)
                   ''')
cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx1_address_idx ON bet_matches (tx1_address)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      status_idx ON bet_matches (status)
                   ''')
    # Bet Expirations
    cursor.execute('''CREATE TABLE IF NOT EXISTS bet_expirations(
                      bet_index INTEGER PRIMARY KEY,
                      bet_hash TEXT UNIQUE,
                      source TEXT,
                      block_indexM
                      FOREIGN KEY (block_index) REFERENCES blocks(block_index),
                      FOREIGN KEY (bet_index, bet_hash) REFERENCES bets(tx_index, tx_hash))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON bet_expirations (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON bet_expirations (source)
                   ''')
    # Bet Match Expirations
sor.execute('''CREATE TABLE IF NOT EXISTS bet_match_expirations(
                      bet_match_id TEXT PRIMARY KEY,
                      tx0_address TEXT,
                      tx1_address TEXT,
                      block_index INTEGER,
                      FOREIGN KEY (bet_match_id) REFERENCES bet_matches(id),
                      FOREIGN KEY (block_index) REFERENCES blocks(block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON bet_matcM
h_expirations (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx0_address_idx ON bet_match_expirations (tx0_address)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx1_address_idx ON bet_match_expirations (tx1_address)
                   ''')
    # Bet Match Resolutions
    cursor.execute('''CREATE TABLE IF NOT EXISTS bet_match_resolutions(
                      bet_match_id TEXT PRIMARY KEY,
        bet_match_type_id INTEGER,
                      block_index INTEGER,
                      winner TEXT,
                      settled BOOL,
                      bull_credit INTEGER,
                      bear_credit INTEGER,
                      escrow_less_fee INTEGER,
                      fee INTEGER,
                      FOREIGN KEY (bet_match_id) REFERENCES bet_matches(id),
                      FOREIGN KEY (block_index) REFERENCES blocks(block_index))
                   ''')
def cancel_bet (db, bM
et, status, block_index):
    cursor = db.cursor()
    # Update status of bet.
        'status': status,
        'tx_hash': bet['tx_hash']
    sql='update bets set status = :status where tx_hash = :tx_hash'
    cursor.execute(sql, bindings)
    log.message(db, block_index, 'update', 'bets', bindings)
    util.credit(db, bet['source'], config.XCP, bet['wager_remaining'], action='recredit wager remaining', event=bet['tx_hash'])
    cursor = db.cursor()
def cancel_bet_match (db, bet_match, sM
tatus, block_index):
fill, etc. constituent bets.
    cursor = db.cursor()
    # Recredit tx0 address.
    util.credit(db, bet_match['tx0_address'], config.XCP,
                bet_match['forward_quantity'], action='recredit forward quantity', event=bet_match['id'])
    # Recredit tx1 address.
    util.credit(db, bet_match['tx1_address'], config.XCP,
                bet_match['backward_quantity'], action='recredit backward quantity', event=bet_match['id'])
    # Update status of bM
        'status': status,
        'bet_match_id': bet_match['id']
    sql='update bet_matches set status = :status where id = :bet_match_id'
    cursor.execute(sql, bindings)
    log.message(db, block_index, 'update', 'bet_matches', bindings)
def get_fee_fraction (db, feed_address):
    '''Get fee fraction from last broadcast from the feed_address address.
    cursor = db.cursor()
    broadcasts = list(cursor.execute('''SELECT * FROM broadcasts WHERE (sM
tatus = ? AND source = ?) ORDER BY tx_index ASC''', ('valid', feed_address)))
        last_broadcast = broadcasts[-1]
        fee_fraction_int = last_broadcast['fee_fraction_int']
        if fee_fraction_int: return fee_fraction_int / 1e8
        else: return 0
def validate (db, source, feed_address, bet_type, deadline, wager_quantity,
              counterwager_quantity, target_value, leverage, expiration, block_index):
erage is None: leverage = 5040
    if wager_quantity > config.MAX_INT or counterwager_quantity > config.MAX_INT or bet_type > config.MAX_INT \
            or deadline > config.MAX_INT or leverage > config.MAX_INT or block_index + expiration > config.MAX_INT:
        problems.append('integer overflow')
    # Look at feed to be bet on.
    cursor = db.cursor()
    broadcasts = list(cursor.execute('''SELECT * FROM broadcasts WHERE (status = ? AND source = ?) ORDER BY tx_index ASC''', ('valid', feedM
    if not broadcasts:
        problems.append('feed doesn
    elif not broadcasts[-1]['text']:
        problems.append('feed is locked')
    elif broadcasts[-1]['timestamp'] >= deadline:
        problems.append('deadline in that feed
    if not bet_type in (0, 1, 2, 3):
        problems.append('unknown bet type')
    # Valid leverage level?
    if leverage != 5040 and bet_type in (2,3):   # Equal, NotEqual
        problems.append('leverage used with Equal or M
    if leverage < 5040 and not bet_type in (0,1):   # BullCFD, BearCFD (fractional leverage makes sense precisely with CFDs)
        problems.append('leverage level too low')
    if bet_type in (0,1):   # BullCFD, BearCFD
        if block_index >= 312350:   # Protocol change.
            problems.append('CFDs temporarily disabled')
    if not isinstance(wager_quantity, int):
        problems.append('wager_quantity must be in satoshis')
        return problems, leverage
    if not isinstance(counterwageM
        problems.append('counterwager_quantity must be in satoshis')
        return problems, leverage
    if not isinstance(expiration, int):
        problems.append('expiration must be expressed as an integer block delta')
        return problems, leverage
    if wager_quantity <= 0: problems.append('non
    if counterwager_quantity <= 0: problems.append('non
positive counterwager')
    if deadline < 0: problems.append('negative deadline')
    if expiration < 0: problems.apM
pend('negative expiration')
    if expiration == 0 and not (block_index >= 317500 or config.TESTNET or config.REGTEST):   # Protocol change.
        problems.append('zero expiration')
    if target_value:
        if bet_type in (0,1):   # BullCFD, BearCFD
            problems.append('CFDs have no target value')
        if target_value < 0:
            problems.append('negative target value')
    if expiration > config.MAX_EXPIRATION:
        problems.append('expiration overflow')
    return problems, leverage
ef compose (db, source, feed_address, bet_type, deadline, wager_quantity,
            counterwager_quantity, target_value, leverage, expiration):
    if util.get_balance(db, source, config.XCP) < wager_quantity:
        raise exceptions.ComposeError('insufficient funds')
    problems, leverage = validate(db, source, feed_address, bet_type, deadline, wager_quantity,
                        counterwager_quantity, target_value, leverage, expiration, util.CURRENT_BLOCK_INDEX)
    if util.date_passed(deadline):
  problems.append('deadline passed')
    if problems: raise exceptions.ComposeError(problems)
    data = message_type.pack(ID)
    data += struct.pack(FORMAT, bet_type, deadline,
                        wager_quantity, counterwager_quantity, target_value,
                        leverage, expiration)
    return (source, [(feed_address, None)], data)
def parse (db, tx, message):
    bet_parse_cursor = db.cursor()
    # Unpack message.
        if len(message) != LENGTH:
            raise exceptions.UnpackM
        (bet_type, deadline, wager_quantity,
         counterwager_quantity, target_value, leverage,
         expiration) = struct.unpack(FORMAT, message)
        status = 'open'
    except (exceptions.UnpackError, struct.error):
        (bet_type, deadline, wager_quantity,
         counterwager_quantity, target_value, leverage,
         expiration, fee_fraction_int) = 0, 0, 0, 0, 0, 0, 0, 0
        status = 'invalid: could not unpack'
    odds, fee_fraction = 0, 0
    feed_address = tx['destination']
            odds = util.price(wager_quantity, counterwager_quantity)
        except ZeroDivisionError:
            odds = 0
        fee_fraction = get_fee_fraction(db, feed_address)
        bet_parse_cursor.execute('''SELECT * FROM balances \
                                    WHERE (address = ? AND asset = ?)''', (tx['source'], config.XCP))
        balances = list(bet_parse_cursor)
        if not balances:
            wager_quantity = 0
 balance = balances[0]['quantity']
            if balance < wager_quantity:
                wager_quantity = balance
                counterwager_quantity = int(util.price(wager_quantity, odds))
        problems, leverage = validate(db, tx['source'], feed_address, bet_type, deadline, wager_quantity,
                            counterwager_quantity, target_value, leverage, expiration, tx['block_index'])
        if problems: status = 'invalid: ' + '; '.join(problems)
    # Debit quantity wagered. (Escrow.)
        util.debit(db, tx['source'], config.XCP, wager_quantity, action='bet', event=tx['tx_hash'])
    # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
        'source': tx['source'],
        'feed_address': feed_address,
        'bet_type': bet_type,
        'deadline': deadline,
        'wager_quantity': wager_quantity,
        'wager_remaining': wager_quanM
        'counterwager_quantity': counterwager_quantity,
        'counterwager_remaining': counterwager_quantity,
        'target_value': target_value,
        'leverage': leverage,
        'expiration': expiration,
        'expire_index': tx['block_index'] + expiration,
        'fee_fraction_int': fee_fraction * 1e8,
        'status': status,
    if "integer overflow" not in status:
        sql = 'insert into bets values(:tx_index, :tx_hash, :block_index, :source, :feed_address, :bet_type, :deadline, :wM
ager_quantity, :wager_remaining, :counterwager_quantity, :counterwager_remaining, :target_value, :leverage, :expiration, :expire_index, :fee_fraction_int, :status)'
        bet_parse_cursor.execute(sql, bindings)
        logger.warn("Not storing [bet] tx [%s]: %s" % (tx['tx_hash'], status))
        logger.debug("Bindings: %s" % (json.dumps(bindings), ))
    if status == 'open' and tx['block_index'] != config.MEMPOOL_BLOCK_INDEX:
        match(db, tx)
    bet_parse_cursor.close()
    cursor = db.cursor()
    # Get bet in question.
    bets = list(cursor.execute('''SELECT * FROM bets\
                                  WHERE (tx_index = ? AND status = ?)''', (tx['tx_index'], 'open')))
        cursor.close()
        assert len(bets) == 1
    # Get counterbet_type.
    if tx1['bet_type'] % 2: counterbet_type = tx1['bet_type'] - 1
    else: counterbet_type = tx1['bet_type'] + 1
    feed_address = tx1['feed_address']
ursor.execute('''SELECT * FROM bets\
                             WHERE (feed_address=? AND status=? AND bet_type=?)''',
                             (tx1['feed_address'], 'open', counterbet_type))
    tx1_wager_remaining = tx1['wager_remaining']
    tx1_counterwager_remaining = tx1['counterwager_remaining']
    bet_matches = cursor.fetchall()
    if tx['block_index'] > 284500 or config.TESTNET or config.REGTEST:  # Protocol change.
        sorted(bet_matches, key=lambda x: x['tx_index'])                           M
             # Sort by tx index second.
        sorted(bet_matches, key=lambda x: util.price(x['wager_quantity'], x['counterwager_quantity']))   # Sort by price first.
    tx1_status = tx1['status']
    for tx0 in bet_matches:
        if tx1_status != 'open': break
        logger.debug('Considering: ' + tx0['tx_hash'])
        tx0_wager_remaining = tx0['wager_remaining']
        tx0_counterwager_remaining = tx0['counterwager_remaining']
        # Bet types must be opposite.
        if counterbet_type != tx0['betM
            logger.debug('Skipping: bet types disagree.')
            continue
        # Leverages must agree exactly
        if tx0['leverage'] != tx1['leverage']:
            logger.debug('Skipping: leverages disagree.')
            continue
        # Target values must agree exactly.
        if tx0['target_value'] != tx1['target_value']:
            logger.debug('Skipping: target values disagree.')
            continue
        # Fee fractions must agree exactly.
        if tx0['fee_fraction_int'] != M
tx1['fee_fraction_int']:
            logger.debug('Skipping: fee fractions disagree.')
            continue
        # Deadlines must agree exactly.
        if tx0['deadline'] != tx1['deadline']:
            logger.debug('Skipping: deadlines disagree.')
            continue
        # If the odds agree, make the trade. The found order sets the odds,
        # and they trade as much as they can.
        tx0_odds = util.price(tx0['wager_quantity'], tx0['counterwager_quantity'])
        tx0_inverse_odds = util.price(tM
x0['counterwager_quantity'], tx0['wager_quantity'])
        tx1_odds = util.price(tx1['wager_quantity'], tx1['counterwager_quantity'])
        if tx['block_index'] < 286000: tx0_inverse_odds = util.price(1, tx0_odds) # Protocol change.
        logger.debug('Tx0 Inverse Odds: {}; Tx1 Odds: {}'.format(float(tx0_inverse_odds), float(tx1_odds)))
        if tx0_inverse_odds > tx1_odds:
            logger.debug('Skipping: price mismatch.')
            logger.debug('Potential forward quantities: {}, {}'.foM
rmat(tx0_wager_remaining, int(util.price(tx1_wager_remaining, tx1_odds))))
            forward_quantity = int(min(tx0_wager_remaining, int(util.price(tx1_wager_remaining, tx1_odds))))
            logger.debug('Forward Quantity: {}'.format(forward_quantity))
            backward_quantity = round(forward_quantity / tx0_odds)
            logger.debug('Backward Quantity: {}'.format(backward_quantity))
            if not forward_quantity:
                logger.debug('Skipping: zero forward quantity.')
            if tx1['block_index'] >= 286500 or config.TESTNET or config.REGTEST:    # Protocol change.
                if not backward_quantity:
                    logger.debug('Skipping: zero backward quantity.')
                    continue
            bet_match_id = util.make_id(tx0['tx_hash'], tx1['tx_hash'])
            # Debit the order.
            # Counterwager remainings may be negative.
            tx0_wager_remaining = tx0_wager_remaining - forward_quantity
            tx0_counterwager_remaiM
ning = tx0_counterwager_remaining - backward_quantity
            tx1_wager_remaining = tx1_wager_remaining - backward_quantity
            tx1_counterwager_remaining = tx1_counterwager_remaining - forward_quantity
            tx0_status = 'open'
            if tx0_wager_remaining <= 0 or tx0_counterwager_remaining <= 0:
                # Fill order, and recredit give_remaining.
                tx0_status = 'filled'
                util.credit(db, tx0['source'], config.XCP, tx0_wager_remaining, eM
vent=tx1['tx_hash'], action='filled')
            bindings = {
                'wager_remaining': tx0_wager_remaining,
                'counterwager_remaining': tx0_counterwager_remaining,
                'status': tx0_status,
                'tx_hash': tx0['tx_hash']
            sql='update bets set wager_remaining = :wager_remaining, counterwager_remaining = :counterwager_remaining, status = :status where tx_hash = :tx_hash'
            cursor.execute(sql, bindings)
            log.message(db, tx['bM
lock_index'], 'update', 'bets', bindings)
            if tx1['block_index'] >= 292000 or config.TESTNET or config.REGTEST:  # Protocol change
                if tx1_wager_remaining <= 0 or tx1_counterwager_remaining <= 0:
                    # Fill order, and recredit give_remaining.
                    tx1_status = 'filled'
                    util.credit(db, tx1['source'], config.XCP, tx1_wager_remaining, event=tx1['tx_hash'], action='filled')
            bindings = {
                'wager_remM
aining': tx1_wager_remaining,
                'counterwager_remaining': tx1_counterwager_remaining,
                'status': tx1_status,
                'tx_hash': tx1['tx_hash']
            sql='update bets set wager_remaining = :wager_remaining, counterwager_remaining = :counterwager_remaining, status = :status where tx_hash = :tx_hash'
            cursor.execute(sql, bindings)
            log.message(db, tx['block_index'], 'update', 'bets', bindings)
            # Get last value of feed.
    broadcasts = list(cursor.execute('''SELECT * FROM broadcasts WHERE (status = ? AND source = ?) ORDER BY tx_index ASC''', ('valid', feed_address)))
            initial_value = broadcasts[-1]['value']
            # Record bet fulfillment.
            bindings = {
                'id': util.make_id(tx0['tx_hash'], tx['tx_hash']),
                'tx0_index': tx0['tx_index'],
                'tx0_hash': tx0['tx_hash'],
                'tx0_address': tx0['source'],
                'tx1_index': tx1['tx_index'],
            'tx1_hash': tx1['tx_hash'],
                'tx1_address': tx1['source'],
                'tx0_bet_type': tx0['bet_type'],
                'tx1_bet_type': tx1['bet_type'],
                'feed_address': tx1['feed_address'],
                'initial_value': initial_value,
                'deadline': tx1['deadline'],
                'target_value': tx1['target_value'],
                'leverage': tx1['leverage'],
                'forward_quantity': forward_quantity,
                'backward_quantity': bM
                'tx0_block_index': tx0['block_index'],
                'tx1_block_index': tx1['block_index'],
                'block_index': max(tx0['block_index'], tx1['block_index']),
                'tx0_expiration': tx0['expiration'],
                'tx1_expiration': tx1['expiration'],
                'match_expire_index': min(tx0['expire_index'], tx1['expire_index']),
                'fee_fraction_int': tx1['fee_fraction_int'],
                'status': 'pending',
ql='insert into bet_matches values(:id, :tx0_index, :tx0_hash, :tx0_address, :tx1_index, :tx1_hash, :tx1_address, :tx0_bet_type, :tx1_bet_type, :feed_address, :initial_value, :deadline, :target_value, :leverage, :forward_quantity, :backward_quantity, :tx0_block_index, :tx1_block_index, :block_index, :tx0_expiration, :tx1_expiration, :match_expire_index, :fee_fraction_int, :status)'
            cursor.execute(sql, bindings)
def expire (db, block_index, block_time):
    cursor = db.curM
    # Expire bets and give refunds for the quantity wager_remaining.
    cursor.execute('''SELECT * FROM bets \
                      WHERE (status = ? AND expire_index < ?)''', ('open', block_index))
    for bet in cursor.fetchall():
        cancel_bet(db, bet, 'expired', block_index)
        # Record bet expiration.
        bindings = {
            'bet_index': bet['tx_index'],
            'bet_hash': bet['tx_hash'],
            'source': bet['source'],
            'block_index': block_index
     sql='insert into bet_expirations values(:bet_index, :bet_hash, :source, :block_index)'
        cursor.execute(sql, bindings)
    # Expire bet matches whose deadline is more than two weeks before the current block time.
    cursor.execute('''SELECT * FROM bet_matches \
                      WHERE (status = ? AND deadline < ?)''', ('pending', block_time - config.TWO_WEEKS))
    for bet_match in cursor.fetchall():
        cancel_bet_match(db, bet_match, 'expired', block_index)
        # Record bet match expiratM
        bindings = {
            'bet_match_id': bet_match['id'],
            'tx0_address': bet_match['tx0_address'],
            'tx1_address': bet_match['tx1_address'],
            'block_index': block_index
        sql='insert into bet_match_expirations values(:bet_match_id, :tx0_address, :tx1_address, :block_index)'
        cursor.execute(sql, bindings)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
sage, with or without a price.
Multiple messages per block are allowed. Bets are be made on the 'timestamp'
field, and not the block index.
An address is a feed of broadcasts. Feeds may be locked with a broadcast whose
text field is identical to
 (case insensitive). Bets on a feed reference
the address that is the source of the feed in an output which includes the
(latest) required fee.
Broadcasts without a price may not be used for betting. Broadcasts about events
with a small number of possible outcoM
mes (e.g. sports games), should be
written, for example, such that a price of 1 XCP means one outcome, 2 XCP means
another, etc., which schema should be described in the 'text' field.
fee_fraction: .05 XCP means 5%. It may be greater than 1, however; but
because it is stored as a four
byte integer, it may not be greater than about
from fractions import Fraction
logger = logging.getLogger(__name__)
from bitcoin.core import VarInM
from counterpartylib.lib import exceptions
from counterpartylib.lib import config
from counterpartylib.lib import util
from counterpartylib.lib import log
from counterpartylib.lib import message_type
# NOTE: Pascal strings are used for storing texts for backwards
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS broadcasts(
                      tx_index INTEGER PRIMARY KEY,
                   tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      timestamp INTEGER,
                      value REAL,
                      fee_fraction_int INTEGER,
                      text TEXT,
                      locked BOOL,
                      status TEXT,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    cursor.execute('''CREATEM
 INDEX IF NOT EXISTS
                      block_index_idx ON broadcasts (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      status_source_idx ON broadcasts (status, source)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      status_source_index_idx ON broadcasts (status, source, tx_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      timestamp_idx ON broadcasts (timesM
                   ''')
def validate (db, source, timestamp, value, fee_fraction_int, text, block_index):
    if timestamp > config.MAX_INT or value > config.MAX_INT or fee_fraction_int > config.MAX_INT:
        problems.append('integer overflow')
    if util.enabled('max_fee_fraction'):
        if fee_fraction_int >= config.UNIT:
            problems.append('fee fraction greater than or equal to 1')
        if fee_fraction_int > 4294967295:
            problemM
s.append('fee fraction greater than 42.94967295')
    if timestamp < 0: problems.append('negative timestamp')
        problems.append('null source address')
    # Check previous broadcast in this feed.
    cursor = db.cursor()
    broadcasts = list(cursor.execute('''SELECT * FROM broadcasts WHERE (status = ? AND source = ?) ORDER BY tx_index ASC''', ('valid', source)))
        last_broadcast = broadcasts[-1]
        if last_broadcast['locked']:
problems.append('locked feed')
        elif timestamp <= last_broadcast['timestamp']:
            problems.append('feed timestamps not monotonically increasing')
    if not (block_index >= 317500 or config.TESTNET or config.REGTEST):  # Protocol change.
        if len(text) > 52:
            problems.append('text too long')
    if util.enabled('options_require_memo') and text and text.lower().startswith('options'):
            # Check for options and if they are valid.
            options = util.parsM
e_options_from_string(text)
            if options is not False:
                util.validate_address_options(options)
        except exceptions.OptionsError as e:
            problems.append(str(e))
def compose (db, source, timestamp, value, fee_fraction, text):
    # Store the fee fraction as an integer.
    fee_fraction_int = int(fee_fraction * 1e8)
    problems = validate(db, source, timestamp, value, fee_fraction_int, text, util.CURRENT_BLOCK_INDEX)
    if problems: raise exceptions.CoM
mposeError(problems)
    data = message_type.pack(ID)
    # always use custom length byte instead of problematic usage of 52p format and make sure to encode('utf-8') for length
    if util.enabled('broadcast_pack_text'):
        data += struct.pack(FORMAT, timestamp, value, fee_fraction_int)
        data += VarIntSerializer.serialize(len(text.encode('utf-8')))
        data += text.encode('utf-8')
        if len(text) <= 52:
            curr_format = FORMAT + '{}p'.format(len(text) + 1)
         curr_format = FORMAT + '{}s'.format(len(text))
        data += struct.pack(curr_format, timestamp, value, fee_fraction_int, text.encode('utf-8'))
    return (source, [], data)
def parse (db, tx, message):
    cursor = db.cursor()
    # Unpack message.
        if util.enabled('broadcast_pack_text', tx['block_index']):
            timestamp, value, fee_fraction_int, rawtext = struct.unpack(FORMAT + '{}s'.format(len(message) - LENGTH), message)
            textlen = VarIntSerializer.deserialize(raM
            if textlen == 0:
                text = b''
                text = rawtext[-textlen:]
            assert len(text) == textlen
            if len(message) - LENGTH <= 52:
                curr_format = FORMAT + '{}p'.format(len(message) - LENGTH)
                curr_format = FORMAT + '{}s'.format(len(message) - LENGTH)
            timestamp, value, fee_fraction_int, text = struct.unpack(curr_format, message)
            text = text.M
        except UnicodeDecodeError:
            text = ''
        status = 'valid'
    except (struct.error) as e:
        timestamp, value, fee_fraction_int, text = 0, None, 0, None
        status = 'invalid: could not unpack'
    if status == 'valid':
        # For SQLite3
        timestamp = min(timestamp, config.MAX_INT)
        value = min(value, config.MAX_INT)
        problems = validate(db, tx['source'], timestamp, value, fee_fraction_int, text, tx['block_index'])
        if problems: statuM
s = 'invalid: ' + '; '.join(problems)
    if text and text.lower() == 'lock':
        timestamp, value, fee_fraction_int, text = 0, None, None, None
        lock = False
    # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
        'source': tx['source'],
        'timestamp': timestamp,
        'value': value,
fee_fraction_int': fee_fraction_int,
        'text': text,
        'locked': lock,
        'status': status,
    if "integer overflow" not in status:
        sql = 'insert into broadcasts values(:tx_index, :tx_hash, :block_index, :source, :timestamp, :value, :fee_fraction_int, :text, :locked, :status)'
        cursor.execute(sql, bindings)
        logger.warn("Not storing [broadcast] tx [%s]: %s" % (tx['tx_hash'], status))
        logger.debug("Bindings: %s" % (json.dumps(bindings), ))
rocessing if broadcast is invalid for any reason
    if util.enabled('broadcast_invalid_check') and status != 'valid':
    # Options? Should not fail to parse due to above checks.
    if util.enabled('options_require_memo') and text and text.lower().startswith('options'):
        options = util.parse_options_from_string(text)
        if options is not False:
            op_bindings = {
                        'block_index': tx['block_index'],
                        'address': tx['source'],
                'options': options
                       }
            sql = 'insert or replace into addresses(address, options, block_index) values(:address, :options, :block_index)'
            cursor = db.cursor()
            cursor.execute(sql, op_bindings)
    # Negative values (default to ignore).
    if value is None or value < 0:
        # Cancel Open Bets?
        if value == -2:
            cursor.execute('''SELECT * FROM bets \
                              WHERE (status = ? AND feed_address = ?)''',
                          ('open', tx['source']))
            for i in list(cursor):
                bet.cancel_bet(db, i, 'dropped', tx['block_index'])
        # Cancel Pending Bet Matches?
        if value == -3:
            cursor.execute('''SELECT * FROM bet_matches \
                              WHERE (status = ? AND feed_address = ?)''',
                           ('pending', tx['source']))
            for bet_match in list(cursor):
                bet.cancel_bet_match(db, bet_match, 'dropped', tx['block_indM
        cursor.close()
    # stop processing if broadcast is invalid for any reason
    # @TODO: remove this check once broadcast_invalid_check has been activated
    if util.enabled('max_fee_fraction') and status != 'valid':
    # Handle bet matches that use this feed.
    cursor.execute('''SELECT * FROM bet_matches \
                      WHERE (status=? AND feed_address=?)
                      ORDER BY tx1_index ASC, tx0_index ASC''',
                   ('pending', tx['sourM
    for bet_match in cursor.fetchall():
        broadcast_bet_match_cursor = db.cursor()
        bet_match_id = util.make_id(bet_match['tx0_hash'], bet_match['tx1_hash'])
        bet_match_status = None
        # Calculate total funds held in escrow and total fee to be paid if
        # the bet match is settled. Escrow less fee is amount to be paid back
        # to betters.
        total_escrow = bet_match['forward_quantity'] + bet_match['backward_quantity']
        if util.enabled('inmutable_fee_fractionM
            fee_fraction = bet_match['fee_fraction_int'] / config.UNIT
            fee_fraction = fee_fraction_int / config.UNIT
        fee = int(fee_fraction * total_escrow)              # Truncate.
        escrow_less_fee = total_escrow - fee
        # Get known bet match type IDs.
        cfd_type_id = util.BET_TYPE_ID['BullCFD'] + util.BET_TYPE_ID['BearCFD']
        equal_type_id = util.BET_TYPE_ID['Equal'] + util.BET_TYPE_ID['NotEqual']
        # Get the bet match type ID of this bet matcM
        bet_match_type_id = bet_match['tx0_bet_type'] + bet_match['tx1_bet_type']
        # Contract for difference, with determinate settlement date.
        if bet_match_type_id == cfd_type_id:
            # Recognise tx0, tx1 as the bull, bear (in the right direction).
            if bet_match['tx0_bet_type'] < bet_match['tx1_bet_type']:
                bull_address = bet_match['tx0_address']
                bear_address = bet_match['tx1_address']
                bull_escrow = bet_match['forward_quantity']
                bear_escrow = bet_match['backward_quantity']
                bull_address = bet_match['tx1_address']
                bear_address = bet_match['tx0_address']
                bull_escrow = bet_match['backward_quantity']
                bear_escrow = bet_match['forward_quantity']
            leverage = Fraction(bet_match['leverage'], 5040)
            initial_value = bet_match['initial_value']
            bear_credit = bear_escrow - (value - initial_value) * leverage * config.UNIT
           bull_credit = escrow_less_fee - bear_credit
            bear_credit = round(bear_credit)
            bull_credit = round(bull_credit)
            # Liquidate, as necessary.
            if bull_credit >= escrow_less_fee or bull_credit <= 0:
                if bull_credit >= escrow_less_fee:
                    bull_credit = escrow_less_fee
                    bear_credit = 0
                    bet_match_status = 'settled: liquidated for bull'
                    util.credit(db, bull_address, config.XCP,M
 bull_credit, action='bet {}'.format(bet_match_status), event=tx['tx_hash'])
                elif bull_credit <= 0:
                    bull_credit = 0
                    bear_credit = escrow_less_fee
                    bet_match_status = 'settled: liquidated for bear'
                    util.credit(db, bear_address, config.XCP, bear_credit, action='bet {}'.format(bet_match_status), event=tx['tx_hash'])
                # Pay fee to feed.
                util.credit(db, bet_match['feed_address'], config.XCP, feeM
, action='feed fee', event=tx['tx_hash'])
                # For logging purposes.
                bindings = {
                    'bet_match_id': bet_match_id,
                    'bet_match_type_id': bet_match_type_id,
                    'block_index': tx['block_index'],
                    'settled': False,
                    'bull_credit': bull_credit,
                    'bear_credit': bear_credit,
                    'winner': None,
                    'escrow_less_fee': None,
                    'fee': feM
                sql='insert into bet_match_resolutions values(:bet_match_id, :bet_match_type_id, :block_index, :settled, :bull_credit, :bear_credit, :winner, :escrow_less_fee, :fee)'
                cursor.execute(sql, bindings)
            # Settle (if not liquidated).
            elif timestamp >= bet_match['deadline']:
                bet_match_status = 'settled'
                util.credit(db, bull_address, config.XCP, bull_credit, action='bet {}'.format(bet_match_status), event=tx['tx_hasM
                util.credit(db, bear_address, config.XCP, bear_credit, action='bet {}'.format(bet_match_status), event=tx['tx_hash'])
                # Pay fee to feed.
                util.credit(db, bet_match['feed_address'], config.XCP, fee, action='feed fee', event=tx['tx_hash'])
                # For logging purposes.
                bindings = {
                    'bet_match_id': bet_match_id,
                    'bet_match_type_id': bet_match_type_id,
                    'block_index': tx['block_indeM
                    'settled': True,
                    'bull_credit': bull_credit,
                    'bear_credit': bear_credit,
                    'winner': None,
                    'escrow_less_fee': None,
                    'fee': fee
                sql='insert into bet_match_resolutions values(:bet_match_id, :bet_match_type_id, :block_index, :settled, :bull_credit, :bear_credit, :winner, :escrow_less_fee, :fee)'
                cursor.execute(sql, bindings)
        # Equal[/NotEqM
        elif bet_match_type_id == equal_type_id and timestamp >= bet_match['deadline']:
            # Recognise tx0, tx1 as the bull, bear (in the right direction).
            if bet_match['tx0_bet_type'] < bet_match['tx1_bet_type']:
                equal_address = bet_match['tx0_address']
                notequal_address = bet_match['tx1_address']
                equal_address = bet_match['tx1_address']
                notequal_address = bet_match['tx0_address']
            # Decide M
who won, and credit appropriately.
            if value == bet_match['target_value']:
                winner = 'Equal'
                bet_match_status = 'settled: for equal'
                util.credit(db, equal_address, config.XCP, escrow_less_fee, action='bet {}'.format(bet_match_status), event=tx['tx_hash'])
                winner = 'NotEqual'
                bet_match_status = 'settled: for notequal'
                util.credit(db, notequal_address, config.XCP, escrow_less_fee, action='bet {}M
'.format(bet_match_status), event=tx['tx_hash'])
            # Pay fee to feed.
            util.credit(db, bet_match['feed_address'], config.XCP, fee, action='feed fee', event=tx['tx_hash'])
            # For logging purposes.
            bindings = {
                'bet_match_id': bet_match_id,
                'bet_match_type_id': bet_match_type_id,
                'block_index': tx['block_index'],
                'settled': None,
                'bull_credit': None,
                'bear_credit': None,
          'winner': winner,
                'escrow_less_fee': escrow_less_fee,
                'fee': fee
            sql='insert into bet_match_resolutions values(:bet_match_id, :bet_match_type_id, :block_index, :settled, :bull_credit, :bear_credit, :winner, :escrow_less_fee, :fee)'
            cursor.execute(sql, bindings)
        # Update the bet match
        if bet_match_status:
            bindings = {
                'status': bet_match_status,
                'bet_match_id': utilM
.make_id(bet_match['tx0_hash'], bet_match['tx1_hash'])
            sql='update bet_matches set status = :status where id = :bet_match_id'
            cursor.execute(sql, bindings)
            log.message(db, tx['block_index'], 'update', 'bet_matches', bindings)
        broadcast_bet_match_cursor.close()
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
= logging.getLogger(__name__)
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
from counterpartylib.lib import util
from counterpartylib.lib import log
from counterpartylib.lib import message_type
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS btcpays(
                      tx_index INTEGER PRIMARY KEY,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                    source TEXT,
                      destination TEXT,
                      btc_amount INTEGER,
                      order_match_id TEXT,
                      status TEXT,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
                      # Disallows invalids: FOREIGN KEY (order_match_id) REFERENCES order_matches(id))
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      blockM
_index_idx ON btcpays (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON btcpays (source)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      destination_idx ON btcpays (destination)
                   ''')
def validate (db, source, order_match_id, block_index):
    order_match = None
    cursor = db.cursor()
    cursor.execute('''SELECT * FROM order_matches \
                      WM
HERE id = ?''', (order_match_id,))
    order_matches = cursor.fetchall()
    if len(order_matches) == 0:
        problems.append('no such order match %s' % order_match_id)
        return None, None, None, None, order_match, problems
    elif len(order_matches) > 1:
        assert False
        order_match = order_matches[0]
        if order_match['status'] == 'expired':
            problems.append('order match expired')
        elif order_match['status'] == 'completed':
blems.append('order match completed')
        elif order_match['status'].startswith('invalid'):
            problems.append('order match invalid')
        elif order_match['status'] != 'pending':
            raise exceptions.OrderError('unrecognised order match status')
    # Figure out to which address the BTC are being paid.
    # Check that source address is correct.
    if order_match['backward_asset'] == config.BTC:
        if source != order_match['tx1_address'] and not (block_index >= 313900 or config.TESTNM
ET or config.REGTEST):  # Protocol change.
            problems.append('incorrect source address')
        destination = order_match['tx0_address']
        btc_quantity = order_match['backward_quantity']
        escrowed_asset  = order_match['forward_asset']
        escrowed_quantity = order_match['forward_quantity']
    elif order_match['forward_asset'] == config.BTC:
        if source != order_match['tx0_address'] and not (block_index >= 313900 or config.TESTNET or config.REGTEST):  # Protocol change.
 problems.append('incorrect source address')
        destination = order_match['tx1_address']
        btc_quantity = order_match['forward_quantity']
        escrowed_asset  = order_match['backward_asset']
        escrowed_quantity = order_match['backward_quantity']
        assert False
    return destination, btc_quantity, escrowed_asset, escrowed_quantity, order_match, problems
def compose (db, source, order_match_id):
    tx0_hash, tx1_hash = util.parse_id(order_match_id)
    destination, btc_quantitM
y, escrowed_asset, escrowed_quantity, order_match, problems = validate(db, source, order_match_id, util.CURRENT_BLOCK_INDEX)
    if problems: raise exceptions.ComposeError(problems)
    # Warn if down to the wire.
    time_left = order_match['match_expire_index'] - util.CURRENT_BLOCK_INDEX
    if time_left < 4:
        logger.warning('Only {} blocks until that order match expires. The payment might not make into the blockchain in time.'.format(time_left))
    if 10 - time_left < 4:
        logger.warning('Order maM
tch has only {} confirmation(s).'.format(10 - time_left))
    tx0_hash_bytes, tx1_hash_bytes = binascii.unhexlify(bytes(tx0_hash, 'utf-8')), binascii.unhexlify(bytes(tx1_hash, 'utf-8'))
    data = message_type.pack(ID)
    data += struct.pack(FORMAT, tx0_hash_bytes, tx1_hash_bytes)
    return (source, [(destination, btc_quantity)], data)
def parse (db, tx, message):
    cursor = db.cursor()
    # Unpack message.
        if len(message) != LENGTH:
            raise exceptions.UnpackError
_bytes, tx1_hash_bytes = struct.unpack(FORMAT, message)
        tx0_hash, tx1_hash = binascii.hexlify(tx0_hash_bytes).decode('utf-8'), binascii.hexlify(tx1_hash_bytes).decode('utf-8')
        order_match_id = util.make_id(tx0_hash, tx1_hash)
        status = 'valid'
    except (exceptions.UnpackError, struct.error) as e:
        tx0_hash, tx1_hash, order_match_id = None, None, None
        status = 'invalid: could not unpack'
    if status == 'valid':
        destination, btc_quantity, escrowed_asset, escrowed_quaM
ntity, order_match, problems = validate(db, tx['source'], order_match_id, tx['block_index'])
        if problems:
            order_match = None
            status = 'invalid: ' + '; '.join(problems)
    if status == 'valid':
        # BTC must be paid all at once.
        if tx['btc_amount'] >= btc_quantity:
            # Credit source address for the currency that he bought with the bitcoins.
            util.credit(db, tx['source'], escrowed_asset, escrowed_quantity, action='btcpay', event=tx['tx_hash'])
       status = 'valid'
            # Update order match.
            bindings = {
                'status': 'completed',
                'order_match_id': order_match_id
            sql='update order_matches set status = :status where id = :order_match_id'
            cursor.execute(sql, bindings)
            log.message(db, tx['block_index'], 'update', 'order_matches', bindings)
            # Update give and get order status as filled if order_match is completed
            if util.enabled('btc_orM
                bindings = {
                    'status': 'pending',
                    'tx0_hash': tx0_hash,
                    'tx1_hash': tx1_hash
                sql='select * from order_matches where status = :status and ((tx0_hash in (:tx0_hash, :tx1_hash)) or ((tx1_hash in (:tx0_hash, :tx1_hash))))'
                cursor.execute(sql, bindings)
                order_matches = cursor.fetchall()
                if len(order_matches) == 0:
                    # mark both btc gM
et and give orders as filled when order_match is completed and give or get remaining = 0
                    bindings = {
                        'status': 'filled',
                        'tx0_hash': tx0_hash,
                        'tx1_hash': tx1_hash
                    }
                    sql='update orders set status = :status where ((tx_hash in (:tx0_hash, :tx1_hash)) and ((give_remaining = 0) or (get_remaining = 0)))'
                    cursor.execute(sql, bindings)
                else:
      # always mark btc get order as filled when order_match is completed and give or get remaining = 0
                    bindings = {
                        'status': 'filled',
                        'source': tx['destination'],
                        'tx0_hash': tx0_hash,
                        'tx1_hash': tx1_hash
                    }
                    sql='update orders set status = :status where ((tx_hash in (:tx0_hash, :tx1_hash)) and ((give_remaining = 0) or (get_remaining = 0)) and (source = :sourcM
                    cursor.execute(sql, bindings)
    # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
        'source': tx['source'],
        'destination': tx['destination'],
        'btc_amount': tx['btc_amount'],
        'order_match_id': order_match_id,
        'status': status,
    if "integer overflow" not in status:
        sql = 'insert into btcpays values(:M
tx_index, :tx_hash, :block_index, :source, :destination, :btc_amount, :order_match_id, :status)'
        cursor.execute(sql, bindings)
        logger.warn("Not storing [btcpay] tx [%s]: %s" % (tx['tx_hash'], status))
        logger.debug("Bindings: %s" % (json.dumps(bindings), ))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
logger = logging.getLogger(__name__)
from fractions import Fraction
from counterpartylib.lib import (config, exceptions, util)
"""Burn {} to earn {} during a special period of time.""".format(config.BTC, config.XCP)
def initialise (db):
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS burns(
                      tx_index INTEGER PRIMARY KEY,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      burned INTEGER,
           earned INTEGER,
                      status TEXT,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      status_idx ON burns (status)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      address_idx ON burns (source)
                   ''')
def validate (db, source, destination, quantity, block_indexM
    # Check destination address.
    if destination != config.UNSPENDABLE:
        problems.append('wrong destination address')
    if not isinstance(quantity, int):
        problems.append('quantity must be in satoshis')
        return problems
    if quantity < 0: problems.append('negative quantity')
    # Try to make sure that the burned funds won't go to waste.
    if block_index < config.BURN_START - 1:
        problems.append('too early')
    elif block_index > config.M
        problems.append('too late')
def compose (db, source, quantity, overburn=False):
    cursor = db.cursor()
    destination = config.UNSPENDABLE
    problems = validate(db, source, destination, quantity, util.CURRENT_BLOCK_INDEX, overburn=overburn)
    if problems: raise exceptions.ComposeError(problems)
    # Check that a maximum of 1 BTC total is burned per address.
    burns = list(cursor.execute('''SELECT * FROM burns WHERE (status = ? AND source = ?)''', ('valid', source))M
    already_burned = sum([burn['burned'] for burn in burns])
    if quantity > (1 * config.UNIT - already_burned) and not overburn:
        raise exceptions.ComposeError('1 {} may be burned per address'.format(config.BTC))
    return (source, [(destination, quantity)], None)
def parse (db, tx, MAINNET_BURNS, message=None):
    burn_parse_cursor = db.cursor()
    if config.TESTNET or config.REGTEST:
        problems = []
        status = 'valid'
        if status == 'valid':
blems = validate(db, tx['source'], tx['destination'], tx['btc_amount'], tx['block_index'], overburn=False)
            if problems: status = 'invalid: ' + '; '.join(problems)
            if tx['btc_amount'] != None:
                sent = tx['btc_amount']
                sent = 0
        if status == 'valid':
            # Calculate quantity of XCP earned. (Maximum 1 BTC in total, ever.)
            cursor = db.cursor()
            cursor.execute('''SELECT * FROM burns WHERE (status = ? AND sourM
ce = ?)''', ('valid', tx['source']))
            burns = cursor.fetchall()
            already_burned = sum([burn['burned'] for burn in burns])
            ONE = 1 * config.UNIT
            max_burn = ONE - already_burned
            if sent > max_burn: burned = max_burn   # Exceeded maximum burn; earn what you can.
            else: burned = sent
            total_time = config.BURN_END - config.BURN_START
            partial_time = config.BURN_END - tx['block_index']
            multiplier = (1000 + (500 * FractM
ion(partial_time, total_time)))
            earned = round(burned * multiplier)
            # Credit source address with earned XCP.
            util.credit(db, tx['source'], config.XCP, earned, action='burn', event=tx['tx_hash'])
            burned = 0
            earned = 0
        tx_index = tx['tx_index']
        tx_hash = tx['tx_hash']
        block_index = tx['block_index']
        source = tx['source']
        # Mainnet burns are hard
            line = MAINNM
ET_BURNS[tx['tx_hash']]
        except KeyError:
        util.credit(db, line['source'], config.XCP, int(line['earned']), action='burn', event=line['tx_hash'])
        tx_index = tx['tx_index']
        tx_hash = line['tx_hash']
        block_index = line['block_index']
        source = line['source']
        burned = line['burned']
        earned = line['earned']
        status = 'valid'
    # Add parsed transaction to message-type
    # TODO: store sent in table
        'tx_index': tx_index,
        'tx_hash': tx_hash,
        'block_index': block_index,
        'source': source,
        'burned': burned,
        'earned': earned,
        'status': status,
    if "integer overflow" not in status:
        sql = 'insert into burns values(:tx_index, :tx_hash, :block_index, :source, :burned, :earned, :status)'
        burn_parse_cursor.execute(sql, bindings)
        logger.warn("Not storing [burn] tx [%s]: %s" % (tx['tx_hash'], status))
        logger.debuM
g("Bindings: %s" % (json.dumps(bindings), ))
    burn_parse_cursor.close()
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
offer_hash is the hash of either a bet or an order.
logger = logging.getLogger(__name__)
from counterpartylib.lib import (config, exceptions, util, message_type)
from . import (order, bet, rps)
def initialise (db):
    cursor = db.cursorM
    cursor.execute('''CREATE TABLE IF NOT EXISTS cancels(
                      tx_index INTEGER PRIMARY KEY,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      offer_hash TEXT,
                      status TEXT,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
                      # Offer hash is not a foreign key. (And itM
 cannot be, because of some invalid cancels.)
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      cancels_block_index_idx ON cancels (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON cancels (source)
                   ''')
def validate (db, source, offer_hash):
    # TODO: make query only if necessary
    cursor = db.cursor()
    cursor.execute('''SELECT * from orders WHERE tx_hash = ?''', (offer_hash,))M
    orders = list(cursor)
    cursor.execute('''SELECT * from bets WHERE tx_hash = ?''', (offer_hash,))
    bets = list(cursor)
    cursor.execute('''SELECT * from rps WHERE tx_hash = ?''', (offer_hash,))
    rps = list(cursor)
    offer_type = None
    if orders: offer_type = 'order'
    elif bets: offer_type = 'bet'
    elif rps: offer_type = 'rps'
    else: problems = ['no open offer with that hash']
        offers = orders + bets + rps
        if offer['source'] != source:
            problems.append('incorrect source address')
        if offer['status'] != 'open':
            problems.append('offer not open')
    return offer, offer_type, problems
def compose (db, source, offer_hash):
    # Check that offer exists.
    offer, offer_type, problems = validate(db, source, offer_hash)
    if problems: raise exceptions.ComposeError(problems)
    offer_hash_bytes = binascii.unhexlify(bytes(offer_hash, 'utf-8'))
    data = message_type.packM
    data += struct.pack(FORMAT, offer_hash_bytes)
    return (source, [], data)
def parse (db, tx, message):
    cursor = db.cursor()
    # Unpack message.
        if len(message) != LENGTH:
            raise exceptions.UnpackError
        offer_hash_bytes = struct.unpack(FORMAT, message)[0]
        offer_hash = binascii.hexlify(offer_hash_bytes).decode('utf-8')
        status = 'valid'
    except (exceptions.UnpackError, struct.error) as e:
        offer_hash = None
        status = 'invalid: couldM
    if status == 'valid':
        offer, offer_type, problems = validate(db, tx['source'], offer_hash)
        if problems:
            status = 'invalid: ' + '; '.join(problems)
    if status == 'valid':
        # Cancel if order.
        if offer_type == 'order':
            order.cancel_order(db, offer, 'cancelled', tx['block_index'])
        # Cancel if bet.
        elif offer_type == 'bet':
            bet.cancel_bet(db, offer, 'cancelled', tx['block_index'])
        # Cancel if rps.
f offer_type == 'rps':
            rps.cancel_rps(db, offer, 'cancelled', tx['block_index'])
        # If neither order or bet, mark as invalid.
            assert False
    # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
        'source': tx['source'],
        'offer_hash': offer_hash,
        'status': status,
    if "integer overflow" not in status:
    sql='INSERT INTO cancels VALUES (:tx_index, :tx_hash, :block_index, :source, :offer_hash, :status)'
        cursor.execute(sql, bindings)
        logger.warn("Not storing [cancel] tx [%s]: %s" % (tx['tx_hash'], status))
        logger.debug("Bindings: %s" % (json.dumps(bindings), ))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
"""Destroy a quantity of an asset."""
logger = logging.geM
from counterpartylib.lib import util
from counterpartylib.lib import config
from counterpartylib.lib import script
from counterpartylib.lib import message_type
from counterpartylib.lib.script import AddressError
from counterpartylib.lib.exceptions import *
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS destructions(
                      tx_index INTEGER PRIMARY KEY,
                      M
tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      asset INTEGER,
                      quantity INTEGER,
                      tag TEXT,
                      status TEXT,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      status_idx ON destructions (status)
                   '''M
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      address_idx ON destructions (source)
                   ''')
def pack(db, asset, quantity, tag):
    data = message_type.pack(ID)
    if isinstance(tag, str):
        tag = bytes(tag.encode('utf8'))[0:MAX_TAG_LENGTH]
    elif isinstance(tag, bytes):
        tag = tag[0:MAX_TAG_LENGTH]
    data += struct.pack(FORMAT, util.get_asset_id(db, asset, util.CURRENT_BLOCK_INDEX), quantity)
def unpack(db, message):
        asset_id, quantity = struct.unpack(FORMAT, message[0:16])
        tag = message[16:]
        asset = util.get_asset_name(db, asset_id, util.CURRENT_BLOCK_INDEX)
    except struct.error:
        raise UnpackError('could not unpack')
    except AssetIDError:
        raise UnpackError('asset id invalid')
    return asset, quantity, tag
def validate (db, source, destination, asset, quantity):
        util.get_asset_id(db, asset, util.CURRENT_BLOCK_INDEX)
        raise ValidateError('asset invalid')
        script.validate(source)
    except AddressError:
        raise ValidateError('source address invalid')
        raise ValidateError('destination exists')
    if asset == config.BTC:
        raise ValidateError('cannot destroy {}'.format(config.BTC))
    if type(quantity) != int:
        raise ValidateError('quantity not integer')
    if quantity > config.MAX_INT:
        raise ValidateError('integer overflow, quanM
    if quantity < 0:
        raise ValidateError('quantity negative')
    if util.get_balance(db, source, asset) < quantity:
        raise BalanceError('balance insufficient')
def compose (db, source, asset, quantity, tag):
    # resolve subassets
    asset = util.resolve_subasset_longname(db, asset)
    validate(db, source, None, asset, quantity)
    data = pack(db, asset, quantity, tag)
    return (source, [], data)
def parse (db, tx, message):
    status = 'valid'
    asset, quantity, tM
ag = None, None, None
        asset, quantity, tag = unpack(db, message)
        validate(db, tx['source'], tx['destination'], asset, quantity)
        util.debit(db, tx['source'], asset, quantity, 'destroy', tx['tx_hash'])
    except UnpackError as e:
        status = 'invalid: ' + ''.join(e.args)
    except (ValidateError, BalanceError) as e:
        status = 'invalid: ' + ''.join(e.args)
                'tx_index': tx['tx_index'],
                'tx_hash': tx['tx_hash'],
      'block_index': tx['block_index'],
                'source': tx['source'],
                'asset': asset,
                'quantity': quantity,
                'tag': tag,
                'status': status,
    if "integer overflow" not in status:
        sql = 'insert into destructions values(:tx_index, :tx_hash, :block_index, :source, :asset, :quantity, :tag, :status)'
        cursor = db.cursor()
        cursor.execute(sql, bindings)
        logger.warn("Not storing [destroy] tx [M
%s]: %s" % (tx['tx_hash'], status))
        logger.debug("Bindings: %s" % (json.dumps(bindings), ))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
# What is a dispenser?
# A dispenser is a type of order where the holder address gives out a given amount
# of units of an asset for a given amount of BTC satoshis received.
# It's a very simple but powerful semantic to allow swaps to operate on-chain.
from math import floor
logger = logging.getLogger(__name__)
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
from counterpartylib.lib import util
from counterpartylib.lib import log
from counterpartylib.lib import message_type
from counterpartylib.lib import address
STATUS_OPEN_EMPTY_ADDRESS = 1
#STATUS_OPEN_ORACLE_PRICE = 20
#STATUS_OPEN_ORACLE_PRICE_EMPTY_ADDRESS = 21
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS dispensers(
                      tx_index INTEGER PRIMARY KEY,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      asset TEXT,
                      give_quantity INTEGER,
                      escrow_quantity INTEGER,
                      satoshirate INTEGER,
                      status INTEGER,
                      give_remaining IM
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
                      # Disallows invalids: FOREIGN KEY (order_match_id) REFERENCES order_matches(id))
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      dispensers_source_idx ON dispensers (source)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      dispensers_asset_idx ON dispensers (asset)
    cursor.execute('''CREATE TABLE IF NOT EXISTS dispenses(
                      tx_index INTEGER,
                      dispense_index INTEGER,
                      tx_hash TEXT,
                      block_index INTEGER,
                      source TEXT,
                      destination TEXT,
                      asset TEXT,
                      dispense_quantity INTEGER,
                      dispenser_tx_hash TEXT,
                      PRIMARY KEY (tx_index, dispense_index, source, destM
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    columns = [column['name'] for column in cursor.execute('''PRAGMA table_info(dispenses)''')]
    if 'dispenser_tx_hash' not in columns:
        cursor.execute('ALTER TABLE dispenses ADD COLUMN dispenser_tx_hash TEXT')
    columns = [column['name'] for column in cursor.execute('''PRAGMA table_info(dispensers)''')]
    if 'oracle_addrM
ess' not in columns:
        cursor.execute('ALTER TABLE dispensers ADD COLUMN oracle_address TEXT')
def validate (db, source, asset, give_quantity, escrow_quantity, mainchainrate, status, open_address, block_index, oracle_address):
    order_match = None
    if asset == config.BTC:
        problems.append('cannot dispense %s' % config.BTC)
        return None, problems
    # resolve subassets
    asset = util.resolve_subasset_longname(db, asset)
    if status == STATUS_OPEM
N or status == STATUS_OPEN_EMPTY_ADDRESS:
        if give_quantity <= 0:
            problems.append('give_quantity must be positive')
        if mainchainrate <= 0:
            problems.append('mainchainrate must be positive')
        if escrow_quantity < give_quantity:
            problems.append('escrow_quantity must be greater or equal than give_quantity')
    elif not(status == STATUS_CLOSED):
        problems.append('invalid status %i' % status)
    cursor = db.cursor()
    cursor.execute('''SELECT quantity M
                      WHERE address = ? and asset = ?''', (source,asset,))
    available = cursor.fetchall()
    if len(available) == 0:
        problems.append('address doesn\'t has the asset %s' % asset)
    elif len(available) >= 1 and available[0]['quantity'] < escrow_quantity:
        problems.append('address doesn\'t has enough balance of %s (%i < %i)' % (asset, available[0]['quantity'], escrow_quantity))
        if status == STATUS_OPEN_EMPTY_ADDRESS and not(open_address):
    open_address = source
            status = STATUS_OPEN
        query_address = open_address if status == STATUS_OPEN_EMPTY_ADDRESS else source
        cursor.execute('''SELECT * FROM dispensers WHERE source = ? AND asset = ? AND status=?''', (query_address, asset, STATUS_OPEN))
        open_dispensers = cursor.fetchall()
        if status == STATUS_OPEN or status == STATUS_OPEN_EMPTY_ADDRESS:
            if len(open_dispensers) > 0 and open_dispensers[0]['satoshirate'] != mainchainrate:
                problemM
s.append('address has a dispenser already opened for asset %s with a different mainchainrate' % asset)
            if len(open_dispensers) > 0 and open_dispensers[0]['give_quantity'] != give_quantity:
                problems.append('address has a dispenser already opened for asset %s with a different give_quantity' % asset)
        elif status == STATUS_CLOSED:
            if len(open_dispensers) == 0:
                problems.append('address doesnt has an open dispenser for asset %s' % asset)
== STATUS_OPEN_EMPTY_ADDRESS:
            cursor.execute('''SELECT count(*) cnt FROM balances WHERE address = ?''', (query_address,))
            existing_balances = cursor.fetchall()
            if existing_balances[0]['cnt'] > 0:
                problems.append('cannot open on another address if it has any balance history')
        if len(problems) == 0:
            asset_id = util.generate_asset_id(asset, block_index)
            if asset_id == 0:
                problems.append('cannot dispense %s' % asset) # M
How can we test this on a test vector?
    if oracle_address is not None and util.enabled('oracle_dispensers', block_index):
        last_price, last_fee, last_label, last_updated = util.get_oracle_last_price(db, oracle_address, block_index)
        if last_price is None:
            problems.append('The oracle address %s has not broadcasted any price yet' % oracle_address)
    if len(problems) > 0:
        return None, problems
        return asset_id, None
pose (db, source, asset, give_quantity, escrow_quantity, mainchainrate, status, open_address=None, oracle_address=None):
    assetid, problems = validate(db, source, asset, give_quantity, escrow_quantity, mainchainrate, status, open_address, util.CURRENT_BLOCK_INDEX, oracle_address)
    if problems: raise exceptions.ComposeError(problems)
    destination = []
    data = message_type.pack(ID)
    data += struct.pack(FORMAT, assetid, give_quantity, escrow_quantity, mainchainrate, status)
    if status == STATUS_OPENM
_EMPTY_ADDRESS and open_address:
        data += address.pack(open_address)
    if oracle_address is not None and util.enabled('oracle_dispensers'):
        oracle_fee = calculate_oracle_fee(db, escrow_quantity, give_quantity, mainchainrate, oracle_address, util.CURRENT_BLOCK_INDEX)
        if oracle_fee >= config.DEFAULT_REGULAR_DUST_SIZE:
            destination.append((oracle_address,oracle_fee))
        data += address.pack(oracle_address)
    return (source, destination, data)
lculate_oracle_fee(db, escrow_quantity, give_quantity, mainchainrate, oracle_address, block_index):
    last_price, last_fee, last_fiat_label, last_updated = util.get_oracle_last_price(db, oracle_address, block_index)
    last_fee_multiplier = (last_fee / config.UNIT)
    #Format mainchainrate to ######.##
    oracle_mainchainrate = util.satoshirate_to_fiat(mainchainrate)
    oracle_mainchainrate_btc = oracle_mainchainrate/last_price
    #Calculate the total amount earned for dispenser and M
    remaining = int(floor(escrow_quantity / give_quantity))
    total_quantity_btc = oracle_mainchainrate_btc * remaining
    oracle_fee_btc = int(total_quantity_btc * last_fee_multiplier *config.UNIT)
    return oracle_fee_btc
def parse (db, tx, message):
    cursor = db.cursor()
    # Unpack message.
        action_address = tx['source']
        oracle_address = None
        assetid, give_quantity, escrow_quantity, mainchainrate, dispenser_status = struct.unpack(FORMAT, message[0:LENGTH])
        read = LENGTH
        if dispenser_status == STATUS_OPEN_EMPTY_ADDRESS:
            action_address = address.unpack(message[LENGTH:LENGTH+21])
            read = LENGTH + 21
        if len(message) > read:
            oracle_address = address.unpack(message[read:read+21])
        asset = util.generate_asset_name(assetid, util.CURRENT_BLOCK_INDEX)
        status = 'valid'
    except (exceptions.UnpackError, struct.error) as e:
        assetid, give_quantity, mainchainrate, asset = None, None, None, None
    status = 'invalid: could not unpack'
    if status == 'valid':
        if util.enabled("dispenser_parsing_validation", util.CURRENT_BLOCK_INDEX):
            asset_id, problems = validate(db, tx['source'], asset, give_quantity, escrow_quantity, mainchainrate, dispenser_status, action_address if dispenser_status == STATUS_OPEN_EMPTY_ADDRESS else None, tx['block_index'], oracle_address)
            problems = None
        if problems:
            status = 'invalid: ' + '; '.join(problM
            if dispenser_status == STATUS_OPEN or dispenser_status == STATUS_OPEN_EMPTY_ADDRESS:
                cursor.execute('SELECT * FROM dispensers WHERE source=:source AND asset=:asset AND status=:status', {
                    'source': action_address,
                    'asset': asset,
                    'status': STATUS_OPEN
                existing = cursor.fetchall()
                if len(existing) == 0:
                    if (oracle_address != None) and utiM
l.enabled('oracle_dispensers', tx['block_index']):
                        oracle_fee = calculate_oracle_fee(db, escrow_quantity, give_quantity, mainchainrate, oracle_address, tx['block_index'])

                        if oracle_fee >= config.DEFAULT_REGULAR_DUST_SIZE:
                            if tx["destination"] != oracle_address or tx["btc_amount"] < oracle_fee:
                                status = 'invalid: insufficient or non-existent oracle fee'


                    if status == 'valid':
                        # Create the new dispenser
                        try:
                            if dispenser_status == STATUS_OPEN_EMPTY_ADDRESS:
                                cursor.execute('SELECT count(*) cnt FROM balances WHERE address=:address AND quantity > 0', {
                                    'address': action_address
                                })
                                counts = cursor.fetchall()[0]
                   if counts['cnt'] == 0:
                                    util.debit(db, tx['source'], asset, escrow_quantity, action='open dispenser empty addr', event=tx['tx_hash'])
                                    util.credit(db, action_address, asset, escrow_quantity, action='open dispenser empty addr', event=tx['tx_hash'])
                                    util.debit(db, action_address, asset, escrow_quantity, action='open dispenser empty addr', event=tx['tx_hash'])
                                elsM
                                    status = 'invalid: address not empty'
                            else:
                                util.debit(db, tx['source'], asset, escrow_quantity, action='open dispenser', event=tx['tx_hash'])
                        except util.DebitError as e:
                            status = 'invalid: insufficient funds'
                    if status == 'valid':
                        bindings = {
                            'tx_index': tx['tx_index'],
                      M
      'tx_hash': tx['tx_hash'],
                            'block_index': tx['block_index'],
                            'source': action_address,
                            'asset': asset,
                            'give_quantity': give_quantity,
                            'escrow_quantity': escrow_quantity,
                            'satoshirate': mainchainrate,
                            'status': STATUS_OPEN,
                            'give_remaining': escrow_quantity,
                            'oraM
cle_address': oracle_address
                        }
                        sql = 'insert into dispensers values(:tx_index, :tx_hash, :block_index, :source, :asset, :give_quantity, :escrow_quantity, :satoshirate, :status, :give_remaining, :oracle_address)'
                        cursor.execute(sql, bindings)
                elif len(existing) == 1 and existing[0]['satoshirate'] == mainchainrate and existing[0]['give_quantity'] == give_quantity:
                    if tx["source"]==action_address:
          if (oracle_address != None) and util.enabled('oracle_dispensers', tx['block_index']):
                            oracle_fee = calculate_oracle_fee(db, escrow_quantity, give_quantity, mainchainrate, oracle_address, tx['block_index'])

                            if oracle_fee >= config.DEFAULT_REGULAR_DUST_SIZE:
                                if tx["destination"] != oracle_address or tx["btc_amount"] < oracle_fee:
                                    status = 'invalid: iM
nsufficient or non-existent oracle fee'

                        if status == 'valid':
                            # Refill the dispenser by the given amount
                            bindings = {
                                'source': tx['source'],
                                'asset': asset,
                                'prev_status': dispenser_status,
                                'give_remaining': existing[0]['give_remaining'] + escrow_quantity,
                             M
   'status': STATUS_OPEN,
                                'block_index': tx['block_index'],
                                'action':'refill dispenser',
                                'escrow_quantity':escrow_quantity
                            }
                            try:
                                util.debit(db, tx['source'], asset, escrow_quantity, action='refill dispenser', event=tx['tx_hash'])
                                sql = 'UPDATE dispensers SET give_remaining=:give_remaining \
                         WHERE source=:source AND asset=:asset AND status=:status'
                                cursor.execute(sql, bindings)
                            except (util.DebitError):
                                status = 'insufficient funds'
                    else:
                        status = 'invalid: can only refill dispenser from source'
                else:
                    status = 'can only have one open dispenser per asset per address'
if dispenser_status == STATUS_CLOSED:
                cursor.execute('SELECT tx_index, give_remaining FROM dispensers WHERE source=:source AND asset=:asset AND status=:status', {
                    'source': tx['source'],
                    'asset': asset,
                    'status': STATUS_OPEN
                existing = cursor.fetchall()
                if len(existing) == 1:
                    util.credit(db, tx['source'], asset, existing[0]['give_remaining'], action='close dispenser', eM
                    bindings = {
                        'source': tx['source'],
                        'asset': asset,
                        'status': STATUS_CLOSED,
                        'block_index': tx['block_index'],
                        'tx_index': existing[0]['tx_index']
                    }
                    sql = 'UPDATE dispensers SET give_remaining=0, status=:status WHERE source=:source AND asset=:asset'
                    cursor.execute(sql, bindings)
                elsM
                    status = 'dispenser inexistent'
                status = 'invalid: status must be one of OPEN or CLOSE'
    if status != 'valid':
        logger.warn("Not storing [dispenser] tx [%s]: %s" % (tx['tx_hash'], status))
def is_dispensable(db, address, amount):
    cursor = db.cursor()
    cursor.execute('SELECT * FROM dispensers WHERE source=:source AND status=:status', {
        'source': address,
        'status': STATUS_OPEN
    dispensers = cuM
    for next_dispenser in dispensers:
        if next_dispenser["oracle_address"] != None:
            last_price, last_fee, last_fiat_label, last_updated = util.get_oracle_last_price(db, next_dispenser['oracle_address'], util.CURRENT_BLOCK_INDEX)
            fiatrate = util.satoshirate_to_fiat(next_dispenser["satoshirate"])
            if amount >= fiatrate/last_price:
                return True
            if amount >= next_dispenser["satoshirate"]:
def dispense(db, tx):
    cursor = db.cursor()
    cursor.execute('SELECT * FROM dispensers WHERE source=:source AND status=:status ORDER BY asset', {
        'source': tx['destination'],
        'status': STATUS_OPEN
    dispensers = cursor.fetchall()
    dispense_index = 0
    for dispenser in dispensers:
        satoshirate = dispenser['satoshirate']
        give_quantity = dispenser['give_quantity']
        if satoshirate > 0 and give_quantity > 0:
if (dispenser['oracle_address'] != None) and util.enabled('oracle_dispensers', tx['block_index']):
                last_price, last_fee, last_fiat_label, last_updated = util.get_oracle_last_price(db, dispenser['oracle_address'], tx['block_index'])
                fiatrate = util.satoshirate_to_fiat(satoshirate)
                must_give = int(floor(((tx['btc_amount'] / config.UNIT) * last_price)/fiatrate))
                must_give = int(floor(tx['btc_amount'] / satoshirate))
        remaining = int(floor(dispenser['give_remaining'] / give_quantity))
            actually_given = min(must_give, remaining) * give_quantity
            give_remaining = dispenser['give_remaining'] - actually_given
            assert give_remaining >= 0
            # Skip dispense if quantity is 0
            if util.enabled('zero_quantity_value_adjustment_1') and actually_given==0:
                continue
            util.credit(db, tx['source'], dispenser['asset'], actually_given, action='dispense', eveM
            dispenser['give_remaining'] = give_remaining
            if give_remaining < dispenser['give_quantity']:
                # close the dispenser
                dispenser['give_remaining'] = 0
                if give_remaining > 0:
                    # return the remaining to the owner
                    util.credit(db, dispenser['source'], dispenser['asset'], give_remaining, action='dispenser close', event=tx['tx_hash'])
                dispenser['status'] = STATUS_CLOSED
  dispenser['block_index'] = tx['block_index']
            dispenser['prev_status'] = STATUS_OPEN
            cursor.execute('UPDATE DISPENSERS SET give_remaining=:give_remaining, status=:status \
                    WHERE source=:source AND asset=:asset AND satoshirate=:satoshirate AND give_quantity=:give_quantity AND status=:prev_status', dispenser)
            bindings = {
                'tx_index': tx['tx_index'],
                'tx_hash': tx['tx_hash'],
                'dispense_index': dispense_index,
            'block_index': tx['block_index'],
                'source': tx['destination'],
                'destination': tx['source'],
                'asset': dispenser['asset'],
                'dispense_quantity': actually_given,
                'dispenser_tx_hash': dispenser['tx_hash']
            sql = 'INSERT INTO dispenses(tx_index, dispense_index, tx_hash, block_index, source, destination, asset, dispense_quantity, dispenser_tx_hash) \
                    VALUES(:tx_index, :dispense_index, :tM
x_hash, :block_index, :source, :destination, :asset, :dispense_quantity, :dispenser_tx_hash);'
            cursor.execute(sql, bindings)
            dispense_index += 1
"""Pay out dividends."""
logger = logging.getLogger(__name__)
from counterpartylib.lib import (config, exceptions, util, message_type)
def initialise (db):
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS dividends(
                      tx_index INTEGER PRIMARY KEY,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      asset TEXT,
                      dividend_asset TEXT,
                      quantity_per_unit INTEGER,
                      fee_paid INTEGER,
                      status TEXT,
                      FOREIM
GN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON dividends (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON dividends (source)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      asset_idx ON dividends (asset)
                   ''')
lidate (db, source, quantity_per_unit, asset, dividend_asset, block_index):
    cursor = db.cursor()
    if asset == config.BTC:
        problems.append('cannot pay dividends to holders of {}'.format(config.BTC))
    if asset == config.XCP:
        if (not block_index >= 317500) or block_index >= 320000 or config.TESTNET or config.REGTEST:   # Protocol change.
            problems.append('cannot pay dividends to holders of {}'.format(config.XCP))
    if quantity_per_unit <= 0:
positive quantity per unit')
    if quantity_per_unit > config.MAX_INT:
        problems.append('integer overflow')
    # Examine asset.
    issuances = list(cursor.execute('''SELECT * FROM issuances WHERE (status = ? AND asset = ?) ORDER BY tx_index ASC''', ('valid', asset)))
    if not issuances:
        problems.append('no such asset, {}.'.format(asset))
        return None, None, problems, 0
    divisible = issuances[0]['divisible']
    # Only issuer can pay dividends.
lock_index >= 320000 or config.TESTNET or config.REGTEST:   # Protocol change.
        if issuances[-1]['issuer'] != source:
            problems.append('only issuer can pay dividends')
    # Examine dividend asset.
    if dividend_asset in (config.BTC, config.XCP):
        dividend_divisible = True
        issuances = list(cursor.execute('''SELECT * FROM issuances WHERE (status = ? AND asset = ?)''', ('valid', dividend_asset)))
        if not issuances:
            problems.append('no such dividend asseM
t, {}.'.format(dividend_asset))
            return None, None, problems, 0
        dividend_divisible = issuances[0]['divisible']
    # Calculate dividend quantities.
    exclude_empty = False
    if util.enabled('zero_quantity_value_adjustment_1'):
        exclude_empty = True
    holders = util.holders(db, asset, exclude_empty)
    dividend_total = 0
    for holder in holders:
        if block_index < 294500 and not (config.TESTNET or config.REGTEST): # Protocol change.
       if holder['escrow']: continue
        address = holder['address']
        address_quantity = holder['address_quantity']
        if block_index >= 296000 or config.TESTNET or config.REGTEST: # Protocol change.
            if address == source: continue
        dividend_quantity = address_quantity * quantity_per_unit
        if divisible: dividend_quantity /= config.UNIT
        if not util.enabled('nondivisible_dividend_fix') and not dividend_divisible: dividend_quantity /= config.UNIT # Pre-fix behaviourM
        if dividend_asset == config.BTC and dividend_quantity < config.DEFAULT_MULTISIG_DUST_SIZE: continue    # A bit hackish.
        dividend_quantity = int(dividend_quantity)
        outputs.append({'address': address, 'address_quantity': address_quantity, 'dividend_quantity': dividend_quantity})
        addresses.append(address)
        dividend_total += dividend_quantity
    if not dividend_total: problems.append('zero dividend')
    if dividend_asset != config.BTC:
        dividend_balances = list(cursoM
r.execute('''SELECT * FROM balances WHERE (address = ? AND asset = ?)''', (source, dividend_asset)))
        if not dividend_balances or dividend_balances[0]['quantity'] < dividend_total:
            problems.append('insufficient funds ({})'.format(dividend_asset))
    if not problems and dividend_asset != config.BTC:
        holder_count = len(set(addresses))
        if block_index >= 330000 or config.TESTNET or config.REGTEST: # Protocol change.
            fee = int(0.0002 * config.UNIT * holder_couM
            balances = list(cursor.execute('''SELECT * FROM balances WHERE (address = ? AND asset = ?)''', (source, config.XCP)))
            if not balances or balances[0]['quantity'] < fee:
                problems.append('insufficient funds ({})'.format(config.XCP))
    if not problems and dividend_asset == config.XCP:
        total_cost = dividend_total + fee
        if not dividend_balances or dividend_balances[0]['quantity'] < total_cost:
            problems.append('insufficient funds ({M
})'.format(dividend_asset))
    if fee > config.MAX_INT or dividend_total > config.MAX_INT:
        problems.append('integer overflow')
    return dividend_total, outputs, problems, fee
def compose (db, source, quantity_per_unit, asset, dividend_asset):
    # resolve subassets
    asset = util.resolve_subasset_longname(db, asset)
    dividend_asset = util.resolve_subasset_longname(db, dividend_asset)
    dividend_total, outputs, problems, fee = validate(db, source, quantityM
_per_unit, asset, dividend_asset, util.CURRENT_BLOCK_INDEX)
    if problems: raise exceptions.ComposeError(problems)
    logger.info('Total quantity to be distributed in dividends: {} {}'.format(util.value_out(db, dividend_total, dividend_asset), dividend_asset))
    if dividend_asset == config.BTC:
        return (source, [(output['address'], output['dividend_quantity']) for output in outputs], None)
    asset_id = util.get_asset_id(db, asset, util.CURRENT_BLOCK_INDEX)
    dividend_asset_id = util.get_asset_id(dM
b, dividend_asset, util.CURRENT_BLOCK_INDEX)
    data = message_type.pack(ID)
    data += struct.pack(FORMAT_2, quantity_per_unit, asset_id, dividend_asset_id)
    return (source, [], data)
def parse (db, tx, message):
    dividend_parse_cursor = db.cursor()
    # Unpack message.
        if (tx['block_index'] > 288150 or config.TESTNET or config.REGTEST) and len(message) == LENGTH_2:
            quantity_per_unit, asset_id, dividend_asset_id = struct.unpack(FORMAT_2, message)
            asset = util.getM
_asset_name(db, asset_id, tx['block_index'])
            dividend_asset = util.get_asset_name(db, dividend_asset_id, tx['block_index'])
            status = 'valid'
        elif len(message) == LENGTH_1:
            quantity_per_unit, asset_id = struct.unpack(FORMAT_1, message)
            asset = util.get_asset_name(db, asset_id, tx['block_index'])
            dividend_asset = config.XCP
            status = 'valid'
            raise exceptions.UnpackError
    except (exceptions.UnpackError, exceptioM
ns.AssetNameError, struct.error) as e:
        dividend_asset, quantity_per_unit, asset = None, None, None
        status = 'invalid: could not unpack'
    if dividend_asset == config.BTC:
        status = 'invalid: cannot pay {} dividends within protocol'.format(config.BTC)
    if status == 'valid':
        # For SQLite3
        quantity_per_unit = min(quantity_per_unit, config.MAX_INT)
        dividend_total, outputs, problems, fee = validate(db, tx['source'], quantity_per_unit, asset, dividend_asset, block_inM
dex=tx['block_index'])
        if problems: status = 'invalid: ' + '; '.join(problems)
    if status == 'valid':
        util.debit(db, tx['source'], dividend_asset, dividend_total, action='dividend', event=tx['tx_hash'])
        if tx['block_index'] >= 330000 or config.TESTNET or config.REGTEST: # Protocol change.
            util.debit(db, tx['source'], config.XCP, fee, action='dividend fee', event=tx['tx_hash'])
        for output in outputs:
            if not util.enabled('M
dont_credit_zero_dividend') or output['dividend_quantity'] > 0:
                util.credit(db, output['address'], dividend_asset, output['dividend_quantity'], action='dividend', event=tx['tx_hash'])
    # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
        'source': tx['source'],
        'asset': asset,
        'dividend_asset': dividend_asset,
        'quantity_per_unit': M
        'fee_paid': fee,
        'status': status,
    if "integer overflow" not in status:
        sql = 'insert into dividends values(:tx_index, :tx_hash, :block_index, :source, :asset, :dividend_asset, :quantity_per_unit, :fee_paid, :status)'
        dividend_parse_cursor.execute(sql, bindings)
        logger.warn("Not storing [dividend] tx [%s]: %s" % (tx['tx_hash'], status))
        logger.debug("Bindings: %s" % (json.dumps(bindings), ))
    dividend_parse_cursor.close()
 vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
Allow simultaneous lock and transfer.
logger = logging.getLogger(__name__)
from counterpartylib.lib import (config, util, exceptions, util, message_type)
LENGTH_1 = 8 + 8 + 1
FORMAT_2 = '>QQ??If'
LENGTH_2 = 8 + 8 + 1 + 1 + 4 + 4
SUBASSET_FORMAT = '>QQ?B'
SUBASSET_FORMAT_LENGTH = 8 + 8 + 1 + 1
# NOTE: Pascal strings are used for storing descriptions for backwards
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS issuances(
                      tx_index INTEGER PRIMARY KEY,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      asset TEXT,
                      quantity INTEGER,
                      divisible BOOL,
                      source TEXT,
                      issuer TEXT,
                      transfer BOOL,
                      callable BOOL,
                      call_date INTEGER,
                      call_price REAL,
                      description TEXT,
                      fee_paid INTEGER,
                      locked BOOL,
                      status TEXT,
                      asset_longname TEXT,
                      reset BOOL,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
    # Add asset_longname for sub-assets
t do `ALTER TABLE IF COLUMN NOT EXISTS`.
    columns = [column['name'] for column in cursor.execute('''PRAGMA table_info(issuances)''')]
    if 'asset_longname' not in columns:
        cursor.execute('''ALTER TABLE issuances ADD COLUMN asset_longname TEXT''')
    if 'reset' not in columns:
        cursor.execute('''ALTER TABLE issuances ADD COLUMN reset BOOL''')
    # If sweep_hotfix activated, Create issuances copy, copy old data, drop old tabM
le, rename new table, recreate indexes
t do `ALTER TABLE IF COLUMN NOT EXISTS` nor can drop UNIQUE constraints
    if 'msg_index' not in columns:
            cursor.execute('''CREATE TABLE IF NOT EXISTS new_issuances(
                              tx_index INTEGER,
                              tx_hash TEXT,
                              msg_index INTEGER DEFAULT 0,
                              block_index INTEGER,
                              asset TEXT,
                              quantitM
                              divisible BOOL,
                              source TEXT,
                              issuer TEXT,
                              transfer BOOL,
                              callable BOOL,
                              call_date INTEGER,
                              call_price REAL,
                              description TEXT,
                              fee_paid INTEGER,
                              locked BOOL,
                              status TEXT,
                     asset_longname TEXT,
                              reset BOOL,
                              PRIMARY KEY (tx_index, msg_index),
                              FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index),
                              UNIQUE (tx_hash, msg_index))
                           ''')
            cursor.execute('''INSERT INTO new_issuances(tx_index, tx_hash, msg_index,
                block_index, asset, quantity, divisible, sourcM
e, issuer, transfer, callable,
                call_date, call_price, description, fee_paid, locked, status, asset_longname, reset)
                SELECT tx_index, tx_hash, 0, block_index, asset, quantity, divisible, source,
                issuer, transfer, callable, call_date, call_price, description, fee_paid,
                locked, status, asset_longname, reset FROM issuances''', {})
            cursor.execute('DROP TABLE issuances')
            cursor.execute('ALTER TABLE new_issuances RENAME TO issuances')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON issuances (block_index)
                    ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      valid_asset_idx ON issuances (asset, status)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      status_idx ON issuances (status)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON issuances (source)
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      asset_longname_idx ON issuances (asset_longname)
                   ''')
def validate (db, source, destination, asset, quantity, divisible, lock, reset, callable_, call_date, call_price, description, subasset_parent, subasset_longname, block_index):
    if asset in (config.BTC, config.XCP):
        problems.append('cannot issue {} or {}'.format(config.BTC, config.XCP))
    if call_date is None: cM
    if call_price is None: call_price = 0.0
    if description is None: description = ""
    if divisible is None: divisible = True
    if lock is None: lock = False
    if reset is None: reset = False
    if isinstance(call_price, int): call_price = float(call_price)
    #^ helps especially with calls from JS
based clients, where parseFloat(15) returns 15 (not 15.0), which json takes as an int
    if not isinstance(quantity, int):
        problems.append('quantity must be in satoshis')
urn call_date, call_price, problems, fee, description, divisible, None, None
    if call_date and not isinstance(call_date, int):
        problems.append('call_date must be epoch integer')
        return call_date, call_price, problems, fee, description, divisible, None, None
    if call_price and not isinstance(call_price, float):
        problems.append('call_price must be a float')
        return call_date, call_price, problems, fee, description, divisible, None, None
    if quantity < 0: problems.append('negatM
    if call_price < 0: problems.append('negative call price')
    if call_date < 0: problems.append('negative call date')
    # Callable, or not.
    if not callable_:
        if block_index >= 312500 or config.TESTNET or config.REGTEST: # Protocol change.
            call_date = 0
            call_price = 0.0
        elif block_index >= 310000:                 # Protocol change.
            if call_date:
                problems.append('call date for non
            if call_priceM
                problems.append('call price for non
    # Valid re-issuance?
    cursor = db.cursor()
    cursor.execute('''SELECT * FROM issuances \
                      WHERE (status = ? AND asset = ?)
                      ORDER BY tx_index ASC''', ('valid', asset))
    issuances = cursor.fetchall()
    reissued_asset_longname = None
        reissuance = True
        last_issuance = issuances[-1]
        reissued_asset_longname = last_issuance['asset_loM
        issuance_locked = False
        if util.enabled('issuance_lock_fix'):
            for issuance in issuances:
                if issuance['locked']:
                    issuance_locked = True
                    break
        elif last_issuance['locked']:
            # before the issuance_lock_fix, only the last issuance was checked
            issuance_locked = True
        if last_issuance['issuer'] != source:
            problems.append('issued by another address')
        if (bool(last_issuanceM
['divisible']) != bool(divisible)) and ((not util.enabled("cip03", block_index)) or (not reset)):
            problems.append('cannot change divisibility')
        if bool(last_issuance['callable']) != bool(callable_):
            problems.append('cannot change callability')
        if last_issuance['call_date'] > call_date and (call_date != 0 or (block_index < 312500 and (not config.TESTNET or not config.REGTEST))):
            problems.append('cannot advance call date')
        if last_issuance['call_price'] > caM
            problems.append('cannot reduce call price')
        if issuance_locked and quantity:
            problems.append('locked asset and non
        if issuance_locked and reset:
            problems.append('cannot reset a locked asset')
        reissuance = False
        if description.lower() == 'lock':
            problems.append('cannot lock a non
        #if destination:
        #    problems.append('cannot transfer a non
            problems.append('cannot reset a non existent asset')
    # validate parent ownership for subasset
    if subasset_longname is not None and not reissuance:
        cursor = db.cursor()
        cursor.execute('''SELECT * FROM issuances \
                          WHERE (status = ? AND asset = ?)
                          ORDER BY tx_index ASC''', ('valid', subasset_parent))
        parent_issuances = cursor.fetchall()
        cursor.close()
        if parent_issuances:
            last_parent_M
issuance = parent_issuances[-1]
            if last_parent_issuance['issuer'] != source:
                problems.append('parent asset owned by another address')
            problems.append('parent asset not found')
    # validate subasset issuance is not a duplicate
    if subasset_longname is not None and not reissuance:
        cursor = db.cursor()
        cursor.execute('''SELECT * FROM assets \
                          WHERE (asset_longname = ?)''', (subasset_longname,))
        assets = cursorM
        if len(assets) > 0:
            problems.append('subasset already exists')
        # validate that the actual asset is numeric
        if asset[0] != 'A':
            problems.append('a subasset must be a numeric asset')
    # Check for existence of fee funds.
    if quantity or (block_index >= 315000 or config.TESTNET or config.REGTEST):   # Protocol change.
        if not reissuance or (block_index < 310000 and not config.TESTNET and not config.REGTEST):  # Pay fee only upon first issuanceM
. (Protocol change.)
            cursor = db.cursor()
            cursor.execute('''SELECT * FROM balances \
                              WHERE (address = ? AND asset = ?)''', (source, config.XCP))
            balances = cursor.fetchall()
            cursor.close()
            if util.enabled('numeric_asset_names'):  # Protocol change.
                if subasset_longname is not None and util.enabled('subassets'): # Protocol change.
                    # subasset issuance is 0.25
                    fee = int(0.25M
                elif len(asset) >= 13:
                    fee = 0
                else:
                    fee = int(0.5 * config.UNIT)
            elif block_index >= 291700 or config.TESTNET or config.REGTEST:     # Protocol change.
                fee = int(0.5 * config.UNIT)
            elif block_index >= 286000 or config.TESTNET or config.REGTEST:   # Protocol change.
                fee = 5 * config.UNIT
            elif block_index > 281236 or config.TESTNET or config.REGTEST:    # ProtocoM
                fee = 5
            if fee and (not balances or balances[0]['quantity'] < fee):
                problems.append('insufficient funds')
    if not (block_index >= 317500 or config.TESTNET or config.REGTEST):  # Protocol change.
        if len(description) > 42:
            problems.append('description too long')
    call_date = min(call_date, config.MAX_INT)
    assert isinstance(quantity, int)
    if reset and util.enabled("cip03", block_index):#reset will overwrite the M
        if quantity > config.MAX_INT:
            problems.append('total quantity overflow')
        total = sum([issuance['quantity'] for issuance in issuances])
        if total + quantity > config.MAX_INT:
            problems.append('total quantity overflow')
    if util.enabled("cip03", block_index) and reset and issuances:
        cursor = db.cursor()
        #Checking that all supply are held by the owner of the asset
        cursor.execute('''SELECT * FROM balances \
          WHERE asset = ? AND quantity > 0''', (asset,))
        balances = cursor.fetchall()
        cursor.close()
        if (len(balances) == 0):
            if util.asset_supply(db, asset) > 0:
                problems.append('Cannot reset an asset with no holder')
        elif (len(balances) > 1):
            problems.append('Cannot reset an asset with many holders')
        elif (len(balances) == 1):
            if (balances[0]['address'] != last_issuance["issuer"]):
                problems.append(M
'Cannot reset an asset held by a different address than the owner')
    #if destination and quantity:
    #    problems.append('cannot issue and transfer simultaneously')
    if util.enabled('integer_overflow_fix', block_index=block_index) and (fee > config.MAX_INT or quantity > config.MAX_INT):
        problems.append('integer overflow')
    return call_date, call_price, problems, fee, description, divisible, lock, reset, reissuance, reissued_asset_longname
def compose (db, source, transfer_M
destination, asset, quantity, divisible, lock, reset, description):
    # Callability is deprecated, so for re
issuances set relevant parameters
    # to old values; for first issuances, make uncallable.
    cursor = db.cursor()
    cursor.execute('''SELECT * FROM issuances \
                      WHERE (status = ? AND asset = ?)
                      ORDER BY tx_index ASC''', ('valid', asset))
    issuances = cursor.fetchall()
        last_issuance = issuances[-1]
        callable_ = last_issuM
        call_date = last_issuance['call_date']
        call_price = last_issuance['call_price']
        callable_ = False
        call_date = 0
        call_price = 0.0
    # check subasset
    subasset_parent = None
    subasset_longname = None
    if util.enabled('subassets'): # Protocol change.
        subasset_parent, subasset_longname = util.parse_subasset_from_asset_name(asset)
        if subasset_longname is not None:
            # try to find an existing subassM
            sa_cursor = db.cursor()
            sa_cursor.execute('''SELECT * FROM assets \
                              WHERE (asset_longname = ?)''', (subasset_longname,))
            assets = sa_cursor.fetchall()
            sa_cursor.close()
            if len(assets) > 0:
                # this is a reissuance
                asset = assets[0]['asset_name']
                # this is a new issuance
                #   generate a random numeric asset id which will map to this subasset
           asset = util.generate_random_asset()
    call_date, call_price, problems, fee, description, divisible, lock, reset, reissuance, reissued_asset_longname = validate(db, source, transfer_destination, asset, quantity, divisible, lock, reset, callable_, call_date, call_price, description, subasset_parent, subasset_longname, util.CURRENT_BLOCK_INDEX)
    if problems: raise exceptions.ComposeError(problems)
    asset_id = util.generate_asset_id(asset, util.CURRENT_BLOCK_INDEX)
    if subasset_longname is NoneM
        asset_format = util.get_value_by_block_index("issuance_asset_serialization_format")
        asset_format_length = util.get_value_by_block_index("issuance_asset_serialization_length")
        # Type 20 standard issuance FORMAT_2 >QQ??If
        #   used for standard issuances and all reissuances
        data = message_type.pack(ID)
        if (len(description) <= 42) and not util.enabled('pascal_string_removed'):
            curr_format = FORMAT_2 + '{}p'.format(len(description) + 1)M
            curr_format = asset_format + '{}s'.format(len(description))
        if (asset_format_length <= 19):# callbacks parameters were removed
            data += struct.pack(curr_format, asset_id, quantity, 1 if divisible else 0, 1 if lock else 0, 1 if reset else 0, description.encode('utf-8'))
        elif (asset_format_length <= 26):
            data += struct.pack(curr_format, asset_id, quantity, 1 if divisible else 0, 1 if callable_ else 0,
                call_date or 0, call_priceM
 or 0.0, description.encode('utf-8'))
        elif (asset_format_length <= 27):# param reset was inserted
            data += struct.pack(curr_format, asset_id, quantity, 1 if divisible else 0, 1 if reset else 0, 1 if callable_ else 0,
                call_date or 0, call_price or 0.0, description.encode('utf-8'))
        elif (asset_format_length <= 28):# param lock was inserted
            data += struct.pack(curr_format, asset_id, quantity, 1 if divisible else 0, 1 if lock else 0, 1 if reset else 0, 1 if callablM
                call_date or 0, call_price or 0.0, description.encode('utf-8'))
        subasset_format = util.get_value_by_block_index("issuance_subasset_serialization_format",util.CURRENT_BLOCK_INDEX)
        subasset_format_length = util.get_value_by_block_index("issuance_subasset_serialization_length",util.CURRENT_BLOCK_INDEX)
        # Type 21 subasset issuance SUBASSET_FORMAT >QQ?B
        #   Used only for initial subasset issuance
        # compacts a subasset name to save space
  compacted_subasset_longname = util.compact_subasset_longname(subasset_longname)
        compacted_subasset_length = len(compacted_subasset_longname)
        data = message_type.pack(SUBASSET_ID)
        curr_format = subasset_format + '{}s'.format(compacted_subasset_length) + '{}s'.format(len(description))
        if subasset_format_length <= 18:
            data += struct.pack(curr_format, asset_id, quantity, 1 if divisible else 0, compacted_subasset_length, compacted_subasset_longname, description.encoM
        elif subasset_format_length <= 19:# param reset was inserted
            data += struct.pack(curr_format, asset_id, quantity, 1 if divisible else 0, 1 if reset else 0, compacted_subasset_length, compacted_subasset_longname, description.encode('utf-8'))
        elif subasset_format_length <= 20:# param lock was inserted
            data += struct.pack(curr_format, asset_id, quantity, 1 if divisible else 0, 1 if lock else 0, 1 if reset else 0, compacted_subasset_length, compacted_subasset_longnaM
me, description.encode('utf-8'))
    if transfer_destination:
        destination_outputs = [(transfer_destination, None)]
        destination_outputs = []
    return (source, destination_outputs, data)
def parse (db, tx, message, message_type_id):
    issuance_parse_cursor = db.cursor()
    asset_format = util.get_value_by_block_index("issuance_asset_serialization_format",tx['block_index'])
    asset_format_length = util.get_value_by_block_index("issuance_asset_serialization_length",tx['block_index'])
    subasset_format = util.get_value_by_block_index("issuance_subasset_serialization_format",tx['block_index'])
    subasset_format_length = util.get_value_by_block_index("issuance_subasset_serialization_length",tx['block_index'])
    # Unpack message.
        subasset_longname = None
        if message_type_id == SUBASSET_ID:
            if not util.enabled('subassets', block_index=tx['block_index']):
                logger.warn("subassets are not enabled at block %s" % tx['block_index'])
 raise exceptions.UnpackError
            # parse a subasset original issuance message
            lock = None
            reset = None
            if subasset_format_length <= 18:
                asset_id, quantity, divisible, compacted_subasset_length = struct.unpack(subasset_format, message[0:subasset_format_length])
            elif subasset_format_length <= 19:# param reset was inserted
                asset_id, quantity, divisible, reset, compacted_subasset_length = struct.unpack(subasset_formatM
, message[0:subasset_format_length])
            elif subasset_format_length <= 20:# param lock was inserted
                asset_id, quantity, divisible, lock, reset, compacted_subasset_length = struct.unpack(subasset_format, message[0:subasset_format_length])
            description_length = len(message) - subasset_format_length - compacted_subasset_length
            if description_length < 0:
                logger.warn("invalid subasset length: [issuance] tx [%s]: %s" % (tx['tx_haM
sh'], compacted_subasset_length))
                raise exceptions.UnpackError
            messages_format = '>{}s{}s'.format(compacted_subasset_length, description_length)
            compacted_subasset_longname, description = struct.unpack(messages_format, message[subasset_format_length:])
            subasset_longname = util.expand_subasset_longname(compacted_subasset_longname)
            callable_, call_date, call_price = False, 0, 0.0
                description = description.decode('utf-8')
            except UnicodeDecodeError:
                description = ''
        elif (tx['block_index'] > 283271 or config.TESTNET or config.REGTEST) and len(message) >= asset_format_length: # Protocol change.
            if (len(message) - asset_format_length <= 42) and not util.enabled('pascal_string_removed'):
                curr_format = asset_format + '{}p'.format(len(message) - asset_format_length)
                curr_format = asset_format + '{}s'.format(len(message) - asset_format_length)M
            lock = None
            reset = None
            if (asset_format_length <= 19):# callbacks parameters were removed
                asset_id, quantity, divisible, lock, reset, description = struct.unpack(curr_format, message)
                callable_, call_date, call_price = False, 0, 0.0
            elif (asset_format_length <= 26):#the reset param didn't even exist
                asset_id, quantity, divisible, callable_, call_date, call_price, description = struct.unpack(curr_format, mM
            elif (asset_format_length <= 27):# param reset was inserted
                asset_id, quantity, divisible, reset, callable_, call_date, call_price, description = struct.unpack(curr_format, message)
            elif (asset_format_length <= 28):# param lock was inserted
                asset_id, quantity, divisible, lock, reset, callable_, call_date, call_price, description = struct.unpack(curr_format, message)
            call_price = round(call_price, 6) # TODO: arbitrary
                description = description.decode('utf-8')
            except UnicodeDecodeError:
                description = ''
            if len(message) != LENGTH_1:
                raise exceptions.UnpackError
            asset_id, quantity, divisible = struct.unpack(FORMAT_1, message)
            lock, reset, callable_, call_date, call_price, description = False, False, False, 0, 0.0, ''
            asset = util.generate_asset_name(asset_id, tx['block_index'])
            ##This is for backwards compatibility with assets names longer than 12 characters
            if asset.startswith('A'):
                namedAsset = util.get_asset_name(db, asset_id, tx['block_index'])
                if (namedAsset != 0):
                    asset = namedAsset
            status = 'valid'
        except exceptions.AssetIDError:
            asset = None
            status = 'invalid: bad asset name'
    except exceptions.UnpackError as e:
et, quantity, divisible, lock, reset, callable_, call_date, call_price, description = None, None, None, None, None, None, None, None, None
        status = 'invalid: could not unpack'
    # parse and validate the subasset from the message
    subasset_parent = None
    if status == 'valid' and subasset_longname is not None: # Protocol change.
            # ensure the subasset_longname is valid
            util.validate_subasset_longname(subasset_longname)
            subasset_parent, subasset_longnameM
 = util.parse_subasset_from_asset_name(subasset_longname)
        except exceptions.AssetNameError as e:
            asset = None
            status = 'invalid: bad subasset name'
    reissuance = None
    if status == 'valid':
        call_date, call_price, problems, fee, description, divisible, lock, reset, reissuance, reissued_asset_longname = validate(db, tx['source'], tx['destination'], asset, quantity, divisible, lock, reset, callable_, call_date, call_price, description, subasset_parent, subasseM
t_longname, block_index=tx['block_index'])
        if problems: status = 'invalid: ' + '; '.join(problems)
        if not util.enabled('integer_overflow_fix', block_index=tx['block_index']) and 'total quantity overflow' in problems:
            quantity = 0
    if (status == 'valid') and reset and util.enabled("cip03", tx['block_index']):
        balances_cursor = issuance_parse_cursor.execute('''SELECT * FROM balances WHERE asset = ? AND quantity > 0''', (asset,))
        balances_result = balances_M
        if len(balances_result) <= 1:
            if len(balances_result) == 0:
                issuances_cursor = issuance_parse_cursor.execute('''SELECT * FROM issuances WHERE asset = ? ORDER BY tx_index DESC''', (asset,))
                issuances_result = issuances_cursor.fetchall()
                owner_balance = 0
                owner_address = issuances_result[0]['issuer']
                owner_balance = balances_result[0]["quantity"]
     owner_address = balances_result[0]["address"]
            if owner_address == tx['source']:
                if owner_balance > 0:
                    util.debit(db, tx['source'], asset, owner_balance, 'reset destroy', tx['tx_hash'])

                    bindings = {
                        'tx_index': tx['tx_index'],
                        'tx_hash': tx['tx_hash'],
                        'block_index': tx['block_index'],
                        'source': tx['source'],
                 'asset': asset,
                        'quantity': owner_balance,
                        'tag': "reset",
                        'status': "valid",
                        'reset': True,
                       }
                    sql = 'insert into destructions values(:tx_index, :tx_hash, :block_index, :source, :asset, :quantity, :tag, :status)'
                    issuance_parse_cursor.execute(sql, bindings)
                bindings= {
                    'tx_index': tx['tx_index'],
                   'tx_hash': tx['tx_hash'],
                    'block_index': tx['block_index'],
                    'asset': asset,
                    'quantity': quantity,
                    'divisible': divisible,
                    'source': tx['source'],
                    'issuer': tx['source'],
                    'transfer': False,
                    'callable': callable_,
                    'call_date': call_date,
                    'call_price': call_price,
                    'description': descM
                    'fee_paid': 0,
                    'locked': lock,
                    'status': status,
                    'reset': True,
                    'asset_longname': reissued_asset_longname,
                sql='insert into issuances values(:tx_index, :tx_hash, 0, :block_index, :asset, :quantity, :divisible, :source, :issuer, :transfer, :callable, :call_date, :call_price, :description, :fee_paid, :locked, :status, :asset_longname, :reset)'
                issuM
ance_parse_cursor.execute(sql, bindings)
                # Credit.
                if quantity:
                    util.credit(db, tx['source'], asset, quantity, action="reset issuance", event=tx['tx_hash'])
        if tx['destination']:
            issuer = tx['destination']
            transfer = True
            #quantity = 0
            issuer = tx['source']
            transfer = False
        # Debit fee.
        if status == 'valid':
            util.debit(db, tx['sourM
ce'], config.XCP, fee, action="issuance fee", event=tx['tx_hash'])
        if not isinstance(lock,bool):
            lock = False
        if status == 'valid':
            if (description and description.lower() == 'lock') or lock:
                lock = True
                cursor = db.cursor()
                issuances = list(cursor.execute('''SELECT * FROM issuances \
                                                   WHERE (status = ? AND asset = ?)
                                             M
      ORDER BY tx_index ASC''', ('valid', asset)))
                cursor.close()
                if len(issuances) > 0:
                    description = issuances[-1]['description']  # Use last description
            if not reissuance:
                # Add to table of assets.
                bindings= {
                    'asset_id': str(asset_id),
                    'asset_name': str(asset),
                    'block_index': tx['block_index'],
                    'asset_longname': subasset_longname,
                sql='insert into assets values(:asset_id, :asset_name, :block_index, :asset_longname)'
                issuance_parse_cursor.execute(sql, bindings)
        if status == 'valid' and reissuance:
            # when reissuing, add the asset_longname to the issuances table for API lookups
            asset_longname = reissued_asset_longname
            asset_longname = subasset_longname
        # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
            'tx_hash': tx['tx_hash'],
            'block_index': tx['block_index'],
            'asset': asset,
            'quantity': quantity,
            'divisible': divisible,
            'source': tx['source'],
            'issuer': issuer,
            'transfer': transfer,
            'callable': callable_,
            'call_date': call_date,
            'call_price': call_price,
            'description': description,
            'fee_paid': fee,
            'locked': loM
            'reset': reset,
            'status': status,
            'asset_longname': asset_longname,
        if "integer overflow" not in status:
            sql='insert into issuances values(:tx_index, :tx_hash, 0, :block_index, :asset, :quantity, :divisible, :source, :issuer, :transfer, :callable, :call_date, :call_price, :description, :fee_paid, :locked, :status, :asset_longname, :reset)'
            issuance_parse_cursor.execute(sql, bindings)
            logger.warn("Not storing M
[issuance] tx [%s]: %s" % (tx['tx_hash'], status))
            logger.debug("Bindings: %s" % (json.dumps(bindings), ))
        if status == 'valid' and quantity:
            util.credit(db, tx['source'], asset, quantity, action="issuance", event=tx['tx_hash'])
        issuance_parse_cursor.close()
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
# Filled orders may not be re
opened, so only orders not involving BTC (and so
# which cannot haveM
 expired order matches) may be filled.
logger = logging.getLogger(__name__)
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
from counterpartylib.lib import util
from counterpartylib.lib import backend
from counterpartylib.lib import log
from counterpartylib.lib import message_type
LENGTH = 8 + 8 + 8 + 8 + 2 + 8
    cursor = db.cursor()
or.execute('''CREATE TABLE IF NOT EXISTS orders(
                      tx_index INTEGER UNIQUE,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      give_asset TEXT,
                      give_quantity INTEGER,
                      give_remaining INTEGER,
                      get_asset TEXT,
                      get_quantity INTEGER,
                      get_remaining INTEGER,
                      expiration INTEGER,
                  expire_index INTEGER,
                      fee_required INTEGER,
                      fee_required_remaining INTEGER,
                      fee_provided INTEGER,
                      fee_provided_remaining INTEGER,
                      status TEXT,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index),
                      PRIMARY KEY (tx_index, tx_hash))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISM
                      block_index_idx ON orders (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      index_hash_idx ON orders (tx_index, tx_hash)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      expire_idx ON orders (expire_index, status)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      give_status_idx ON orders (give_asset, status)
                   ''')
.execute('''CREATE INDEX IF NOT EXISTS
                      source_give_status_idx ON orders (source, give_asset, status)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      give_get_status_idx ON orders (get_asset, give_asset, status)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON orders (source)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      give_asset_idx ON orM
                   ''')
    cursor.execute('''CREATE TABLE IF NOT EXISTS order_matches(
                      id TEXT PRIMARY KEY,
                      tx0_index INTEGER,
                      tx0_hash TEXT,
                      tx0_address TEXT,
                      tx1_index INTEGER,
                      tx1_hash TEXT,
                      tx1_address TEXT,
                      forward_asset TEXT,
                      forward_quantity INTEGER,
                      baM
                      backward_quantity INTEGER,
                      tx0_block_index INTEGER,
                      tx1_block_index INTEGER,
                      block_index INTEGER,
                      tx0_expiration INTEGER,
                      tx1_expiration INTEGER,
                      match_expire_index INTEGER,
                      fee_paid INTEGER,
                      status TEXT,
                      FOREIGN KEY (tx0_index, tx0_hash, tx0_block_index) REFERENCES transactions(tM
x_index, tx_hash, block_index),
                      FOREIGN KEY (tx1_index, tx1_hash, tx1_block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      match_expire_idx ON order_matches (status, match_expire_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      forward_status_idx ON order_matches (forward_asset, status)
                   ''')
    cursor.execute(''M
'CREATE INDEX IF NOT EXISTS
                      backward_status_idx ON order_matches (backward_asset, status)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      id_idx ON order_matches (id)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx0_address_idx ON order_matches (tx0_address)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx1_address_idx ON order_matches (tx1_address)
                   ''')
    # Order Expirations
    cursor.execute('''CREATE TABLE IF NOT EXISTS order_expirations(
                      order_index INTEGER PRIMARY KEY,
                      order_hash TEXT UNIQUE,
                      source TEXT,
                      block_index INTEGER,
                      FOREIGN KEY (block_index) REFERENCES blocks(block_index),
                      FOREIGN KEY (order_index, order_hash) REFERENCES orders(tx_index, tx_hash))
                   ''')
    cursor.execute('''M
CREATE INDEX IF NOT EXISTS
                      block_index_idx ON order_expirations (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON order_expirations (source)
                   ''')
    # Order Match Expirations
    cursor.execute('''CREATE TABLE IF NOT EXISTS order_match_expirations(
                      order_match_id TEXT PRIMARY KEY,
                      tx0_address TEXT,
                      tx1_address TEXT,
                    M
  block_index INTEGER,
                      FOREIGN KEY (order_match_id) REFERENCES order_matches(id),
                      FOREIGN KEY (block_index) REFERENCES blocks(block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON order_match_expirations (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx0_address_idx ON order_match_expirations (tx0_address)
                   ''')
or.execute('''CREATE INDEX IF NOT EXISTS
                      tx1_address_idx ON order_match_expirations (tx1_address)
                   ''')
def exact_penalty (db, address, block_index, order_match_id):
    # Penalize addresses that don
t make BTC payments. If an address lets an
    # order match expire, expire sell BTC orders from that address.
    cursor = db.cursor()
    bad_orders = list(cursor.execute('''SELECT * FROM orders \
                                        WHERE (source = ? AND gM
ive_asset = ? AND status = ?)''',
                                     (address, config.BTC, 'open')))
    for bad_order in bad_orders:
        cancel_order(db, bad_order, 'expired', block_index)
    if not (block_index >= 314250 or config.TESTNET or config.REGTEST):   # Protocol change.
        # Order matches.
        bad_order_matches = list(cursor.execute('''SELECT * FROM order_matches \
                                                   WHERE ((tx0_address = ? AND forward_asset = ?) OR (tx1_address = ? AND baM
ckward_asset = ?)) AND (status = ?)''',
                                         (address, config.BTC, address, config.BTC, 'pending')))
        for bad_order_match in bad_order_matches:
            cancel_order_match(db, bad_order_match, 'expired', block_index)
def cancel_order (db, order, status, block_index):
    cursor = db.cursor()
    # Update status of order.
        'status': status,
        'tx_hash': order['tx_hash']
    sql='update orders set statuM
s = :status where tx_hash = :tx_hash'
    cursor.execute(sql, bindings)
    log.message(db, block_index, 'update', 'orders', bindings)
    if order['give_asset'] != config.BTC:    # Can
        util.credit(db, order['source'], order['give_asset'], order['give_remaining'], action='cancel order', event=order['tx_hash'])
    if status == 'expired':
        # Record offer expiration.
        bindings = {
            'order_index': order['tx_index'],
            'order_hash': order['tx_hash'],
    'source': order['source'],
            'block_index': block_index
        sql='insert into order_expirations values(:order_index, :order_hash, :source, :block_index)'
        cursor.execute(sql, bindings)
def cancel_order_match (db, order_match, status, block_index):
    '''The only cancelling is an expiration.
    cursor = db.cursor()
    # Skip order matches just expired as a penalty. (Not very efficient.)
    if not (block_index >= 314250 or config.TESTNET or config.RM
EGTEST):   # Protocol change.
        order_matches = list(cursor.execute('''SELECT * FROM order_matches \
                                               WHERE (id = ? AND status = ?)''',
                                            (order_match['id'], 'expired')))
        if order_matches:
            cursor.close()
    # Update status of order match.
        'status': status,
        'order_match_id': order_match['id']
    sql='update order_matches set status = :status whM
ere id = :order_match_id'
    cursor.execute(sql, bindings)
    log.message(db, block_index, 'update', 'order_matches', bindings)
    order_match_id = util.make_id(order_match['tx0_hash'], order_match['tx1_hash'])
    # If tx0 is dead, credit address directly; if not, replenish give remaining, get remaining, and fee required remaining.
    orders = list(cursor.execute('''SELECT * FROM orders \
                                    WHERE tx_index = ?''',
                                 (order_match['tx0_index'],)))M
    assert len(orders) == 1
    tx0_order = orders[0]
    if tx0_order['status'] in ('expired', 'cancelled'):
        tx0_order_status = tx0_order['status']
        if order_match['forward_asset'] != config.BTC:
            util.credit(db, order_match['tx0_address'],
                        order_match['forward_asset'],
                        order_match['forward_quantity'], action='order {}'.format(tx0_order_status), event=order_match['id'])
        tx0_give_remaining = tx0_order['give_remaining'] + orM
der_match['forward_quantity']
        tx0_get_remaining = tx0_order['get_remaining'] + order_match['backward_quantity']
        if tx0_order['get_asset'] == config.BTC and (block_index >= 297000 or config.TESTNET or config.REGTEST):    # Protocol change.
            tx0_fee_required_remaining = tx0_order['fee_required_remaining'] + order_match['fee_paid']
            tx0_fee_required_remaining = tx0_order['fee_required_remaining']
        tx0_order_status = tx0_order['status']
_order_status == 'filled' and util.enabled("reopen_order_when_btcpay_expires_fix", block_index)): #This case could happen if a BTCpay expires and before the expiration, the order was filled by a correct BTCpay
            tx0_order_status = 'open' # So, we have to open the order again
        bindings = {
            'give_remaining': tx0_give_remaining,
            'get_remaining': tx0_get_remaining,
            'status': tx0_order_status,
            'fee_required_remaining': tx0_fee_required_reM
            'tx_hash': order_match['tx0_hash']
        sql='update orders set give_remaining = :give_remaining, get_remaining = :get_remaining, fee_required_remaining = :fee_required_remaining, status = :status where tx_hash = :tx_hash'
        cursor.execute(sql, bindings)
        log.message(db, block_index, 'update', 'orders', bindings)
    # If tx1 is dead, credit address directly; if not, replenish give remaining, get remaining, and fee required remaining.
    orders = list(cursor.execute('M
''SELECT * FROM orders \
                                    WHERE tx_index = ?''',
                                 (order_match['tx1_index'],)))
    assert len(orders) == 1
    tx1_order = orders[0]
    if tx1_order['status'] in ('expired', 'cancelled'):
        tx1_order_status = tx1_order['status']
        if order_match['backward_asset'] != config.BTC:
            util.credit(db, order_match['tx1_address'],
                        order_match['backward_asset'],
                        order_match['backward_quaM
ntity'], action='order {}'.format(tx1_order_status), event=order_match['id'])
        tx1_give_remaining = tx1_order['give_remaining'] + order_match['backward_quantity']
        tx1_get_remaining = tx1_order['get_remaining'] + order_match['forward_quantity']
        if tx1_order['get_asset'] == config.BTC and (block_index >= 297000 or config.TESTNET or config.REGTEST):    # Protocol change.
            tx1_fee_required_remaining = tx1_order['fee_required_remaining'] + order_match['fee_paid']
            tx1_fee_required_remaining = tx1_order['fee_required_remaining']
        tx1_order_status = tx1_order['status']
        if (tx1_order_status == 'filled' and util.enabled("reopen_order_when_btcpay_expires_fix", block_index)): #This case could happen if a BTCpay expires and before the expiration, the order was filled by a correct BTCpay
            tx1_order_status = 'open' # So, we have to open the order again
        bindings = {
            'give_remaining': tx1_give_remaining,
et_remaining': tx1_get_remaining,
            'status': tx1_order_status,
            'fee_required_remaining': tx1_fee_required_remaining,
            'tx_hash': order_match['tx1_hash']
        sql='update orders set give_remaining = :give_remaining, get_remaining = :get_remaining, fee_required_remaining = :fee_required_remaining, status = :status where tx_hash = :tx_hash'
        cursor.execute(sql, bindings)
        log.message(db, block_index, 'update', 'orders', bindings)
    if block_index < 286500M
:    # Protocol change.
        # Sanity check: one of the two must have expired.
        tx0_order_time_left = tx0_order['expire_index'] - block_index
        tx1_order_time_left = tx1_order['expire_index'] - block_index
        assert tx0_order_time_left or tx1_order_time_left
    # Penalize tardiness.
    if block_index >= 313900 or config.TESTNET or config.REGTEST:  # Protocol change.
        if tx0_order['status'] == 'expired' and order_match['forward_asset'] == config.BTC:
            exact_penalty(db, orderM
_match['tx0_address'], block_index, order_match['id'])
        if tx1_order['status'] == 'expired' and order_match['backward_asset'] == config.BTC:
            exact_penalty(db, order_match['tx1_address'], block_index, order_match['id'])
    if block_index >= 310000 or config.TESTNET or config.REGTEST: # Protocol change.
        if not (block_index >= 315000 or config.TESTNET or config.REGTEST):   # Protocol change.
            cursor.execute('''SELECT * FROM transactions\
                       M
       WHERE tx_hash = ?''', (tx0_order['tx_hash'],))
            match(db, list(cursor)[0], block_index)
            cursor.execute('''SELECT * FROM transactions\
                              WHERE tx_hash = ?''', (tx1_order['tx_hash'],))
            match(db, list(cursor)[0], block_index)
    if status == 'expired':
        # Record order match expiration.
        bindings = {
            'order_match_id': order_match['id'],
            'tx0_address': order_match['tx0_address'],
            'tx1_address': orderM
_match['tx1_address'],
            'block_index': block_index
        sql='insert into order_match_expirations values(:order_match_id, :tx0_address, :tx1_address, :block_index)'
        cursor.execute(sql, bindings)
def validate (db, source, give_asset, give_quantity, get_asset, get_quantity, expiration, fee_required, block_index):
    cursor = db.cursor()
    if give_quantity > config.MAX_INT or get_quantity > config.MAX_INT or fee_required > conM
fig.MAX_INT or block_index + expiration > config.MAX_INT:
        problems.append('integer overflow')
    if give_asset == config.BTC and get_asset == config.BTC:
        problems.append('cannot trade {} for itself'.format(config.BTC))
    if not isinstance(give_quantity, int):
        problems.append('give_quantity must be in satoshis')
        return problems
    if not isinstance(get_quantity, int):
        problems.append('get_quantity must be in satoshis')
        return problems
    if not isinstance(fee_reM
        problems.append('fee_required must be in satoshis')
        return problems
    if not isinstance(expiration, int):
        problems.append('expiration must be expressed as an integer block delta')
        return problems
    if give_quantity <= 0: problems.append('non
positive give quantity')
    if get_quantity <= 0: problems.append('non
positive get quantity')
    if fee_required < 0: problems.append('negative fee_required')
    if expiration < 0: problems.append('negative expiration')M
    if expiration == 0 and not (block_index >= 317500 or config.TESTNET or config.REGTEST):   # Protocol change.
        problems.append('zero expiration')
    if not give_quantity or not get_quantity:
        problems.append('zero give or zero get')
    cursor.execute('select * from issuances where (status = ? and asset = ?)', ('valid', give_asset))
    if give_asset not in (config.BTC, config.XCP) and not cursor.fetchall():
        problems.append('no such asset to give ({})'.format(give_asset))
ute('select * from issuances where (status = ? and asset = ?)', ('valid', get_asset))
    if get_asset not in (config.BTC, config.XCP) and not cursor.fetchall():
        problems.append('no such asset to get ({})'.format(get_asset))
    if expiration > config.MAX_EXPIRATION:
        problems.append('expiration overflow')
def compose (db, source, give_asset, give_quantity, get_asset, get_quantity, expiration, fee_required):
    cursor = db.cursor()
    # resolve subassets
  give_asset = util.resolve_subasset_longname(db, give_asset)
    get_asset = util.resolve_subasset_longname(db, get_asset)
    # Check balance.
    if give_asset != config.BTC:
        balances = list(cursor.execute('''SELECT * FROM balances WHERE (address = ? AND asset = ?)''', (source, give_asset)))
        if (not balances or balances[0]['quantity'] < give_quantity):
            raise exceptions.ComposeError('insufficient funds')
    problems = validate(db, source, give_asset, give_quantity, get_asset, get_quM
antity, expiration, fee_required, util.CURRENT_BLOCK_INDEX)
    if problems: raise exceptions.ComposeError(problems)
    give_id = util.get_asset_id(db, give_asset, util.CURRENT_BLOCK_INDEX)
    get_id = util.get_asset_id(db, get_asset, util.CURRENT_BLOCK_INDEX)
    data = message_type.pack(ID)
    data += struct.pack(FORMAT, give_id, give_quantity, get_id, get_quantity,
                        expiration, fee_required)
    return (source, [], data)
def parse (db, tx, message):
cursor = db.cursor()
    # Unpack message.
        if len(message) != LENGTH:
            raise exceptions.UnpackError
        give_id, give_quantity, get_id, get_quantity, expiration, fee_required = struct.unpack(FORMAT, message)
        give_asset = util.get_asset_name(db, give_id, tx['block_index'])
        get_asset = util.get_asset_name(db, get_id, tx['block_index'])
        status = 'open'
    except (exceptions.UnpackError, exceptions.AssetNameError, struct.error) as e:
        give_asset, give_quaM
ntity, get_asset, get_quantity, expiration, fee_required = 0, 0, 0, 0, 0, 0
        status = 'invalid: could not unpack'
    if status == 'open':
            price = util.price(get_quantity, give_quantity)
        except ZeroDivisionError:
            price = 0
        order_parse_cursor.execute('''SELECT * FROM balances \
                                      WHERE (address = ? AND asset = ?)''', (tx['source'], give_asset))
        balances = list(order_parse_cursorM
        if give_asset != config.BTC:
            if not balances:
                give_quantity = 0
                balance = balances[0]['quantity']
                if balance < give_quantity:
                    give_quantity = balance
                    get_quantity = int(price * give_quantity)
        problems = validate(db, tx['source'], give_asset, give_quantity, get_asset, get_quantity, expiration, fee_required, tx['block_index'])
        if problems: status = 'invalid: ' + '; '.join(prM
        if util.enabled('btc_order_minimum'):
            min_btc_quantity = 0.001 * config.UNIT  # 0.001 BTC
            if util.enabled('btc_order_minimum_adjustment_1'):
                min_btc_quantity = 0.00001 * config.UNIT  # 0.00001 BTC
            if (give_asset == config.BTC and give_quantity < min_btc_quantity) or (get_asset == config.BTC and get_quantity < min_btc_quantity):
                if problems:
                    status += '; btc order below minimum'
                else:
         status = 'invalid: btc order below minimum'
    # Debit give quantity. (Escrow.)
    if status == 'open':
        if give_asset != config.BTC:  # No need (or way) to debit BTC.
            util.debit(db, tx['source'], give_asset, give_quantity, action='open order', event=tx['tx_hash'])
    # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
        'source': tx['source']M
        'give_asset': give_asset,
        'give_quantity': give_quantity,
        'give_remaining': give_quantity,
        'get_asset': get_asset,
        'get_quantity': get_quantity,
        'get_remaining': get_quantity,
        'expiration': expiration,
        'expire_index': tx['block_index'] + expiration,
        'fee_required': fee_required,
        'fee_required_remaining': fee_required,
        'fee_provided': tx['fee'],
        'fee_provided_remaining': tx['fee'],
        'status': status,
 "integer overflow" not in status:
        sql = 'insert into orders values(:tx_index, :tx_hash, :block_index, :source, :give_asset, :give_quantity, :give_remaining, :get_asset, :get_quantity, :get_remaining, :expiration, :expire_index, :fee_required, :fee_required_remaining, :fee_provided, :fee_provided_remaining, :status)'
        order_parse_cursor.execute(sql, bindings)
        logger.warn("Not storing [order] tx [%s]: %s" % (tx['tx_hash'], status))
        logger.debug("Bindings: %s" % (json.dumps(biM
    if status == 'open' and tx['block_index'] != config.MEMPOOL_BLOCK_INDEX:
        match(db, tx)
    order_parse_cursor.close()
def match (db, tx, block_index=None):
    cursor = db.cursor()
    # Get order in question.
    orders = list(cursor.execute('''SELECT * FROM orders\
                                    WHERE (tx_index = ? AND status = ?)''', (tx['tx_index'], 'open')))
        cursor.close()
        assert len(orders) == 1
    cursor.execute('''SELECT * FROM orders \
                      WHERE (give_asset=? AND get_asset=? AND status=? AND tx_hash != ?)''',
                   (tx1['get_asset'], tx1['give_asset'], 'open', tx1['tx_hash']))
    tx1_give_remaining = tx1['give_remaining']
    tx1_get_remaining = tx1['get_remaining']
    order_matches = cursor.fetchall()
    if tx['block_index'] > 284500 or config.TESTNET or config.REGTEST:  # Protocol change.
        order_matches = sorted(order_matches, key=lambda x: x['tM
x_index'])                              # Sort by tx index second.
        order_matches = sorted(order_matches, key=lambda x: util.price(x['get_quantity'], x['give_quantity']))   # Sort by price first.
    # Get fee remaining.
    tx1_fee_required_remaining = tx1['fee_required_remaining']
    tx1_fee_provided_remaining = tx1['fee_provided_remaining']
    tx1_status = tx1['status']
    for tx0 in order_matches:
        order_match_id = util.make_id(tx0['tx_hash'], tx1['tx_hash'])
        if not block_index:
       block_index = max(tx0['block_index'], tx1['block_index'])
        if tx1_status != 'open': break
        logger.debug('Considering: ' + tx0['tx_hash'])
        tx0_give_remaining = tx0['give_remaining']
        tx0_get_remaining = tx0['get_remaining']
        # Ignore previous matches. (Both directions, just to be sure.)
        cursor.execute('''SELECT * FROM order_matches
                          WHERE id = ? ''', (util.make_id(tx0['tx_hash'], tx1['tx_hash']), ))
        if list(cursor):
ger.debug('Skipping: previous match')
            continue
        cursor.execute('''SELECT * FROM order_matches
                          WHERE id = ? ''', (util.make_id(tx1['tx_hash'], tx0['tx_hash']), ))
        if list(cursor):
            logger.debug('Skipping: previous match')
            continue
        # Get fee provided remaining.
        tx0_fee_required_remaining = tx0['fee_required_remaining']
        tx0_fee_provided_remaining = tx0['fee_provided_remaining']
        # Make sure that that both orderM
s still have funds remaining (if order involves BTC, and so cannot be
        if tx0['give_asset'] == config.BTC or tx0['get_asset'] == config.BTC: # Gratuitous
            if tx0_give_remaining <= 0 or tx1_give_remaining <= 0:
                logger.debug('Skipping: negative give quantity remaining')
                continue
            if block_index >= 292000 and block_index <= 310500 and not config.TESTNET or config.REGTEST:  # Protocol changes
                if tx0_get_remaining <= 0 or tx1_getM
                    logger.debug('Skipping: negative get quantity remaining')
                    continue
            if block_index >= 294000 or config.TESTNET or config.REGTEST:  # Protocol change.
                if tx0['fee_required_remaining'] < 0:
                    logger.debug('Skipping: negative tx0 fee required remaining')
                    continue
                if tx0['fee_provided_remaining'] < 0:
                    logger.debug('Skipping: negative tx0 fee provided remaining')
                    continue
                if tx1_fee_provided_remaining < 0:
                    logger.debug('Skipping: negative tx1 fee provided remaining')
                    continue
                if tx1_fee_required_remaining < 0:
                    logger.debug('Skipping: negative tx1 fee required remaining')
                    continue
        # If the prices agree, make the trade. The found order sets the price,
        # and they trade as much as they can.
        tx0_price = util.price(tx0['get_qM
uantity'], tx0['give_quantity'])
        tx1_price = util.price(tx1['get_quantity'], tx1['give_quantity'])
        tx1_inverse_price = util.price(tx1['give_quantity'], tx1['get_quantity'])
        # Protocol change.
        if tx['block_index'] < 286000: tx1_inverse_price = util.price(1, tx1_price)
        logger.debug('Tx0 Price: {}; Tx1 Inverse Price: {}'.format(float(tx0_price), float(tx1_inverse_price)))
        if tx0_price > tx1_inverse_price:
            logger.debug('Skipping: price mismatch.')
            logger.debug('Potential forward quantities: {}, {}'.format(tx0_give_remaining, int(util.price(tx1_give_remaining, tx0_price))))
            forward_quantity = int(min(tx0_give_remaining, int(util.price(tx1_give_remaining, tx0_price))))
            logger.debug('Forward Quantity: {}'.format(forward_quantity))
            backward_quantity = round(forward_quantity * tx0_price)
            logger.debug('Backward Quantity: {}'.format(backward_quantity))
            if not forward_quantity:
    logger.debug('Skipping: zero forward quantity.')
                continue
            if block_index >= 286500 or config.TESTNET or config.REGTEST:    # Protocol change.
                if not backward_quantity:
                    logger.debug('Skipping: zero backward quantity.')
                    continue
            forward_asset, backward_asset = tx1['get_asset'], tx1['give_asset']
            if block_index >= 313900 or config.TESTNET or config.REGTEST: # Protocol change.
                min_btc_quantiM
ty = 0.001 * config.UNIT  # 0.001 BTC
                if (forward_asset == config.BTC and forward_quantity <= min_btc_quantity) or (backward_asset == config.BTC and backward_quantity <= min_btc_quantity):
                    logger.debug('Skipping: below minimum {} quantity'.format(config.BTC))
                    continue
            # Check and update fee remainings.
            if block_index >= 286500 or config.TESTNET or config.REGTEST: # Protocol change. Deduct fee_required from provided_M
remaining, etc., if possible (else don
                if tx1['get_asset'] == config.BTC:
                    if block_index >= 310500 or config.TESTNET or config.REGTEST:     # Protocol change.
                        fee = int(tx1['fee_required'] * util.price(backward_quantity, tx1['give_quantity']))
                    else:
                        fee = int(tx1['fee_required_remaining'] * util.price(forward_quantity, tx1_get_remaining))
                    logger.debug('Tx0 fee provided remaining:M
 {}; required fee: {}'.format(tx0_fee_provided_remaining / config.UNIT, fee / config.UNIT))
                    if tx0_fee_provided_remaining < fee:
                        logger.debug('Skipping: tx0 fee provided remaining is too low.')
                        continue
                    else:
                        tx0_fee_provided_remaining -= fee
                        if block_index >= 287800 or config.TESTNET or config.REGTEST:  # Protocol change.
                            tx1_fee_required_remaining -= fM
                elif tx1['give_asset'] == config.BTC:
                    if block_index >= 310500 or config.TESTNET or config.REGTEST:      # Protocol change.
                        fee = int(tx0['fee_required'] * util.price(backward_quantity, tx0['give_quantity']))
                    else:
                        fee = int(tx0['fee_required_remaining'] * util.price(backward_quantity, tx0_get_remaining))
                    logger.debug('Tx1 fee provided remaining: {}; required fee: {}'.format(tx1_fee_provM
ided_remaining / config.UNIT, fee / config.UNIT))
                    if tx1_fee_provided_remaining < fee:
                        logger.debug('Skipping: tx1 fee provided remaining is too low.')
                        continue
                    else:
                        tx1_fee_provided_remaining -= fee
                        if block_index >= 287800 or config.TESTNET or config.REGTEST:  # Protocol change.
                            tx0_fee_required_remaining -= fee
            else:   # Don
                if tx1['get_asset'] == config.BTC:
                    if tx0_fee_provided_remaining < tx1['fee_required']: continue
                elif tx1['give_asset'] == config.BTC:
                    if tx1_fee_provided_remaining < tx0['fee_required']: continue
            if config.BTC in (tx1['give_asset'], tx1['get_asset']):
                status = 'pending'
                status = 'completed'
                # Credit.
                util.credit(db, tx1['source'], tx1['get_asset'],
                                   forward_quantity, action='order match', event=order_match_id)
                util.credit(db, tx0['source'], tx0['get_asset'],
                                    backward_quantity, action='order match', event=order_match_id)
            # Debit the order, even if it involves giving bitcoins, and so one
            # can't debit the sending account.
            # Get remainings may be negative.
            tx0_give_remaining -= forward_quantity
            tx0_get_remaining -= baM
            tx1_give_remaining -= backward_quantity
            tx1_get_remaining -= forward_quantity
            # Update give_remaining, get_remaining.
            tx0_status = 'open'
            if tx0_give_remaining <= 0 or (tx0_get_remaining <= 0 and (block_index >= 292000 or config.TESTNET or config.REGTEST)):    # Protocol change
                if tx0['give_asset'] != config.BTC and tx0['get_asset'] != config.BTC:
                    # Fill order, and recredit give_remainiM
                    tx0_status = 'filled'
                    util.credit(db, tx0['source'], tx0['give_asset'], tx0_give_remaining, event=tx1['tx_hash'], action='filled')
            bindings = {
                'give_remaining': tx0_give_remaining,
                'get_remaining': tx0_get_remaining,
                'fee_required_remaining': tx0_fee_required_remaining,
                'fee_provided_remaining': tx0_fee_provided_remaining,
                'status': tx0_status,
                'tx_hash': tx0['tx_hM
            sql='update orders set give_remaining = :give_remaining, get_remaining = :get_remaining, fee_required_remaining = :fee_required_remaining, fee_provided_remaining = :fee_provided_remaining, status = :status where tx_hash = :tx_hash'
            cursor.execute(sql, bindings)
            log.message(db, block_index, 'update', 'orders', bindings)
            if tx1_give_remaining <= 0 or (tx1_get_remaining <= 0 and (block_index >= 292000 or config.TESTNET or config.REGTM
EST)):    # Protocol change
                if tx1['give_asset'] != config.BTC and tx1['get_asset'] != config.BTC:
                    # Fill order, and recredit give_remaining.
                    tx1_status = 'filled'
                    util.credit(db, tx1['source'], tx1['give_asset'], tx1_give_remaining, event=tx0['tx_hash'], action='filled')
            bindings = {
                'give_remaining': tx1_give_remaining,
                'get_remaining': tx1_get_remaining,
                'fee_required_remaining'M
: tx1_fee_required_remaining,
                'fee_provided_remaining': tx1_fee_provided_remaining,
                'status': tx1_status,
                'tx_hash': tx1['tx_hash']
            sql='update orders set give_remaining = :give_remaining, get_remaining = :get_remaining, fee_required_remaining = :fee_required_remaining, fee_provided_remaining = :fee_provided_remaining, status = :status where tx_hash = :tx_hash'
            cursor.execute(sql, bindings)
            log.message(db, block_index,M
 'update', 'orders', bindings)
            # Calculate when the match will expire.
            if block_index >= 308000 or config.TESTNET or config.REGTEST:      # Protocol change.
                match_expire_index = block_index + 20
            elif block_index >= 286500 or config.TESTNET or config.REGTEST:    # Protocol change.
                match_expire_index = block_index + 10
                match_expire_index = min(tx0['expire_index'], tx1['expire_index'])
            # Record order matM
            bindings = {
                'id': util.make_id(tx0['tx_hash'], tx['tx_hash']),
                'tx0_index': tx0['tx_index'],
                'tx0_hash': tx0['tx_hash'],
                'tx0_address': tx0['source'],
                'tx1_index': tx1['tx_index'],
                'tx1_hash': tx1['tx_hash'],
                'tx1_address': tx1['source'],
                'forward_asset': forward_asset,
                'forward_quantity': forward_quantity,
                'backward_asset': backward_asset,
                'backward_quantity': backward_quantity,
                'tx0_block_index': tx0['block_index'],
                'tx1_block_index': tx1['block_index'],
                'block_index': block_index,
                'tx0_expiration': tx0['expiration'],
                'tx1_expiration': tx1['expiration'],
                'match_expire_index': match_expire_index,
                'fee_paid': fee,
                'status': status,
            sql='insert into order_matches values(:id, :tx0_indexM
, :tx0_hash, :tx0_address, :tx1_index, :tx1_hash, :tx1_address, :forward_asset, :forward_quantity, :backward_asset, :backward_quantity, :tx0_block_index, :tx1_block_index, :block_index, :tx0_expiration, :tx1_expiration, :match_expire_index, :fee_paid, :status)'
            cursor.execute(sql, bindings)
            if tx1_status == 'filled':
                break
def expire (db, block_index):
    cursor = db.cursor()
    # Expire orders and give refunds for the quantity give_remainiM
ng (if non-zero; if not BTC).
    cursor.execute('''SELECT * FROM orders \
                      WHERE (status = ? AND expire_index < ?)''', ('open', block_index))
    orders = list(cursor)
    for order in orders:
        cancel_order(db, order, 'expired', block_index)
    # Expire order_matches for BTC with no BTC.
    cursor.execute('''SELECT * FROM order_matches \
                      WHERE (status = ? and match_expire_index < ?)''', ('pending', block_index))
    order_matches = list(cursor)
ch in order_matches:
        cancel_order_match(db, order_match, 'expired', block_index)
        # Expire btc sell order if match expires
        if util.enabled('btc_sell_expire_on_match_expire'):
            # Check for other pending order matches involving either tx0_hash or tx1_hash
            bindings = {
                'status': 'pending',
                'tx0_hash': order_match['tx0_hash'],
                'tx1_hash': order_match['tx1_hash']
            sql='select * from order_matches whereM
 status = :status and ((tx0_hash in (:tx0_hash, :tx1_hash)) or ((tx1_hash in (:tx0_hash, :tx1_hash))))'
            cursor.execute(sql, bindings)
            order_matches_pending = cursor.fetchall()
            # Set BTC sell order status as expired only if there are no pending order matches
            if len(order_matches_pending) == 0:
                if order_match['backward_asset'] == "BTC" and order_match['status'] == "expired":
                    cursor.execute('''SELECT * FROM orders \
                   M
                   WHERE tx_hash = ?''', (order_match['tx1_hash'],))
                    cancel_order(db, list(cursor)[0], 'expired', block_index)
                if order_match['forward_asset'] == "BTC" and order_match['status'] == "expired":
                    cursor.execute('''SELECT * FROM orders \
                                      WHERE tx_hash = ?''', (order_match['tx0_hash'],))
                    cancel_order(db, list(cursor)[0], 'expired', block_index)
    if block_index >= 315000 or config.TESTNET oM
r config.REGTEST: # Protocol change.
        for order_match in order_matches:
            cursor.execute('''SELECT * FROM transactions\
                              WHERE tx_hash = ?''', (order_match['tx0_hash'],))
            match(db, list(cursor)[0], block_index)
            cursor.execute('''SELECT * FROM transactions\
                              WHERE tx_hash = ?''', (order_match['tx1_hash'],))
            match(db, list(cursor)[0], block_index)
xpandtab shiftwidth=4 softtabstop=4
Transaction 1: rps (Open the game)
source: address used to play the game
wager: amount to bet
move_random_hash: sha256(sha256(move + random)) (stored as bytes, 16 bytes random)
possible_moves: arbitrary odd number >= 3
expiration: how many blocks the game is valid
Matching conditions:
- tx0_possible_moves = tx1_possible_moves
- tx0_wager = tx1_wager
Transaction 2:  rpsresolve (Resolve the game)
source: same address as first transaM
random: 16 bytes random
move: the move number
rps_match_id: matching id
from counterpartylib.lib import config
from counterpartylib.lib import exceptions
from counterpartylib.lib import util
from counterpartylib.lib import log
from counterpartylib.lib import message_type
# possible_moves wager move_random_hash expiration
LENGTH = 2 + 8 + 32 + 4
def initialise (db):
    cursor = db.cursM
    # RPS (Rock-Paper-Scissors)
    cursor.execute('''CREATE TABLE IF NOT EXISTS rps(
                      tx_index INTEGER UNIQUE,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      possible_moves INTEGER,
                      wager INTEGER,
                      move_random_hash TEXT,
                      expiration INTEGER,
                      expire_index INTEGER,
                      status TEXT,
           FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index),
                      PRIMARY KEY (tx_index, tx_hash))
                  ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON rps (source)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      matching_idx ON rps (wager, possible_moves)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                   M
   status_idx ON rps (status)
                   ''')
    cursor.execute('''CREATE TABLE IF NOT EXISTS rps_matches(
                      id TEXT PRIMARY KEY,
                      tx0_index INTEGER,
                      tx0_hash TEXT,
                      tx0_address TEXT,
                      tx1_index INTEGER,
                      tx1_hash TEXT,
                      tx1_address TEXT,
                      tx0_move_random_hash TEXT,
                      tx1_move_random_hash TEXT,
              wager INTEGER,
                      possible_moves INTEGER,
                      tx0_block_index INTEGER,
                      tx1_block_index INTEGER,
                      block_index INTEGER,
                      tx0_expiration INTEGER,
                      tx1_expiration INTEGER,
                      match_expire_index INTEGER,
                      status TEXT,
                      FOREIGN KEY (tx0_index, tx0_hash, tx0_block_index) REFERENCES transactions(tx_index, tx_hash, block_index),
                     FOREIGN KEY (tx1_index, tx1_hash, tx1_block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      rps_match_expire_idx ON rps_matches (status, match_expire_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      rps_tx0_address_idx ON rps_matches (tx0_address)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
        rps_tx1_address_idx ON rps_matches (tx1_address)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      status_idx ON rps_matches (status)
                   ''')
    # RPS Expirations
    cursor.execute('''CREATE TABLE IF NOT EXISTS rps_expirations(
                      rps_index INTEGER PRIMARY KEY,
                      rps_hash TEXT UNIQUE,
                      source TEXT,
                      block_index INTEGER,
                      FOREIGN KEY (block_indeM
x) REFERENCES blocks(block_index),
                      FOREIGN KEY (rps_index, rps_hash) REFERENCES rps(tx_index, tx_hash))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON rps_expirations (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON rps_expirations (source)
                   ''')
    # RPS Match Expirations
    cursor.execute('''CREATE TABLE IF NOT EXISTS rps_match_expiM
                      rps_match_id TEXT PRIMARY KEY,
                      tx0_address TEXT,
                      tx1_address TEXT,
                      block_index INTEGER,
                      FOREIGN KEY (rps_match_id) REFERENCES rps_matches(id),
                      FOREIGN KEY (block_index) REFERENCES blocks(block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON rps_match_expirations (block_index)
                   ''')
cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx0_address_idx ON rps_match_expirations (tx0_address)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      tx1_address_idx ON rps_match_expirations (tx1_address)
                   ''')
def cancel_rps (db, rps, status, block_index):
    cursor = db.cursor()
    # Update status of rps.
        'status': status,
        'tx_hash': rps['tx_hash']
    sql='''UPDATE rps SET status = :stM
atus WHERE tx_hash = :tx_hash'''
    cursor.execute(sql, bindings)
    log.message(db, block_index, 'update', 'rps', bindings)
    util.credit(db, rps['source'], 'XCP', rps['wager'], action='recredit wager', event=rps['tx_hash'])
def update_rps_match_status (db, rps_match, status, block_index):
    cursor = db.cursor()
    if status in ['expired', 'concluded: tie']:
        # Recredit tx0 address.
        util.credit(db, rps_match['tx0_address'], 'XCP',
                    rps_match['wager'],M
 action='recredit wager', event=rps_match['id'])
        # Recredit tx1 address.
        util.credit(db, rps_match['tx1_address'], 'XCP',
                    rps_match['wager'], action='recredit wager', event=rps_match['id'])
    elif status.startswith('concluded'):
        # Credit the winner
        winner = rps_match['tx0_address'] if status == 'concluded: first player wins' else rps_match['tx1_address']
        util.credit(db, winner, 'XCP',
                    2 * rps_match['wager'], action='wins', event=rps_mM
    # Update status of rps match.
        'status': status,
        'rps_match_id': rps_match['id']
    sql='UPDATE rps_matches SET status = :status WHERE id = :rps_match_id'
    cursor.execute(sql, bindings)
    log.message(db, block_index, 'update', 'rps_matches', bindings)
def validate (db, source, possible_moves, wager, move_random_hash, expiration, block_index):
    if util.enabled('disable_rps'):
        problems.append('rps disabled'M
    if not isinstance(possible_moves, int):
        problems.append('possible_moves must be a integer')
        return problems
    if not isinstance(wager, int):
        problems.append('wager must be in satoshis')
        return problems
    if not isinstance(expiration, int):
        problems.append('expiration must be expressed as an integer block delta')
        return problems
    if not all(c in string.hexdigits for c in move_random_hash):
        problems.append('move_random_hash must be an hexadecimal M
        return problems
    move_random_hash_bytes = binascii.unhexlify(move_random_hash)
    if possible_moves < 3:
        problems.append('possible moves must be at least 3')
    if possible_moves % 2 == 0:
        problems.append('possible moves must be odd')
        problems.append('non
    if expiration < 0: problems.append('negative expiration')
    if expiration == 0 and not (block_index >= 317500 or config.TESTNET or config.REGTEST):   # Protocol change.
    problems.append('zero expiration')
    if expiration > config.MAX_EXPIRATION:
        problems.append('expiration overflow')
    if len(move_random_hash_bytes) != 32:
        problems.append('move_random_hash must be 32 bytes in hexadecimal format')
def compose(db, source, possible_moves, wager, move_random_hash, expiration):
    problems = validate(db, source, possible_moves, wager, move_random_hash, expiration, util.CURRENT_BLOCK_INDEX)
    if problems: raise exceptions.ComposeError(prM
    data = message_type.pack(ID)
    data += struct.pack(FORMAT, possible_moves, wager, binascii.unhexlify(move_random_hash), expiration)
    return (source, [], data)
def parse(db, tx, message):
    rps_parse_cursor = db.cursor()
    # Unpack message.
        if len(message) != LENGTH:
            raise exceptions.UnpackError
        (possible_moves, wager, move_random_hash, expiration) = struct.unpack(FORMAT, message)
        status = 'open'
    except (exceptions.UnpackError, struct.error):
       (possible_moves, wager, move_random_hash, expiration) = 0, 0, '', 0
        status = 'invalid: could not unpack'
    if status == 'open':
        move_random_hash = binascii.hexlify(move_random_hash).decode('utf8')
        rps_parse_cursor.execute('''SELECT * FROM balances \
                                    WHERE (address = ? AND asset = ?)''', (tx['source'], 'XCP'))
        balances = list(rps_parse_cursor)
        if not balances:
            wager = 0
e = balances[0]['quantity']
            if balance < wager:
                wager = balance
        problems = validate(db, tx['source'], possible_moves, wager, move_random_hash, expiration, tx['block_index'])
        if problems: status = 'invalid: {}'.format(', '.join(problems))
    # Debit quantity wagered. (Escrow.)
    if status == 'open':
        util.debit(db, tx['source'], 'XCP', wager, action="open RPS", event=tx['tx_hash'])
    # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
        'source': tx['source'],
        'possible_moves': possible_moves,
        'wager': wager,
        'move_random_hash': move_random_hash,
        'expiration': expiration,
        'expire_index': tx['block_index'] + expiration,
        'status': status,
    sql = '''INSERT INTO rps VALUES (:tx_index, :tx_hash, :block_index, :source, :possible_moves, :wager, :move_random_hash, :expiration, :exM
pire_index, :status)'''
    rps_parse_cursor.execute(sql, bindings)
    if status == 'open':
        match(db, tx, tx['block_index'])
    rps_parse_cursor.close()
def match (db, tx, block_index):
    cursor = db.cursor()
    # Get rps in question.
    rps = list(cursor.execute('''SELECT * FROM rps WHERE tx_index = ? AND status = ?''', (tx['tx_index'], 'open')))
        cursor.close()
        assert len(rps) == 1
    possible_moves = tx1['posM
    wager = tx1['wager']
    tx1_status = 'open'
    bindings = (possible_moves, 'open', wager, tx1['source'])
    # dont match twice same RPS
    already_matched = []
    old_rps_matches = cursor.execute('''SELECT * FROM rps_matches WHERE tx0_hash = ? OR tx1_hash = ?''', (tx1['tx_hash'], tx1['tx_hash']))
    for old_rps_match in old_rps_matches:
        counter_tx_hash = old_rps_match['tx1_hash'] if tx1['tx_hash'] == old_rps_match['tx0_hash'] else old_rps_match['tx0_hash']
  already_matched.append(counter_tx_hash)
    already_matched_cond = ''
    if already_matched:
        already_matched_cond = '''AND tx_hash NOT IN ({})'''.format(','.join(['?' for e in range(0, len(already_matched))]))
        bindings += tuple(already_matched)
    sql = '''SELECT * FROM rps WHERE (possible_moves = ? AND status = ? AND wager = ? AND source != ? {}) ORDER BY tx_index LIMIT 1'''.format(already_matched_cond)
    rps_matches = list(cursor.execute(sql, bindings))
        # update status
        for txn in [tx0, tx1]:
            bindings = {
                'status': 'matched',
                'tx_index': txn['tx_index']
            cursor.execute('''UPDATE rps SET status = :status WHERE tx_index = :tx_index''', bindings)
            log.message(db, block_index, 'update', 'rps', bindings)
        bindings = {
            'id': util.make_id(tx0['tx_hash'], tx1['tx_hash']),
            'tx0_index': tx0['tx_index'],
            'tx0_hash': tx0['tx_M
            'tx0_address': tx0['source'],
            'tx1_index': tx1['tx_index'],
            'tx1_hash': tx1['tx_hash'],
            'tx1_address': tx1['source'],
            'tx0_move_random_hash': tx0['move_random_hash'],
            'tx1_move_random_hash': tx1['move_random_hash'],
            'wager': wager,
            'possible_moves': possible_moves,
            'tx0_block_index': tx0['block_index'],
            'tx1_block_index': tx1['block_index'],
            'block_index': block_index,
    'tx0_expiration': tx0['expiration'],
            'tx1_expiration': tx1['expiration'],
            'match_expire_index': block_index + 20,
            'status': 'pending'
        sql = '''INSERT INTO rps_matches VALUES (:id, :tx0_index, :tx0_hash, :tx0_address, :tx1_index, :tx1_hash, :tx1_address,
                                                 :tx0_move_random_hash, :tx1_move_random_hash, :wager, :possible_moves,
                                                 :tx0_block_index, :tx1_block_index, :blM
ock_index, :tx0_expiration, :tx1_expiration,
                                                 :match_expire_index, :status)'''
        cursor.execute(sql, bindings)
def expire (db, block_index):
    cursor = db.cursor()
    # Expire rps and give refunds for the quantity wager.
    cursor.execute('''SELECT * FROM rps WHERE (status = ? AND expire_index < ?)''', ('open', block_index))
    for rps in cursor.fetchall():
        cancel_rps(db, rps, 'expired', block_index)
        # Record rps expirM
        bindings = {
            'rps_index': rps['tx_index'],
            'rps_hash': rps['tx_hash'],
            'source': rps['source'],
            'block_index': block_index
        sql = '''INSERT INTO rps_expirations VALUES (:rps_index, :rps_hash, :source, :block_index)'''
        cursor.execute(sql, bindings)
    # Expire rps matches
    expire_bindings = ('pending', 'pending and resolved', 'resolved and pending', block_index)
    cursor.execute('''SELECT * FROM rps_matches WHERE (status IM
N (?, ?, ?) AND match_expire_index < ?)''', expire_bindings)
    for rps_match in cursor.fetchall():
        new_rps_match_status = 'expired'
        # pending loses against resolved
        if rps_match['status'] == 'pending and resolved':
            new_rps_match_status = 'concluded: second player wins'
        elif rps_match['status'] == 'resolved and pending':
            new_rps_match_status = 'concluded: first player wins'
        update_rps_match_status(db, rps_match, new_rps_match_status, block_index)
      # Record rps match expiration.
        bindings = {
            'rps_match_id': rps_match['id'],
            'tx0_address': rps_match['tx0_address'],
            'tx1_address': rps_match['tx1_address'],
            'block_index': block_index
        sql = '''INSERT INTO rps_match_expirations VALUES (:rps_match_id, :tx0_address, :tx1_address, :block_index)'''
        cursor.execute(sql, bindings)
        # Rematch not expired and not resolved RPS
        if new_rps_match_status == 'expired':
     sql = '''SELECT * FROM rps WHERE tx_hash IN (?, ?) AND status = ? AND expire_index >= ?'''
            bindings = (rps_match['tx0_hash'], rps_match['tx1_hash'], 'matched', block_index)
            matched_rps = list(cursor.execute(sql, bindings))
            for rps in matched_rps:
                cursor.execute('''UPDATE rps SET status = ? WHERE tx_index = ?''', ('open', rps['tx_index']))
                # Re-debit XCP refund by close_rps_match.
                util.debit(db, rps['source'], 'XCP', rps['wager'M
], action='reopen RPS after matching expiration', event=rps_match['id'])
                # Rematch
                match(db, {'tx_index': rps['tx_index']}, block_index)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
logger = logging.getLogger(__name__)
from counterpartylib.lib import (config, exceptions, util, message_type)
# move random rps_match_id
LENGTH = 2 + 16 + 32 + 32
def initialise (db):
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS rpsresolves(
                      tx_index INTEGER PRIMARY KEY,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      move INTEGER,
                      random TEXT,
                      rps_match_id TEXT,
                      status TEXT,
                      FOREIGN KEY (tx_indeM
x, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON rpsresolves (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON rpsresolves (source)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      rps_match_id_idx ON rpsresolves (rps_match_id)
                   ''')
ef validate (db, source, move, random, rps_match_id):
    rps_match = None
    if not isinstance(move, int):
        problems.append('move must be a integer')
        return None, None, problems
    if not all(c in string.hexdigits for c in random):
        problems.append('random must be an hexadecimal string')
        return None, None, problems
    random_bytes = binascii.unhexlify(random)
    if len(random_bytes) != 16:
        problems.append('random must be 16 bytes in hexadecimal format'M
        return None, None, problems
    cursor = db.cursor()
    rps_matches = list(cursor.execute('''SELECT * FROM rps_matches WHERE id = ?''', (rps_match_id,)))
    if len(rps_matches) == 0:
        problems.append('no such rps match')
        return None, rps_match, problems
    elif len(rps_matches) > 1:
        assert False
    rps_match = rps_matches[0]
        problems.append('move must be greater than 0')
    elif move > rps_match['possible_moves']:
        problems.apM
pend('move must be lower than {}'.format(rps_match['possible_moves']))
    if source not in [rps_match['tx0_address'], rps_match['tx1_address']]:
        problems.append('invalid source address')
        return None, rps_match, problems
    if rps_match['tx0_address'] == source:
        rps_match_status = ['pending', 'pending and resolved']
        rps_match_status = ['pending', 'resolved and pending']
    move_random_hash = util.dhash(random_bytes + int(move).to_bytes(2M
    move_random_hash = binascii.hexlify(move_random_hash).decode('utf-8')
    if rps_match['tx{}_move_random_hash'.format(txn)] != move_random_hash:
        problems.append('invalid move or random value')
        return txn, rps_match, problems
    if rps_match['status'] == 'expired':
        problems.append('rps match expired')
    elif rps_match['status'].startswith('concluded'):
        problems.append('rps match concluded')
    elif rps_match['status'].startswith('invalid'):
s.append('rps match invalid')
    elif rps_match['status'] not in rps_match_status:
        problems.append('rps already resolved')
    return txn, rps_match, problems
def compose (db, source, move, random, rps_match_id):
    tx0_hash, tx1_hash = util.parse_id(rps_match_id)
    txn, rps_match, problems = validate(db, source, move, random, rps_match_id)
    if problems: raise exceptions.ComposeError(problems)
    # Warn if down to the wire.
    time_left = rps_match['match_expire_index'] - util.CURRENT_BLOCK_INDM
    if time_left < 4:
        logger.warning('Only {} blocks until that rps match expires. The conclusion might not make into the blockchain in time.'.format(time_left))
    tx0_hash_bytes = binascii.unhexlify(bytes(tx0_hash, 'utf-8'))
    tx1_hash_bytes = binascii.unhexlify(bytes(tx1_hash, 'utf-8'))
    random_bytes = binascii.unhexlify(bytes(random, 'utf-8'))
    data = message_type.pack(ID)
    data += struct.pack(FORMAT, move, random_bytes, tx0_hash_bytes, tx1_hash_bytes)
    return (source, [], data)
parse (db, tx, message):
    cursor = db.cursor()
    # Unpack message.
        if len(message) != LENGTH:
            raise exceptions.UnpackError
        move, random, tx0_hash_bytes, tx1_hash_bytes = struct.unpack(FORMAT, message)
        tx0_hash, tx1_hash = binascii.hexlify(tx0_hash_bytes).decode('utf-8'), binascii.hexlify(tx1_hash_bytes).decode('utf-8')
        rps_match_id = util.make_id(tx0_hash, tx1_hash)
        random = binascii.hexlify(random).decode('utf-8')
        status = 'valid'
t (exceptions.UnpackError, struct.error) as e:
        move, random, tx0_hash, tx1_hash, rps_match_id = None, None, None, None, None
        status = 'invalid: could not unpack'
    if status == 'valid':
        txn, rps_match, problems = validate(db, tx['source'], move, random, rps_match_id)
        if problems:
            rps_match = None
            status = 'invalid: ' + '; '.join(problems)
    # Add parsed transaction to message-type
    rpsresolves_bindings = {
        'tx_index': tx['tx_M
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
        'source': tx['source'],
        'move': move,
        'random': random,
        'rps_match_id': rps_match_id,
        'status': status
    if status == 'valid':
        rps_match_status = 'concluded'
        if rps_match['status'] == 'pending':
            rps_match_status = 'resolved and pending' if txn==0 else 'pending and resolved'
        if rps_match_status == 'concluded':
            counter_txn = 0 if txn ==M
            counter_source = rps_match['tx{}_address'.format(counter_txn)]
            sql = '''SELECT * FROM rpsresolves WHERE rps_match_id = ? AND source = ? AND status = ?'''
            counter_games = list(cursor.execute(sql, (rps_match_id, counter_source, 'valid')))
            assert len(counter_games) == 1
            counter_game = counter_games[0]
            winner = resolve_game(db, rpsresolves_bindings, counter_game)
            if winner == 0:
                rps_match_status = 'concluded:M
            elif winner == counter_game['tx_index']:
                rps_match_status = 'concluded: {} player wins'.format('first' if counter_txn == 0 else 'second')
                rps_match_status = 'concluded: {} player wins'.format('first' if txn == 0 else 'second')
        rps.update_rps_match_status(db, rps_match, rps_match_status, tx['block_index'])
    sql = '''INSERT INTO rpsresolves VALUES (:tx_index, :tx_hash, :block_index, :source, :move, :random, :rps_match_id, :status)'''
 cursor.execute(sql, rpsresolves_bindings)
# https://en.wikipedia.org/wiki/Rock-paper-scissors#Additional_weapons:
def resolve_game(db, resovlerps1, resovlerps2):
    move1 = resovlerps1['move']
    move2 = resovlerps2['move']
    same_parity = (move1 % 2) == (move2 % 2)
    if (same_parity and move1 < move2) or (not same_parity and move1 > move2):
        return resovlerps1['tx_index']
    elif (same_parity and move1 > move2) or (not same_parity and move1 < move2):
        return resovlerps2M
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
from counterpartylib.lib.messages.versions import send1
from counterpartylib.lib.messages.versions import enhanced_send
from counterpartylib.lib.messages.versions import mpma
from counterpartylib.lib import util
from counterpartylib.lib import exceptions
from counterpartylib.lib import config
def initialise (db):
    cursor = db.cursor()
    cursor.execute('''CM
REATE TABLE IF NOT EXISTS sends(
                      tx_index INTEGER PRIMARY KEY,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      destination TEXT,
                      asset TEXT,
                      quantity INTEGER,
                      status TEXT,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
lumn['name'] for column in cursor.execute('''PRAGMA table_info(sends)''')]
    # If CIP10 activated, Create Sends copy, copy old data, drop old table, rename new table, recreate indexes
t do `ALTER TABLE IF COLUMN NOT EXISTS` nor can drop UNIQUE constraints
    if 'msg_index' not in columns:
        if 'memo' not in columns:
            cursor.execute('''CREATE TABLE IF NOT EXISTS new_sends(
                              tx_index INTEGER,
                              tx_hash TEXT,
                   block_index INTEGER,
                              source TEXT,
                              destination TEXT,
                              asset TEXT,
                              quantity INTEGER,
                              status TEXT,
                              msg_index INTEGER DEFAULT 0,
                              PRIMARY KEY (tx_index, msg_index),
                              FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index),
                              UNIQUE (tx_hash, msg_index) ON CONFLICT FAIL)
                           ''')
            cursor.execute('''INSERT INTO new_sends(tx_index, tx_hash, block_index, source, destination, asset, quantity, status)
                SELECT tx_index, tx_hash, block_index, source, destination, asset, quantity, status
                FROM sends''', {})
            cursor.execute('''CREATE TABLE IF NOT EXISTS new_sends(
                  tx_index INTEGER,
                  tx_hash TEXM
                  block_index INTEGER,
                  source TEXT,
                  destination TEXT,
                  asset TEXT,
                  quantity INTEGER,
                  status TEXT,
                  memo BLOB,
                  msg_index INTEGER DEFAULT 0,
                  PRIMARY KEY (tx_index, msg_index),
                  FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index),
                  UNIQUE (tx_hash, msg_index) ON CONFLICT FAIL)
            cursor.execute('''INSERT INTO new_sends (tx_index, tx_hash, block_index, source, destination, asset, quantity, status, memo)
                SELECT tx_index, tx_hash, block_index, source, destination, asset, quantity, status, memo
                FROM sends''', {})
        cursor.execute('DROP TABLE sends')
        cursor.execute('ALTER TABLE new_sends RENAME TO sends')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON sends (block_index)
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON sends (source)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      destination_idx ON sends (destination)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      asset_idx ON sends (asset)
                   ''')
    # Adds a memo to sends
t do `ALTER TABLE IF COLUMN NOT EXISTS`.
    if 'memo' not in columns:M
        cursor.execute('''ALTER TABLE sends ADD COLUMN memo BLOB''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      memo_idx ON sends (memo)
                   ''')
def unpack(db, message, block_index):
    return send1.unpack(db, message, block_index)
def validate (db, source, destination, asset, quantity, block_index):
    return send1.validate(db, source, destination, asset, quantity, block_index)
def compose (db, source, destination, asset, quantity, memo=None, memo_is_hex=False, usM
e_enhanced_send=None):
    # special case - enhanced_send replaces send by default when it is enabled
    #   but it can be explicitly disabled with an API parameter
    if util.enabled('enhanced_sends'):
        # Another special case, if destination, asset and quantity are arrays, it's an MPMA send
        if isinstance(destination, list) and isinstance(asset, list) and isinstance(quantity, list):
            if util.enabled('mpma_sends'):
                if len(destination) == len(asset) and len(asset) == len(quM
                    # Sending memos in a MPMA message can be done by several approaches:
                    # 1. Send a list of memos, there must be one for each send and they correspond to the sends by index
                    #   - In this case memo_is_hex should be a list with the same cardinality
                    # 2. Send a dict with the message specific memos and the message wide memo (same for the hex specifier):
                    #   - Each dict should have 2 members:
                    #  M
   + list: same as case (1). An array that specifies the memo for each send
                    #     + msg_wide: the memo for the whole message. This memo will be used for sends that don't have a memo specified. Same as in (3)
                    # 3. Send one memo (either bytes or string) and True/False in memo_is_hex. This will be interpreted as a message wide memo.
                    if (len(destination) > config.MPMA_LIMIT):
                        raise exceptions.ComposeError('mpma sends have a maximum of 'M
+str(config.MPMA_LIMIT)+' sends')

                    if isinstance(memo, list) and isinstance(memo_is_hex, list):
                        # (1) implemented here
                        if len(memo) != len(memo_is_hex):
                            raise exceptions.ComposeError('memo and memo_is_hex lists should have the same length')
                        elif len(memo) != len(destination):
                            raise exceptions.ComposeError('memo/memo_is_hex lists should have the same M
                        return mpma.compose(db, source, util.flat(zip(asset, destination, quantity, memo, memo_is_hex)), None, None)
                    elif isinstance(memo, dict) and isinstance(memo_is_hex, dict):
                        # (2) implemented here
                        if not('list' in memo and 'list' in memo_is_hex and 'msg_wide' in memo and 'msg_wide' in memo_is_hex):
                            raise exceptions.ComposeError('when specifying memo/memo_is_hex as a dict, they musM
t contain keys "list" and "msg_wide"')
                        elif len(memo['list']) != len(memo_is_hex['list']):
                            raise exceptions.ComposeError('length of memo.list and memo_is_hex.list must be equal')
                        elif len(memo['list']) != len(destination):
                            raise exceptions.ComposeError('length of memo.list/memo_is_hex.list must be equal to the amount of sends')
                        return mpma.compose(db, source, util.flat(zip(asset, destinatM
ion, quantity, memo['list'], memo_is_hex['list'])), memo['msg_wide'], memo_is_hex['msg_wide'])
                    else:
                        # (3) the default case
                        return mpma.compose(db, source, util.flat(zip(asset, destination, quantity)), memo, memo_is_hex)
                else:
                    raise exceptions.ComposeError('destination, asset and quantity arrays must have the same amount of elements')
                raise exceptions.ComposeError('mpma sends areM
        elif use_enhanced_send is None or use_enhanced_send == True:
            return enhanced_send.compose(db, source, destination, asset, quantity, memo, memo_is_hex)
    elif memo is not None or use_enhanced_send == True:
        raise exceptions.ComposeError('enhanced sends are not enabled')
    return send1.compose(db, source, destination, asset, quantity)
def parse (db, tx, message):    # TODO: *args
    return send1.parse(db, tx, message)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstM
from counterpartylib.lib import exceptions
from counterpartylib.lib import config
from counterpartylib.lib import util
from counterpartylib.lib import log
from counterpartylib.lib import message_type
from counterpartylib.lib import address
from counterpartylib.lib.exceptions import *
MAX_MEMO_LENGTH = 34 # Could be higher, but we will keep it consistent with enhanced send
ANTISPAM_FEE_DECIMAL = 0.5
ANTISPAM_FEE_DECIMAL * config.UNIT
FLAG_BINARY_MEMO = 4
FLAGS_ALL = FLAG_BINARY_MEMO | FLAG_BALANCES | FLAG_OWNERSHIP
    cursor = db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS sweeps(
                      tx_index INTEGER PRIMARY KEY,
                      tx_hash TEXT UNIQUE,
                      block_index INTEGER,
                      source TEXT,
                      destination TEXT,
                      flags INTEGER,
            status TEXT,
                      memo BLOB,
                      fee_paid INTEGER,
                      FOREIGN KEY (tx_index, tx_hash, block_index) REFERENCES transactions(tx_index, tx_hash, block_index))
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      block_index_idx ON sweeps (block_index)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      source_idx ON sweeps (source)
                   ''')
cute('''CREATE INDEX IF NOT EXISTS
                      destination_idx ON sweeps (destination)
                   ''')
    cursor.execute('''CREATE INDEX IF NOT EXISTS
                      memo_idx ON sweeps (memo)
                   ''')
def validate (db, source, destination, flags, memo, block_index):
    if source == destination:
        problems.append('destination cannot be the same as source')
    cursor = db.cursor()
    cursor.execute('''SELECT * FROM balances WHERE (address = ? ANDM
 asset = ?)''', (source, 'XCP'))
    result = cursor.fetchall()
    if len(result) == 0:
        problems.append('insufficient XCP balance for sweep. Need %s XCP for antispam fee' % ANTISPAM_FEE_DECIMAL)
    elif result[0]['quantity'] < ANTISPAM_FEE:
        problems.append('insufficient XCP balance for sweep. Need %s XCP for antispam fee' % ANTISPAM_FEE_DECIMAL)
    if flags > FLAGS_ALL:
        problems.append('invalid flags %i' % flags)
    elif not(flags & (FLAG_BALANCES | FLAG_OWNERSHIP))M
        problems.append('must specify which kind of transfer in flags')
    if memo and len(memo) > MAX_MEMO_LENGTH:
        problems.append('memo too long')
def compose (db, source, destination, flags, memo):
    if memo is None:
    elif flags & FLAG_BINARY_MEMO:
        memo = bytes.fromhex(memo)
        memo = memo.encode('utf-8')
        memo = struct.pack(">{}s".format(len(memo)), memo)
    block_index = util.CURRENT_BLOCK_INDEX
    problems = validate(dbM
, source, destination, flags, memo, block_index)
    if problems: raise exceptions.ComposeError(problems)
    short_address_bytes = address.pack(destination)
    data = message_type.pack(ID)
    data += struct.pack(FORMAT, short_address_bytes, flags)
    return (source, [], data)
def unpack(db, message, block_index):
        memo_bytes_length = len(message) - LENGTH
        if memo_bytes_length < 0:
            raise exceptions.UnpackError('invalid message length')
        if memo_byteM
s_length > MAX_MEMO_LENGTH:
            raise exceptions.UnpackError('memo too long')
        struct_format = FORMAT + ('{}s'.format(memo_bytes_length))
        short_address_bytes, flags, memo_bytes = struct.unpack(struct_format, message)
        if len(memo_bytes) == 0:
            memo_bytes = None
        elif not(flags & FLAG_BINARY_MEMO):
            memo_bytes = memo_bytes.decode('utf-8')
        # unpack address
        full_address = address.unpack(short_address_bytes)
    except (struct.error) as e:
     logger.warning("sweep send unpack error: {}".format(e))
        raise exceptions.UnpackError('could not unpack')
      'destination': full_address,
      'flags': flags,
      'memo': memo_bytes,
def parse (db, tx, message):
    cursor = db.cursor()
    fee_paid = round(config.UNIT/2)
    # Unpack message.
        unpacked = unpack(db, message, tx['block_index'])
        destination, flags, memo_bytes = unpacked['destination'], unpacked['flags'], unpackedM
        status = 'valid'
    except (exceptions.UnpackError, exceptions.AssetNameError, struct.error) as e:
        destination, flags, memo_bytes = None, None, None
        status = 'invalid: could not unpack ({})'.format(e)
    except BalanceError:
        destination, flags, memo_bytes = None, None, None
        status = 'invalid: insufficient balance for antispam fee for sweep'
    except Exception as err:
        destination, flags, memo_bytes = None, None, None
        status = 'invalid: could not uM
    if status == 'valid':
        problems = validate(db, tx['source'], destination, flags, memo_bytes, tx['block_index'])
        if problems: status = 'invalid: ' + '; '.join(problems)
    if status == 'valid':
            util.debit(db, tx['source'], 'XCP', fee_paid, action='sweep fee', event=tx['tx_hash'])
        except BalanceError:
            destination, flags, memo_bytes = None, None, None
            status = 'invalid: insufficient balance for antispam fee for sweep'
   if status == 'valid':
        cursor.execute('''SELECT * FROM balances WHERE address = ?''', (tx['source'],))
        balances = cursor.fetchall()
        if flags & FLAG_BALANCES:
            for balance in balances:
                util.debit(db, tx['source'], balance['asset'], balance['quantity'], action='sweep', event=tx['tx_hash'])
                util.credit(db, destination, balance['asset'], balance['quantity'], action='sweep', event=tx['tx_hash'])
        if flags & FLAG_OWNERSHIP:
            sweep_posM
            for balance in balances:
                cursor.execute('''SELECT * FROM issuances \
                                  WHERE (status = ? AND asset = ?)
                                  ORDER BY tx_index ASC''', ('valid', balance['asset']))
                issuances = cursor.fetchall()
                if len(issuances) > 0:
                    last_issuance = issuances[-1]
                    if last_issuance['issuer'] == tx['source']:
                        bindings= {
                           M
 'tx_index': tx['tx_index'],
                            'tx_hash': tx['tx_hash'],
                            'msg_index': sweep_pos,
                            'block_index': tx['block_index'],
                            'asset': balance['asset'],
                            'quantity': 0,
                            'divisible': last_issuance['divisible'],
                            'source': last_issuance['source'],
                            'issuer': destination,
                            'transfer': TrM
                            'callable': last_issuance['callable'],
                            'call_date': last_issuance['call_date'],
                            'call_price': last_issuance['call_price'],
                            'description': last_issuance['description'],
                            'fee_paid': 0,
                            'locked': last_issuance['locked'],
                            'status': status,
                            'asset_longname': last_issuance['asset_longname'],
                       'reset': False
                        }
                        sql='insert into issuances values(:tx_index, :tx_hash, :msg_index, :block_index, :asset, :quantity, :divisible, :source, :issuer, :transfer, :callable, :call_date, :call_price, :description, :fee_paid, :locked, :status, :asset_longname, :reset)'
                        cursor.execute(sql, bindings)
                        sweep_pos += 1
        bindings = {
            'tx_index': tx['tx_index'],
            'tx_hash': tx['tx_hM
            'block_index': tx['block_index'],
            'source': tx['source'],
            'destination': destination,
            'flags': flags,
            'status': status,
            'memo': memo_bytes,
            'fee_paid': fee_paid
        sql = 'insert into sweeps values(:tx_index, :tx_hash, :block_index, :source, :destination, :flags, :status, :memo, :fee_paid)'
        cursor.execute(sql, bindings)
# Each message gets identified by itsM
# The only exception is send.version1 which is 0 the first to fourth byte.
# Used IDs for messages:
# 1 send.enhanced_send
# 21 issuance.subasset
# Allocate each new type of message within the "logical" 10 number boundary
# Only allocate a 10 number boundary if it makes sense
#### enhanced_send.py
logger = logging.getLogger(__name__)
from counterpartylib.lib import (config, util, exceptions, util, message_type, address)
MAX_MEMO_LENGTH = 34
def unpack(db, message, block_index):
        # account for memo bytes
        memo_bytes_length = len(message) - LENGTH
        if memo_bytes_length < 0:
            raise exceptions.UnpackError('invalid message length')
        if memo_bytes_length > MAX_MEMO_LENGTH:
            raise exceptions.UnpackError('memo too long')
        struct_format = FORMAT + ('{}s'.format(memo_bytes_length))
        asset_id, quantity, short_address_bytes, memo_bytes = struct.unpack(struct_format, message)
        if len(memo_bytes) == 0:
            memo_bytes = None
        # unpack address
        full_address = address.unpack(short_address_bytes)
        # asset id to name
        asset = util.generate_asset_name(asset_id, block_index)
        if asset == config.BTC:
            raise exceM
ptions.AssetNameError('{} not allowed'.format(config.BTC))
    except (struct.error) as e:
        logger.warning("enhanced send unpack error: {}".format(e))
        raise exceptions.UnpackError('could not unpack')
    except (exceptions.AssetNameError, exceptions.AssetIDError) as e:
        logger.warning("enhanced send invalid asset id: {}".format(e))
        raise exceptions.UnpackError('asset id invalid')
      'asset': asset,
      'quantity': quantity,
      'address': full_address,
def validate (db, source, destination, asset, quantity, memo_bytes, block_index):
    if asset == config.BTC: problems.append('cannot send {}'.format(config.BTC))
    if not isinstance(quantity, int):
        problems.append('quantity must be in satoshis')
        return problems
    if quantity < 0:
        problems.append('negative quantity')
    if quantity == 0:
        problems.append('zero quantity')
    if quantity > confM
        problems.append('integer overflow')
    # destination is always required
    if not destination:
        problems.append('destination is required')
    if memo_bytes is not None and len(memo_bytes) > MAX_MEMO_LENGTH:
      problems.append('memo is too long')
    if util.enabled('options_require_memo'):
        cursor = db.cursor()
            results = cursor.execute('SELECT options FROM addresses WHERE address=?', (destination,))
            if results:
        result = results.fetchone()
                if result and util.active_options(result['options'], config.ADDRESS_OPTION_REQUIRE_MEMO):
                    if memo_bytes is None or (len(memo_bytes) == 0):
                        problems.append('destination requires memo')
            cursor.close()
def compose (db, source, destination, asset, quantity, memo, memo_is_hex):
    cursor = db.cursor()
    # Just send BTC?
    if asset == config.BTC:
        return (source, M
[(destination, quantity)], None)
    # resolve subassets
    asset = util.resolve_subasset_longname(db, asset)
    #quantity must be in int satoshi (not float, string, etc)
    if not isinstance(quantity, int):
        raise exceptions.ComposeError('quantity must be an int (in satoshi)')
    # Only for outgoing (incoming will overburn).
    balances = list(cursor.execute('''SELECT * FROM balances WHERE (address = ? AND asset = ?)''', (source, asset)))
    if not balances or balances[0]['quantity'] < quantity:
      raise exceptions.ComposeError('insufficient funds')
    # convert memo to memo_bytes based on memo_is_hex setting
    if memo is None:
        memo_bytes = b''
    elif memo_is_hex:
        memo_bytes = bytes.fromhex(memo)
        memo = memo.encode('utf-8')
        memo_bytes = struct.pack(">{}s".format(len(memo)), memo)
    block_index = util.CURRENT_BLOCK_INDEX
    problems = validate(db, source, destination, asset, quantity, memo_bytes, block_index)
    if problems: raise exceptions.ComposeErM
    asset_id = util.get_asset_id(db, asset, block_index)
    short_address_bytes = address.pack(destination)
    data = message_type.pack(ID)
    data += struct.pack(FORMAT, asset_id, quantity, short_address_bytes)
    data += memo_bytes
    # return an empty array as the second argument because we don't need to send BTC dust to the recipient
    return (source, [], data)
def parse (db, tx, message):
    cursor = db.cursor()
    # Unpack message.
        unpacked = unM
pack(db, message, tx['block_index'])
        asset, quantity, destination, memo_bytes = unpacked['asset'], unpacked['quantity'], unpacked['address'], unpacked['memo']
        status = 'valid'
    except (exceptions.UnpackError, exceptions.AssetNameError, struct.error) as e:
        asset, quantity, destination, memo_bytes = None, None, None, None
        status = 'invalid: could not unpack ({})'.format(e)
        asset, quantity, destination, memo_bytes = None, None, None, None
        status = 'invalM
id: could not unpack'
    if status == 'valid':
        # don't allow sends over MAX_INT at all
        if quantity and quantity > config.MAX_INT:
            status = 'invalid: quantity is too large'
            quantity = None
    if status == 'valid':
        problems = validate(db, tx['source'], destination, asset, quantity, memo_bytes, tx['block_index'])
        if problems: status = 'invalid: ' + '; '.join(problems)
    if status == 'valid':
        # verify balance is present
        cursor.execute('''SELM
ECT * FROM balances \
                                     WHERE (address = ? AND asset = ?)''', (tx['source'], asset))
        balances = cursor.fetchall()
        if not balances or balances[0]['quantity'] < quantity:
            status = 'invalid: insufficient funds'
    if status == 'valid':
        util.debit(db, tx['source'], asset, quantity, action='send', event=tx['tx_hash'])
        util.credit(db, destination, asset, quantity, action='send', event=tx['tx_hash'])
    # log invalid transactions
        if quantity is None:
            logger.warn("Invalid send from %s with status %s. (%s)" % (tx['source'], status, tx['tx_hash']))
            logger.warn("Invalid send of %s %s from %s to %s. status is %s. (%s)" % (quantity, asset, tx['source'], destination, status, tx['tx_hash']))
    # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
   'source': tx['source'],
        'destination': destination,
        'asset': asset,
        'quantity': quantity,
        'status': status,
        'memo': memo_bytes,
    if "integer overflow" not in status and "quantity must be in satoshis" not in status:
        sql = 'insert into sends (tx_index, tx_hash, block_index, source, destination, asset, quantity, status, memo) values(:tx_index, :tx_hash, :block_index, :source, :destination, :asset, :quantity, :status, :memo)'
        cursor.execute(sql, bindinM
        logger.warn("Not storing [send] tx [%s]: %s" % (tx['tx_hash'], status))
        logger.debug("Bindings: %s" % (json.dumps(bindings), ))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
from bitcoin.core import key
from functools import reduce
from itertools import groupby
logger = logging.getLogger(__name__)
from bitstring import ReadError
artylib.lib import (config, util, exceptions, util, message_type, address)
from .mpma_util.internals import (_decode_mpmaSendDecode, _encode_mpmaSend)
ID = 3 # 0x03 is this specific message type
## expected functions for message version
def unpack(db, message, block_index):
        unpacked = _decode_mpmaSendDecode(message, block_index)
    except (struct.error) as e:
        raise exceptions.UnpackError('could not unpack')
    except (exceptions.AssetNameError, exceptions.AssetIDError) as e:
ise exceptions.UnpackError('invalid asset in mpma send')
    except (ReadError) as e:
        raise exceptions.UnpackError('truncated data')
def validate (db, source, asset_dest_quant_list, block_index):
    if len(asset_dest_quant_list) == 0:
        problems.append('send list cannot be empty')
    if len(asset_dest_quant_list) == 1:
        problems.append('send list cannot have only one element')
    if len(asset_dest_quant_list) > 0:
        # Need to manually unpack tM
he tuple to avoid errors on scenarios where no memo is specified
        grpd = groupby([(t[0], t[1]) for t in asset_dest_quant_list])
        lengrps = [len(list(grpr)) for (group, grpr) in grpd]
        cardinality = max(lengrps)
        if cardinality > 1:
            problems.append('cannot specify more than once a destination per asset')
    cursor = db.cursor()
    for t in asset_dest_quant_list:
        # Need to manually unpack the tuple to avoid errors on scenarios where no memo is specified
        destination = t[1]
        quantity = t[2]
        sendMemo = None
        if len(t) > 3:
            sendMemo = t[3]
        if asset == config.BTC: problems.append('cannot send {} to {}'.format(config.BTC, destination))
        if not isinstance(quantity, int):
            problems.append('quantities must be an int (in satoshis) for {} to {}'.format(asset, destination))
        if quantity < 0:
            problems.append('negative quantity for {} to {}'.format(asset, destination))
            problems.append('zero quantity for {} to {}'.format(asset, destination))
        # For SQLite3
        if quantity > config.MAX_INT:
            problems.append('integer overflow for {} to {}'.format(asset, destination))
        # destination is always required
        if not destination:
            problems.append('destination is required for {}'.format(asset))
        if util.enabled('options_require_memo'):
            results = cursor.execute('SELECT options FROM addresses WHERE M
address=?', (destination,))
            if results:
                result = results.fetchone()
                if result and result['options'] & config.ADDRESS_OPTION_REQUIRE_MEMO and (sendMemo is None):
                    problems.append('destination {} requires memo'.format(destination))
def compose (db, source, asset_dest_quant_list, memo, memo_is_hex):
    cursor = db.cursor()
    out_balances = util.accumulate([(t[0], t[2]) for t in asset_dest_quant_list])
asset, quantity) in out_balances:
        if util.enabled('mpma_subasset_support'):
            # resolve subassets
            asset = util.resolve_subasset_longname(db, asset)
        if not isinstance(quantity, int):
            raise exceptions.ComposeError('quantities must be an int (in satoshis) for {}'.format(asset))
        balances = list(cursor.execute('''SELECT * FROM balances WHERE (address = ? AND asset = ?)''', (source, asset)))
        if not balances or balances[0]['quantity'] < quantity:
    raise exceptions.ComposeError('insufficient funds for {}'.format(asset))
    block_index = util.CURRENT_BLOCK_INDEX
    problems = validate(db, source, asset_dest_quant_list, block_index)
    if problems: raise exceptions.ComposeError(problems)
    data = message_type.pack(ID)
    data += _encode_mpmaSend(db, asset_dest_quant_list, block_index, memo=memo, memo_is_hex=memo_is_hex)
    return (source, [], data)
def parse (db, tx, message):
        unpacked = unpack(db, message, tM
        status = 'valid'
    except (struct.error) as e:
        status = 'invalid: truncated message'
    except (exceptions.AssetNameError, exceptions.AssetIDError) as e:
        status = 'invalid: invalid asset name/id'
    except (Exception) as e:
        status = 'invalid: couldn\'t unpack; %s' % e
    cursor = db.cursor()
    plain_sends = []
    all_credits = []
    if status == 'valid':
        for asset_id in unpacked:
                asset = util.geM
t_asset_name(db, asset_id, tx['block_index'])
            except (exceptions.AssetNameError) as e:
                status = 'invalid: asset %s invalid at block index %i' % (asset_id, tx['block_index'])
                break
            cursor.execute('''SELECT * FROM balances \
                              WHERE (address = ? AND asset = ?)''', (tx['source'], asset_id))
            balances = cursor.fetchall()
            if not balances:
                status = 'invalid: insufficient funds for asset %s, addressM
 %s has no balance' % (asset_id, tx['source'])
                break
            credits = unpacked[asset_id]
            total_sent = reduce(lambda p, t: p + t[1], credits, 0)
            if balances[0]['quantity'] < total_sent:
                status = 'invalid: insufficient funds for asset %s, needs %i' % (asset_id, total_sent)
                break
            if status == 'valid':
                plain_sends += map(lambda t: util.py34TupleAppend(asset_id, t), credits)
                all_credits += map(lamM
bda t: {"asset": asset_id, "destination": t[0], "quantity": t[1]}, credits)
                all_debits.append({"asset": asset_id, "quantity": total_sent})
    if status == 'valid':
        problems = validate(db, tx['source'], plain_sends, tx['block_index'])
        if problems: status = 'invalid:' + '; '.join(problems)
    if status == 'valid':
        for op in all_credits:
            util.credit(db, op['destination'], op['asset'], op['quantity'], action='mpma send', event=tx['tx_hash'])
        for op in alM
            util.debit(db, tx['source'], op['asset'], op['quantity'], action='mpma send', event=tx['tx_hash'])
        # Enumeration of the plain sends needs to be deterministic, so we sort them by asset and then by address
        plain_sends = sorted(plain_sends, key=lambda x: ''.join([x[0], x[1]]))
        for i, op in enumerate(plain_sends):
            if len(op) > 3:
                memo_bytes = op[3]
                memo_bytes = None
            bindings = {
                'tx_M
index': tx['tx_index'],
                'tx_hash': tx['tx_hash'],
                'block_index': tx['block_index'],
                'source': tx['source'],
                'asset': op[0],
                'destination': op[1],
                'quantity': op[2],
                'status': status,
                'memo': memo_bytes,
                'msg_index': i
            sql = 'insert into sends (tx_index, tx_hash, block_index, source, destination, asset, quantity, status, memo, msg_index) values(:txM
_index, :tx_hash, :block_index, :source, :destination, :asset, :quantity, :status, :memo, :msg_index)'
            cursor.execute(sql, bindings)
    if status != 'valid':
        logger.warn("Not storing [mpma] tx [%s]: %s" % (tx['tx_hash'], status))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
"""Create and parse 'send'-type messages."""
logger = logging.getLogger(__name__)
from ... import (confiM
g, exceptions, util, message_type)
def unpack(db, message, block_index):
    # Only used for `unpack` API call at the moment.
        asset_id, quantity = struct.unpack(FORMAT, message)
        asset = util.get_asset_name(db, asset_id, block_index)
    except struct.error:
        raise exceptions.UnpackError('could not unpack')
    except AssetNameError:
        raise exceptions.UnpackError('asset id invalid')
                'asset': asset,
           'quantity': quantity
def validate (db, source, destination, asset, quantity, block_index):
    if asset == config.BTC: problems.append('cannot send bitcoins')  # Only for parsing.
    if not isinstance(quantity, int):
        problems.append('quantity must be in satoshis')
        return problems
    if quantity < 0:
        problems.append('negative quantity')
    if quantity > config.MAX_INT:
        problems.append('integer M
    if util.enabled('send_destination_required'):  # Protocol change.
        if not destination:
            problems.append('destination is required')
    if util.enabled('options_require_memo'):
        # Check destination address options
        cursor = db.cursor()
        results = cursor.execute('SELECT options FROM addresses WHERE address=?', (destination,))
            result = results.fetchone()
            if result and util.active_options(result['options'], config.ADDREM
SS_OPTION_REQUIRE_MEMO):
                problems.append('destination requires memo')
        cursor.close()
def compose (db, source, destination, asset, quantity):
    cursor = db.cursor()
    # Just send BTC?
    if asset == config.BTC:
        return (source, [(destination, quantity)], None)
    # resolve subassets
    asset = util.resolve_subasset_longname(db, asset)
    #quantity must be in int satoshi (not float, string, etc)
    if not isinstance(quantity, int):
        raise exceptiM
ons.ComposeError('quantity must be an int (in satoshi)')
    # Only for outgoing (incoming will overburn).
    balances = list(cursor.execute('''SELECT * FROM balances WHERE (address = ? AND asset = ?)''', (source, asset)))
    if not balances or balances[0]['quantity'] < quantity:
        raise exceptions.ComposeError('insufficient funds')
    block_index = util.CURRENT_BLOCK_INDEX
    problems = validate(db, source, destination, asset, quantity, block_index)
    if problems: raise exceptions.ComposeError(problM
    asset_id = util.get_asset_id(db, asset, block_index)
    data = message_type.pack(ID)
    data += struct.pack(FORMAT, asset_id, quantity)
    return (source, [(destination, None)], data)
def parse (db, tx, message):
    cursor = db.cursor()
    # Unpack message.
        if len(message) != LENGTH:
            raise exceptions.UnpackError
        asset_id, quantity = struct.unpack(FORMAT, message)
        asset = util.get_asset_name(db, asset_id, tx['block_index'])
    except (exceptions.UnpackError, exceptions.AssetNameError, struct.error) as e:
        asset, quantity = None, None
        status = 'invalid: could not unpack'
    if status == 'valid':
        cursor.execute('''SELECT * FROM balances \
                                     WHERE (address = ? AND asset = ?)''', (tx['source'], asset))
        balances = cursor.fetchall()
        if not balances:
            status = 'invalid: insufficient funds'
        elif balances[0]['quantitM
            quantity = min(balances[0]['quantity'], quantity)
        quantity = min(quantity, config.MAX_INT)
    if status == 'valid':
        problems = validate(db, tx['source'], tx['destination'], asset, quantity, tx['block_index'])
        if problems: status = 'invalid: ' + '; '.join(problems)
    if status == 'valid':
        util.debit(db, tx['source'], asset, quantity, action='send', event=tx['tx_hash'])
        util.credit(db, tx['destination'], assetM
, quantity, action='send', event=tx['tx_hash'])
    # Add parsed transaction to message-type
        'tx_index': tx['tx_index'],
        'tx_hash': tx['tx_hash'],
        'block_index': tx['block_index'],
        'source': tx['source'],
        'destination': tx['destination'],
        'asset': asset,
        'quantity': quantity,
        'status': status,
    if "integer overflow" not in status and "quantity must be in satoshis" not in status:
        sql = 'insert into seM
nds (tx_index, tx_hash, block_index, source, destination, asset, quantity, status, memo) values(:tx_index, :tx_hash, :block_index, :source, :destination, :asset, :quantity, :status, NULL)'
        cursor.execute(sql, bindings)
        logger.warn("Not storing [send] tx [%s]: %s" % (tx['tx_hash'], status))
        logger.debug("Bindings: %s" % (json.dumps(bindings), ))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
from bitcoin.core import key
from functools import reduce
from itertools import groupby
from bitstring import BitArray, BitStream, ConstBitStream, ReadError
logger = logging.getLogger(__name__)
from counterpartylib.lib import (config, util, exceptions, util, message_type, address)
## encoding functions
def _encode_constructBaseLUT(snds):
    # t is a tuple of the form (asset, addr, amnt [, memo, is_hex])
    return sorted(list(set([t[1] for t in snM
ds]))) # Sorted to make list determinist
def _encode_constructBaseAssets(sends):
    # t is a tuple of the form (asset, addr, amnt [, memo, is_hex])
    return sorted(list(set([t[0] for t in sends]))) # Sorted to make list determinist
def _encode_constructLUT(sends):
    baseLUT = _encode_constructBaseLUT(sends)
    # What's this? It calculates the minimal number of bits needed to represent an item index inside the baseLUT
    lutNbits = math.ceil(math.log2(len(baseLUT)))
        "nbits": lutNbits,M
        "addrs": baseLUT
def _encode_compressLUT(lut):
    return b''.join([struct.pack('>H', len(lut['addrs']))] +
            address.pack(addr)
            for addr in lut['addrs']
def _encode_memo(memo=None, is_hex=False):
    '''Tightly pack a memo as a Bit array'''
    if memo is not None:
        # signal a 1 bit for existence of the memo
        barr = BitArray('0b1')
            # signal a 1 bit for hex encoded memos
            barr.append('0b1')
    if type(memo) is str: # append the string as hex-string
                barr.append('uint:6=%i' % (len(memo) >> 1))
                memo = '0x%s' % memo
                barr.append('uint:6=%i' % len(memo))
            barr.append(memo)
            # signal a 0 bit for a string encoded memo
            barr.append('0b0')
            barr.append('uint:6=%i' % len(memo))
            barr.append(BitArray(memo.encode('utf-8')))
        # if the memo is M
None, return just a 0 bit
        return BitArray('0b0')
def _safe_tuple_index(t, i):
    '''Get an element from a tuple, returning None if it's out of bounds'''
def _encode_constructSendList(send_asset, lut, sends):
    # t is a tuple of the form (asset, addr, amnt, memo, is_hex)
    # if there's no memo specified, memo and is_hex are None
        (lut['addrs'].index(t[1]), t[2], _safe_tuple_index(t, 3), _safe_tuple_index(t, 4))
        for t in sends
        if t[0] == send_asset
def _solve_asset(db, assetName, block_index):
    asset = util.resolve_subasset_longname(db, assetName)
    return util.get_asset_id(db, asset, block_index)
def _encode_compressSendList(db, nbits, send, block_index):
    r.append('uintbe:64=%i' % _solve_asset(db, send['assetName'], block_index))
    r.append('uint:%i=%i' % (nbits, len(send['sendList'])-1))
    for sendItem in send['sendList']:
        idx = sendItem[0]
        r.append('uint:%i=%i' % (nbits, idx))
        r.append('uintbe:64=%i' % amnt)
            memoStr = _encode_memo(memo=sendItem[2], is_hex=sendItem[3])
            memoStr = BitArray('0b0')
        r.append(memoStr)
def _encode_constructSends(sends):
    lut = _encode_constructLUT(sends)
    assets = _encode_constructBaseAssets(sends)
            "assetName": asset,
            "sendList": _encode_constructSendList(asset, lutM
        for asset in assets
        "sendLists": sendLists
def _encode_compressSends(db, mpmaSend, block_index, memo=None, memo_is_hex=False):
    compressedLUT = _encode_compressLUT(mpmaSend['lut'])
    memo_arr = _encode_memo(memo, memo_is_hex).bin
    isends = '0b' + memo_arr + ''.join([
        ''.join(['1', _encode_compressSendList(db, mpmaSend['lut']['nbits'], sendList, block_index).bin])
        for sendList in mpmaSend['sendLists']
  bstr = ''.join([isends, '0'])
    pad = '0' * ((8 - (len(bstr) - 2)) % 8) # That -2 is because the prefix 0b is there
    barr = BitArray(bstr + pad)
    return b''.join([
        compressedLUT,
def _encode_mpmaSend(db, sends, block_index, memo=None, memo_is_hex=False):
    mpma = _encode_constructSends(sends)
    send = _encode_compressSends(db, mpma, block_index, memo=memo, memo_is_hex=memo_is_hex)
## decoding functions
def _decode_decodeLUT(data):
,) = struct.unpack('>H', data[0:2])
    if numAddresses == 0:
        raise exceptions.DecodeError('address list can\'t be empty')
    addressList = []
    bytesPerAddress = 21
    for i in range(0, numAddresses):
        addr_raw = data[p:p+bytesPerAddress]
        addressList.append(address.unpack(addr_raw))
        p += bytesPerAddress
    lutNbits = math.ceil(math.log2(numAddresses))
    return addressList, lutNbits, data[p:]
def _decode_decodeSendList(stream, nbits, lut, block_index):
id = stream.read('uintbe:64')
        numRecipients = stream.read('uint:%i' % nbits)
        rangeLimit = numRecipients + 1
        numRecipients = 1
        rangeLimit = numRecipients
    asset = util.generate_asset_name(asset_id, block_index)
    for i in range(0, rangeLimit):
        if nbits > 0:
            idx = stream.read('uint:%i' % nbits)
        addr = lut[idx]
        amount = stream.read('uintbe:64')
        memo, is_hex M
= _decode_memo(stream)
        if memo is not None:
            sendList.append((addr, amount, memo, is_hex))
            sendList.append((addr, amount))
    return asset, sendList
def _decode_decodeSends(stream, nbits, lut, block_index):
    #stream = ConstBitStream(data)
    while stream.read('bool'):
        asset, sendList = _decode_decodeSendList(stream, nbits, lut, block_index)
        sends[asset] = sendList
def _decode_memo(stream):
    if stream.read('booM
        is_hex = stream.read('bool')
        mlen = stream.read('uint:6')
        data = stream.read('bytes:%i' % mlen)
        if not(is_hex):
            # is an utf8 string
            data = data.decode('utf-8')
        return data, is_hex
        return None, None
def _decode_mpmaSendDecode(data, block_index):
    lut, nbits, remain = _decode_decodeLUT(data)
    stream = ConstBitStream(remain)
    memo, is_hex = _decode_memo(stream)
    sends = _decode_decodeSends(stream, nbits, lut, block_inM,
    if memo is not None:
        for asset in sends:
            sendList = sends[asset]
            for idx, send in enumerate(sendList):
                if len(send) == 2:
                    sendList[idx] = (send[0], send[1], memo, is_hex)
AUUUUUUUUUUUHUUUUUUUUUUUUUUUUUUi
!22222222222222222222222222222222222222222222222222
TUUUUUUUUUUUUUUUUUUUUUUUUUUUU
FPUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
text/plain;charset=utf-8
SjLPQuesto dovrebbe essere il limite per gli 80 caratteri di un testo op_return ciao
FjDOUT:2C73338A350D8C3395F29B96DB61A2295FC00D2FA324697D20F40623CBF42E54
 3e48013a564f5d725e88da2709abb6c7G0D
 4ae201a374e28e0b41697e7a5cc8a9baH0E
()*89:HIJWXYZghijwxyz
()*789:FGHIJUVWXYZdefghijstuvwxyz
c/Foundry USA Pool #dropgold/
EjCs:ETH.ETH:0x18A99CF66D9d80837Ee21734fA5C3d4D4686bb1A:261054731:ss:0
DjB=:ETH.ETH:0x6b749E0134288737dfc4827ba6D90A54ab7346F6:12723469:te:0
IjGREFUND:AB61703B275F8235DF30734970CB8FDA87E5CF161D6CF5E7F56A4BC5159ADFE6
Copyright Apple Inc., 2023
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
)4)))))4>444444>>>>>>>>KKKKKKWWWWWbbbbbbbbbb
+fE9Effffffffffffffffffffffffffffffffffffffffffffffffff
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 9.0-c000 79.171c27fab, 2022/08/16-22:35:41        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpMM:OriginalDocumentID="xmpM
.did:8187f80b-58da-b441-beb6-f4facd64d755" xmpMM:DocumentID="xmp.did:49D755B5A32D11ED9141BCEBB78737A9" xmpMM:InstanceID="xmp.iid:49D755B4A32D11ED9141BCEBB78737A9" xmp:CreatorTool="Adobe Photoshop 24.1 (Windows)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:cee66003-89ea-6e42-8659-2c4688cd6775" stRef:documentID="xmp.did:8187f80b-58da-b441-beb6-f4facd64d755"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>
 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
This is better than a JPG
MjK=:BNB.BUSD-BD1:bnb1aaahj4ye2rgavhqfm9cwgzem2tcs9xpt2f2n94:466681064925:t:30]
Bj@=:ETH.ETH:0x6eb4978c5d07379Bc7759F21f30B2b53EDBA0491:455695:te:0
Ahttp://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.5.0"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" photoshop:ColorMode="3" photoshop:ICCProfile="M
sRGB IEC61966-2.1" xmp:ModifyDate="2023-02-02T17:30:32-05:00" xmp:MetadataDate="2023-02-02T17:30:32-05:00"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="produced" stEvt:softwareAgent="Affinity Photo 1.10.6" stEvt:when="2023-02-02T17:30:32-05:00"/> </rdf:Seq> </xmpMM:History> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                       M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                  <?xpacket end="w"?>
+?7BA>7<;ENcTEI^K;<VvW^gjopoCSz
3kG<Gkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Ahttp://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.5.0"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" photoshop:ColorMode="3" photoshop:M
ICCProfile="sRGB IEC61966-2.1" xmp:ModifyDate="2023-02-02T17:30:06-05:00" xmp:MetadataDate="2023-02-02T17:30:06-05:00"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="produced" stEvt:softwareAgent="Affinity Photo 1.10.6" stEvt:when="2023-02-02T17:30:06-05:00"/> </rdf:Seq> </xmpMM:History> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                           M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                              <?xpacket end="w"?>
+?7BA>7<;ENcTEI^K;<VvW^gjopoCM
3kG<Gkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
c/SBICrypto.com Pool/
MjK=:BNB.BUSD-BD1:bnb1aaahj4ye2rgavhqfm9cwgzem2tcs9xpt2f2n94:467933815166:t:30
SjLPs:ETH.USDC-3606EB48:0x18A99CF66D9d80837Ee21734fA5C3d4D4686bb1A:214007541697:ss:0
9j7+:BTC/BTC::bc1q3f787hr38pmal87yxtpq8tng09q60ljjqqd759:0V
Aj?=:BNB.BNB:bnb1em5ake82afp2u6xtrnl9x879689gra3ezku0cz:17364:te:0
Aj?=:ETH.ETH:0x6eb4978c5d07379Bc7759F21f30B2b53EDBA0491:39697:te:0
CjA=:BNB.BNB:bnb15cy0flkvuhuvsjpsp0tphsauprxguuzj8ekuqv:2782480:te:0
EjC=:BNB.BTCB-1DE:bnb1l65zmzsteq2swtncp74f3etcmmsjfsqu7hdrkh:7482:te:0
IjGREFUND:CEEED9FCC85F8260DF2604F5C4DD4F7F7582602EEA9E2880D11B1E5E0E4A5278
FjDOUT:7FED7BBEDB95F8D99A6E191E785B3DCAAF3054152FDC6944CF952C2BD6090EE7
FjDOUT:21FECF0DFDDCE4C43C593F46B9C53203B3B81A5A0200F648C2A60E1FD2D9F237
FjDOUT:9D1038CC280A43152E0414C3BC25CD7B000DFA4CA3C336A8A1E27DCA8C2F6EC5
IjGREFUND:04BB70BADD38ACFB6DB78A85928267CB76D9F38DE42C25E1F10F9EC37C6C38A7
Bj@=:ETH.ETH:0x2E3E96d59d3052A1B73B579f777c5241441A9E93:194320:te:0
text/plain;charset=utf-8
INDUSTRIAL SOCIETY AND ITS FUTURE
1. The Industrial Revolution and its consequences have been a disaster for the
   human race. They have greatly increased the life-expectancy of those of us
 countries, but they have destabilized society, have
   made life unfulfilling, have subjected human beings to indignities, have led
   to widespread psychological suffering (in the Third World to physical
   suffering as well) and have inflicted severe damage on the natural worlM
   continued development of technology will worsen the situation. It will
   certainly subject human beings to greater indignities and inflict greater
   damage on the natural world, it will probably lead to greater social
   disruption and psychological suffering, and it may lead to increased physical
   suffering even in
2. The industrial-technological system may survive or it may break down. If it
   survives, it MAY eventually achieve a low level of physical and psychologM
   suffering, but only after passing through a long and very painful period of
   adjustment and only at the cost of permanently reducing human beings and many
   other living organisms to engineered products and mere cogs in the social
   machine. Furthermore, if the system survives, the consequences will be
   inevitable: There is no way of reforming or modifying the system so as to
   prevent it from depriving people of dignity and autonomy.
3. If the system breaks down the consequences will still beM
   the bigger the system grows the more disastrous the results of its breakdown
   will be, so if it is to break down it had best break down sooner rather than
4. We therefore advocate a revolution against the industrial system. This
   revolution may or may not make use of violence; it may be sudden or it may be
   a relatively gradual process spanning a few decades. We can
   that. But we do outline in a very general way the measures that those who
he industrial system should take in order to prepare the way for
   a revolution against that form of society. This is not to be a POLITICAL
   revolution. Its object will be to overthrow not governments but the economic
   and technological basis of the present society.
5. In this article we give attention to only some of the negative developments
   that have grown out of the industrial-technological system. Other such
   developments we mention only briefly or ignore altogether. This does not mean
 we regard these other developments as unimportant. For practical reasons
   we have to confine our discussion to areas that have received insufficient
   public attention or in which we have something new to say. For example, since
   there are well-developed environmental and wilderness movements, we have
   written very little about environmental degradation or the destruction of
   wild nature, even though we consider these to be highly important.
THE PSYCHOLOGY OF MODERN LEFTISM
6. Almost everyone will M
agree that we live in a deeply troubled society. One of
   the most widespread manifestations of the craziness of our world is leftism,
   so a discussion of the psychology of leftism can serve as an introduction to
   the discussion of the problems of modern society in general.
7. But what is leftism? During the first half of the 20th century leftism could
   have been practically identified with socialism. Today the movement is
   fragmented and it is not clear who can properly be called a leftist. When we M
   speak of leftists in this article we have in mind mainly socialists,
 types, feminists, gay and disability
   activists, animal rights activists and the like. But not everyone who is
   associated with one of these movements is a leftist. What we are trying to
   get at in discussing leftism is not so much movement or an ideology as
   a psychological type, or rather a collection of related types. Thus, what we
 will emerge more clearly inM
 the course of our discussion of
   leftist psychology. (Also, see paragraphs 227-230.)
8. Even so, our conception of leftism will remain a good deal less clear than we
   would wish, but there doesn
t seem to be any remedy for this. All we are
   trying to do here is indicate in a rough and approximate way the two
   psychological tendencies that we believe are the main driving force of modern
   leftism. We by no means claim to be telling the WHOLE truth about leftist
   psychology. Also, our discussion M
is meant to apply to modern leftism only. We
   leave open the question of the extent to which our discussion could be
   applied to the leftists of the 19th and early 20th centuries.
9. The two psychological tendencies that underlie modern leftism we call
feelings of inferiority
 Feelings of inferiority
   are characteristic of modern leftism as a whole, while oversocialization is
   characteristic only of a certain segment of modern leftism; but this segment
FEELINGS OF INFERIORITY
feelings of inferiority
 we mean not only inferiority feelings in the
    strict sense but a whole spectrum of related traits; low self-esteem,
    feelings of powerlessness, depressive tendencies, defeatism, guilt, self-
    hatred, etc. We argue that modern leftists tend to have some such feelings
    (possibly more or less repressed) and that these feelings are decisive in
    determining the direction of modern leftism.
11. When someone interprets as deM
rogatory almost anything that is said about him
    (or about groups with whom he identifies) we conclude that he has
    inferiority feelings or low self-esteem. This tendency is pronounced among
    minority rights activists, whether or not they belong to the minority groups
    whose rights they defend. They are hypersensitive about the words used to
    designate minorities and about anything that is said concerning minorities.
    Asian, a disabled person or a woman originally had no derogatory
 were merely the feminine equivalents of
 The negative connotations have been attached to
    these terms by the activists themselves. Some animal rights activists have
    gone so far as to reject the word
 and insist on its replacement by
 Leftish anthropologists go to great lengths to avoid
 anything about primitive peoples that could conceivably be
    interpreted as negative. They want to replace the world
 They seem almost paranoid about anything that might suggest
    that any primitive culture is inferior to our own. (We do not mean to imply
    that primitive cultures ARE inferior to ours. We merely point out the
    hypersensitivity of leftish anthropologists.)
12. Those who are most sensitive about
politically incorrect
not the average black ghetto- dweller, Asian immigrant, abused woman or
    disabled person, but a minority of activists, many of whom do not even
 group but come from privileged strata of society.
    Political correctness has its stronghold among university professors, who
    have secure employment with comfortable salaries, and the majority of whom
    are heterosexual white males from middle- to upper-middle-class families.
13. Many leftists have an intense identificationM
 with the problems of groups
    that have an image of being weak (women), defeated (American Indians),
    repellent (homosexuals) or otherwise inferior. The leftists themselves feel
    that these groups are inferior. They would never admit to themselves that
    they have such feelings, but it is precisely because they do see these
    groups as inferior that they identify with their problems. (We do not mean
    to suggest that women, Indians, etc. ARE inferior; we are only making
    a point about leftiM
14. Feminists are desperately anxious to prove that women are as strong and as
    capable as men. Clearly they are nagged by a fear that women may NOT be as
    strong and as capable as men.
15. Leftists tend to hate anything that has an image of being strong, good and
    successful. They hate America, they hate Western civilization, they hate
    white males, they hate rationality. The reasons that leftists give for
    hating the West, etc. clearly do not correspond with their real motiveM
    They SAY they hate the West because it is warlike, imperialistic, sexist,
    ethnocentric and so forth, but where these same faults appear in socialist
    countries or in primitive cultures, the leftist finds excuses for them, or
    at best he GRUDGINGLY admits that they exist; whereas he ENTHUSIASTICALLY
    points out (and often greatly exaggerates) these faults where they appear in
    Western civilization. Thus it is clear that these faults are not the
s real motive for hating AmeM
rica and the West. He hates America and
    the West because they are strong and successful.
 etc., play little role in the liberal and leftist vocabulary.
    The leftist is anti-individualistic, pro-collectivist. He wants society to
s problems for them, satisfy everyone
s needs for them, take
    care of them. He is not the sort of person who has an inner sense of
fidence in his ability to solve his own problems and satisfy his own
    needs. The leftist is antagonistic to the concept of competition because,
    deep inside, he feels like a loser.
17. Art forms that appeal to modern leftish intellectuals tend to focus on
    sordidness, defeat and despair, or else they take an orgiastic tone,
    throwing off rational control as if there were no hope of accomplishing
    anything through rational calculation and all that was left was to immerse
    oneself in the sensM
ations of the moment.
18. Modern leftish philosophers tend to dismiss reason, science, objective
    reality and to insist that everything is culturally relative. It is true
    that one can ask serious questions about the foundations of scientific
    knowledge and about how, if at all, the concept of objective reality can be
    defined. But it is obvious that modern leftish philosophers are not simply
    cool-headed logicians systematically analyzing the foundations of knowledge.
    They are deeply invoM
lved emotionally in their attack on truth and reality.
    They attack these concepts because of their own psychological needs. For one
    thing, their attack is an outlet for hostility, and, to the extent that it
    is successful, it satisfies the drive for power. More importantly, the
    leftist hates science and rationality because they classify certain beliefs
    as true (i.e., successful, superior) and other beliefs as false (i.e.,
    failed, inferior). The leftist
s feelings of inferiority run soM
    cannot tolerate any classification of some things as successful or superior
    and other things as failed or inferior. This also underlies the rejection by
    many leftists of the concept of mental illness and of the utility of IQ
    tests. Leftists are antagonistic to genetic explanations of human abilities
    or behavior because such explanations tend to make some persons appear
    superior or inferior to others. Leftists prefer to give society the credit
    or blame for an individuM
s ability or lack of it. Thus if a person is
 it is not his fault, but society
s, because he has not been
    brought up properly.
19. The leftist is not typically the kind of person whose feelings of
    inferiority make him a braggart, an egotist, a bully, a self-promoter,
    a ruthless competitor. This kind of person has not wholly lost faith in
    himself. He has a deficit in his sense of power and self-worth, but he can
    still conceive of himself as having the capacity to bM
    efforts to make himself strong produce his unpleasant behavior. [1] But the
    leftist is too far gone for that. His feelings of inferiority are so
    ingrained that he cannot conceive of himself as individually strong and
    valuable. Hence the collectivism of the leftist. He can feel strong only as
    a member of a large organization or a mass movement with which he identifies
20. Notice the masochistic tendency of leftist tactics. Leftists protest by
in front of vehicles, they intentionally provoke police or
    racists to abuse them, etc. These tactics may often be effective, but many
    leftists use them not as a means to an end but because they PREFER
    masochistic tactics. Self-hatred is a leftist trait.
21. Leftists may claim that their activism is motivated by compassion or by
    moral principles, and moral principle does play a role for the leftist of
    the oversocialized type. But compassion and moral principle cannot be the
s for leftist activism. Hostility is too prominent a component of
    leftist behavior; so is the drive for power. Moreover, much leftist behavior
    is not rationally calculated to be of benefit to the people whom the
    leftists claim to be trying to help. For example, if one believes that
    affirmative action is good for black people, does it make sense to demand
    affirmative action in hostile or dogmatic terms? Obviously it would be more
    productive to take a diplomatic and conciliatory approachM
 that would make at
    least verbal and symbolic concessions to white people who think that
    affirmative action discriminates against them. But leftist activists do not
    take such an approach because it would not satisfy their emotional needs.
    Helping black people is not their real goal. Instead, race problems serve as
    an excuse for them to express their own hostility and frustrated need for
    power. In doing so they actually harm black people, because the activists
    hostile attitude tM
oward the white majority tends to intensify race hatred.
22. If our society had no social problems at all, the leftists would have to
    INVENT problems in order to provide themselves with an excuse for making
23. We emphasize that the foregoing does not pretend to be an accurate
    description of everyone who might be considered a leftist. It is only
    a rough indication of a general tendency of leftism.
24. Psychologists use the term
 to designate the pM
    children are trained to think and act as society demands. A person is said
    to be well socialized if he believes in and obeys the moral code of his
    society and fits in well as a functioning part of that society. It may seem
    senseless to say that many leftists are oversocialized, since the leftist is
    perceived as a rebel. Nevertheless, the position can be defended. Many
    leftists are not such rebels as they seem.
25. The moral code of our society is so demanding that no oM
    and act in a completely moral way. For example, we are not supposed to hate
    anyone, yet almost everyone hates somebody at some time or other, whether he
    admits it to himself or not. Some people are so highly socialized that the
    attempt to think, feel and act morally imposes a severe burden on them. In
    order to avoid feelings of guilt, they continually have to deceive
    themselves about their own motives and find moral explanations for feelings
    and actions that in M
reality have a non-moral origin. We use the term
 to describe such people. [2]
26. Oversocialization can lead to low self-esteem, a sense of powerlessness,
    defeatism, guilt, etc. One of the most important means by which our society
    socializes children is by making them feel ashamed of behavior or speech
    that is contrary to society
s expectations. If this is overdone, or if
    a particular child is especially susceptible to such feelings, he ends by
    feeling ashamed oM
f HIMSELF. Moreover the thought and the behavior of the
    oversocialized person are more restricted by society
s expectations than are
    those of the lightly socialized person. The majority of people engage in
    a significant amount of naughty behavior. They lie, they commit petty
    thefts, they break traffic laws, they goof off at work, they hate someone,
    they say spiteful things or they use some underhanded trick to get ahead of
    the other guy. The oversocialized person cannot do these thinM
    does do them he generates in himself a sense of shame and self-hatred. The
    oversocialized person cannot even experience, without guilt, thoughts or
    feelings that are contrary to the accepted morality; he cannot think
 thoughts. And socialization is not just a matter of morality; we
    are socialized to conform to many norms of behavior that do not fall under
    the heading of morality. Thus the oversocialized person is kept on
    a psychological leash and spends hM
is life running on rails that society has
    laid down for him. In many oversocialized people this results in a sense of
    constraint and powerlessness that can be a severe hardship. We suggest that
    oversocialization is among the more serious cruelties that human beings
    inflict on one another.
27. We argue that a very important and influential segment of the modern left is
    oversocialized and that their oversocialization is of great importance in
    determining the direction of modern leftism.M
 Leftists of the oversocialized
    type tend to be intellectuals or members of the upper-middle class. Notice
    that university intellectuals [3] constitute the most highly socialized
    segment of our society and also the most left-wing segment.
28. The leftist of the oversocialized type tries to get off his psychological
    leash and assert his autonomy by rebelling. But usually he is not strong
    enough to rebel against the most basic values of society. Generally
    speaking, the goals of today
s leftists are NOT in conflict with the
    accepted morality. On the contrary, the left takes an accepted moral
    principle, adopts it as its own, and then accuses mainstream society of
    violating that principle. Examples: racial equality, equality of the sexes,
    helping poor people, peace as opposed to war, nonviolence generally, freedom
    of expression, kindness to animals. More fundamentally, the duty of the
    individual to serve society and the duty of society to take care of the
ual. All these have been deeply rooted values of our society (or at
    least of its middle and upper classes [4] for a long time. These values are
    explicitly or implicitly expressed or presupposed in most of the material
    presented to us by the mainstream communications media and the educational
    system. Leftists, especially those of the oversocialized type, usually do
    not rebel against these principles but justify their hostility to society by
    claiming (with some degree of truth) that sociM
ety is not living up to these
29. Here is an illustration of the way in which the oversocialized leftist shows
    his real attachment to the conventional attitudes of our society while
    pretending to be in rebellion against it. Many leftists push for affirmative
    action, for moving black people into high-prestige jobs, for improved
    education in black schools and more money for such schools; the way of life
 they regard as a social disgrace. They wanM
    integrate the black man into the system, make him a business executive,
    a lawyer, a scientist just like upper-middle-class white people. The
    leftists will reply that the last thing they want is to make the black man
    into a copy of the white man; instead, they want to preserve African
    American culture. But in what does this preservation of African American
    culture consist? It can hardly consist in anything more than eating
    black-style food, listening to black-style music, wearM
    clothing and going to a black- style church or mosque. In other words, it
    can express itself only in superficial matters. In all ESSENTIAL respects
    most leftists of the oversocialized type want to make the black man conform
    to white, middle-class ideals. They want to make him study technical
    subjects, become an executive or a scientist, spend his life climbing the
    status ladder to prove that black people are as good as white. They want to
    make black fathers
 they want black gangs to become
    nonviolent, etc. But these are exactly the values of the
    industrial-technological system. The system couldn
t care less what kind of
    music a man listens to, what kind of clothes he wears or what religion he
    believes in as long as he studies in school, holds a respectable job, climbs
    the status ladder, is a
 parent, is nonviolent and so forth. In
    effect, however much he may deny it, the oversocialized leftist wants to
ntegrate the black man into the system and make him adopt its values.
30. We certainly do not claim that leftists, even of the oversocialized type,
    NEVER rebel against the fundamental values of our society. Clearly they
    sometimes do. Some oversocialized leftists have gone so far as to rebel
    against one of modern society
s most important principles by engaging in
    physical violence. By their own account, violence is for them a form of
 In other words, by committing violencM
e they break through the
    psychological restraints that have been trained into them. Because they are
    oversocialized these restraints have been more confining for them than for
    others; hence their need to break free of them. But they usually justify
    their rebellion in terms of mainstream values. If they engage in violence
    they claim to be fighting against racism or the like.
31. We realize that many objections could be raised to the foregoing thumbnail
    sketch of leftist psychology. TheM
 real situation is complex, and anything
    like a complete description of it would take several volumes even if the
    necessary data were available. We claim only to have indicated very roughly
    the two most important tendencies in the psychology of modern leftism.
32. The problems of the leftist are indicative of the problems of our society as
    a whole. Low self-esteem, depressive tendencies and defeatism are not
    restricted to the left. Though they are especially noticeable in the left,
ey are widespread in our society. And today
s society tries to socialize
    us to a greater extent than any previous society. We are even told by
    experts how to eat, how to exercise, how to make love, how to raise our kids
33. Human beings have a need (probably based in biology) for something that we
 This is closely related to the need for power
    (which is widely recognized) but is not quite the same thing. The power
ocess has four elements. The three most clear-cut of these we call goal,
    effort and attainment of goal. (Everyone needs to have goals whose
    attainment requires effort, and needs to succeed in attaining at least some
    of his goals.) The fourth element is more difficult to define and may not be
    necessary for everyone. We call it autonomy and will discuss it later
    (paragraphs 42-44).
34. Consider the hypothetical case of a man who can have anything he wants just
    by wishing for it. Such a M
man has power, but he will develop serious
    psychological problems. At first he will have a lot of fun, but by and by he
    will become acutely bored and demoralized. Eventually he may become
    clinically depressed. History shows that leisured aristocracies tend to
    become decadent. This is not true of fighting aristocracies that have to
    struggle to maintain their power. But leisured, secure aristocracies that
    have no need to exert themselves usually become bored, hedonistic and
zed, even though they have power. This shows that power is not
    enough. One must have goals toward which to exercise one
35. Everyone has goals; if nothing else, to obtain the physical necessities of
    life: food, water and whatever clothing and shelter are made necessary by
    the climate. But the leisured aristocrat obtains these things without
    effort. Hence his boredom and demoralization.
36. Nonattainment of important goals results in death if the goals are physical
and in frustration if nonattainment of the goals is compatible
    with survival. Consistent failure to attain goals throughout life results in
    defeatism, low self-esteem or depression.
37, Thus, in order to avoid serious psychological problems, a human being needs
    goals whose attainment requires effort, and he must have a reasonable rate
    of success in attaining his goals.
SURROGATE ACTIVITIES
38. But not every leisured aristocrat becomes bored and demoralized. For
    example, the emperor HirohM
ito, instead of sinking into decadent hedonism,
    devoted himself to marine biology, a field in which he became distinguished.
    When people do not have to exert themselves to satisfy their physical needs
    they often set up artificial goals for themselves. In many cases they then
    pursue these goals with the same energy and emotional involvement that they
    otherwise would have put into the search for physical necessities. Thus the
    aristocrats of the Roman Empire had their literary pretensionsM
    European aristocrats a few centuries ago invested tremendous time and energy
    in hunting, though they certainly didn
t need the meat; other aristocracies
    have competed for status through elaborate displays of wealth; and a few
    aristocrats, like Hirohito, have turned to science.
39. We use the term
 to designate an activity that is
    directed toward an artificial goal that people set up for themselves merely
    in order to have some goal to work toward, or leM
t us say, merely for the
 that they get from pursuing the goal. Here is
    a rule of thumb for the identification of surrogate activities. Given
    a person who devotes much time and energy to the pursuit of goal X, ask
    yourself this: If he had to devote most of his time and energy to satisfying
    his biological needs, and if that effort required him to use his physical
    and mental faculties in a varied and interesting way, would he feel
    seriously deprived becaM
use he did not attain goal X? If the answer is no,
s pursuit of goal X is a surrogate activity. Hirohito
    studies in marine biology clearly constituted a surrogate activity, since it
    is pretty certain that if Hirohito had had to spend his time working at
    interesting non-scientific tasks in order to obtain the necessities of life,
    he would not have felt deprived because he didn
t know all about the anatomy
    and life-cycles of marine animals. On the other hand the pM
    love (for example) is not a surrogate activity, because most people, even if
    their existence were otherwise satisfactory, would feel deprived if they
    passed their lives without ever having a relationship with a member of the
    opposite sex. (But pursuit of an excessive amount of sex, more than one
    really needs, can be a surrogate activity.)
40. In modern industrial society only minimal effort is necessary to satisfy
s physical needs. It is enough to go through a M
training program to
    acquire some petty technical skill, then come to work on time and exert the
    very modest effort needed to hold a job. The only requirements are
    a moderate amount of intelligence and, most of all, simple OBEDIENCE. If one
    has those, society takes care of one from cradle to grave. (Yes, there is an
    underclass that cannot take the physical necessities for granted, but we are
    speaking here of mainstream society.) Thus it is not surprising that modern
    society is fullM
 of surrogate activities. These include scientific work,
    athletic achievement, humanitarian work, artistic and literary creation,
    climbing the corporate ladder, acquisition of money and material goods far
    beyond the point at which they cease to give any additional physical
    satisfaction, and social activism when it addresses issues that are not
    important for the activist personally, as in the case of white activists who
    work for the rights of nonwhite minorities. These are not always PUM
    surrogate activities, since for many people they may be motivated in part by
    needs other than the need to have some goal to pursue. Scientific work may
    be motivated in part by a drive for prestige, artistic creation by a need to
    express feelings, militant social activism by hostility. But for most people
    who pursue them, these activities are in large part surrogate activities.
    For example, the majority of scientists will probably agree that the
heir work is more important than the money and
    prestige they earn.
41. For many if not most people, surrogate activities are less satisfying than
    the pursuit of real goals (that is, goals that people would want to attain
    even if their need for the power process were already fulfilled). One
    indication of this is the fact that, in many or most cases, people who are
    deeply involved in surrogate activities are never satisfied, never at rest.
    Thus the money-maker constantly strives for morM
e and more wealth. The
    scientist no sooner solves one problem than he moves on to the next. The
    long-distance runner drives himself to run always farther and faster. Many
    people who pursue surrogate activities will say that they get far more
    fulfillment from these activities than they do from the
    of satisfying their biological needs, but that is because in our society the
    effort needed to satisfy the biological needs has been reduced to
    triviality. More impoM
rtantly, in our society people do not satisfy their
    biological needs AUTONOMOUSLY but by functioning as parts of an immense
    social machine. In contrast, people generally have a great deal of autonomy
    in pursuing their surrogate activities.
42. Autonomy as a part of the power process may not be necessary for every
    individual. But most people need a greater or lesser degree of autonomy in
    working toward their goals. Their efforts must be undertaken on their own
    initiative and M
must be under their own direction and control. Yet most
    people do not have to exert this initiative, direction and control as single
    individuals. It is usually enough to act as a member of a SMALL group. Thus
    if half a dozen people discuss a goal among themselves and make a successful
    joint effort to attain that goal, their need for the power process will be
    served. But if they work under rigid orders handed down from above that
    leave them no room for autonomous decision and initiativeM
    for the power process will not be served. The same is true when decisions
    are made on a collective basis if the group making the collective decision
    is so large that the role of each individual is insignificant. [5]
43. It is true that some individuals seem to have little need for autonomy.
    Either their drive for power is weak or they satisfy it by identifying
    themselves with some powerful organization to which they belong. And then
    there are unthinking, animal typesM
 who seem to be satisfied with a purely
    physical sense of power (the good combat soldier, who gets his sense of
    power by developing fighting skills that he is quite content to use in blind
    obedience to his superiors).
44. But for most people it is through the power process
having a goal, making an
    AUTONOMOUS effort and attaining the goal
that self-esteem, self-confidence
    and a sense of power are acquired. When one does not have adequate
    opportunity to go through the power process M
the consequences are (depending
    on the individual and on the way the power process is disrupted) boredom,
    demoralization, low self-esteem, inferiority feelings, defeatism,
    depression, anxiety, guilt, frustration, hostility, spouse or child abuse,
    insatiable hedonism, abnormal sexual behavior, sleep disorders, eating
    disorders, etc. [6]
SOURCES OF SOCIAL PROBLEMS
45. Any of the foregoing symptoms can occur in any society, but in modern
    industrial society they are present on a massive M
    to mention that the world today seems to be going crazy. This sort of thing
    is not normal for human societies. There is good reason to believe that
    primitive man suffered from less stress and frustration and was better
    satisfied with his way of life than modern man is. It is true that not all
    was sweetness and light in primitive societies. Abuse of women was common
    among the Australian aborigines, transexuality was fairly common among some
can Indian tribes. But it does appear that GENERALLY SPEAKING
    the kinds of problems that we have listed in the preceding paragraph were
    far less common among primitive peoples than they are in modern society.
46. We attribute the social and psychological problems of modern society to the
    fact that that society requires people to live under conditions radically
    different from those under which the human race evolved and to behave in
    ways that conflict with the patterns of behavior that the M
    developed while living under the earlier conditions. It is clear from what
    we have already written that we consider lack of opportunity to properly
    experience the power process as the most important of the abnormal
    conditions to which modern society subjects people. But it is not the only
    one. Before dealing with disruption of the power process as a source of
    social problems we will discuss some of the other sources.
47. Among the abnormal conditions present in modern indusM
    excessive density of population, isolation of man from nature, excessive
    rapidity of social change and the breakdown of natural small-scale
    communities such as the extended family, the village or the tribe.
48. It is well known that crowding increases stress and aggression. The degree
    of crowding that exists today and the isolation of man from nature are
    consequences of technological progress. All pre-industrial societies were
    predominantly rural. The Industrial RevoM
lution vastly increased the size of
    cities and the proportion of the population that lives in them, and modern
    agricultural technology has made it possible for the Earth to support a far
    denser population than it ever did before. (Also, technology exacerbates the
    effects of crowding because it puts increased disruptive powers in people
    hands. For example, a variety of noise- making devices: power mowers,
    radios, motorcycles, etc. If the use of these devices is unrestricted,
ople who want peace and quiet are frustrated by the noise. If their use is
    restricted, people who use the devices are frustrated by the regulations.
    But if these machines had never been invented there would have been no
    conflict and no frustration generated by them.)
49. For primitive societies the natural world (which usually changes only
    slowly) provided a stable framework and therefore a sense of security. In
    the modern world it is human society that dominates nature rather than the
  other way around, and modern society changes very rapidly owing to
    technological change. Thus there is no stable framework.
50. The conservatives are fools: They whine about the decay of traditional
    values, yet they enthusiastically support technological progress and
    economic growth. Apparently it never occurs to them that you can
    rapid, drastic changes in the technology and the economy of a society
    without causing rapid changes in all other aspects of the society as well,
and that such rapid changes inevitably break down traditional values.
51. The breakdown of traditional values to some extent implies the breakdown of
    the bonds that hold together traditional small-scale social groups. The
    disintegration of small-scale social groups is also promoted by the fact
    that modern conditions often require or tempt individuals to move to new
    locations, separating themselves from their communities. Beyond that,
    a technological society HAS TO weaken family ties and loM
    it is to function efficiently. In modern society an individual
    must be first to the system and only secondarily to a small-scale community,
    because if the internal loyalties of small-scale communities were stronger
    than loyalty to the system, such communities would pursue their own
    advantage at the expense of the system.
52. Suppose that a public official or a corporation executive appoints his
    cousin, his friend or his co- religionist to a position rathM
    appointing the person best qualified for the job. He has permitted personal
    loyalty to supersede his loyalty to the system, and that is
 both of which are terrible sins in modern society.
    Would-be industrial societies that have done a poor job of subordinating
    personal or local loyalties to loyalty to the system are usually very
    inefficient. (Look at Latin America.) Thus an advanced industrial society
    can tolerate only those small-scaM
le communities that are emasculated, tamed
    and made into tools of the system. [7]
53. Crowding, rapid change and the breakdown of communities have been widely
    recognized as sources of social problems. But we do not believe they are
    enough to account for the extent of the problems that are seen today.
54. A few pre-industrial cities were very large and crowded, yet their
    inhabitants do not seem to have suffered from psychological problems to the
    same extent as modern man. In America today M
there still are uncrowded rural
    areas, and we find there the same problems as in urban areas, though the
    problems tend to be less acute in the rural areas. Thus crowding does not
    seem to be the decisive factor.
55. On the growing edge of the American frontier during the 19th century, the
    mobility of the population probably broke down extended families and
    small-scale social groups to at least the same extent as these are broken
    down today. In fact, many nuclear families lived by choicM
    isolation, having no neighbors within several miles, that they belonged to
    no community at all, yet they do not seem to have developed problems as
56. Furthermore, change in American frontier society was very rapid and deep.
    A man might be born and raised in a log cabin, outside the reach of law and
    order and fed largely on wild meat; and by the time he arrived at old age he
    might be working at a regular job and living in an ordered community with
w enforcement. This was a deeper change than that which
    typically occurs in the life of a modern individual, yet it does not seem to
    have led to psychological problems. In fact, 19th century American society
    had an optimistic and self-confident tone, quite unlike that of today
57. The difference, we argue, is that modern man has the sense (largely
    justified) that change is IMPOSED on him, whereas the 19th century
    frontiersman had the sense (also largely justified) thaM
t he created change
    himself, by his own choice. Thus a pioneer settled on a piece of land of his
    own choosing and made it into a farm through his own effort. In those days
    an entire county might have only a couple of hundred inhabitants and was
    a far more isolated and autonomous entity than a modern county is. Hence the
    pioneer farmer participated as a member of a relatively small group in the
    creation of a new, ordered community. One may well question whether the
    creation of thisM
 community was an improvement, but at any rate it satisfied
s need for the power process.
58. It would be possible to give other examples of societies in which there has
    been rapid change and/or lack of close community ties without the kind of
    massive behavioral aberration that is seen in today
s industrial society. We
    contend that the most important cause of social and psychological problems
    in modern society is the fact that people have insufficient opportunity to
 through the power process in a normal way. We don
    modern society is the only one in which the power process has been
    disrupted. Probably most if not all civilized societies have interfered with
    the power process to a greater or lesser extent. But in modern industrial
    society the problem has become particularly acute. Leftism, at least in its
    recent (mid- to late-20th century) form, is in part a symptom of deprivation
    with respect to the power process.
OF THE POWER PROCESS IN MODERN SOCIETY
59. We divide human drives into three groups: (1) those drives that can be
    satisfied with minimal effort; (2) those that can be satisfied but only at
    the cost of serious effort; (3) those that cannot be adequately satisfied no
    matter how much effort one makes. The power process is the process of
    satisfying the drives of the second group. The more drives there are in the
    third group, the more there is frustration, anger, eventually defeatism,
60. In modern industrial society natural human drives tend to be pushed into the
    first and third groups, and the second group tends to consist increasingly
    of artificially created drives.
61. In primitive societies, physical necessities generally fall into group 2:
    They can be obtained, but only at the cost of serious effort. But modern
    society tends to guaranty the physical necessities to everyone [9] in
    exchange for only minimal effort, hence physical needs are pushed into M
    1. (There may be disagreement about whether the effort needed to hold a job
; but usually, in lower- to middle- level jobs, whatever effort
    is required is merely that of OBEDIENCE. You sit or stand where you are told
    to sit or stand and do what you are told to do in the way you are told to do
    it. Seldom do you have to exert yourself seriously, and in any case you have
    hardly any autonomy in work, so that the need for the power process is not
. Social needs, such as sex, love and status, often remain in group 2 in
    modern society, depending on the situation of the individual. [10] But,
    except for people who have a particularly strong drive for status, the
    effort required to fulfill the social drives is insufficient to satisfy
    adequately the need for the power process.
63. So certain artificial needs have been created that fall into group 2, hence
    serve the need for the power process. Advertising and marketing techniques
e been developed that make many people feel they need things that their
    grandparents never desired or even dreamed of. It requires serious effort to
    earn enough money to satisfy these artificial needs, hence they fall into
    group 2. (But see paragraphs 80-82.) Modern man must satisfy his need for
    the power process largely through pursuit of the artificial needs created by
    the advertising and marketing industry [11], and through surrogate
64. It seems that for many people, mM
aybe the majority, these artificial forms of
    the power process are insufficient. A theme that appears repeatedly in the
    writings of the social critics of the second half of the 20th century is the
    sense of purposelessness that afflicts many people in modern society. (This
    purposelessness is often called by other names such as
middle-class vacuity.
) We suggest that the so-called
    actually a search for a sense of purpose, often for commitmentM
    surrogate activity. It may be that existentialism is in large part
    a response to the purposelessness of modern life. [12] Very widespread in
    modern society is the search for
 But we think that for the
    majority of people an activity whose main goal is fulfillment (that is,
    a surrogate activity) does not bring completely satisfactory fulfillment. In
    other words, it does not fully satisfy the need for the power process. (See
    paragraph 41.) That need cM
an be fully satisfied only through activities that
    have some external goal, such as physical necessities, sex, love, status,
65. Moreover, where goals are pursued through earning money, climbing the status
    ladder or functioning as part of the system in some other way, most people
    are not in a position to pursue their goals AUTONOMOUSLY. Most workers are
s employee and, as we pointed out in paragraph 61, must spend
    their days doing what they are told to do M
in the way they are told to do it.
    Even people who are in business for themselves have only limited autonomy.
    It is a chronic complaint of small-business persons and entrepreneurs that
    their hands are tied by excessive government regulation. Some of these
    regulations are doubtless unnecessary, but for the most part government
    regulations are essential and inevitable parts of our extremely complex
    society. A large portion of small business today operates on the franchise
 was reported in the Wall Street Journal a few years ago that many
    of the franchise-granting companies require applicants for franchises to
    take a personality test that is designed to EXCLUDE those who have
    creativity and initiative, because such persons are not sufficiently docile
    to go along obediently with the franchise system. This excludes from small
    business many of the people who most need autonomy.
66. Today people live more by virtue of what the system does FOR them or TO them
  than by virtue of what they do for themselves. And what they do for
    themselves is done more and more along channels laid down by the system.
    Opportunities tend to be those that the system provides, the opportunities
    must be exploited in accord with rules and regulations [13], and techniques
    prescribed by experts must be followed if there is to be a chance of
67. Thus the power process is disrupted in our society through a deficiency of
    real goals and a deficiency of autonomM
y in the pursuit of goals. But it is
    also disrupted because of those human drives that fall into group 3: the
    drives that one cannot adequately satisfy no matter how much effort one
    makes. One of these drives is the need for security. Our lives depend on
    decisions made by other people; we have no control over these decisions and
    usually we do not even know the people who make them. (
    in which relatively few people
Philip B. Heymann of Harvard Law School, quoted by Anthony Lewis,
    New York Times, April 21, 1995.) Our lives depend on whether safety
    standards at a nuclear power plant are properly maintained; on how much
    pesticide is allowed to get into our food or how much pollution into our
    air; on how skillful (or incompetent) our doctor is; whether we lose or get
    a job may depend on decisions made by government economists or corporation
    executives; and so forth. Most individuals are noM
t in a position to secure
    themselves against these threats to more [than] a very limited extent. The
s search for security is therefore frustrated, which leads to
    a sense of powerlessness.
68. It may be objected that primitive man is physically less secure than modern
    man, as is shown by his shorter life expectancy; hence modern man suffers
    from less, not more than the amount of insecurity that is normal for human
    beings. But psychological security does not closely corresM
    security. What makes us FEEL secure is not so much objective security as
    a sense of confidence in our ability to take care of ourselves. Primitive
    man, threatened by a fierce animal or by hunger, can fight in self-defense
    or travel in search of food. He has no certainty of success in these
    efforts, but he is by no means helpless against the things that threaten
    him. The modern individual on the other hand is threatened by many things
    against which he is helplessM
: nuclear accidents, carcinogens in food,
    environmental pollution, war, increasing taxes, invasion of his privacy by
    large organizations, nationwide social or economic phenomena that may
    disrupt his way of life.
69. It is true that primitive man is powerless against some of the things that
    threaten him; disease for example. But he can accept the risk of disease
    stoically. It is part of the nature of things, it is no one
    it is the fault of some imaginary, impersonal dM
emon. But threats to the
    modern individual tend to be MAN-MADE. They are not the results of chance
    but are IMPOSED on him by other persons whose decisions he, as an
    individual, is unable to influence. Consequently he feels frustrated,
    humiliated and angry.
70. Thus primitive man for the most part has his security in his own hands
    (either as an individual or as a member of a SMALL group) whereas the
    security of modern man is in the hands of persons or organizations that are
mote or too large for him to be able personally to influence them. So
s drive for security tends to fall into groups 1 and 3; in some
    areas (food, shelter etc.) his security is assured at the cost of only
    trivial effort, whereas in other areas he CANNOT attain security. (The
    foregoing greatly simplifies the real situation, but it does indicate in
    a rough, general way how the condition of modern man differs from that of
71. People have many transitory driveM
s or impulses that are necessarily
    frustrated in modern life, hence fall into group 3. One may become angry,
    but modern society cannot permit fighting. In many situations it does not
    even permit verbal aggression. When going somewhere one may be in a hurry,
    or one may be in a mood to travel slowly, but one generally has no choice
    but to move with the flow of traffic and obey the traffic signals. One may
s work in a different way, but usually one can work only
rding to the rules laid down by one
s employer. In many other ways as
    well, modern man is strapped down by a network of rules and regulations
    (explicit or implicit) that frustrate many of his impulses and thus
    interfere with the power process. Most of these regulations cannot be
    dispensed with, because they are necessary for the functioning of industrial
72. Modern society is in certain respects extremely permissive. In matters that
    are irrelevant to the functioning of the M
system we can generally do what we
    please. We can believe in any religion we like (as long as it does not
    encourage behavior that is dangerous to the system). We can go to bed with
    anyone we like (as long as we practice
). We can do anything we
    like as long as it is UNIMPORTANT. But in all IMPORTANT matters the system
    tends increasingly to regulate our behavior.
73. Behavior is regulated not only through explicit rules and not only by the
    government. Control is often exeM
rcised through indirect coercion or through
    psychological pressure or manipulation, and by organizations other than the
    government, or by the system as a whole. Most large organizations use some
    form of propaganda [14] to manipulate public attitudes or behavior.
    Propaganda is not limited to
 and advertisements, and sometimes
    it is not even consciously intended as propaganda by the people who make it.
    For instance, the content of entertainment programming is a powerful M
    propaganda. An example of indirect coercion: There is no law that says we
    have to go to work every day and follow our employer
s orders. Legally there
    is nothing to prevent us from going to live in the wild like primitive
    people or from going into business for ourselves. But in practice there is
    very little wild country left, and there is room in the economy for only
    a limited number of small business owners. Hence most of us can survive only
74. We suggest that modern man
s obsession with longevity, and with maintaining
    physical vigor and sexual attractiveness to an advanced age, is a symptom of
    unfulfillment resulting from deprivation with respect to the power process.
 also is such a symptom. So is the lack of interest in
    having children that is fairly common in modern society but almost
    unheard-of in primitive societies.
75. In primitive societies life is a succession of stages. The needs and
    purposes of one stage having been fulfilled, there is no particular
    reluctance about passing on to the next stage. A young man goes through the
    power process by becoming a hunter, hunting not for sport or for fulfillment
    but to get meat that is necessary for food. (In young women the process is
    more complex, with greater emphasis on social power; we won
    here.) This phase having been successfully passed through, the young man has
    no reluctance about settling down toM
 the responsibilities of raising
    a family. (In contrast, some modern people indefinitely postpone having
    children because they are too busy seeking some kind of
    suggest that the fulfillment they need is adequate experience of the power
with real goals instead of the artificial goals of surrogate
    activities.) Again, having successfully raised his children, going through
    the power process by providing them with the physical necessities, the
man feels that his work is done and he is prepared to accept old
    age (if he survives that long) and death. Many modern people, on the other
    hand, are disturbed by the prospect of physical deterioration and death, as
    is shown by the amount of effort they expend trying to maintain their
    physical condition, appearance and health. We argue that this is due to
    unfulfillment resulting from the fact that they have never put their
    physical powers to any practical use, have never gone through tM
    process using their bodies in a serious way. It is not the primitive man,
    who has used his body daily for practical purposes, who fears the
    deterioration of age, but the modern man, who has never had a practical use
    for his body beyond walking from his car to his house. It is the man whose
    need for the power process has been satisfied during his life who is best
    prepared to accept the end of that life.
76. In response to the arguments of this section someone will say,
    find a way to give people the opportunity to go through the power process.
    For such people the value of the opportunity is destroyed by the very fact
    that society gives it to them. What they need is to find or make their own
    opportunities. As long as the system GIVES them their opportunities it still
    has them on a leash. To attain autonomy they must get off that leash.
HOW SOME PEOPLE ADJUST
77. Not everyone in industrial-technological society suffers from psychological
roblems. Some people even profess to be quite satisfied with society as it
    is. We now discuss some of the reasons why people differ so greatly in their
    response to modern society.
78. First, there doubtless are differences in the strength of the drive for
    power. Individuals with a weak drive for power may have relatively little
    need to go through the power process, or at least relatively little need for
    autonomy in the power process. These are docile types who would have been
 plantation darkies in the Old South. (We don
t mean to sneer at the
 of the Old South. To their credit, most of the slaves
    were NOT content with their servitude. We do sneer at people who ARE content
    with servitude.)
79. Some people may have some exceptional drive, in pursuing which they satisfy
    their need for the power process. For example, those who have an unusually
    strong drive for social status may spend their whole lives climbing the
    status ladder withM
out ever getting bored with that game.
80. People vary in their susceptibility to advertising and marketing techniques.
    Some are so susceptible that, even if they make a great deal of money, they
    cannot satisfy their constant craving for the the shiny new toys that the
    marketing industry dangles before their eyes. So they always feel
    hard-pressed financially even if their income is large, and their cravings
81. Some people have low susceptibility to advertising and marketiM
    These are the people who aren
t interested in money. Material acquisition
    does not serve their need for the power process.
82. People who have medium susceptibility to advertising and marketing
    techniques are able to earn enough money to satisfy their craving for goods
    and services, but only at the cost of serious effort (putting in overtime,
    taking a second job, earning promotions, etc.). Thus material acquisition
    serves their need for the power process. But it does M
not necessarily follow
    that their need is fully satisfied. They may have insufficient autonomy in
    the power process (their work may consist of following orders) and some of
    their drives may be frustrated (e.g., security, aggression). (We are guilty
    of oversimplification in paragraphs 80- 82 because we have assumed that the
    desire for material acquisition is entirely a creation of the advertising
    and marketing industry. Of course it
s not that simple. [11]
83. Some people partly satiM
sfy their need for power by identifying themselves
    with a powerful organization or mass movement. An individual lacking goals
    or power joins a movement or an organization, adopts its goals as his own,
    then works toward those goals. When some of the goals are attained, the
    individual, even though his personal efforts have played only an
    insignificant part in the attainment of the goals, feels (through his
    identification with the movement or organization) as if he had gone through
he power process. This phenomenon was exploited by the fascists, nazis and
    communists. Our society uses it too, though less crudely. Example: Manuel
    Noriega was an irritant to the U.S. (goal: punish Noriega). The U.S. invaded
    Panama (effort) and punished Noriega (attainment of goal). Thus the U.S.
    went through the power process and many Americans, because of their
    identification with the U.S., experienced the power process vicariously.
    Hence the widespread public approval of the PanamaM
 invasion; it gave people
    a sense of power. [15] We see the same phenomenon in armies, corporations,
    political parties, humanitarian organizations, religious or ideological
    movements. In particular, leftist movements tend to attract people who are
    seeking to satisfy their need for power. But for most people identification
    with a large organization or a mass movement does not fully satisfy the need
84. Another way in which people satisfy their need for the power process is
    through surrogate activities. As we explained in paragraphs 38-40,
    a surrogate activity is an activity that is directed toward an artificial
    goal that the individual pursues for the sake of the
    gets from pursuing the goal, not because he needs to attain the goal itself.
    For instance, there is no practical motive for building enormous muscles,
    hitting a little ball into a hole or acquiring a complete series of postage
    stamps. Yet many people in our society M
devote themselves with passion to
    bodybuilding, golf or stamp-collecting. Some people are more
 than others, and therefore will more readily attach
    importance to a surrogate activity simply because the people around them
    treat it as important or because society tells them it is important. That is
    why some people get very serious about essentially trivial activities such
    as sports, or bridge, or chess, or arcane scholarly pursuits, whereas others
    who are more clM
ear-sighted never see these things as anything but the
    surrogate activities that they are, and consequently never attach enough
    importance to them to satisfy their need for the power process in that way.
    It only remains to point out that in many cases a person
    a living is also a surrogate activity. Not a PURE surrogate activity, since
    part of the motive for the activity is to gain the physical necessities and
    (for some people) social status and the luxuries that adveM
    want. But many people put into their work far more effort than is necessary
    to earn whatever money and status they require, and this extra effort
    constitutes a surrogate activity. This extra effort, together with the
    emotional investment that accompanies it, is one of the most potent forces
    acting toward the continual development and perfecting of the system, with
    negative consequences for individual freedom (see paragraph 131).
    Especially, for the most creativeM
 scientists and engineers, work tends to be
    largely a surrogate activity. This point is so important that it deserves
    a separate discussion, which we shall give in a moment (paragraphs 87-92).
85. In this section we have explained how many people in modern society do
    satisfy their need for the power process to a greater or lesser extent. But
    we think that for the majority of people the need for the power process is
    not fully satisfied. In the first place, those who have an insatiable driveM
    for status, or who get firmly
 on a surrogate activity, or who
    identify strongly enough with a movement or organization to satisfy their
    need for power in that way, are exceptional personalities. Others are not
    fully satisfied with surrogate activities or by identification with an
    organization (see paragraphs 41, 64). In the second place, too much control
    is imposed by the system through explicit regulation or through
    socialization, which results in a deficiency of auM
tonomy, and in frustration
    due to the impossibility of attaining certain goals and the necessity of
    restraining too many impulses.
86. But even if most people in industrial-technological society were well
    satisfied, we (FC) would still be opposed to that form of society, because
    (among other reasons) we consider it demeaning to fulfill one
    power process through surrogate activities or through identification with an
    organization, rather than through pursuit of real goaM
THE MOTIVES OF SCIENTISTS
87. Science and technology provide the most important examples of surrogate
    activities. Some scientists claim that they are motivated by
 But it is easy to see that neither of
    these can be the principal motive of most scientists. As for
    that notion is simply absurd. Most scientists work on highly specialized
    problems that are not the object of any normal curiosity. For example, is an
   astronomer, a mathematician or an entomologist curious about the properties
    of isopropyltrimethylmethane? Of course not. Only a chemist is curious about
    such a thing, and he is curious about it only because chemistry is his
    surrogate activity. Is the chemist curious about the appropriate
    classification of a new species of beetle? No. That question is of interest
    only to the entomologist, and he is interested in it only because entomology
    is his surrogate activity. If the chemist andM
 the entomologist had to exert
    themselves seriously to obtain the physical necessities, and if that effort
    exercised their abilities in an interesting way but in some nonscientific
    pursuit, then they wouldn
t give a damn about isopropyltrimethylmethane or
    the classification of beetles. Suppose that lack of funds for postgraduate
    education had led the chemist to become an insurance broker instead of
    a chemist. In that case he would have been very interested in insurance
ut would have cared nothing about isopropyltrimethylmethane. In any
    case it is not normal to put into the satisfaction of mere curiosity the
    amount of time and effort that scientists put into their work. The
 explanation for the scientists
t work any better. Some
    scientific work has no conceivable relation to the welfare of the human
most of archaeology or comparative linguistics M
for example. Some other
    areas of science present obviously dangerous possibilities. Yet scientists
    in these areas are just as enthusiastic about their work as those who
    develop vaccines or study air pollution. Consider the case of Dr. Edward
    Teller, who had an obvious emotional involvement in promoting nuclear power
    plants. Did this involvement stem from a desire to benefit humanity? If so,
t Dr. Teller get emotional about other
 such a humanitarian then why did he help to develop the H- bomb?
    As with many other scientific achievements, it is very much open to question
    whether nuclear power plants actually do benefit humanity. Does the cheap
    electricity outweigh the accumulating waste and the risk of accidents? Dr.
    Teller saw only one side of the question. Clearly his emotional involvement
    with nuclear power arose not from a desire to
    a personal fulfillment he got from his work M
and from seeing it put to
89. The same is true of scientists generally. With possible rare exceptions,
    their motive is neither curiosity nor a desire to benefit humanity but the
    need to go through the power process: to have a goal (a scientific problem
    to solve), to make an effort (research) and to attain the goal (solution of
    the problem.) Science is a surrogate activity because scientists work mainly
    for the fulfillment they get out of the work itself.
s not that simple. Other motives do play a role for many
    scientists. Money and status for example. Some scientists may be persons of
    the type who have an insatiable drive for status (see paragraph 79) and this
    may provide much of the motivation for their work. No doubt the majority of
    scientists, like the majority of the general population, are more or less
    susceptible to advertising and marketing techniques and need money to
    satisfy their craving for goods and services. Thus sciM
    surrogate activity. But it is in large part a surrogate activity.
91. Also, science and technology constitute a power mass movement, and many
    scientists gratify their need for power through identification with this
    mass movement (see paragraph 83).
92. Thus science marches on blindly, without regard to the real welfare of the
    human race or to any other standard, obedient only to the psychological
    needs of the scientists and of the government officials and corporation
   executives who provide the funds for research.
THE NATURE OF FREEDOM
93. We are going to argue that industrial-technological society cannot be
    reformed in such a way as to prevent it from progressively narrowing the
    sphere of human freedom. But, because
 is a word that can be
    interpreted in many ways, we must first make clear what kind of freedom we
    are concerned with.
 we mean the opportunity to go through the power process, with
    real goals not the arM
tificial goals of surrogate activities, and without
    interference, manipulation or supervision from anyone, especially from any
    large organization. Freedom means being in control (either as an individual
    or as a member of a SMALL group) of the life-and-death issues of one
    existence; food, clothing, shelter and defense against whatever threats
    there may be in one
s environment. Freedom means having power; not the power
    to control other people but the power to control the circumstanM
    own life. One does not have freedom if anyone else (especially a large
    organization) has power over one, no matter how benevolently, tolerantly and
    permissively that power may be exercised. It is important not to confuse
    freedom with mere permissiveness (see paragraph 72).
95. It is said that we live in a free society because we have a certain number
    of constitutionally guaranteed rights. But these are not as important as
    they seem. The degree of personal freedom that eM
xists in a society is
    determined more by the economic and technological structure of the society
    than by its laws or its form of government. [16] Most of the Indian nations
    of New England were monarchies, and many of the cities of the Italian
    Renaissance were controlled by dictators. But in reading about these
    societies one gets the impression that they allowed far more personal
    freedom than our society does. In part this was because they lacked
    efficient mechanisms for enforcing M
s will: There were no modern,
    well-organized police forces, no rapid long-distance communications, no
    surveillance cameras, no dossiers of information about the lives of average
    citizens. Hence it was relatively easy to evade control.
96. As for our constitutional rights, consider for example that of freedom of
    the press. We certainly don
t mean to knock that right; it is very important
    tool for limiting concentration of political power and for keeping those who
political power in line by publicly exposing any misbehavior on
    their part. But freedom of the press is of very little use to the average
    citizen as an individual. The mass media are mostly under the control of
    large organizations that are integrated into the system. Anyone who has
    a little money can have something printed, or can distribute it on the
    Internet or in some such way, but what he has to say will be swamped by the
    vast volume of material put out by the media, hence it will M
    practical effect. To make an impression on society with words is therefore
    almost impossible for most individuals and small groups. Take us (FC) for
    example. If we had never done anything violent and had submitted the present
    writings to a publisher, they probably would not have been accepted. If they
    had been been accepted and published, they probably would not have attracted
    many readers, because it
s more fun to watch the entertainment put out by
    the media than to reaM
d a sober essay. Even if these writings had had many
    readers, most of these readers would soon have forgotten what they had read
    as their minds were flooded by the mass of material to which the media
    expose them. In order to get our message before the public with some chance
    of making a lasting impression, we
ve had to kill people.
97. Constitutional rights are useful up to a point, but they do not serve to
    guarantee much more than what might be called the bourgeois conception of
eedom. According to the bourgeois conception, a
 man is essentially
    an element of a social machine and has only a certain set of prescribed and
    delimited freedoms; freedoms that are designed to serve the needs of the
    social machine more than those of the individual. Thus the bourgeois
 man has economic freedom because that promotes growth and progress;
    he has freedom of the press because public criticism restrains misbehavior
    by political leaders; he has a rightM
 to a fair trial because imprisonment at
    the whim of the powerful would be bad for the system. This was clearly the
    attitude of Simon Bolivar. To him, people deserved liberty only if they used
    it to promote progress (progress as conceived by the bourgeois). Other
    bourgeois thinkers have taken a similar view of freedom as a mere means to
    collective ends. Chester C. Tan,
Chinese Political Thought in the Twentieth
 page 202, explains the philosophy of the Kuomintang leader HM
An individual is granted rights because he is a member of society
    and his community life requires such rights. By community Hu meant the whole
    society of the nation.
 And on page 259 Tan states that according to Carsum
    Chang (Chang Chun-mai, head of the State Socialist Party in China) freedom
    had to be used in the interest of the state and of the people as a whole.
    But what kind of freedom does one have if one can use it only as someone
    else prescribes? FC
eption of freedom is not that of Bolivar, Hu,
    Chang or other bourgeois theorists. The trouble with such theorists is that
    they have made the development and application of social theories their
    surrogate activity. Consequently the theories are designed to serve the
    needs of the theorists more than the needs of any people who may be unlucky
    enough to live in a society on which the theories are imposed.
98. One more point to be made in this section: It should not be assumed that
n has enough freedom just because he SAYS he has enough. Freedom is
    restricted in part by psychological controls of which people are
    unconscious, and moreover many people
s ideas of what constitutes freedom
    are governed more by social convention than by their real needs. For
s likely that many leftists of the oversocialized type would say
    that most people, including themselves, are socialized too little rather
    than too much, yet the oversocialized leftist pays a heavy pM
    price for his high level of socialization.
SOME PRINCIPLES OF HISTORY
99. Think of history as being the sum of two components: an erratic component
    that consists of unpredictable events that follow no discernible pattern,
    and a regular component that consists of long-term historical trends. Here
    we are concerned with the long-term trends.
100. FIRST PRINCIPLE. If a SMALL change is made that affects a long-term
     historical trend, then the effect of that change will almost alwM
the trend will soon revert to its original state. (Example:
     A reform movement designed to clean up political corruption in a society
     rarely has more than a short-term effect; sooner or later the reformers
     relax and corruption creeps back in. The level of political corruption in
     a given society tends to remain constant, or to change only slowly with the
     evolution of the society. Normally, a political cleanup will be permanent
     only if accompanied by widespM
read social changes; a SMALL change in the
t be enough.) If a small change in a long-term historical trend
     appears to be permanent, it is only because the change acts in the
     direction in which the trend is already moving, so that the trend is not
     altered by only pushed a step ahead.
101. The first principle is almost a tautology. If a trend were not stable with
     respect to small changes, it would wander at random rather than following
     a definite direction; in other M
words it would not be a long- term trend at
102. SECOND PRINCIPLE. If a change is made that is sufficiently large to alter
     permanently a long-term historical trend, then it will alter the society as
     a whole. In other words, a society is a system in which all parts are
     interrelated, and you can
t permanently change any important part without
     changing all other parts as well.
103. THIRD PRINCIPLE. If a change is made that is large enough to alter
     permanently a long-term trM
end, then the consequences for the society as
     a whole cannot be predicted in advance. (Unless various other societies
     have passed through the same change and have all experienced the same
     consequences, in which case one can predict on empirical grounds that
     another society that passes through the same change will be like to
     experience similar consequences.)
104. FOURTH PRINCIPLE. A new kind of society cannot be designed on paper. That
     is, you cannot plan out a new form of societM
y in advance, then set it up
     and expect it to function as it was designed to do.
105. The third and fourth principles result from the complexity of human
     societies. A change in human behavior will affect the economy of a society
     and its physical environment; the economy will affect the environment and
     vice versa, and the changes in the economy and the environment will affect
     human behavior in complex, unpredictable ways; and so forth. The network of
     causes and effects is far tooM
 complex to be untangled and understood.
106. FIFTH PRINCIPLE. People do not consciously and rationally choose the form
     of their society. Societies develop through processes of social evolution
     that are not under rational human control.
107. The fifth principle is a consequence of the other four.
108. To illustrate: By the first principle, generally speaking an attempt at
     social reform either acts in the direction in which the society is
     developing anyway (so that it merely accelerates a M
change that would have
     occurred in any case) or else it has only a transitory effect, so that the
     society soon slips back into its old groove. To make a lasting change in
     the direction of development of any important aspect of a society, reform
     is insufficient and revolution is required. (A revolution does not
     necessarily involve an armed uprising or the overthrow of a government.) By
     the second principle, a revolution never changes only one aspect of
     a society, it changes M
the whole society; and by the third principle changes
     occur that were never expected or desired by the revolutionaries. By the
     fourth principle, when revolutionaries or utopians set up a new kind of
     society, it never works out as planned.
109. The American Revolution does not provide a counterexample. The American
 was not a revolution in our sense of the word, but a war of
     independence followed by a rather far-reaching political reform. The
     Founding Fathers did M
not change the direction of development of American
     society, nor did they aspire to do so. They only freed the development of
     American society from the retarding effect of British rule. Their political
     reform did not change any basic trend, but only pushed American political
     culture along its natural direction of development. British society, of
     which American society was an offshoot, had been moving for a long time in
     the direction of representative democracy. And prior to the WM
     Independence the Americans were already practicing a significant degree of
     representative democracy in the colonial assemblies. The political system
     established by the Constitution was modeled on the British system and on
     the colonial assemblies. With major alteration, to be sure
     doubt that the Founding Fathers took a very important step. But it was
     a step along the road that English-speaking world was already traveling.
     The proof is that Britain and allM
 of its colonies that were populated
     predominantly by people of British descent ended up with systems of
     representative democracy essentially similar to that of the United States.
     If the Founding Fathers had lost their nerve and declined to sign the
     Declaration of Independence, our way of life today would not have been
     significantly different. Maybe we would have had somewhat closer ties to
     Britain, and would have had a Parliament and Prime Minister instead of
d President. No big deal. Thus the American Revolution
     provides not a counterexample to our principles but a good illustration of
110. Still, one has to use common sense in applying the principles. They are
     expressed in imprecise language that allows latitude for interpretation,
     and exceptions to them can be found. So we present these principles not as
     inviolable laws but as rules of thumb, or guides to thinking, that may
     provide a partial antidote to naive ideas about theM
 future of society. The
     principles should be borne constantly in mind, and whenever one reaches
     a conclusion that conflicts with them one should carefully reexamine one
     thinking and retain the conclusion only if one has good, solid reasons for
    INDUSTRIAL-TECHNOLOGICAL SOCIETY CANNOT BE REFORMED
111. The foregoing principles help to show how hopelessly difficult it would be
     to reform the industrial system in such a way as to prevent it from
     progressively narrowM
ing our sphere of freedom. There has been a consistent
     tendency, going back at least to the Industrial Revolution for technology
     to strengthen the system at a high cost in individual freedom and local
     autonomy. Hence any change designed to protect freedom from technology
     would be contrary to a fundamental trend in the development of our society.
     Consequently, such a change either would be a transitory one
     by the tide of history
or, if large enough to be permanentM
     nature of our whole society. This by the first and second principles.
     Moreover, since society would be altered in a way that could not be
     predicted in advance (third principle) there would be great risk. Changes
     large enough to make a lasting difference in favor of freedom would not be
     initiated because it would be realized that they would gravely disrupt the
     system. So any attempts at reform would be too timid to be effective. Even
     if changes large enough M
to make a lasting difference were initiated, they
     would be retracted when their disruptive effects became apparent. Thus,
     permanent changes in favor of freedom could be brought about only by
     persons prepared to accept radical, dangerous and unpredictable alteration
     of the entire system. In other words by revolutionaries, not reformers.
112. People anxious to rescue freedom without sacrificing the supposed benefits
     of technology will suggest naive schemes for some new form of society tM
     would reconcile freedom with technology. Apart from the fact that people
     who make such suggestions seldom propose any practical means by which the
     new form of society could be set up in the first place, it follows from the
     fourth principle that even if the new form of society could be once
     established, it either would collapse or would give results very different
     from those expected.
113. So even on very general grounds it seems highly improbable that any way of
ng society could be found that would reconcile freedom with modern
     technology. In the next few sections we will give more specific reasons for
     concluding that freedom and technological progress are incompatible.
RESTRICTION OF FREEDOM IS UNAVOIDABLE IN INDUSTRIAL SOCIETY
114. As explained in paragraphs 65-67, 70-73, modern man is strapped down by
     a network of rules and regulations, and his fate depends on the actions of
     persons remote from him whose decisions he cannot influence. This is nM
     accidental or a result of the arbitrariness of arrogant bureaucrats. It is
     necessary and inevitable in any technologically advanced society. The
     system HAS TO regulate human behavior closely in order to function. At work
     people have to do what they are told to do, otherwise production would be
     thrown into chaos. Bureaucracies HAVE TO be run according to rigid rules.
     To allow any substantial personal discretion to lower-level bureaucrats
     would disrupt the system and lead M
to charges of unfairness due to
     differences in the way individual bureaucrats exercised their discretion.
     It is true that some restrictions on our freedom could be eliminated, but
     GENERALLY SPEAKING the regulation of our lives by large organizations is
     necessary for the functioning of industrial-technological society. The
     result is a sense of powerlessness on the part of the average person. It
     may be, however, that formal regulations will tend increasingly to be
 psychological tools that make us want to do what the system
     requires of us. (Propaganda [14], educational techniques,
     programs, etc.)
115. The system HAS TO force people to behave in ways that are increasingly
     remote from the natural pattern of human behavior. For example, the system
     needs scientists, mathematicians and engineers. It can
     them. So heavy pressure is put on children to excel in these fields. It
t natural for an adolesM
cent human being to spend the bulk of his time
     sitting at a desk absorbed in study. A normal adolescent wants to spend his
     time in active contact with the real world. Among primitive peoples the
     things that children are trained to do tend to be in reasonable harmony
     with natural human impulses. Among the American Indians, for example, boys
     were trained in active outdoor pursuits
just the sort of thing that boys
     like. But in our society children are pushed into studying technicaM
     subjects, which most do grudgingly.
116. Because of the constant pressure that the system exerts to modify human
     behavior, there is a gradual increase in the number of people who cannot or
     will not adjust to society
s requirements: welfare leeches, youth-gang
     members, cultists, anti-government rebels, radical environmentalist
     saboteurs, dropouts and resisters of various kinds.
117. In any technologically advanced society the individual
     on decisions thatM
 he personally cannot influence to any great extent.
     A technological society cannot be broken down into small, autonomous
     communities, because production depends on the cooperation of very large
     numbers of people and machines. Such a society MUST be highly organized and
     decisions HAVE TO be made that affect very large numbers of people. When
     a decision affects, say, a million people, then each of the affected
     individuals has, on the average, only a one-millionth share in making tM
     decision. What usually happens in practice is that decisions are made by
     public officials or corporation executives, or by technical specialists,
     but even when the public votes on a decision the number of voters
     ordinarily is too large for the vote of any one individual to be
     significant. [17] Thus most individuals are unable to influence measurably
     the major decisions that affect their lives. There is no conceivable way to
     remedy this in a technologically advanced socieM
ty. The system tries to
 this problem by using propaganda to make people WANT the decisions
     that have been made for them, but even if this
     successful in making people feel better, it would be demeaning.
118. Conservatives and some others advocate more
     communities once did have autonomy, but such autonomy becomes less and less
     possible as local communities become more enmeshed with and dependent on
systems like public utilities, computer networks, highway
     systems, the mass communications media, the modern health care system. Also
     operating against autonomy is the fact that technology applied in one
     location often affects people at other locations far way. Thus pesticide or
     chemical use near a creek may contaminate the water supply hundreds of
     miles downstream, and the greenhouse effect affects the whole world.
119. The system does not and cannot exist to satisfy human needs. InsM
     human behavior that has to be modified to fit the needs of the system. This
     has nothing to do with the political or social ideology that may pretend to
     guide the technological system. It is the fault of technology, because the
     system is guided not by ideology but by technical necessity. [18] Of course
     the system does satisfy many human needs, but generally speaking it does
     this only to the extend that it is to the advantage of the system to do it.
     It is the needM
s of the system that are paramount, not those of the human
     being. For example, the system provides people with food because the system
t function if everyone starved; it attends to people
     needs whenever it can CONVENIENTLY do so, because it couldn
     too many people became depressed or rebellious. But the system, for good,
     solid, practical reasons, must exert constant pressure on people to mold
     their behavior to the needs of the system. To M
much waste accumulating? The
     government, the media, the educational system, environmentalists, everyone
     inundates us with a mass of propaganda about recycling. Need more technical
     personnel? A chorus of voices exhorts kids to study science. No one stops
     to ask whether it is inhumane to force adolescents to spend the bulk of
     their time studying subjects most of them hate. When skilled workers are
     put out of a job by technical advances and have to undergo
 one asks whether it is humiliating for them to be pushed around in this
     way. It is simply taken for granted that everyone must bow to technical
     necessity. and for good reason: If human needs were put before technical
     necessity there would be economic problems, unemployment, shortages or
     worse. The concept of
 in our society is defined largely by
     the extent to which an individual behaves in accord with the needs of the
     system and does so without showing signs oM
120. Efforts to make room for a sense of purpose and for autonomy within the
     system are no better than a joke. For example, one company, instead of
     having each of its employees assemble only one section of a catalogue, had
     each assemble a whole catalogue, and this was supposed to give them a sense
     of purpose and achievement. Some companies have tried to give their
     employees more autonomy in their work, but for practical reasons this
     usually can be done only to a very lM
imited extent, and in any case
     employees are never given autonomy as to ultimate goals
     efforts can never be directed toward goals that they select personally, but
     only toward their employer
s goals, such as the survival and growth of the
     company. Any company would soon go out of business if it permitted its
     employees to act otherwise. Similarly, in any enterprise within a socialist
     system, workers must direct their efforts toward the goals of the
enterprise, otherwise the enterprise will not serve its purpose as part of
     the system. Once again, for purely technical reasons it is not possible for
     most individuals or small groups to have much autonomy in industrial
     society. Even the small-business owner commonly has only limited autonomy.
     Apart from the necessity of government regulation, he is restricted by the
     fact that he must fit into the economic system and conform to its
     requirements. For instance, when someone developM
s a new technology, the
     small-business person often has to use that technology whether he wants to
     or not, in order to remain competitive.
 PARTS OF TECHNOLOGY CANNOT BE SEPARATED FROM THE
121. A further reason why industrial society cannot be reformed in favor of
     freedom is that modern technology is a unified system in which all parts
     are dependent on one another. You can
     technology and retain only the
rts. Take modern medicine, for
     example. Progress in medical science depends on progress in chemistry,
     physics, biology, computer science and other fields. Advanced medical
     treatments require expensive, high-tech equipment that can be made
     available only by a technologically progressive, economically rich society.
     Clearly you can
t have much progress in medicine without the whole
     technological system and everything that goes with it.
122. Even if medical progress could be maintM
ained without the rest of the
     technological system, it would by itself bring certain evils. Suppose for
     example that a cure for diabetes is discovered. People with a genetic
     tendency to diabetes will then be able to survive and reproduce as well as
     anyone else. Natural selection against genes for diabetes will cease and
     such genes will spread throughout the population. (This may be occurring to
     some extent already, since diabetes, while not curable, can be controlled
h use of insulin.) The same thing will happen with many other
     diseases susceptibility to which is affected by genetic degradation of the
     population. The only solution will be some sort of eugenics program or
     extensive genetic engineering of human beings, so that man in the future
     will no longer be a creation of nature, or of chance, or of God (depending
     on your religious or philosophical opinions), but a manufactured product.
123. If you think that big government interferes in your liM
fe too much NOW, just
     wait till the government starts regulating the genetic constitution of your
     children. Such regulation will inevitably follow the introduction of
     genetic engineering of human beings, because the consequences of
     unregulated genetic engineering would be disastrous. [19]
124. The usual response to such concerns is to talk about
     a code of ethics would not serve to protect freedom in the face of medical
     progress; it would only make matteM
rs worse. A code of ethics applicable to
     genetic engineering would be in effect a means of regulating the genetic
     constitution of human beings. Somebody (probably the upper-middle class,
     mostly) would decide that such and such applications of genetic engineering
 and others were not, so that in effect they would be
     imposing their own values on the genetic constitution of the population at
     large. Even if a code of ethics were chosen on a completely democratic
   basis, the majority would be imposing their own values on any minorities
     who might have a different idea of what constituted an
     genetic engineering. The only code of ethics that would truly protect
     freedom would be one that prohibited ANY genetic engineering of human
     beings, and you can be sure that no such code will ever be applied in
     a technological society. No code that reduced genetic engineering to
     a minor role could stand up for long, because the temM
ptation presented by
     the immense power of biotechnology would be irresistible, especially since
     to the majority of people many of its applications will seem obviously and
     unequivocally good (eliminating physical and mental diseases, giving people
     the abilities they need to get along in today
s world). Inevitably, genetic
     engineering will be used extensively, but only in ways consistent with the
     needs of the industrial- technological system. [20]
TECHNOLOGY IS A MORE POWERFUL SM
OCIAL FORCE THAN THE ASPIRATION FOR FREEDOM
125. It is not possible to make a LASTING compromise between technology and
     freedom, because technology is by far the more powerful social force and
     continually encroaches on freedom through REPEATED compromises. Imagine the
     case of two neighbors, each of whom at the outset owns the same amount of
     land, but one of whom is more powerful than the other. The powerful one
     demands a piece of the other
s land. The weak one refuses. The powerful M
s compromise. Give me half of what I asked.
     has little choice but to give in. Some time later the powerful neighbor
     demands another piece of land, again there is a compromise, and so forth.
     By forcing a long series of compromises on the weaker man, the powerful one
     eventually gets all of his land. So it goes in the conflict between
     technology and freedom.
126. Let us explain why technology is a more powerful social force than the
127. A technological advance that appears not to threaten freedom often turns
     out to threaten it very seriously later on. For example, consider motorized
     transport. A walking man formerly could go where he pleased, go at his own
     pace without observing any traffic regulations, and was independent of
     technological support-systems. When motor vehicles were introduced they
     appeared to increase man
s freedom. They took no freedom away from the
     walking man, no onM
e had to have an automobile if he didn
     anyone who did choose to buy an automobile could travel much faster and
     farther than a walking man. But the introduction of motorized transport
     soon changed society in such a way as to restrict greatly man
     locomotion. When automobiles became numerous, it became necessary to
     regulate their use extensively. In a car, especially in densely populated
     areas, one cannot just go where one likes at one
     is governed by the flow of traffic and by various traffic laws. One is tied
     down by various obligations: license requirements, driver test, renewing
     registration, insurance, maintenance required for safety, monthly payments
     on purchase price. Moreover, the use of motorized transport is no longer
     optional. Since the introduction of motorized transport the arrangement of
     our cities has changed in such a way that the majority of people no longer
     live within walM
king distance of their place of employment, shopping areas
     and recreational opportunities, so that they HAVE TO depend on the
     automobile for transportation. Or else they must use public transportation,
     in which case they have even less control over their own movement than when
     driving a car. Even the walker
s freedom is now greatly restricted. In the
     city he continually has to stop to wait for traffic lights that are
     designed mainly to serve auto traffic. In the country, motor M
     it dangerous and unpleasant to walk along the highway. (Note this important
     point that we have just illustrated with the case of motorized transport:
     When a new item of technology is introduced as an option that an individual
     can accept or not as he chooses, it does not necessarily REMAIN optional.
     In many cases the new technology changes society in such a way that people
     eventually find themselves FORCED to use it.)
128. While technological progress AS A WHOLE conM
tinually narrows our sphere of
     freedom, each new technical advance CONSIDERED BY ITSELF appears to be
     desirable. Electricity, indoor plumbing, rapid long-distance communications
     ... how could one argue against any of these things, or against any other
     of the innumerable technical advances that have made modern society? It
     would have been absurd to resist the introduction of the telephone, for
     example. It offered many advantages and no disadvantages. Yet, as we
paragraphs 59-76, all these technical advances taken together
     have created a world in which the average man
s fate is no longer in his
     own hands or in the hands of his neighbors and friends, but in those of
     politicians, corporation executives and remote, anonymous technicians and
     bureaucrats whom he as an individual has no power to influence. [21] The
     same process will continue in the future. Take genetic engineering, for
     example. Few people will resist the introduction of a geM
     that eliminates a hereditary disease. It does no apparent harm and prevents
     much suffering. Yet a large number of genetic improvements taken together
     will make the human being into an engineered product rather than a free
     creation of chance (or of God, or whatever, depending on your religious
129. Another reason why technology is such a powerful social force is that,
     within the context of a given society, technological progress marches in
 direction; it can never be reversed. Once a technical innovation
     has been introduced, people usually become dependent on it, so that they
     can never again do without it, unless it is replaced by some still more
     advanced innovation. Not only do people become dependent as individuals on
     a new item of technology, but, even more, the system as a whole becomes
     dependent on it. (Imagine what would happen to the system today if
     computers, for example, were eliminated.) Thus the system cM
     one direction, toward greater technologization. Technology repeatedly
     forces freedom to take a step back, but technology can never take a step
short of the overthrow of the whole technological system.
130. Technology advances with great rapidity and threatens freedom at many
     different points at the same time (crowding, rules and regulations,
     increasing dependence of individuals on large organizations, propaganda and
     other psychological techniques, genetic M
engineering, invasion of privacy
     through surveillance devices and computers, etc.). To hold back any ONE of
     the threats to freedom would require a long and difficult social struggle.
     Those who want to protect freedom are overwhelmed by the sheer number of
     new attacks and the rapidity with which they develop, hence they become
     apathetic and no longer resist. To fight each of the threats separately
     would be futile. Success can be hoped for only by fighting the
     technological sM
ystem as a whole; but that is revolution, not reform.
131. Technicians (we use this term in its broad sense to describe all those who
     perform a specialized task that requires training) tend to be so involved
     in their work (their surrogate activity) that when a conflict arises
     between their technical work and freedom, they almost always decide in
     favor of their technical work. This is obvious in the case of scientists,
     but it also appears elsewhere: Educators, humanitarian groups, consM
     organizations do not hesitate to use propaganda or other psychological
     techniques to help them achieve their laudable ends. Corporations and
     government agencies, when they find it useful, do not hesitate to collect
     information about individuals without regard to their privacy. Law
     enforcement agencies are frequently inconvenienced by the constitutional
     rights of suspects and often of completely innocent persons, and they do
     whatever they can do legally (or sometimeM
s illegally) to restrict or
     circumvent those rights. Most of these educators, government officials and
     law officers believe in freedom, privacy and constitutional rights, but
     when these conflict with their work, they usually feel that their work is
     more important.
132. It is well known that people generally work better and more persistently
     when striving for a reward than when attempting to avoid a punishment or
     negative outcome. Scientists and other technicians are motivated maM
     the rewards they get through their work. But those who oppose technological
     invasions of freedom are working to avoid a negative outcome, consequently
     there are few who work persistently and well at this discouraging task. If
     reformers ever achieved a signal victory that seemed to set up a solid
     barrier against further erosion of freedom through technical progress, most
     would tend to relax and turn their attention to more agreeable pursuits.
     But the scientists wouldM
 remain busy in their laboratories, and technology
     as it progresses would find ways, in spite of any barriers, to exert more
     and more control over individuals and make them always more dependent on
133. No social arrangements, whether laws, institutions, customs or ethical
     codes, can provide permanent protection against technology. History shows
     that all social arrangements are transitory; they all change or break down
     eventually. But technological advances are permaM
nent within the context of
     a given civilization. Suppose for example that it were possible to arrive
     at some social arrangements that would prevent genetic engineering from
     being applied to human beings, or prevent it from being applied in such
     a way as to threaten freedom and dignity. Still, the technology would
     remain waiting. Sooner or later the social arrangement would break down.
     Probably sooner, given the pace of change in our society. Then genetic
     engineering would bM
egin to invade our sphere of freedom, and this invasion
     would be irreversible (short of a breakdown of technological civilization
     itself). Any illusions about achieving anything permanent through social
     arrangements should be dispelled by what is currently happening with
     environmental legislation. A few years ago its seemed that there were
     secure legal barriers preventing at least SOME of the worst forms of
     environmental degradation. A change in the political wind, and those
  barriers begin to crumble.
134. For all of the foregoing reasons, technology is a more powerful social
     force than the aspiration for freedom. But this statement requires an
     important qualification. It appears that during the next several decades
     the industrial-technological system will be undergoing severe stresses due
     to economic and environmental problems, and especially due to problems of
     human behavior (alienation, rebellion, hostility, a variety of social and
l difficulties). We hope that the stresses through which the
     system is likely to pass will cause it to break down, or at least will
     weaken it sufficiently so that a revolution against it becomes possible. If
     such a revolution occurs and is successful, then at that particular moment
     the aspiration for freedom will have proved more powerful than technology.
135. In paragraph 125 we used an analogy of a weak neighbor who is left
     destitute by a strong neighbor who takes all his land by foM
     a series of compromises. But suppose now that the strong neighbor gets
     sick, so that he is unable to defend himself. The weak neighbor can force
     the strong one to give him his land back, or he can kill him. If he lets
     the strong man survive and only forces him to give the land back, he is
     a fool, because when the strong man gets well he will again take all the
     land for himself. The only sensible alternative for the weaker man is to
     kill the strong one while he M
has the chance. In the same way, while the
     industrial system is sick we must destroy it. If we compromise with it and
     let it recover from its sickness, it will eventually wipe out all of our
SIMPLER SOCIAL PROBLEMS HAVE PROVED INTRACTABLE
136. If anyone still imagines that it would be possible to reform the system in
     such a way as to protect freedom from technology, let him consider how
     clumsily and for the most part unsuccessfully our society has dealt with
al problems that are far more simple and straightforward. Among
     other things, the system has failed to stop environmental degradation,
     political corruption, drug trafficking or domestic abuse.
137. Take our environmental problems, for example. Here the conflict of values
     is straightforward: economic expedience now versus saving some of our
     natural resources for our grandchildren. [22] But on this subject we get
     only a lot of blather and obfuscation from the people who have power, and M
     nothing like a clear, consistent line of action, and we keep on piling up
     environmental problems that our grandchildren will have to live with.
     Attempts to resolve the environmental issue consist of struggles and
     compromises between different factions, some of which are ascendant at one
     moment, others at another moment. The line of struggle changes with the
     shifting currents of public opinion. This is not a rational process, nor is
     it one that is likely to lead to a timely M
and successful solution to the
     problem. Major social problems, if they get
 at all, are rarely or
     never solved through any rational, comprehensive plan. They just work
     themselves out through a process in which various competing groups pursuing
     their own (usually short- term) self-interest [23] arrive (mainly by luck)
     at some more or less stable modus vivendi. In fact, the principles we
     formulated in paragraphs 100-106 make it seem doubtful that rational,
rm social planning can EVER be successful.
138. Thus it is clear that the human race has at best a very limited capacity
     for solving even relatively straightforward social problems. How then is it
     going to solve the far more difficult and subtle problem of reconciling
     freedom with technology? Technology presents clear-cut material advantages,
     whereas freedom is an abstraction that means different things to different
     people, and its loss is easily obscured by propaganda and fancy talk.M
139. And note this important difference: It is conceivable that our
     environmental problems (for example) may some day be settled through
     a rational, comprehensive plan, but if this happens it will be only because
     it is in the long-term interest of the system to solve these problems. But
     it is NOT in the interest of the system to preserve freedom or small-group
     autonomy. On the contrary, it is in the interest of the system to bring
     human behavior under control to the greatest poM
ssible extent. [24] Thus,
     while practical considerations may eventually force the system to take
     a rational, prudent approach to environmental problems, equally practical
     considerations will force the system to regulate human behavior ever more
     closely (preferably by indirect means that will disguise the encroachment
     on freedom). This isn
t just our opinion. Eminent social scientists (e.g.
     James Q. Wilson) have stressed the importance of
REVOLUTION IS EASIER THAN REFORM
140. We hope we have convinced the reader that the system cannot be reformed in
     such a way as to reconcile freedom with technology. The only way out is to
     dispense with the industrial-technological system altogether. This implies
     revolution, not necessarily an armed uprising, but certainly a radical and
     fundamental change in the nature of society.
141. People tend to assume that because a revolution involves a much greater
     change than reformM
 does, it is more difficult to bring about than reform
     is. Actually, under certain circumstances revolution is much easier than
     reform. The reason is that a revolutionary movement can inspire an
     intensity of commitment that a reform movement cannot inspire. A reform
     movement merely offers to solve a particular social problem.
     A revolutionary movement offers to solve all problems at one stroke and
     create a whole new world; it provides the kind of ideal for which people
take great risks and make great sacrifices. For this reasons it would
     be much easier to overthrow the whole technological system than to put
     effective, permanent restraints on the development or application of any
     one segment of technology, such as genetic engineering, for example. Not
     many people will devote themselves with single-minded passion to imposing
     and maintaining restraints on genetic engineering, but under suitable
     conditions large numbers of people may devote themselM
ves passionately to
     a revolution against the industrial-technological system. As we noted in
     paragraph 132, reformers seeking to limit certain aspects of technology
     would be working to avoid a negative outcome. But revolutionaries work to
     gain a powerful reward
fulfillment of their revolutionary vision
     therefore work harder and more persistently than reformers do.
142. Reform is always restrained by the fear of painful consequences if changes
     go too far. But once a revolM
utionary fever has taken hold of a society,
     people are willing to undergo unlimited hardships for the sake of their
     revolution. This was clearly shown in the French and Russian Revolutions.
     It may be that in such cases only a minority of the population is really
     committed to the revolution, but this minority is sufficiently large and
     active so that it becomes the dominant force in society. We will have more
     to say about revolution in paragraphs 180-205.
CONTROL OF HUMAN BEHAVIORM
143. Since the beginning of civilization, organized societies have had to put
     pressures on human beings of the sake of the functioning of the social
     organism. The kinds of pressures vary greatly from one society to another.
     Some of the pressures are physical (poor diet, excessive labor,
     environmental pollution), some are psychological (noise, crowding, forcing
     human behavior into the mold that society requires). In the past, human
     nature has been approximately constant, or at aM
ny rate has varied only
     within certain bounds. Consequently, societies have been able to push
     people only up to certain limits. When the limit of human endurance has
     been passed, things start going wrong: rebellion, or crime, or corruption,
     or evasion of work, or depression and other mental problems, or an elevated
     death rate, or a declining birth rate or something else, so that either the
     society breaks down, or its functioning becomes too inefficient and it is
 gradually, through conquest, attrition or evolution) replaced
     by some more efficient form of society. [25]
144. Thus human nature has in the past put certain limits on the development of
     societies. People could be pushed only so far and no farther. But today
     this may be changing, because modern technology is developing ways of
     modifying human beings.
145. Imagine a society that subjects people to conditions that make them
     terribly unhappy, then gives them drugs to take away their unM
     Science fiction? It is already happening to some extent in our own society.
     It is well known that the rate of clinical depression has been greatly
     increasing in recent decades. We believe that this is due to disruption of
     the power process, as explained in paragraphs 59-76. But even if we are
     wrong, the increasing rate of depression is certainly the result of SOME
     conditions that exist in today
s society. Instead of removing the
     conditions that make people deprM
essed, modern society gives them
     antidepressant drugs. In effect, antidepressants are a means of modifying
s internal state in such a way as to enable him to tolerate
     social conditions that he would otherwise find intolerable. (Yes, we know
     that depression is often of purely genetic origin. We are referring here to
     those cases in which environment plays the predominant role.)
146. Drugs that affect the mind are only one example of the new methods of
uman behavior that modern society is developing. Let us look
     at some of the other methods.
147. To start with, there are the techniques of surveillance. Hidden video
     cameras are now used in most stores and in many other places, computers are
     used to collect and process vast amounts of information about individuals.
     Information so obtained greatly increases the effectiveness of physical
     coercion (i.e., law enforcement). [26] Then there are the methods of
     propaganda, for which theM
 mass communication media provide effective
     vehicles. Efficient techniques have been developed for winning elections,
     selling products, influencing public opinion. The entertainment industry
     serves as an important psychological tool of the system, possibly even when
     it is dishing out large amounts of sex and violence. Entertainment provides
     modern man with an essential means of escape. While absorbed in television,
     videos, etc., he can forget stress, anxiety, frustration, dissatiM
     Many primitive peoples, when they don
t have work to do, are quite content
     to sit for hours at a time doing nothing at all, because they are at peace
     with themselves and their world. But most modern people must be constantly
     occupied or entertained, otherwise they get
     fidgety, uneasy, irritable.
148. Other techniques strike deeper than the foregoing. Education is no longer
     a simple affair of paddling a kid
s behind when he doesn
     and patting him on the head when he does know them. It is becoming
     a scientific technique for controlling the child
s development. Sylvan
     Learning Centers, for example, have had great success in motivating
     children to study, and psychological techniques are also used with more or
     less success in many conventional schools.
 techniques that are
     taught to parents are designed to make children accept fundamental values
     of the system and behave in wM
ays that the system finds desirable.
 techniques, psychotherapy and so forth are
     ostensibly designed to benefit individuals, but in practice they usually
     serve as methods for inducing individuals to think and behave as the system
     requires. (There is no contradiction here; an individual whose attitudes or
     behavior bring him into conflict with the system is up against a force that
     is too powerful for him to conquer or escape from, henM
     suffer from stress, frustration, defeat. His path will be much easier if he
     thinks and behaves as the system requires. In that sense the system is
     acting for the benefit of the individual when it brainwashes him into
     conformity.) Child abuse in its gross and obvious forms is disapproved in
     most if not all cultures. Tormenting a child for a trivial reason or no
     reason at all is something that appalls almost everyone. But many
     psychologists interpret the coM
ncept of abuse much more broadly. Is
     spanking, when used as part of a rational and consistent system of
     discipline, a form of abuse? The question will ultimately be decided by
     whether or not spanking tends to produce behavior that makes a person fit
     in well with the existing system of society. In practice, the word
     tends to be interpreted to include any method of child-rearing that
     produces behavior inconvenient for the system. Thus, when they go beyond
ention of obvious, senseless cruelty, programs for preventing
 are directed toward the control of human behavior on behalf
149. Presumably, research will continue to increase the effectiveness of
     psychological techniques for controlling human behavior. But we think it is
     unlikely that psychological techniques alone will be sufficient to adjust
     human beings to the kind of society that technology is creating. Biological
     methods probably will have toM
 be used. We have already mentioned the use of
     drugs in this connection. Neurology may provide other avenues for modifying
     the human mind. Genetic engineering of human beings is already beginning to
     occur in the form of
 and there is no reason to assume that
     such methods will not eventually be used to modify those aspects of the
     body that affect mental functioning.
150. As we mentioned in paragraph 134, industrial society seems likely to be
     entering a period oM
f severe stress, due in part to problems of human
     behavior and in part to economic and environmental problems. And
     a considerable proportion of the system
s economic and environmental
     problems result from the way human beings behave. Alienation, low
     self-esteem, depression, hostility, rebellion; children who won
     youth gangs, illegal drug use, rape, child abuse, other crimes, unsafe sex,
     teen pregnancy, population growth, political corruption, race hatred,
c rivalry, bitter ideological conflict (e.g., pro-choice vs. pro-
     life), political extremism, terrorism, sabotage, anti-government groups,
     hate groups. All these threaten the very survival of the system. The system
     will therefore be FORCED to use every practical means of controlling human
151. The social disruption that we see today is certainly not the result of mere
     chance. It can only be a result of the conditions of life that the system
     imposes on people. (We have M
argued that the most important of these
     conditions is disruption of the power process.) If the systems succeeds in
     imposing sufficient control over human behavior to assure its own survival,
     a new watershed in human history will have been passed. Whereas formerly
     the limits of human endurance have imposed limits on the development of
     societies (as we explained in paragraphs 143, 144),
     industrial-technological society will be able to pass those limits by
     modifying human beinM
gs, whether by psychological methods or biological
     methods or both. In the future, social systems will not be adjusted to suit
     the needs of human beings. Instead, human being will be adjusted to suit
     the needs of the system. [27]
152. Generally speaking, technological control over human behavior will probably
     not be introduced with a totalitarian intention or even through a conscious
     desire to restrict human freedom. [28] Each new step in the assertion of
     control over the human M
mind will be taken as a rational response to
     a problem that faces society, such as curing alcoholism, reducing the crime
     rate or inducing young people to study science and engineering. In many
     cases there will be a humanitarian justification. For example, when
     a psychiatrist prescribes an anti-depressant for a depressed patient, he is
     clearly doing that individual a favor. It would be inhumane to withhold the
     drug from someone who needs it. When parents send their children to SylM
     Learning Centers to have them manipulated into becoming enthusiastic about
     their studies, they do so from concern for their children
     be that some of these parents wish that one didn
t have to have specialized
     training to get a job and that their kid didn
t have to be brainwashed into
     becoming a computer nerd. But what can they do? They can
     and their child may be unemployable if he doesn
t have certain skills. So
153. Thus control over human behavior will be introduced not by a calculated
     decision of the authorities but through a process of social evolution
     (RAPID evolution, however). The process will be impossible to resist,
     because each advance, considered by itself, will appear to be beneficial,
     or at least the evil involved in making the advance will appear to be
     beneficial, or at least the evil involved in making the advance will seem
     to be less than that which would reM
sult from not making it (see paragraph
     127). Propaganda for example is used for many good purposes, such as
     discouraging child abuse or race hatred. [14] Sex education is obviously
     useful, yet the effect of sex education (to the extent that it is
     successful) is to take the shaping of sexual attitudes away from the family
     and put it into the hands of the state as represented by the public school
154. Suppose a biological trait is discovered that increases the likelihood tM
     a child will grow up to be a criminal, and suppose some sort of gene
     therapy can remove this trait. [29] Of course most parents whose children
     possess the trait will have them undergo the therapy. It would be inhumane
     to do otherwise, since the child would probably have a miserable life if he
     grew up to be a criminal. But many or most primitive societies have a low
     crime rate in comparison with that of our society, even though they have
     neither high- tech methods of chiM
ld-rearing nor harsh systems of
     punishment. Since there is no reason to suppose that more modern men than
     primitive men have innate predatory tendencies, the high crime rate of our
     society must be due to the pressures that modern conditions put on people,
     to which many cannot or will not adjust. Thus a treatment designed to
     remove potential criminal tendencies is at least in part a way of
     re-engineering people so that they suit the requirements of the system.
155. Our society teM
 any mode of thought or behavior
     that is inconvenient for the system, and this is plausible because when an
     individual doesn
t fit into the system it causes pain to the individual as
     well as problems for the system. Thus the manipulation of an individual to
     adjust him to the system is seen as a
156. In paragraph 127 we pointed out that if the use of a new item of technology
     is INITIALLY optM
ional, it does not necessarily REMAIN optional, because the
     new technology tends to change society in such a way that it becomes
     difficult or impossible for an individual to function without using that
     technology. This applies also to the technology of human behavior. In
     a world in which most children are put through a program to make them
     enthusiastic about studying, a parent will almost be forced to put his kid
     through such a program, because if he does not, then the kid will gM
     to be, comparatively speaking, an ignoramus and therefore unemployable. Or
     suppose a biological treatment is discovered that, without undesirable
     side-effects, will greatly reduce the psychological stress from which so
     many people suffer in our society. If large numbers of people choose to
     undergo the treatment, then the general level of stress in society will be
     reduced, so that it will be possible for the system to increase the
     stress-producing pressures. In fact, M
something like this seems to have
     happened already with one of our society
s most important psychological
     tools for enabling people to reduce (or at least temporarily escape from)
     stress, namely, mass entertainment (see paragraph 147). Our use of mass
     entertainment is
: No law requires us to watch television, listen
     to the radio, read magazines. Yet mass entertainment is a means of escape
     and stress-reduction on which most of us have become dependent. Everyone
   complains about the trashiness of television, but almost everyone watches
     it. A few have kicked the TV habit, but it would be a rare person who could
     get along today without using ANY form of mass entertainment. (Yet until
     quite recently in human history most people got along very nicely with no
     other entertainment than that which each local community created for
     itself.) Without the entertainment industry the system probably would not
     have been able to get away with putting aM
s much stress-producing pressure
     on us as it does.
157. Assuming that industrial society survives, it is likely that technology
     will eventually acquire something approaching complete control over human
     behavior. It has been established beyond any rational doubt that human
     thought and behavior have a largely biological basis. As experimenters have
     demonstrated, feelings such as hunger, pleasure, anger and fear can be
     turned on and off by electrical stimulation of appropriate partM
     brain. Memories can be destroyed by damaging parts of the brain or they can
     be brought to the surface by electrical stimulation. Hallucinations can be
     induced or moods changed by drugs. There may or may not be an immaterial
     human soul, but if there is one it clearly is less powerful that the
     biological mechanisms of human behavior. For if that were not the case then
     researchers would not be able so easily to manipulate human feelings and
     behavior with drugs and eleM
158. It presumably would be impractical for all people to have electrodes
     inserted in their heads so that they could be controlled by the
     authorities. But the fact that human thoughts and feelings are so open to
     biological intervention shows that the problem of controlling human
     behavior is mainly a technical problem; a problem of neurons, hormones and
     complex molecules; the kind of problem that is accessible to scientific
     attack. Given the outstanding record oM
f our society in solving technical
     problems, it is overwhelmingly probable that great advances will be made in
     the control of human behavior.
159. Will public resistance prevent the introduction of technological control of
     human behavior? It certainly would if an attempt were made to introduce
     such control all at once. But since technological control will be
     introduced through a long sequence of small advances, there will be no
     rational and effective public resistance. (See paraM
graphs 127, 132, 153.)
160. To those who think that all this sounds like science fiction, we point out
s science fiction is today
s fact. The Industrial Revolution
     has radically altered man
s environment and way of life, and it is only to
     be expected that as technology is increasingly applied to the human body
     and mind, man himself will be altered as radically as his environment and
     way of life have been.
HUMAN RACE AT A CROSSROADS
161. But we have gotten ahead M
of our story. It is one thing to develop in the
     laboratory a series of psychological or biological techniques for
     manipulating human behavior and quite another to integrate these techniques
     into a functioning social system. The latter problem is the more difficult
     of the two. For example, while the techniques of educational psychology
     doubtless work quite well in the
 where they are developed, it
     is not necessarily easy to apply them effectively throughout our
    educational system. We all know what many of our schools are like. The
     teachers are too busy taking knives and guns away from the kids to subject
     them to the latest techniques for making them into computer nerds. Thus, in
     spite of all its technical advances relating to human behavior, the system
     to date has not been impressively successful in controlling human beings.
     The people whose behavior is fairly well under the control of the system
     are those of the type that might be M
     growing numbers of people who in one way or another are rebels against the
     system: welfare leaches, youth gangs, cultists, satanists, nazis, radical
     environmentalists, militiamen, etc.
162. The system is currently engaged in a desperate struggle to overcome certain
     problems that threaten its survival, among which the problems of human
     behavior are the most important. If the system succeeds in acquiring
     sufficient control over human behavior M
quickly enough, it will probably
     survive. Otherwise it will break down. We think the issue will most likely
     be resolved within the next several decades, say 40 to 100 years.
163. Suppose the system survives the crisis of the next several decades. By that
     time it will have to have solved, or at least brought under control, the
     principal problems that confront it, in particular that of
     human beings; that is, making people sufficiently docile so that heir
 no longer threatens the system. That being accomplished, it does
     not appear that there would be any further obstacle to the development of
     technology, and it would presumably advance toward its logical conclusion,
     which is complete control over everything on Earth, including human beings
     and all other important organisms. The system may become a unitary,
     monolithic organization, or it may be more or less fragmented and consist
     of a number of organizations coexisting in a relatioM
nship that includes
     elements of both cooperation and competition, just as today the government,
     the corporations and other large organizations both cooperate and compete
     with one another. Human freedom mostly will have vanished, because
     individuals and small groups will be impotent vis-a-vis large organizations
     armed with supertechnology and an arsenal of advanced psychological and
     biological tools for manipulating human beings, besides instruments of
     surveillance and physiM
cal coercion. Only a small number of people will have
     any real power, and even these probably will have only very limited
     freedom, because their behavior too will be regulated; just as today our
     politicians and corporation executives can retain their positions of power
     only as long as their behavior remains within certain fairly narrow limits.
t imagine that the systems will stop developing further techniques for
     controlling human beings and nature once the crisis of the neM
     is over and increasing control is no longer necessary for the system
     survival. On the contrary, once the hard times are over the system will
     increase its control over people and nature more rapidly, because it will
     no longer be hampered by difficulties of the kind that it is currently
     experiencing. Survival is not the principal motive for extending control.
     As we explained in paragraphs 87-90, technicians and scientists carry on
     their work largely as a suM
rrogate activity; that is, they satisfy their
     need for power by solving technical problems. They will continue to do this
     with unabated enthusiasm, and among the most interesting and challenging
     problems for them to solve will be those of understanding the human body
     and mind and intervening in their development. For the
165. But suppose on the other hand that the stresses of the coming decades prove
     to be too much for the system. If the systemM
 breaks down there may be
     a period of chaos, a
 such as those that history has
     recorded at various epochs in the past. It is impossible to predict what
     would emerge from such a time of troubles, but at any rate the human race
     would be given a new chance. The greatest danger is that industrial society
     may begin to reconstitute itself within the first few years after the
     breakdown. Certainly there will be many people (power-hungry types
     especially) who wM
ill be anxious to get the factories running again.
166. Therefore two tasks confront those who hate the servitude to which the
     industrial system is reducing the human race. First, we must work to
     heighten the social stresses within the system so as to increase the
     likelihood that it will break down or be weakened sufficiently so that
     a revolution against it becomes possible. Second, it is necessary to
     develop and propagate an ideology that opposes technology and the
ociety if and when the system becomes sufficiently weakened.
     And such an ideology will help to assure that, if and when industrial
     society breaks down, its remnants will be smashed beyond repair, so that
     the system cannot be reconstituted. The factories should be destroyed,
     technical books burned, etc.
167. The industrial system will not break down purely as a result of
     revolutionary action. It will not be vulnerable to revolutionary attack
     unless its own internM
al problems of development lead it into very serious
     difficulties. So if the system breaks down it will do so either
     spontaneously, or through a process that is in part spontaneous but helped
     along by revolutionaries. If the breakdown is sudden, many people will die,
     since the world
s population has become so overblown that it cannot even
     feed itself any longer without advanced technology. Even if the breakdown
     is gradual enough so that reduction of the population can occur morM
     through lowering of the birth rate than through elevation of the death
     rate, the process of de- industrialization probably will be very chaotic
     and involve much suffering. It is naive to think it likely that technology
     can be phased out in a smoothly managed, orderly way, especially since the
     technophiles will fight stubbornly at every step. Is it therefore cruel to
     work for the breakdown of the system? Maybe, but maybe not. In the first
     place, revolutionaries will not beM
 able to break the system down unless it
     is already in enough trouble so that there would be a good chance of its
     eventually breaking down by itself anyway; and the bigger the system grows,
     the more disastrous the consequences of its breakdown will be; so it may be
     that revolutionaries, by hastening the onset of the breakdown, will be
     reducing the extent of the disaster.
168. In the second place, one has to balance struggle and death against the loss
     of freedom and dignity. To mM
any of us, freedom and dignity are more
     important than a long life or avoidance of physical pain. Besides, we all
     have to die some time, and it may be better to die fighting for survival,
     or for a cause, than to live a long but empty and purposeless life.
169. In the third place, it is not at all certain that survival of the system
     will lead to less suffering than breakdown of the system would. The system
     has already caused, and is continuing to cause, immense suffering all over
 the world. Ancient cultures, that for hundreds of years gave people
     a satisfactory relationship with each other and with their environment,
     have been shattered by contact with industrial society, and the result has
     been a whole catalogue of economic, environmental, social and psychological
     problems. One of the effects of the intrusion of industrial society has
     been that over much of the world traditional controls on population have
     been thrown out of balance. Hence the populatioM
n explosion, with all that
     that implies. Then there is the psychological suffering that is widespread
     throughout the supposedly fortunate countries of the West (see paragraphs
     44, 45). No one knows what will happen as a result of ozone depletion, the
     greenhouse effect and other environmental problems that cannot yet be
     foreseen. And, as nuclear proliferation has shown, new technology cannot be
     kept out of the hands of dictators and irresponsible Third World nations.
ou like to speculate about what Iraq or North Korea will do with
     genetic engineering?
 say the technophiles,
Science is going to fix all that! We will
     conquer famine, eliminate psychological suffering, make everybody healthy
s what they said 200 years ago. The Industrial
     Revolution was supposed to eliminate poverty, make everybody happy, etc.
     The actual result has been quite different. The technophiles are hopelessly
lf-deceiving) in their understanding of social problems. They
     are unaware of (or choose to ignore) the fact that when large changes, even
     seemingly beneficial ones, are introduced into a society, they lead to
     a long sequence of other changes, most of which are impossible to predict
     (paragraph 103). The result is disruption of the society. So it is very
     probable that in their attempts to end poverty and disease, engineer
     docile, happy personalities and so forth, the technophiles wM
     social systems that are terribly troubled, even more so than the present
     once. For example, the scientists boast that they will end famine by
     creating new, genetically engineered food plants. But this will allow the
     human population to keep expanding indefinitely, and it is well known that
     crowding leads to increased stress and aggression. This is merely one
     example of the PREDICTABLE problems that will arise. We emphasize that, as
     past experience has shown, techM
nical progress will lead to other new
     problems that CANNOT be predicted in advance (paragraph 103). In fact, ever
     since the Industrial Revolution, technology has been creating new problems
     for society far more rapidly than it has been solving old ones. Thus it
     will take a long and difficult period of trial and error for the
     technophiles to work the bugs out of their Brave New World (if they every
     do). In the meantime there will be great suffering. So it is not at all
that the survival of industrial society would involve less suffering
     than the breakdown of that society would. Technology has gotten the human
     race into a fix from which there is not likely to be any easy escape.
171. But suppose now that industrial society does survive the next several
     decades and that the bugs do eventually get worked out of the system, so
     that it functions smoothly. What kind of system will it be? We will
     consider several possibilities.
us postulate that the computer scientists succeed in developing
     intelligent machines that can do all things better than human beings can do
     them. In that case presumably all work will be done by vast, highly
     organized systems of machines and no human effort will be necessary. Either
     of two cases might occur. The machines might be permitted to make all of
     their own decisions without human oversight, or else human control over the
     machines might be retained.
173. If the machines aM
re permitted to make all their own decisions, we can
     make any conjectures as to the results, because it is impossible to guess
     how such machines might behave. We only point out that the fate of the
     human race would be at the mercy of the machines. It might be argued that
     the human race would never be foolish enough to hand over all power to the
     machines. But we are suggesting neither that the human race would
     voluntarily turn power over to the machines nor that the machines wM
     willfully seize power. What we do suggest is that the human race might
     easily permit itself to drift into a position of such dependence on the
     machines that it would have no practical choice but to accept all of the
 decisions. As society and the problems that face it become more
     and more complex and as machines become more and more intelligent, people
     will let machines make more and more of their decisions for them, simply
     because machine-made decisions wilM
l bring better results than man-made
     ones. Eventually a stage may be reached at which the decisions necessary to
     keep the system running will be so complex that human beings will be
     incapable of making them intelligently. At that stage the machines will be
     in effective control. People won
t be able to just turn the machines off,
     because they will be so dependent on them that turning them off would
     amount to suicide.
174. On the other hand it is possible that human control overM
     be retained. In that case the average man may have control over certain
     private machines of his own, such as his car or his personal computer, but
     control over large systems of machines will be in the hands of a tiny
just as it is today, but with two differences. Due to improved
     techniques the elite will have greater control over the masses; and because
     human work will no longer be necessary the masses will be superfluous,
     a useless burden on the sM
ystem. If the elite is ruthless they may simply
     decide to exterminate the mass of humanity. If they are humane they may use
     propaganda or other psychological or biological techniques to reduce the
     birth rate until the mass of humanity becomes extinct, leaving the world to
     the elite. Or, if the elite consists of soft- hearted liberals, they may
     decide to play the role of good shepherds to the rest of the human race.
     They will see to it that everyone
s physical needs are satisfieM
     children are raised under psychologically hygienic conditions, that
     everyone has a wholesome hobby to keep him busy, and that anyone who may
     become dissatisfied undergoes
     life will be so purposeless that people will have to be biologically or
     psychologically engineered either to remove their need for the power
     process or to make them
 their drive for power into some
     harmless hobby. These engineM
ered human beings may be happy in such
     a society, but they most certainly will not be free. They will have been
     reduced to the status of domestic animals.
175. But suppose now that the computer scientists do not succeed in developing
     artificial intelligence, so that human work remains necessary. Even so,
     machines will take care of more and more of the simpler tasks so that there
     will be an increasing surplus of human workers at the lower levels of
     ability. (We see this happeningM
 already. There are many people who find it
     difficult or impossible to get work, because for intellectual or
     psychological reasons they cannot acquire the level of training necessary
     to make themselves useful in the present system.) On those who are
     employed, ever-increasing demands will be placed: They will need more and
     more training, more and more ability, and will have to be ever more
     reliable, conforming and docile, because they will be more and more like
ant organism. Their tasks will be increasingly specialized, so
     that their work will be, in a sense, out of touch with the real world,
     being concentrated on one tiny slice of reality. The system will have to
     use any means that it can, whether psychological or biological, to engineer
     people to be docile, to have the abilities that the system requires and to
 their drive for power into some specialized task. But the
     statement that the people of such a society will havM
     require qualification. The society may find competitiveness useful,
     provided that ways are found of directing competitiveness into channels
     that serve the needs of the system. We can imagine a future society in
     which there is endless competition for positions of prestige and power. But
     no more than a very few people will ever reach the top, where the only real
     power is (see end of paragraph 163). Very repellent is a society in which
     a person can satisfy hM
is need for power only by pushing large numbers of
     other people out of the way and depriving them of THEIR opportunity for
176. One can envision scenarios that incorporate aspects of more than one of the
     possibilities that we have just discussed. For instance, it may be that
     machines will take over most of the work that is of real, practical
     importance, but that human beings will be kept busy by being given
     relatively unimportant work. It has been suggested, for example, M
     a great development of the service industries might provide work for human
     beings. Thus people would spent their time shining each other
     driving each other around in taxicabs, making handicrafts for one another,
     waiting on each other
s tables, etc. This seems to us a thoroughly
     contemptible way for the human race to end up, and we doubt that many
     people would find fulfilling lives in such pointless busy-work. They would
     seek other, dangerous outlets (drugsM
 hate groups) unless
     they were biologically or psychologically engineered to adapt them to such
177. Needless to say, the scenarios outlined above do not exhaust all the
     possibilities. They only indicate the kinds of outcomes that seem to us
     most likely. But we can envision no plausible scenarios that are any more
     palatable than the ones we
ve just described. It is overwhelmingly probable
     that if the industrial- technological system survivesM
 the next 40 to 100
     years, it will by that time have developed certain general characteristics:
     Individuals (at least those of the
 type, who are integrated
     into the system and make it run, and who therefore have all the power) will
     be more dependent than ever on large organizations; they will be more
 than ever and their physical and mental qualities to
     a significant extent (possibly to a very great extent) will be those that
     are engineered iM
nto them rather than being the results of chance (or of
s will, or whatever); and whatever may be left of wild nature will be
     reduced to remnants preserved for scientific study and kept under the
     supervision and management of scientists (hence it will no longer be truly
     wild). In the long run (say a few centuries from now) it is likely that
     neither the human race nor any other important organisms will exist as we
     know them today, because once you start modifying organisms tM
     engineering there is no reason to stop at any particular point, so that the
     modifications will probably continue until man and other organisms have
     been utterly transformed.
178. Whatever else may be the case, it is certain that technology is creating
     for human beings a new physical and social environment radically different
     from the spectrum of environments to which natural selection has adapted
     the human race physically and psychologically. If man is not adjusteM
     this new environment by being artificially re-engineered, then he will be
     adapted to it through a long and painful process of natural selection. The
     former is far more likely than the latter.
179. It would be better to dump the whole stinking system and take the
180. The technophiles are taking us all on an utterly reckless ride into the
     unknown. Many people understand something of what technological progress is
     doing to us yet take a passive attituM
de toward it because they think it is
     inevitable. But we (FC) don
t think it is inevitable. We think it can be
     stopped, and we will give here some indications of how to go about stopping
181. As we stated in paragraph 166, the two main tasks for the present are to
     promote social stress and instability in industrial society and to develop
     and propagate an ideology that opposes technology and the industrial
     system. When the system becomes sufficiently stressed and unstable, M
     a revolution against technology may be possible. The pattern would be
     similar to that of the French and Russian Revolutions. French society and
     Russian society, for several decades prior to their respective revolutions,
     showed increasing signs of stress and weakness. Meanwhile, ideologies were
     being developed that offered a new world view that was quite different from
     the old one. In the Russian case, revolutionaries were actively working to
     undermine the old order. Then, wM
hen the old system was put under sufficient
     additional stress (by financial crisis in France, by military defeat in
     Russia) it was swept away by revolution. What we propose is something along
     the same lines.
182. It will be objected that the French and Russian Revolutions were failures.
     But most revolutions have two goals. One is to destroy an old form of
     society and the other is to set up the new form of society envisioned by
     the revolutionaries. The French and Russian revolutiM
     (fortunately!) to create the new kind of society of which they dreamed, but
     they were quite successful in destroying the old society. We have no
     illusions about the feasibility of creating a new, ideal form of society.
     Our goal is only to destroy the existing form of society.
183. But an ideology, in order to gain enthusiastic support, must have
     a positive ideal as well as a negative one; it must be FOR something as
     well as AGAINST something. The positive ideal thM
at we propose is Nature.
     That is, WILD nature: those aspects of the functioning of the Earth and its
     living things that are independent of human management and free of human
     interference and control. And with wild nature we include human nature, by
     which we mean those aspects of the functioning of the human individual that
     are not subject to regulation by organized society but are products of
     chance, or free will, or God (depending on your religious or philosophical
184. Nature makes a perfect counter-ideal to technology for several reasons.
     Nature (that which is outside the power of the system) is the opposite of
     technology (which seeks to expand indefinitely the power of the system).
     Most people will agree that nature is beautiful; certainly it has
     tremendous popular appeal. The radical environmentalists ALREADY hold an
     ideology that exalts nature and opposes technology. [30] It is not
     necessary for the sake of nature to set up some cM
himerical utopia or any
     new kind of social order. Nature takes care of itself: It was a spontaneous
     creation that existed long before any human society, and for countless
     centuries many different kinds of human societies coexisted with nature
     without doing it an excessive amount of damage. Only with the Industrial
     Revolution did the effect of human society on nature become really
     devastating. To relieve the pressure on nature it is not necessary to
     create a special kind of M
social system, it is only necessary to get rid of
     industrial society. Granted, this will not solve all problems. Industrial
     society has already done tremendous damage to nature and it will take
     a very long time for the scars to heal. Besides, even pre-industrial
     societies can do significant damage to nature. Nevertheless, getting rid of
     industrial society will accomplish a great deal. It will relieve the worst
     of the pressure on nature so that the scars can begin to heal. It willM
     remove the capacity of organized society to keep increasing its control
     over nature (including human nature). Whatever kind of society may exist
     after the demise of the industrial system, it is certain that most people
     will live close to nature, because in the absence of advanced technology
     there is no other way that people CAN live. To feed themselves they must be
     peasants or herdsmen or fishermen or hunters, etc. And, generally speaking,
     local autonomy should tend to incM
rease, because lack of advanced technology
     and rapid communications will limit the capacity of governments or other
     large organizations to control local communities.
185. As for the negative consequences of eliminating industrial society
t eat your cake and have it too. To gain one thing you have to
     sacrifice another.
186. Most people hate psychological conflict. For this reason they avoid doing
     any serious thinking about difficult social issues, and they like to haM
     such issues presented to them in simple, black-and-white terms: THIS is all
     good and THAT is all bad. The revolutionary ideology should therefore be
     developed on two levels.
187. On the more sophisticated level the ideology should address itself to
     people who are intelligent, thoughtful and rational. The object should be
     to create a core of people who will be opposed to the industrial system on
     a rational, thought-out basis, with full appreciation of the problems and
biguities involved, and of the price that has to be paid for getting rid
     of the system. It is particularly important to attract people of this type,
     as they are capable people and will be instrumental in influencing others.
     These people should be addressed on as rational a level as possible. Facts
     should never intentionally be distorted and intemperate language should be
     avoided. This does not mean that no appeal can be made to the emotions, but
     in making such appeal care should M
be taken to avoid misrepresenting the
     truth or doing anything else that would destroy the intellectual
     respectability of the ideology.
188. On a second level, the ideology should be propagated in a simplified form
     that will enable the unthinking majority to see the conflict of technology
     vs. nature in unambiguous terms. But even on this second level the ideology
     should not be expressed in language that is so cheap, intemperate or
     irrational that it alienates people of the thoughM
tful and rational type.
     Cheap, intemperate propaganda sometimes achieves impressive short-term
     gains, but it will be more advantageous in the long run to keep the loyalty
     of a small number of intelligently committed people than to arouse the
     passions of an unthinking, fickle mob who will change their attitude as
     soon as someone comes along with a better propaganda gimmick. However,
     propaganda of the rabble-rousing type may be necessary when the system is
     nearing the point oM
f collapse and there is a final struggle between rival
     ideologies to determine which will become dominant when the old world-view
189. Prior to that final struggle, the revolutionaries should not expect to have
     a majority of people on their side. History is made by active, determined
     minorities, not by the majority, which seldom has a clear and consistent
     idea of what it really wants. Until the time comes for the final push
     toward revolution [31], the task of revolutM
ionaries will be less to win the
     shallow support of the majority than to build a small core of deeply
     committed people. As for the majority, it will be enough to make them aware
     of the existence of the new ideology and remind them of it frequently;
     though of course it will be desirable to get majority support to the extent
     that this can be done without weakening the core of seriously committed
190. Any kind of social conflict helps to destabilize the system, but one shouM
     be careful about what kind of conflict one encourages. The line of conflict
     should be drawn between the mass of the people and the power-holding elite
     of industrial society (politicians, scientists, upper-level business
     executives, government officials, etc.). It should NOT be drawn between the
     revolutionaries and the mass of the people. For example, it would be bad
     strategy for the revolutionaries to condemn Americans for their habits of
     consumption. Instead, the averagM
e American should be portrayed as a victim
     of the advertising and marketing industry, which has suckered him into
     buying a lot of junk that he doesn
t need and that is very poor
     compensation for his lost freedom. Either approach is consistent with the
     facts. It is merely a matter of attitude whether you blame the advertising
     industry for manipulating the public or blame the public for allowing
     itself to be manipulated. As a matter of strategy one should generally
191. One should think twice before encouraging any other social conflict than
     that between the power- holding elite (which wields technology) and the
     general public (over which technology exerts its power). For one thing,
     other conflicts tend to distract attention from the important conflicts
     (between power-elite and ordinary people, between technology and nature);
     for another thing, other conflicts may actually tend to encourage
     technologization, because each M
side in such a conflict wants to use
     technological power to gain advantages over its adversary. This is clearly
     seen in rivalries between nations. It also appears in ethnic conflicts
     within nations. For example, in America many black leaders are anxious to
     gain power for African Americans by placing back individuals in the
     technological power-elite. They want there to be many black government
     officials, scientists, corporation executives and so forth. In this way
elping to absorb the African American subculture into the
     technological system. Generally speaking, one should encourage only those
     social conflicts that can be fitted into the framework of the conflicts of
     power-elite vs. ordinary people, technology vs nature.
192. But the way to discourage ethnic conflict is NOT through militant advocacy
     of minority rights (see paragraphs 21, 29). Instead, the revolutionaries
     should emphasize that although minorities do suffer more or less
advantage, this disadvantage is of peripheral significance. Our real
     enemy is the industrial- technological system, and in the struggle against
     the system, ethnic distinctions are of no importance.
193. The kind of revolution we have in mind will not necessarily involve an
     armed uprising against any government. It may or may not involve physical
     violence, but it will not be a POLITICAL revolution. Its focus will be on
     technology and economics, not politics. [32]
194. Probably the revM
olutionaries should even AVOID assuming political power,
     whether by legal or illegal means, until the industrial system is stressed
     to the danger point and has proved itself to be a failure in the eyes of
     most people. Suppose for example that some
 party should win control
     of the United States Congress in an election. In order to avoid betraying
     or watering down their own ideology they would have to take vigorous
     measures to turn economic growth into economic shrinkageM
     man the results would appear disastrous: There would be massive
     unemployment, shortages of commodities, etc. Even if the grosser ill
     effects could be avoided through superhumanly skillful management, still
     people would have to begin giving up the luxuries to which they have become
     addicted. Dissatisfaction would grow, the
 party would be voted out
     of office and the revolutionaries would have suffered a severe setback. For
     this reason the revolutiM
onaries should not try to acquire political power
     until the system has gotten itself into such a mess that any hardships will
     be seen as resulting from the failures of the industrial system itself and
     not from the policies of the revolutionaries. The revolution against
     technology will probably have to be a revolution by outsiders, a revolution
     from below and not from above.
195. The revolution must be international and worldwide. It cannot be carried
     out on a nation-by-nation baM
sis. Whenever it is suggested that the United
     States, for example, should cut back on technological progress or economic
     growth, people get hysterical and start screaming that if we fall behind in
     technology the Japanese will get ahead of us. Holy robots! The world will
     fly off its orbit if the Japanese ever sell more cars than we do!
     (Nationalism is a great promoter of technology.) More reasonably, it is
     argued that if the relatively democratic nations of the world fall behind
     in technology while nasty, dictatorial nations like China, Vietnam and
     North Korea continue to progress, eventually the dictators may come to
     dominate the world. That is why the industrial system should be attacked in
     all nations simultaneously, to the extent that this may be possible. True,
     there is no assurance that the industrial system can be destroyed at
     approximately the same time all over the world, and it is even conceivable
     that the attempt to overthrow the system cM
ould lead instead to the
     domination of the system by dictators. That is a risk that has to be taken.
     And it is worth taking, since the difference between a
     industrial system and one controlled by dictators is small compared with
     the difference between an industrial system and a non-industrial one. [33]
     It might even be argued that an industrial system controlled by dictators
     would be preferable, because dictator-controlled systems usually have
cient, hence they are presumably more likely to break down.
196. Revolutionaries might consider favoring measures that tend to bind the
     world economy into a unified whole. Free trade agreements like NAFTA and
     GATT are probably harmful to the environment in the short run, but in the
     long run they may perhaps be advantageous because they foster economic
     interdependence between nations. It will be easier to destroy the
     industrial system on a worldwide basis if the worM
ld economy is so unified
     that its breakdown in any one major nation will lead to its breakdown in
     all industrialized nations.
197. Some people take the line that modern man has too much power, too much
     control over nature; they argue for a more passive attitude on the part of
     the human race. At best these people are expressing themselves unclearly,
     because they fail to distinguish between power for LARGE ORGANIZATIONS and
     power for INDIVIDUALS and SMALL GROUPS. It is a mistake tM
     powerlessness and passivity, because people NEED power. Modern man as
     a collective entity
that is, the industrial system
has immense power over
     nature, and we (FC) regard this as evil. But modern INDIVIDUALS and SMALL
     GROUPS OF INDIVIDUALS have far less power than primitive man ever did.
     Generally speaking, the vast power of
 over nature is exercised
     not by individuals or small groups but by large organizations. To the
     extent that the averageM
 modern INDIVIDUAL can wield the power of
     technology, he is permitted to do so only within narrow limits and only
     under the supervision and control of the system. (You need a license for
     everything and with the license come rules and regulations.) The individual
     has only those technological powers with which the system chooses to
     provide him. His PERSONAL power over nature is slight.
198. Primitive INDIVIDUALS and SMALL GROUPS actually had considerable power over
     nature; or maybM
e it would be better to say power WITHIN nature. When
     primitive man needed food he knew how to find and prepare edible roots, how
     to track game and take it with homemade weapons. He knew how to protect
     himself from heat, cold, rain, dangerous animals, etc. But primitive man
     did relatively little damage to nature because the COLLECTIVE power of
     primitive society was negligible compared to the COLLECTIVE power of
     industrial society.
199. Instead of arguing for powerlessness and paM
ssivity, one should argue that
     the power of the INDUSTRIAL SYSTEM should be broken, and that this will
     greatly INCREASE the power and freedom of INDIVIDUALS and SMALL GROUPS.
200. Until the industrial system has been thoroughly wrecked, the destruction of
     that system must be the revolutionaries
 ONLY goal. Other goals would
     distract attention and energy from the main goal. More importantly, if the
     revolutionaries permit themselves to have any other goal than the
     destruction ofM
 technology, they will be tempted to use technology as a tool
     for reaching that other goal. If they give in to that temptation, they will
     fall right back into the technological trap, because modern technology is
     a unified, tightly organized system, so that, in order to retain SOME
     technology, one finds oneself obliged to retain MOST technology, hence one
     ends up sacrificing only token amounts of technology.
201. Suppose for example that the revolutionaries took
     a goal. Human nature being what it is, social justice would not come about
     spontaneously; it would have to be enforced. In order to enforce it the
     revolutionaries would have to retain central organization and control. For
     that they would need rapid long-distance transportation and communication,
     and therefore all the technology needed to support the transportation and
     communication systems. To feed and clothe poor people they would have to
     use agricultural and manufacturinM
g technology. And so forth. So that the
     attempt to insure social justice would force them to retain most parts of
     the technological system. Not that we have anything against social justice,
     but it must not be allowed to interfere with the effort to get rid of the
     technological system.
202. It would be hopeless for revolutionaries to try to attack the system
     without using SOME modern technology. If nothing else they must use the
     communications media to spread their message. But tM
hey should use modern
     technology for only ONE purpose: to attack the technological system.
203. Imagine an alcoholic sitting with a barrel of wine in front of him. Suppose
     he starts saying to himself,
t bad for you if used in moderation.
     Why, they say small amounts of wine are even good for you! It won
     any harm if I take just one little drink....
 Well you know what is going
     to happen. Never forget that the human race with technology is just like an
coholic with a barrel of wine.
204. Revolutionaries should have as many children as they can. There is strong
     scientific evidence that social attitudes are to a significant extent
     inherited. No one suggests that a social attitude is a direct outcome of
s genetic constitution, but it appears that personality traits are
     partly inherited and that certain personality traits tend, within the
     context of our society, to make a person more likely to hold this or that
ttitude. Objections to these findings have been raised, but the
     objections are feeble and seem to be ideologically motivated. In any event,
     no one denies that children tend on the average to hold social attitudes
     similar to those of their parents. From our point of view it doesn
     all that much whether the attitudes are passed on genetically or through
     childhood training. In either case they ARE passed on.
205. The trouble is that many of the people who are inclined to rebel M
     the industrial system are also concerned about the population problems,
     hence they are apt to have few or no children. In this way they may be
     handing the world over to the sort of people who support or at least accept
     the industrial system. To insure the strength of the next generation of
     revolutionaries the present generation should reproduce itself abundantly.
     In doing so they will be worsening the population problem only slightly.
     And the important problem is toM
 get rid of the industrial system, because
     once the industrial system is gone the world
s population necessarily will
     decrease (see paragraph 167); whereas, if the industrial system survives,
     it will continue developing new techniques of food production that may
     enable the world
s population to keep increasing almost indefinitely.
206. With regard to revolutionary strategy, the only points on which we
     absolutely insist are that the single overriding goal must be the
ion of modern technology, and that no other goal can be allowed to
     compete with this one. For the rest, revolutionaries should take an
     empirical approach. If experience indicates that some of the
     recommendations made in the foregoing paragraphs are not going to give good
     results, then those recommendations should be discarded.
TWO KINDS OF TECHNOLOGY
207. An argument likely to be raised against our proposed revolution is that it
     is bound to fail, because (it is claimed) throughout hiM
story technology has
     always progressed, never regressed, hence technological regression is
     impossible. But this claim is false.
208. We distinguish between two kinds of technology, which we will call
     small-scale technology and organization-dependent technology. Small-scale
     technology is technology that can be used by small-scale communities
     without outside assistance. Organization-dependent technology is technology
     that depends on large-scale social organization. We are aware ofM
     significant cases of regression in small-scale technology. But
     organization-dependent technology DOES regress when the social organization
     on which it depends breaks down. Example: When the Roman Empire fell apart
 small-scale technology survived because any clever village
     craftsman could build, for instance, a water wheel, any skilled smith could
     make steel by Roman methods, and so forth. But the Romans
     organization-dependent technology DID regress. TheM
ir aqueducts fell into
     disrepair and were never rebuilt. Their techniques of road construction
     were lost. The Roman system of urban sanitation was forgotten, so that not
     until rather recent times did the sanitation of European cities equal that
     of Ancient Rome.
209. The reason why technology has seemed always to progress is that, until
     perhaps a century or two before the Industrial Revolution, most technology
     was small-scale technology. But most of the technology developed sinceM
     Industrial Revolution is organization-dependent technology. Take the
     refrigerator for example. Without factory-made parts or the facilities of
     a post-industrial machine shop it would be virtually impossible for
     a handful of local craftsmen to build a refrigerator. If by some miracle
     they did succeed in building one it would be useless to them without
     a reliable source of electric power. So they would have to dam a stream and
     build a generator. Generators require large M
amounts of copper wire. Imagine
     trying to make that wire without modern machinery. And where would they get
     a gas suitable for refrigeration? It would be much easier to build an
     icehouse or preserve food by drying or picking, as was done before the
     invention of the refrigerator.
210. So it is clear that if the industrial system were once thoroughly broken
     down, refrigeration technology would quickly be lost. The same is true of
     other organization-dependent technology. And once tM
his technology had been
     lost for a generation or so it would take centuries to rebuild it, just as
     it took centuries to build it the first time around. Surviving technical
     books would be few and scattered. An industrial society, if built from
     scratch without outside help, can only be built in a series of stages: You
     need tools to make tools to make tools to make tools ... . A long process
     of economic development and progress in social organization is required.
the absence of an ideology opposed to technology, there is no
     reason to believe that anyone would be interested in rebuilding industrial
     society. The enthusiasm for
 is a phenomenon peculiar to the
     modern form of society, and it seems not to have existed prior to the 17th
     century or thereabouts.
211. In the late Middle Ages there were four main civilizations that were about
: Europe, the Islamic world, India, and the Far East
     (China, Japan, KoM
rea). Three of those civilizations remained more or less
     stable, and only Europe became dynamic. No one knows why Europe became
     dynamic at that time; historians have their theories but these are only
     speculation. At any rate, it is clear that rapid development toward
     a technological form of society occurs only under special conditions. So
     there is no reason to assume that a long-lasting technological regression
     cannot be brought about.
212. Would society EVENTUALLY develop againM
 toward an industrial-technological
     form? Maybe, but there is no use in worrying about it, since we can
     predict or control events 500 or 1,000 years in the future. Those problems
     must be dealt with by the people who will live at that time.
THE DANGER OF LEFTISM
213. Because of their need for rebellion and for membership in a movement,
     leftists or persons of similar psychological type often are unattracted to
     a rebellious or activist movement whose goals and membership are not
   initially leftist. The resulting influx of leftish types can easily turn
     a non-leftist movement into a leftist one, so that leftist goals replace or
     distort the original goals of the movement.
214. To avoid this, a movement that exalts nature and opposes technology must
     take a resolutely anti-leftist stance and must avoid all collaboration with
     leftists. Leftism is in the long run inconsistent with wild nature, with
     human freedom and with the elimination of modern technology. LeftiM
     collectivist; it seeks to bind together the entire world (both nature and
     the human race) into a unified whole. But this implies management of nature
     and of human life by organized society, and it requires advanced
     technology. You can
t have a united world without rapid transportation and
     communication, you can
t make all people love one another without
     sophisticated psychological techniques, you can
     without the necessary technologM
ical base. Above all, leftism is driven by
     the need for power, and the leftist seeks power on a collective basis,
     through identification with a mass movement or an organization. Leftism is
     unlikely ever to give up technology, because technology is too valuable
     a source of collective power.
215. The anarchist [34] too seeks power, but he seeks it on an individual or
     small-group basis; he wants individuals and small groups to be able to
     control the circumstances of their own livesM
. He opposes technology because
     it makes small groups dependent on large organizations.
216. Some leftists may seem to oppose technology, but they will oppose it only
     so long as they are outsiders and the technological system is controlled by
     non-leftists. If leftism ever becomes dominant in society, so that the
     technological system becomes a tool in the hands of leftists, they will
     enthusiastically use it and promote its growth. In doing this they will be
     repeating a pattern thM
at leftism has shown again and again in the past.
     When the Bolsheviks in Russia were outsiders, they vigorously opposed
     censorship and the secret police, they advocated self-determination for
     ethnic minorities, and so forth; but as soon as they came into power
     themselves, they imposed a tighter censorship and created a more ruthless
     secret police than any that had existed under the tsars, and they oppressed
     ethnic minorities at least as much as the tsars had done. In the United
     States, a couple of decades ago when leftists were a minority in our
     universities, leftist professors were vigorous proponents of academic
     freedom, but today, in those of our universities where leftists have become
     dominant, they have shown themselves ready to take away from everyone
s academic freedom. (This is
political correctness.
     happen with leftists and technology: They will use it to oppress everyone
     else if they ever get it under their ownM
217. In earlier revolutions, leftists of the most power-hungry type, repeatedly,
     have first cooperated with non-leftist revolutionaries, as well as with
     leftists of a more libertarian inclination, and later have double- crossed
     them to seize power for themselves. Robespierre did this in the French
     Revolution, the Bolsheviks did it in the Russian Revolution, the communists
     did it in Spain in 1938 and Castro and his followers did it in Cuba. Given
     the past history of lefM
tism, it would be utterly foolish for non-leftist
     revolutionaries today to collaborate with leftists.
218. Various thinkers have pointed out that leftism is a kind of religion.
     Leftism is not a religion in the strict sense because leftist doctrine does
     not postulate the existence of any supernatural being. But, for the
     leftist, leftism plays a psychological role much like that which religion
     plays for some people. The leftist NEEDS to believe in leftism; it plays
     a vital role inM
 his psychological economy. His beliefs are not easily
     modified by logic or facts. He has a deep conviction that leftism is
     morally Right with a capital R, and that he has not only a right but a duty
     to impose leftist morality on everyone. (However, many of the people we are
     referring to as
 do not think of themselves as leftists and would
     not describe their system of beliefs as leftism. We use the term
t know of any better words to deM
signate the spectrum of
     related creeds that includes the feminist, gay rights, political
     correctness, etc., movements, and because these movements have a strong
     affinity with the old left. See paragraphs 227-230.)
219. Leftism is a totalitarian force. Wherever leftism is in a position of power
     it tends to invade every private corner and force every thought into
     a leftist mold. In part this is because of the quasi-religious character of
     leftism; everything contrary to leftist belM
iefs represents Sin. More
     importantly, leftism is a totalitarian force because of the leftists
     for power. The leftist seeks to satisfy his need for power through
     identification with a social movement and he tries to go through the power
     process by helping to pursue and attain the goals of the movement (see
     paragraph 83). But no matter how far the movement has gone in attaining its
     goals the leftist is never satisfied, because his activism is a surrogate
ee paragraph 41). That is, the leftist
s real motive is not to
     attain the ostensible goals of leftism; in reality he is motivated by the
     sense of power he gets from struggling for and then reaching a social goal.
     [35] Consequently the leftist is never satisfied with the goals he has
     already attained; his need for the power process leads him always to pursue
     some new goal. The leftist wants equal opportunities for minorities. When
     that is attained he insists on statistical equalM
ity of achievement by
     minorities. And as long as anyone harbors in some corner of his mind
     a negative attitude toward some minority, the leftist has to re-educated
     him. And ethnic minorities are not enough; no one can be allowed to have
     a negative attitude toward homosexuals, disabled people, fat people, old
     people, ugly people, and on and on and on. It
s not enough that the public
     should be informed about the hazards of smoking; a warning has to be
     stamped on every packaM
ge of cigarettes. Then cigarette advertising has to
     be restricted if not banned. The activists will never be satisfied until
     tobacco is outlawed, and after that it will be alcohol, then junk food,
     etc. Activists have fought gross child abuse, which is reasonable. But now
     they want to stop all spanking. When they have done that they will want to
     ban something else they consider unwholesome, then another thing and then
     another. They will never be satisfied until they have complete M
     all child rearing practices. And then they will move on to another cause.
220. Suppose you asked leftists to make a list of ALL the things that were wrong
     with society, and then suppose you instituted EVERY social change that they
     demanded. It is safe to say that within a couple of years the majority of
     leftists would find something new to complain about, some new social
     to correct because, once again, the leftist is motivated less by distress
s ills than by the need to satisfy his drive for power by
     imposing his solutions on society.
221. Because of the restrictions placed on their thoughts and behavior by their
     high level of socialization, many leftists of the over-socialized type
     cannot pursue power in the ways that other people do. For them the drive
     for power has only one morally acceptable outlet, and that is in the
     struggle to impose their morality on everyone.
222. Leftists, especially those of the oversocializedM
 type, are True Believers
     in the sense of Eric Hoffer
     Believers are of the same psychological type as leftists. Presumably
     a true-believing nazi, for instance, is very different psychologically from
     a true-believing leftist. Because of their capacity for single-minded
     devotion to a cause, True Believers are a useful, perhaps a necessary,
     ingredient of any revolutionary movement. This presents a problem with
     which we must aM
t know how to deal. We aren
     harness the energies of the True Believer to a revolution against
     technology. At present all we can say is that no True Believer will make
     a safe recruit to the revolution unless his commitment is exclusively to
     the destruction of technology. If he is committed also to another ideal, he
     may want to use technology as a tool for pursuing that other ideal (see
     paragraphs 220, 221).
223. Some readers may say,
out leftism is a lot of crap. I know
     John and Jane who are leftish types and they don
     totalitarian tendencies.
s quite true that many leftists, possibly even
     a numerical majority, are decent people who sincerely believe in tolerating
 values (up to a point) and wouldn
t want to use high-handed methods
     to reach their social goals. Our remarks about leftism are not meant to
     apply to every individual leftist but to describe the general characterM
     leftism as a movement. And the general character of a movement is not
     necessarily determined by the numerical proportions of the various kinds of
     people involved in the movement.
224. The people who rise to positions of power in leftist movements tend to be
     leftists of the most power- hungry type, because power-hungry people are
     those who strive hardest to get into positions of power. Once the
     power-hungry types have captured control of the movement, there are many
tists of a gentler breed who inwardly disapprove of many of the actions
     of the leaders, but cannot bring themselves to oppose them. They NEED their
     faith in the movement, and because they cannot give up this faith they go
     along with the leaders. True, SOME leftists do have the guts to oppose the
     totalitarian tendencies that emerge, but they generally lose, because the
     power-hungry types are better organized, are more ruthless and
     Machiavellian and have taken care to build themselM
ves a strong power base.
225. These phenomena appeared clearly in Russia and other countries that were
     taken over by leftists. Similarly, before the breakdown of communism in the
     USSR, leftish types in the West would seldom criticize that country. If
     prodded they would admit that the USSR did many wrong things, but then they
     would try to find excuses for the communists and begin talking about the
     faults of the West. They always opposed Western military resistance to
gression. Leftish types all over the world vigorously protested
     the U.S. military action in Vietnam, but when the USSR invaded Afghanistan
     they did nothing. Not that they approved of the Soviet actions; but because
     of their leftist faith, they just couldn
t bear to put themselves in
     opposition to communism. Today, in those of our universities where
political correctness
 has become dominant, there are probably many
     leftish types who privately disapprove of the suppression M
     freedom, but they go along with it anyway.
226. Thus the fact that many individual leftists are personally mild and fairly
     tolerant people by no means prevents leftism as a whole form having
     a totalitarian tendency.
227. Our discussion of leftism has a serious weakness. It is still far from
     clear what we mean by the word
t seem to be much we
     can do about this. Today leftism is fragmented into a whole spectrum of
     activist movements. Yet nM
ot all activist movements are leftist, and some
     activist movements (e.g., radical environmentalism) seem to include both
     personalities of the leftist type and personalities of thoroughly
     un-leftist types who ought to know better than to collaborate with
     leftists. Varieties of leftists fade out gradually into varieties of
     non-leftists and we ourselves would often be hard-pressed to decide whether
     a given individual is or is not a leftist. To the extent that it is defined
all, our conception of leftism is defined by the discussion of it that
     we have given in this article, and we can only advise the reader to use his
     own judgment in deciding who is a leftist.
228. But it will be helpful to list some criteria for diagnosing leftism. These
     criteria cannot be applied in a cut and dried manner. Some individuals may
     meet some of the criteria without being leftists, some leftists may not
     meet any of the criteria. Again, you just have to use your judgment.
9. The leftist is oriented toward large-scale collectivism. He emphasizes the
     duty of the individual to serve society and the duty of society to take
     care of the individual. He has a negative attitude toward individualism. He
     often takes a moralistic tone. He tends to be for gun control, for sex
     education and other psychologically
 educational methods, for
     social planning, for affirmative action, for multiculturalism. He tends to
     identify with victims. He tends tM
o be against competition and against
     violence, but he often finds excuses for those leftists who do commit
     violence. He is fond of using the common catch- phrases of the left, like
     responsibility.
 Maybe the best diagnostic trait of the leftist is his
     tendency to sympathize with the following movements: femM
     ethnic rights, disability rights, animal rights, political correctness.
     Anyone who strongly sympathizes with ALL of these movements is almost
     certainly a leftist. [36]
230. The more dangerous leftists, that is, those who are most power-hungry, are
     often characterized by arrogance or by a dogmatic approach to ideology.
     However, the most dangerous leftists of all may be certain oversocialized
     types who avoid irritating displays of aggressiveness and refrain fromM
     advertising their leftism, but work quietly and unobtrusively to promote
     collectivist values,
 psychological techniques for socializing
     children, dependence of the individual on the system, and so forth. These
     crypto- leftists (as we may call them) approximate certain bourgeois types
     as far as practical action is concerned, but differ from them in
     psychology, ideology and motivation. The ordinary bourgeois tries to bring
     people under control of the system M
in order to protect his way of life, or
     he does so simply because his attitudes are conventional. The
     crypto-leftist tries to bring people under control of the system because he
     is a True Believer in a collectivistic ideology. The crypto-leftist is
     differentiated from the average leftist of the oversocialized type by the
     fact that his rebellious impulse is weaker and he is more securely
     socialized. He is differentiated from the ordinary well-socialized
     bourgeois by the factM
 that there is some deep lack within him that makes it
     necessary for him to devote himself to a cause and immerse himself in
     a collectivity. And maybe his (well-sublimated) drive for power is stronger
     than that of the average bourgeois.
231. Throughout this article we
ve made imprecise statements and statements that
     ought to have had all sorts of qualifications and reservations attached to
     them; and some of our statements may be flatly false. Lack of sufficient
ormation and the need for brevity made it impossible for us to formulate
     our assertions more precisely or add all the necessary qualifications. And
     of course in a discussion of this kind one must rely heavily on intuitive
     judgment, and that can sometimes be wrong. So we don
     article expresses more than a crude approximation to the truth.
232. All the same, we are reasonably confident that the general outlines of the
     picture we have painted here are roughly correct. M
Just one possible weak
     point needs to be mentioned. We have portrayed leftism in its modern form
     as a phenomenon peculiar to our time and as a symptom of the disruption of
     the power process. But we might possibly be wrong about this.
     Oversocialized types who try to satisfy their drive for power by imposing
     their morality on everyone have certainly been around for a long time. But
     we THINK that the decisive role played by feelings of inferiority, low
     self-esteem, powerlessneM
ss, identification with victims by people who are
     not themselves victims, is a peculiarity of modern leftism. Identification
     with victims by people not themselves victims can be seen to some extent in
     19th century leftism and early Christianity but as far as we can make out,
     symptoms of low self-esteem, etc., were not nearly so evident in these
     movements, or in any other movements, as they are in modern leftism. But we
     are not in a position to assert confidently that no such moveM
     existed prior to modern leftism. This is a significant question to which
     historians ought to give their attention.
1. (Paragraph 19) We are asserting that ALL, or even most, bullies and ruthless
   competitors suffer from feelings of inferiority.
2. (Paragraph 25) During the Victorian period many oversocialized people
   suffered from serious psychological problems as a result of repressing or
   trying to repress their sexual feelings. Freud apparently based his theories
eople of this type. Today the focus of socialization has shifted from sex
3. (Paragraph 27) Not necessarily including specialists in engineering or the
4. (Paragraph 28) There are many individuals of the middle and upper classes who
   resist some of these values, but usually their resistance is more or less
   covert. Such resistance appears in the mass media only to a very limited
   extent. The main thrust of propaganda in our society is in favor of the
   The main reason why these values have become, so to speak, the official values
   of our society is that they are useful to the industrial system. Violence is
   discouraged because it disrupts the functioning of the system. Racism is
   discouraged because ethnic conflicts also disrupt the system, and
   discrimination wastes the talents of minority-group members who could be
   useful to the system. Poverty must be
 because the underclass causes
   problems for the system and contacM
t with the underclass lowers the morale of
   the other classes. Women are encouraged to have careers because their talents
   are useful to the system and, more importantly, because by having regular
   jobs women become better integrated into the system and tied directly to it
   rather than to their families. This helps to weaken family solidarity. (The
   leaders of the system say they want to strengthen the family, but they really
   mean is that they want the family to serve as an effective tool for
cializing children in accord with the needs of the system. We argue in
   paragraphs 51, 52 that the system cannot afford to let the family or other
   small-scale social groups be strong or autonomous.)
5. (Paragraph 42) It may be argued that the majority of people don
   make their own decisions but want leaders to do their thinking for them.
   There is an element of truth in this. People like to make their own decisions
   in small matters, but making decisions on difficult, fundamental questiM
   requires facing up to psychological conflict, and most people hate
   psychological conflict. Hence they tend to lean on others in making difficult
   decisions. But it does not follow that they like to have decisions imposed
   upon them without having any opportunity to influence those decisions. The
   majority of people are natural followers, not leaders, but they like to have
   direct personal access to their leaders, they want to be able to influence
   the leaders and participate to some extenM
t in making even the difficult
   decisions. At least to that degree they need autonomy.
6. (Paragraph 44) Some of the symptoms listed are similar to those shown by
   To explain how these symptoms arise from deprivation with respect to the
   Common-sense understanding of human nature tells one that lack of goals whose
   attainment requires effort leads to boredom and that boredom, long continued,
   often leads eventually to depression. Failure to attain goals leaM
   frustration and lowering of self-esteem. Frustration leads to anger, anger to
   aggression, often in the form of spouse or child abuse. It has been shown that
   long-continued frustration commonly leads to depression and that depression
   tends to cause guilt, sleep disorders, eating disorders and bad feelings about
   oneself. Those who are tending toward depression seek pleasure as an antidote;
   hence insatiable hedonism and excessive sex, with perversions as a means of
   getting new kicks. M
Boredom too tends to cause excessive pleasure-seeking since,
   lacking other goals, people often use pleasure as a goal. See accompanying
   The foregoing is a simplification. Reality is more complex, and of course,
   deprivation with respect to the power process is not the ONLY cause of the
   symptoms described.
   By the way, when we mention depression we do not necessarily mean depression
   that is severe enough to be treated by a psychiatrist. Often only mild forms of
 are involved. And when we speak of goals we do not necessarily mean
   long-term, thought-out goals. For many or most people through much of human
   history, the goals of a hand-to-mouth existence (merely providing oneself and
s family with food from day to day) have been quite sufficient.
7. (Paragraph 52) A partial exception may be made for a few passive,
   inward-looking groups, such as the Amish, which have little effect on the
   wider society. Apart from these, some genuine small-scale commuM
   exist in America today. For instance, youth gangs and
   regards them as dangerous, and so they are, because the members of these
   groups are loyal primarily to one another rather than to the system, hence
   the system cannot control them.
   Or take the gypsies. The gypsies commonly get away with theft and fraud because
   their loyalties are such that they can always get other gypsies to give
 their innocence. Obviously the system wouldM
   serious trouble if too many people belonged to such groups.
   Some of the early-20th century Chinese thinkers who were concerned with
   modernizing China recognized the necessity breaking down small-scale social
   groups such as the family:
(According to Sun Yat-sen) the Chinese people needed
   a new surge of patriotism, which would lead to a transfer of loyalty from the
   family to the state.... (According to Li Huang) traditional attachments,
   particularly to the family had to be abaM
ndoned if nationalism were to develop in
Chinese Political Thought in the Twentieth Century,
   page 125, page 297.)
8. (Paragraph 56) Yes, we know that 19th century America had its problems, and
   serious ones, but for the sake of brevity we have to express ourselves in
   simplified terms.
9. (Paragraph 61) We leave aside the
 We are speaking of the
10. (Paragraph 62) Some social scientists, educators,
als and the like are doing their best to push the social drives
    into group 1 by trying to see to it that everyone has a satisfactory social
11. (Paragraphs 63, 82) Is the drive for endless material acquisition really an
    artificial creation of the advertising and marketing industry? Certainly
    there is no innate human drive for material acquisition. There have been
    many cultures in which people have desired little material wealth beyond
    what was necessary to satisfy their basic phM
ysical needs (Australian
    aborigines, traditional Mexican peasant culture, some African cultures). On
    the other hand there have also been many pre-industrial cultures in which
    material acquisition has played an important role. So we can
s acquisition-oriented culture is exclusively a creation of the
    advertising and marketing industry. But it is clear that the advertising and
    marketing industry has had an important part in creating that culture. The
ations that spend millions on advertising wouldn
    that kind of money without solid proof that they were getting it back in
    increased sales. One member of FC met a sales manager a couple of years ago
    who was frank enough to tell him,
Our job is to make people buy things they
 He then described how an untrained novice could
    present people with the facts about a product, and make no sales at all,
    while a trained and experienced professionM
al salesman would make lots of
    sales to the same people. This shows that people are manipulated into buying
12. (Paragraph 64) The problem of purposelessness seems to have become less
    serious during the last 15 years or so, because people now feel less secure
    physically and economically than they did earlier, and the need for security
    provides them with a goal. But purposelessness has been replaced by
    frustration over the difficulty of attaining securiM
ty. We emphasize the
    problem of purposelessness because the liberals and leftists would wish to
    solve our social problems by having society guarantee everyone
    but if that could be done it would only bring back the problem of
    purposelessness. The real issue is not whether society provides well or
    poorly for people
s security; the trouble is that people are dependent on
    the system for their security rather than having it in their own hands.
    This, by the way, is part M
of the reason why some people get worked up about
    the right to bear arms; possession of a gun puts that aspect of their
    security in their own hands.
13. (Paragraph 66) Conservatives
 efforts to decrease the amount of government
    regulation are of little benefit to the average man. For one thing, only
    a fraction of the regulations can be eliminated because most regulations are
    necessary. For another thing, most of the deregulation affects business
    rather than the average individual, sM
o that its main effect is to take power
    from the government and give it to private corporations. What this means for
    the average man is that government interference in his life is replaced by
    interference from big corporations, which may be permitted, for example, to
    dump more chemicals that get into his water supply and give him cancer. The
    conservatives are just taking the average man for a sucker, exploiting his
    resentment of Big Government to promote the power of Big Business.
 (Paragraph 73) When someone approves of the purpose for which propaganda is
    being used in a given case, he generally calls it
    it some similar euphemism. But propaganda is propaganda regardless of the
    purpose for which it is used.
15. (Paragraph 83) We are not expressing approval or disapproval of the Panama
    invasion. We only use it to illustrate a point.
16. (Paragraph 95) When the American colonies were under British rule there were
    fewer and less effectiveM
 legal guarantees of freedom than there were after
    the American Constitution went into effect, yet there was more personal
    freedom in pre-industrial America, both before and after the War of
    Independence, than there was after the Industrial Revolution took hold in
    this country. We quote from
Violence in America: Historical and Comparative
 edited by Hugh Davis Graham and Ted Robert Gurr, Chapter 12
    by Roger Lane, pages 476-478:
The progressive heighteningM
 of standards of propriety, and with it the
    increasing reliance on official law enforcement (in 19th century America) ...
    were common to the whole society.... [T]he change in social behavior is so long
    term and so widespread as to suggest a connection with the most fundamental of
    contemporary social processes; that of industrial urbanization
Massachusetts in 1835 had a population of some 660,940, 81 percent
    rural, overwhelmingly preindustrial and native born. It
    considerable personal freedom. Whether teamsters, farmers or artisans, they were
    all accustomed to setting their own schedules, and the nature of their work made
    them physically independent of each other.... Individual problems, sins or even
    crimes, were not generally cause for wider social concern....
    the twin movements to the city and to the factory, both just gathering force in
    1835, had a progressive effect on personal behavior throughout the 19tM
    and into the 20th. The factory demanded regularity of behavior, a life governed
    by obedience to the rhythms of clock and calendar, the demands of foreman and
    supervisor. In the city or town, the needs of living in closely packed
    neighborhoods inhibited many actions previously unobjectionable. Both blue- and
    white-collar employees in larger establishments were mutually dependent on their
    fellows; as one man
s work fit into anther
The results of the new organization of life and work were apparent by 1900,
    when some 76 percent of the 2,805,346 inhabitants of Massachusetts were
    classified as urbanites. Much violent or irregular behavior which had been
    tolerable in a casual, independent society was no longer acceptable in the more
    formalized, cooperative atmosphere of the later period.... The move to the
    cities had, in short, produced a more tractable, more socialized, more
eneration than its predecessors.
17. (Paragraph 117) Apologists for the system are fond of citing cases in which
    elections have been decided by one or two votes, but such cases are rare.
18. (Paragraph 119)
Today, in technologically advanced lands, men live very
    similar lives in spite of geographical, religious, and political
    differences. The daily lives of a Christian bank clerk in Chicago,
    a Buddhist bank clerk in Tokyo, and a Communist bank clerk in Moscow are far
    more alike thanM
 the life of any one of them is like that of any single man
    who lived a thousand years ago. These similarities are the result of
    a common technology....
 L. Sprague de Camp,
The Ancient Engineers,
    Ballantine edition, page 17.
    The lives of the three bank clerks are not IDENTICAL. Ideology does have SOME
    effect. But all technological societies, in order to survive, must evolve along
    APPROXIMATELY the same trajectory.
19. (Paragraph 123) Just think an irresponsible genetic enM
gineer might create
    a lot of terrorists.
20. (Paragraph 124) For a further example of undesirable consequences of medical
    progress, suppose a reliable cure for cancer is discovered. Even if the
    treatment is too expensive to be available to any but the elite, it will
    greatly reduce their incentive to stop the escape of carcinogens into the
21. (Paragraph 128) Since many people may find paradoxical the notion that
    a large number of good things can add up to a bad thing, weM
    an analogy. Suppose Mr. A is playing chess with Mr. B. Mr. C, a Grand
    Master, is looking over Mr. A
s shoulder. Mr. A of course wants to win his
    game, so if Mr. C points out a good move for him to make, he is doing Mr.
    A a favor. But suppose now that Mr. C tells Mr. A how to make ALL of his
    moves. In each particular instance he does Mr. A a favor by showing him his
    best move, but by making ALL of his moves for him he spoils his game, since
    there is not point in M
s playing the game at all if someone else makes
    The situation of modern man is analogous to that of Mr. A. The system makes an
s life easier for him in innumerable ways, but in doing so it
    deprives him of control over his own fate.
22. (Paragraph 137) Here we are considering only the conflict of values within
    the mainstream. For the sake of simplicity we leave out of the picture
 values like the idea that wild nature is more importM
    human economic welfare.
23. (Paragraph 137) Self-interest is not necessarily MATERIAL self-interest. It
    can consist in fulfillment of some psychological need, for example, by
s own ideology or religion.
24. (Paragraph 139) A qualification: It is in the interest of the system to
    permit a certain prescribed degree of freedom in some areas. For example,
    economic freedom (with suitable limitations and restraints) has proved
    effective in promoting economic growth.M
 But only planned, circumscribed,
    limited freedom is in the interest of the system. The individual must always
    be kept on a leash, even if the leash is sometimes long (see paragraphs 94,
25. (Paragraph 143) We don
t mean to suggest that the efficiency or the
    potential for survival of a society has always been inversely proportional
    to the amount of pressure or discomfort to which the society subjects
    people. That certainly is not the case. There is good reason to believe that
    many primitive societies subjected people to less pressure than European
    society did, but European society proved far more efficient than any
    primitive society and always won out in conflicts with such societies
    because of the advantages conferred by technology.
26. (Paragraph 147) If you think that more effective law enforcement is
    unequivocally good because it suppresses crime, then remember that crime as
    defined by the system is not necessarily what YOU would call crime. Today,
 smoking marijuana is a
 and, in some places in the U.S., so is
    possession of an unregistered handgun. Tomorrow, possession of ANY firearm,
    registered or not, may be made a crime, and the same thing may happen with
    disapproved methods of child-rearing, such as spanking. In some countries,
    expression of dissident political opinions is a crime, and there is no
    certainty that this will never happen in the U.S., since no constitution or
    political system lasts forever.
If a society needs a large, powerful law enforcement establishment, then there
    is something gravely wrong with that society; it must be subjecting people to
    severe pressures if so many refuse to follow the rules, or follow them only
    because forced. Many societies in the past have gotten by with little or no
    formal law- enforcement.
27. (Paragraph 151) To be sure, past societies have had means of influencing
    human behavior, but these have been primitive and of low effectiveness
d with the technological means that are now being developed.
28. (Paragraph 152) However, some psychologists have publicly expressed opinions
    indicating their contempt for human freedom. And the mathematician Claude
    Shannon was quoted in Omni (August 1987) as saying,
I visualize a time when
    we will be to robots what dogs are to humans, and I
29. (Paragraph 154) This is no science fiction! After writing paragraph 154 we
    came across an article in ScientifM
ic American according to which scientists
    are actively developing techniques for identifying possible future criminals
    and for treating them by a combination of biological and psychological
    means. Some scientists advocate compulsory application of the treatment,
    which may be available in the near future. (See
Seeking the Criminal
 by W. Wayt Gibbs, Scientific American, March 1995.) Maybe you
    think this is OK because the treatment would be applied to those who might
ecome violent criminals. But of course it won
t stop there. Next,
    a treatment will be applied to those who might become drunk drivers (they
    endanger human life too), then perhaps to peel who spank their children,
    then to environmentalists who sabotage logging equipment, eventually to
    anyone whose behavior is inconvenient for the system.
30. (Paragraph 184) A further advantage of nature as a counter-ideal to
    technology is that, in many people, nature inspires the kind of reverence
at is associated with religion, so that nature could perhaps be idealized
    on a religious basis. It is true that in many societies religion has served
    as a support and justification for the established order, but it is also
    true that religion has often provided a basis for rebellion. Thus it may be
    useful to introduce a religious element into the rebellion against
    technology, the more so because Western society today has no strong
    religious foundation. Religion, nowadays either is used M
    transparent support for narrow, short-sighted selfishness (some
    conservatives use it this way), or even is cynically exploited to make easy
    money (by many evangelists), or has degenerated into crude irrationalism
    (fundamentalist protestant sects,
), or is simply stagnant
    (Catholicism, main-line Protestantism). The nearest thing to a strong,
    widespread, dynamic religion that the West has seen in recent times has been
    the quasi-religion of leftism, but leftisM
m today is fragmented and has no
    clear, unified, inspiring goal.
    Thus there is a religious vacuum in our society that could perhaps be filled by
    a religion focused on nature in opposition to technology. But it would be
    a mistake to try to concoct artificially a religion to fill this role. Such an
    invented religion would probably be a failure. Take the
    example. Do its adherents REALLY believe in it or are they just play-acting? If
    they are just play-actiM
ng their religion will be a flop in the end.
    It is probably best not to try to introduce religion into the conflict of nature
    vs. technology unless you REALLY believe in that religion yourself and find that
    it arouses a deep, strong, genuine response in many other people.
31. (Paragraph 189) Assuming that such a final push occurs. Conceivably the
    industrial system might be eliminated in a somewhat gradual or piecemeal
    fashion (see paragraphs 4, 167 and Note 4).
32. (Paragraph 193) It M
is even conceivable (remotely) that the revolution might
    consist only of a massive change of attitudes toward technology resulting in
    a relatively gradual and painless disintegration of the industrial system.
    But if this happens we
ll be very lucky. It
s far more probably that the
    transition to a nontechnological society will be very difficult and full of
    conflicts and disasters.
33. (Paragraph 195) The economic and technological structure of a society are
    far more important than M
its political structure in determining the way the
    average man lives (see paragraphs 95, 119 and Notes 16, 18).
34. (Paragraph 215) This statement refers to our particular brand of anarchism.
    A wide variety of social attitudes have been called
    be that many who consider themselves anarchists would not accept our
    statement of paragraph 215. It should be noted, by the way, that there is
    a nonviolent anarchist movement whose members probably would not accept FC
 as anarchist and certainly would not approve of FC
35. (Paragraph 219) Many leftists are motivated also by hostility, but the
    hostility probably results in part from a frustrated need for power.
36. (Paragraph 229) It is important to understand that we mean someone who
    sympathizes with these MOVEMENTS as they exist today in our society. One who
    believes that women, homosexuals, etc., should have equal rights is not
    necessary a leftist. The feminist, gay rights, etc., moveM
ments that exist in
    our society have the particular ideological tone that characterizes leftism,
    and if one believes, for example, that women should have equal rights it
    does not necessarily follow that one must sympathize with the feminist
    movement as it exists today.
If copyright problems make it impossible for this long quotation to be printed,
then please change Note 16 to read as follows:
16. (Paragraph 95) When the American colonies were under British rule there were
 effective legal guarantees of freedom than there were after
    the American Constitution went into effect, yet there was more personal
    freedom in pre-industrial America, both before and after the War of
    Independence, than there was after the Industrial Revolution took hold in
    this country. In
Violence in America: Historical and Comparative
 edited by Hugh Davis Graham and Ted Robert Gurr, Chapter 12
    by Roger Lane, it is explained how in pre-industrial America the averaL
    person had greater independence and autonomy than he does today, and how the
    process of industrialization necessarily led to the restriction of personal
SjLP1ero q puso nonfinancial data en bloque es 1ero q dijo
c/Foundry USA Pool #dropgold/
IjGREFUND:A1160A936F21C75928B8CB609A64DB506EEDAC042200A18094A68E7E385D9A2B
LjJProcertif:578a55eff2b5a508af6533a09449ee3b0fd200cec5f2688dc8f004490ce3bc87
&"""""""""""""""""""""""""""""""""""""""r
text/plain;charset=utf-8
text/html;charset=utf-8
    "title": "Ordinal Loops",
    "description": "Do Not Fiat",
    "storyline": "First chapter is observing the hostile FIAT environment in which Bitcoin has been born from the ashes of GFC. Such a contemporary landscape remains a living organism - loop. Furiously, Bitcoin ASCII fights the army of five main government currencies - ad infinitum. Conceptualization starts with 'Object 0' being a circular donut of currency interaction. Over time, these objects are deciphered into abstraction [Object 1 tM
o 5] and the 'Object 6' has the Bitcoin logo highlighted and colour coded demonstrating adversity against the government issued currency.",
    "website": "https://www.ordinalloops.xyz/",
    "twitter": "https://twitter.com/Ordinal_Loops"
{	"Object":	"0"	"inscription": 	"c2fe83b53f4eb0b8ba2b4748884727887f840332ef02f3f79b455fcf3a3d11ebi0",	}
{	"Object":	"1"	"inscription": 	"2e785256005b2aee00fd22038d99891e0026d2620e3c4180c9c2d9706fe4b364i0",	}
{	"Object":	"2"	"inscription": 	"dd1f515b828eedabd6b0M
be147cf611ca08c20f39058feee9b96efaa2eba43d9di0",	}
{	"Object":	"3"	"inscription": 	"821eec8cf7672e232aa34998d0a92e638decd5aab9f36c30bccdaedec662a829i0",	}
{	"Object":	"4"	"inscription": 	"fe00c5cb1d042621025b1a9bbb36d682607f0efe1182ec5109840d3fccd7ce4di0",	}
{	"Object":	"5"	"inscription": 	"9c5c6e9b6769fd5eda0aef192d9e39a6133b28ffb3ea2ada5e40b04266485e5bi0",	}
{	"Object":	"6"	"inscription": 	"51db0e3702a0679e8adedeab75d58bc1cabfc5f3d53ff6f59e07de62365dc124i0",	}
6j4ion:1.QmP72xL8L516W516ihb8dJxkusim5SqHsqovAXfg5mhMgL
Aj?=:ETH.ETH:0xdCb7C510423E8c197FD8503d161a9cc4F462086c:38300:te:0
)j'11hLbkAPQzqhohneXthhouZy16KQXmUMGGqGrRh
FjDOUT:D139DEC2EABAA85DD8DC25C7F1BFA35B7657CE445794F6885F8FE83965EAC0A8
FjDOUT:D7C3ED8D9992C353263C9ECD38B3C73B2BC8D8212A456E68A6427C47B293EBC0
CjA=:AVAX.AVAX:0xe66fbc8be19bd6b60a7fdc743a1019435ee0a04f:34722901:t
!22222222222222222222222222222222222222222222222222
1\ Powered by Luxor Tech \
IjGREFUND:16FF38E52C23A71AD390541B9339499F5449CFE3FACB034ABAA8AE02329B73D7
Ahttp://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.5.0"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" photoshop:ColorMode="3" photoshop:ICCProfile="M
sRGB IEC61966-2.1" xmp:ModifyDate="2023-02-02T18:08:59-05:00" xmp:MetadataDate="2023-02-02T18:08:59-05:00"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="produced" stEvt:softwareAgent="Affinity Photo 1.10.6" stEvt:when="2023-02-02T18:08:59-05:00"/> </rdf:Seq> </xmpMM:History> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                       M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                  <?xpacket end="w"?>
 .)10.)-,3:J>36F7,-@WAFLNRSR2>ZaZP`JQRO
&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about=M
"" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-01T14:55:30+03:00" xmp:ModifyDate="2023-02-01T14:55:30+03:00" dc:format="image/jpeg" xmpMM:M
InstanceID="xmp.iid:29c0327d-f970-8344-90bf-be98edc57fc5" xmpMM:DocumentID="adobe:docid:photoshop:d288bca7-b69c-fa45-9c20-27c80addcac8" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stM
Evt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:f1d9e2a9-67df-2e4f-a24f-e2f0dee4dcdd" stEvt:when="2023-02-01T14:55:30+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvtM
:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:29c0327d-f970-8344-90bf-be98edc57fc5" stEvt:when="2023-02-01T14:55:30+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:f1d9e2a9-67df-2e4f-a24f-e2f0dee4dcdd" stRef:documentID="adobe:docid:photoshop:7827a9af-d813-f04d-b2d1-dd034885cb76" stRef:originalDocumentID="xmp.did:8653de18-59b9-7M
643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                 M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                        <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
EzTXtRaw profile type exif
iTXtXML:com.adobe.xmp
" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2"M
 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <rdf:Description rdf:about=""
    xmlns:aux="http://ns.adobe.com/exif/1.0/aux/"
   aux:SerialNumber="20f3f16cb9daf2995495936439d4c8e848849c0c4f91f20e9a0939334ccb1225"/>


                                                     M





                                                                    M





                                                                                   M




                                                                                                  M



'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
  <title>Bitcoin Face</title>
  <g style="isolation:isolate"><rect id="Background-2" width="1025" height="1025" style="fill:#3d4b8a" /><g id="Body-4"><path d="M504,494.22h0A412.66,412.66,0,0,1,916.61,906.88V1003a0,0,0,0,1,0,0H91.3a0,0,0,0,1,0,0V906.88A412.66,412.66,0,0,1,504,494.22Z" style="fill:#6c1908" /></g><g id="Head-11"><path d="M164.72,490.82C164.72,683.66,317,840,504.85,840S845,683.66,845,490.82" transform="translate(0.28)" style="fill:#f5b659M
" /><path d="M186,490.82c0,180.79,142.76,327.34,318.87,327.34S823.71,671.61,823.71,490.82" transform="translate(0.28)" style="fill:#ecdea0" /><path d="M228.5,490.82c0,156.68,123.72,283.7,276.35,283.7s276.34-127,276.34-283.7" transform="translate(0.28)" style="fill:#e18d27" /><polygon points="506.79 774.52 503.45 774.52 503.45 510.93 781.47 510.93 781.47 514.36 506.79 514.36 506.79 774.52" style="fill:#ecdea0" /><polygon points="695.33 688.51 497.93 508.38 760.74 598.31 759.68 601.56 512.31 516.91 697.55 685.94 695.M
33 688.51" style="fill:#ecdea0" /><polygon points="609.89 753.4 503.6 513.35 506.64 511.94 612.93 751.98 609.89 753.4" style="fill:#ecdea0" /><polygon points="506.79 774.52 503.45 774.52 503.45 514.36 228.77 514.36 228.77 510.93 506.79 510.93 506.79 774.52" style="fill:#ecdea0" /><polygon points="314.91 688.51 312.69 685.94 497.93 516.91 250.56 601.56 249.5 598.31 512.31 508.38 314.91 688.51" style="fill:#ecdea0" /><polygon points="400.35 753.4 397.31 751.98 503.6 511.94 506.64 513.35 400.35 753.4" style="fill:#ecdM
ea0" /><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M664.28,601.65A12.63,12.63,0,1,1,676.58,589,12.47,12.47,0,0,1,664.28,601.65Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.09,9.09,0,0,0,664.28,579.83Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M643,579.83a12.63,12.63,0,1,1,12.3-12.63A12.49,12.49,0,0,1,643,579.83ZM643,558a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,643,558Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-bM
lend-mode:overlay"><path d="M738.68,579.83c-12.64,0-22.93-10.56-22.93-23.54s10.29-23.54,22.93-23.54,22.92,10.56,22.92,23.54S751.32,579.83,738.68,579.83Zm0-43.65c-10.8,0-19.59,9-19.59,20.11s8.79,20.11,19.59,20.11,19.58-9,19.58-20.11S749.48,536.18,738.68,536.18Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M685.53,536.18a12.63,12.63,0,1,1,12.3-12.63A12.47,12.47,0,0,1,685.53,536.18Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.08,9.08,0,0,0,685.53,514.36Z" transformM
="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M483.59,732.59c-12.64,0-22.93-10.56-22.93-23.54s10.29-23.54,22.93-23.54,22.93,10.56,22.93,23.54S496.23,732.59,483.59,732.59Zm0-43.65c-10.8,0-19.59,9-19.59,20.11s8.79,20.11,19.59,20.11,19.58-9,19.58-20.11S494.39,688.94,483.59,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M451.7,688.94A12.63,12.63,0,1,1,464,676.32,12.48,12.48,0,0,1,451.7,688.94M
Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,451.7,667.12Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M387.93,601.65A12.63,12.63,0,1,1,400.23,589,12.48,12.48,0,0,1,387.93,601.65Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.09,9.09,0,0,0,387.93,579.83Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M324.16,558a12.63,12.63,0,1,1,12.3-12.62A12.47,12.47,0,0,1,324.16,558Zm0-21.82a9.2,9.2,0,1,0,9,9.2AM
9.09,9.09,0,0,0,324.16,536.18Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M260.38,558a12.63,12.63,0,1,1,12.3-12.62A12.47,12.47,0,0,1,260.38,558Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,260.38,536.18Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M292.27,645.3c-12.64,0-22.93-10.56-22.93-23.54s10.29-23.54,22.93-23.54,22.93,10.56,22.93,23.54S304.91,645.3,292.27,645.3Zm0-43.65c-10.8M
,0-19.59,9-19.59,20.11s8.79,20.11,19.59,20.11,19.59-9,19.59-20.11S303.07,601.65,292.27,601.65Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M324.16,667.12a12.63,12.63,0,1,1,12.3-12.63A12.48,12.48,0,0,1,324.16,667.12Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.09,9.09,0,0,0,324.16,645.3Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M600.5,667.12a12.63,12.63,0,1,1,12.3-12.63A12.48,12.48,0,0,1,600.M
5,667.12Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.08,9.08,0,0,0,600.5,645.3Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M664.28,710.76a12.63,12.63,0,1,1,12.3-12.62A12.47,12.47,0,0,1,664.28,710.76Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,664.28,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M611.13,732.59c-12.64,0-22.92-10.56-22.92-23.54s10.28-23.54,22.92-23.54,22.93,10.56,22.93,23M
.54S623.77,732.59,611.13,732.59Zm0-43.65c-10.8,0-19.58,9-19.58,20.11s8.78,20.11,19.58,20.11,19.59-9,19.59-20.11S621.94,688.94,611.13,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M706.79,645.3a12.63,12.63,0,1,1,12.3-12.63A12.49,12.49,0,0,1,706.79,645.3Zm0-21.83a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,706.79,623.47Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M473,579.83a12.63,12.M
63,0,1,1,12.3-12.63A12.49,12.49,0,0,1,473,579.83ZM473,558a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,473,558Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M430.45,536.18a12.63,12.63,0,1,1,12.29-12.63A12.48,12.48,0,0,1,430.45,536.18Zm0-21.82a9.2,9.2,0,1,0,8.95,9.19A9.09,9.09,0,0,0,430.45,514.36Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M579.25,558a12.63,12.63,0,1,1,12.3-12.62A12.48,12.48M
,0,0,1,579.25,558Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,579.25,536.18Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M558,601.65A12.63,12.63,0,1,1,570.29,589,12.48,12.48,0,0,1,558,601.65Zm0-21.82a9.2,9.2,0,1,0,9,9.19A9.09,9.09,0,0,0,558,579.83Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M494.22,649.82a17.15,17.15,0,1,1,16.7-17.15A17,17,0,0,1,494.22,649.82Zm0-30.87a13.72,13.72M
,0,1,0,13.36,13.72A13.56,13.56,0,0,0,494.22,619Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M536.73,710.76A12.63,12.63,0,1,1,549,698.14,12.48,12.48,0,0,1,536.73,710.76Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,536.73,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M558,758.93a17.15,17.15,0,1,1,16.7-17.15A16.95,16.95,0,0,1,558,758.93Zm0-30.86a13.72,13.72,0,1,0,13.36,13.71A13M
.55,13.55,0,0,0,558,728.07Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M366.67,710.76A12.63,12.63,0,1,1,379,698.14,12.48,12.48,0,0,1,366.67,710.76Zm0-21.82a9.2,9.2,0,1,0,9,9.2A9.09,9.09,0,0,0,366.67,688.94Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><rect x="164.72" y="490.82" width="680.24" height="21.82" transform="translate(1009.97 1003.46) rotate(-180)" style="fill:#aea4b3;opacity:0.52;mix-blend-mode:overlay" /><path d="M845.81,50M
7.17C845.81,314.33,693.53,158,505.69,158S165.57,314.33,165.57,507.17" transform="translate(0.28)" style="fill:#f5b659" /><path d="M824.55,507.17c0-180.79-142.76-327.35-318.86-327.35S186.82,326.38,186.82,507.17" transform="translate(0.28)" style="fill:#ecdea0" /><path d="M782,507.17c0-156.69-123.73-283.7-276.35-283.7s-276.35,127-276.35,283.7" transform="translate(0.28)" style="fill:#e18d27" /><polygon points="504.29 223.47 507.63 223.47 507.63 487.06 229.62 487.06 229.62 483.63 504.29 483.63 504.29 223.47" style="fiM
ll:#ecdea0" /><polygon points="315.76 309.48 513.15 489.61 250.35 399.68 251.4 396.43 498.77 481.07 313.54 312.04 315.76 309.48" style="fill:#ecdea0" /><polygon points="401.19 244.58 507.49 484.63 504.44 486.05 398.15 246 401.19 244.58" style="fill:#ecdea0" /><polygon points="504.29 223.47 507.63 223.47 507.63 483.63 782.31 483.63 782.31 487.06 504.29 487.06 504.29 223.47" style="fill:#ecdea0" /><polygon points="696.17 309.48 698.39 312.04 513.15 481.07 760.53 396.43 761.58 399.68 498.77 489.61 696.17 309.48" styleM
="fill:#ecdea0" /><polygon points="610.73 244.58 613.77 246 507.49 486.05 504.44 484.63 610.73 244.58" style="fill:#ecdea0" /><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M346.26,396.34A12.63,12.63,0,1,1,334,409,12.48,12.48,0,0,1,346.26,396.34Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,346.26,418.16Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M367.51,418.16a12.63,12.63,0,1,1-12.29,12.63A12.48,12.48,0,0,1,367.51,418.16Zm0,21.82a9.2,9.2M
,0,1,0-8.95-9.19A9.08,9.08,0,0,0,367.51,440Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M271.85,418.16c12.65,0,22.93,10.56,22.93,23.54s-10.28,23.54-22.93,23.54-22.92-10.56-22.92-23.54S259.21,418.16,271.85,418.16Zm0,43.65c10.81,0,19.59-9,19.59-20.11s-8.78-20.11-19.59-20.11-19.58,9-19.58,20.11S261.05,461.81,271.85,461.81Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M325,461.81a12.63M
,12.63,0,1,1-12.3,12.62A12.48,12.48,0,0,1,325,461.81Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,325,483.63Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M527,265.4c12.64,0,22.92,10.56,22.92,23.54S539.59,312.48,527,312.48,504,301.92,504,288.94,514.3,265.4,527,265.4Zm0,43.65c10.8,0,19.58-9,19.58-20.11s-8.78-20.11-19.58-20.11-19.59,9-19.59,20.11S516.15,309.05,527,309.05Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mM
ix-blend-mode:overlay"><path d="M558.83,309.05a12.63,12.63,0,1,1-12.3,12.62A12.47,12.47,0,0,1,558.83,309.05Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,558.83,330.87Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M622.61,396.34A12.63,12.63,0,1,1,610.31,409,12.47,12.47,0,0,1,622.61,396.34Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,622.61,418.16Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><M
path d="M686.38,440a12.63,12.63,0,1,1-12.3,12.63A12.49,12.49,0,0,1,686.38,440Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,686.38,461.81Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M750.15,440a12.63,12.63,0,1,1-12.3,12.63A12.49,12.49,0,0,1,750.15,440Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,750.15,461.81Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M718.26,352.69c12.65,0,22.93M
,10.56,22.93,23.54s-10.28,23.54-22.93,23.54-22.92-10.56-22.92-23.54S705.62,352.69,718.26,352.69Zm0,43.65c10.81,0,19.59-9,19.59-20.11s-8.78-20.11-19.59-20.11-19.58,9-19.58,20.11S707.46,396.34,718.26,396.34Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M686.38,330.87a12.63,12.63,0,1,1-12.3,12.62A12.48,12.48,0,0,1,686.38,330.87Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,686.38,352.69Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="M
opacity:0.52;mix-blend-mode:overlay"><path d="M410,330.87a12.63,12.63,0,1,1-12.3,12.62A12.48,12.48,0,0,1,410,330.87Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,410,352.69Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M346.26,287.22A12.63,12.63,0,1,1,334,299.85,12.49,12.49,0,0,1,346.26,287.22Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,346.26,309.05Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlM
ay"><path d="M399.4,265.4c12.64,0,22.93,10.56,22.93,23.54S412,312.48,399.4,312.48s-22.93-10.56-22.93-23.54S386.76,265.4,399.4,265.4Zm0,43.65c10.8,0,19.59-9,19.59-20.11s-8.79-20.11-19.59-20.11-19.59,9-19.59,20.11S388.6,309.05,399.4,309.05Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M303.74,352.69a12.63,12.63,0,1,1-12.3,12.63A12.48,12.48,0,0,1,303.74,352.69Zm0,21.82a9.2,9.2,0,1,0-9-9.19A9.09,9.09,0,0,0,303.74,374.51Z" transform="translate(0.28)" styM
le="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M537.58,418.16a12.63,12.63,0,1,1-12.3,12.63A12.47,12.47,0,0,1,537.58,418.16Zm0,21.82a9.2,9.2,0,1,0-9-9.19A9.08,9.08,0,0,0,537.58,440Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M580.09,461.81a12.63,12.63,0,1,1-12.3,12.62A12.48,12.48,0,0,1,580.09,461.81Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,580.09,483.63Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><gM
 style="opacity:0.52;mix-blend-mode:overlay"><path d="M431.29,440A12.63,12.63,0,1,1,419,452.61,12.49,12.49,0,0,1,431.29,440Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,431.29,461.81Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M452.54,396.34A12.63,12.63,0,1,1,440.25,409,12.47,12.47,0,0,1,452.54,396.34Zm0,21.82a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,452.54,418.16Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blendM
-mode:overlay"><path d="M516.32,348.17a17.15,17.15,0,1,1-16.7,17.15A16.95,16.95,0,0,1,516.32,348.17Zm0,30.86A13.72,13.72,0,1,0,503,365.32,13.55,13.55,0,0,0,516.32,379Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M473.8,287.22a12.63,12.63,0,1,1-12.3,12.63A12.49,12.49,0,0,1,473.8,287.22Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,473.8,309.05Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><patM
h d="M452.54,239.06a17.15,17.15,0,1,1-16.7,17.14A17,17,0,0,1,452.54,239.06Zm0,30.86a13.72,13.72,0,1,0-13.36-13.72A13.56,13.56,0,0,0,452.54,269.92Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><g style="opacity:0.52;mix-blend-mode:overlay"><path d="M643.86,287.22a12.63,12.63,0,1,1-12.3,12.63A12.49,12.49,0,0,1,643.86,287.22Zm0,21.83a9.2,9.2,0,1,0-9-9.2A9.09,9.09,0,0,0,643.86,309.05Z" transform="translate(0.28)" style="fill:#aea4b3" /></g><rect x="165.84" y="485.34" width="680.24" height="21.82" style="fillM
:#aea4b3;opacity:0.52;mix-blend-mode:overlay" /></g><g id="Face-Accessory-1"><circle cx="516.52" cy="942.46" r="62.02" style="fill:#f96020" /><circle cx="516.52" cy="942.46" r="54.28" style="fill:#d74816" /><rect x="487.05" y="879.79" width="35.52" height="96.79" transform="translate(214.46 1954.46) rotate(-135)" style="fill:#ffa520" /><circle cx="510.95" cy="942.07" r="66.36" style="fill:#f96020" /><circle cx="510.94" cy="942.07" r="58.08" style="fill:#d74816" /><g id="_04CbBX.tif" data-name="04CbBX.tif"><path d="M
M499.36,875.6h5.23a5.28,5.28,0,0,0,1.13.08c1.51.13,3,.28,4.52.52a52.15,52.15,0,0,1,10.43,2.72,53.73,53.73,0,0,1,32.17,33.55,52.41,52.41,0,0,1,2.21,10c.15,1.22.26,2.45.31,3.67a1.63,1.63,0,0,0,.08.82v4.31a1.52,1.52,0,0,0-.08.82,46.85,46.85,0,0,1-.52,5.14,52,52,0,0,1-5.39,16.51,53.57,53.57,0,0,1-43.89,28.75,50.62,50.62,0,0,1-8-.07,52.07,52.07,0,0,1-10.21-1.83,53.13,53.13,0,0,1-29.73-21.46,53,53,0,0,1-9.05-25.57,17,17,0,0,0-.16-1.88c0-.61,0-1.22,0-1.83,0-1.1,0-2.2,0-3.3a.77.77,0,0,0,.07-.4,53.09,53.09,0,0,1,5.25-20.37,M
53.67,53.67,0,0,1,35.15-28.6,54.71,54.71,0,0,1,9.34-1.48A8.57,8.57,0,0,0,499.36,875.6Zm-42,53.5a44.61,44.61,0,1,0,44.59-44.62A44.59,44.59,0,0,0,457.33,929.1Z" transform="translate(9.03 13)" style="fill:#ff9317" /><path d="M515.36,927.51a21.52,21.52,0,0,1,5.48,1.69,11.83,11.83,0,0,1,5.27,4.7,12,12,0,0,1,1.52,4.64,17.76,17.76,0,0,1-.27,6.21,10.87,10.87,0,0,1-6.8,8,25.21,25.21,0,0,1-5.77,1.53c-1.34.21-2.68.35-4,.44-.47,0-.47,0-.47.51v7.94c0,.5,0,.51-.51.51H504c-.56,0-.53,0-.53-.53v-7.68c0-.64.05-.57-.58-.57h-5.8c-.46,M
0-.46,0-.47.48v7.73c0,.59,0,.57-.54.57h-5.74c-.55,0-.55,0-.55-.57,0-2.51,0-5,0-7.53,0-.14,0-.27,0-.41s-.06-.29-.26-.27H476.43c-.24,0-.34-.06-.34-.31,0-1.9,0-3.79,0-5.69,0-.27.11-.35.36-.35,1.18,0,2.36,0,3.54,0a10.18,10.18,0,0,0,2.13-.27,1.92,1.92,0,0,0,1.55-1.57,11.89,11.89,0,0,0,.29-2.85V921.52c0-2.47,0-4.95,0-7.43a13.56,13.56,0,0,0-.27-2.69,2,2,0,0,0-1.71-1.68,13.39,13.39,0,0,0-2.75-.24h-2.66c-.47,0-.47,0-.47-.49,0-1.76,0-3.51,0-5.27,0-.6-.06-.56.54-.57h12.55c.57,0,.57,0,.58-.54v-7.89c0-.2.09-.28.28-.26h6c.61,0,.M
56-.06.56.54,0,2.51,0,5,0,7.53,0,.7-.05.62.64.62H503c.46,0,.46,0,.47-.49v-7.94c0-.2.07-.28.27-.26h6c.59,0,.57-.09.57.58v7.84c0,.39,0,.39.39.42a32.44,32.44,0,0,1,6.11,1,17.64,17.64,0,0,1,3.2,1.2,9.17,9.17,0,0,1,5,6.06,14.22,14.22,0,0,1,.12,7.24,10.31,10.31,0,0,1-4.17,6,18.31,18.31,0,0,1-5.34,2.53C515.55,927.36,515.43,927.34,515.36,927.51Zm-18.76,12.4c0,2.77,0,5.53,0,8.3,0,.44,0,.45.44.45h3a44,44,0,0,0,6.39-.31,15,15,0,0,0,3.66-.93,6.31,6.31,0,0,0,3.8-4.16,12,12,0,0,0,.26-6,6.32,6.32,0,0,0-2.8-4.24A9.11,9.11,0,0,0,50M
8.7,932a23.93,23.93,0,0,0-4.61-.65c-2.39-.14-4.78,0-7.17-.08-.26,0-.34.1-.32.33s0,.24,0,.36Zm0-22.76v4.25c0,1.05,0,2.09,0,3.13,0,.25,0,.37.34.37a68.58,68.58,0,0,0,7.72-.23,14.47,14.47,0,0,0,3.67-.89,5.57,5.57,0,0,0,3.45-4A11.75,11.75,0,0,0,512,915a5.49,5.49,0,0,0-3.83-4.58,18.25,18.25,0,0,0-5-.88c-2-.1-4,0-6,0h-.21c-.17,0-.25.08-.24.25s0,.27,0,.41Z" transform="translate(9.03 13)" style="fill:#ff9317" /></g><circle cx="459.8" cy="882.7" r="13.97" style="fill:#ff9317" /><circle cx="438.84" cy="861.74" r="13.97" styleM
="fill:#ff9317" /><circle cx="417.89" cy="840.79" r="13.97" style="fill:#ff9317" /><circle cx="396.93" cy="819.83" r="13.97" style="fill:#ff9317" /><circle cx="564.57" cy="882.7" r="13.97" style="fill:#f96020" /><circle cx="585.53" cy="861.74" r="13.97" style="fill:#f96020" /><circle cx="606.48" cy="840.79" r="13.97" style="fill:#f96020" /><circle cx="627.44" cy="819.83" r="13.97" style="fill:#f96020" /></g><g id="Earrings-1"><circle cx="141.68" cy="475.44" r="61.24" style="fill:#f26227" /><circle cx="141.68" cy="4M
75.44" r="53.6" style="fill:#d74b27" /><g><path d="M134.36,420.84h4.82a6.06,6.06,0,0,0,1,.07c1.4.12,2.79.26,4.18.48A48.47,48.47,0,0,1,154,423.9a49.56,49.56,0,0,1,29.69,31,47.44,47.44,0,0,1,2,9.2c.13,1.13.24,2.25.28,3.39a1.48,1.48,0,0,0,.07.75v4a1.37,1.37,0,0,0-.07.75,42.22,42.22,0,0,1-.48,4.75,47.88,47.88,0,0,1-5,15.23,49.3,49.3,0,0,1-47.87,26.48,47.84,47.84,0,0,1-9.43-1.7,49.07,49.07,0,0,1-27.44-19.8,49.09,49.09,0,0,1-8.35-23.6,12.49,12.49,0,0,0-.15-1.73c0-.57,0-1.13,0-1.69,0-1,0-2,0-3.05a.57.57,0,0,0,.07-.36,47.0M
7,47.07,0,0,1,.76-6.38,48.23,48.23,0,0,1,4.09-12.43,49.32,49.32,0,0,1,41.06-27.75A9.08,9.08,0,0,0,134.36,420.84ZM95.57,470.21A41.17,41.17,0,1,0,136.72,429,41.12,41.12,0,0,0,95.57,470.21Z" transform="translate(4.96 5.26)" style="fill:#f79421" /><path d="M149.13,468.75a19.6,19.6,0,0,1,5.05,1.56,10.88,10.88,0,0,1,4.87,4.33,11.08,11.08,0,0,1,1.4,4.28,16.24,16.24,0,0,1-.25,5.73,10.06,10.06,0,0,1-6.28,7.4,23.28,23.28,0,0,1-5.33,1.41c-1.23.19-2.46.33-3.71.4-.43,0-.44,0-.44.48v7.33c0,.46,0,.46-.47.46h-5.35c-.52,0-.49,0-.49M
-.48v-7.09c0-.59.05-.53-.54-.53h-5.34c-.43,0-.43,0-.43.44,0,2.38,0,4.76,0,7.14,0,.55.05.52-.5.52H126c-.5,0-.51,0-.51-.52v-7.33c0-.17-.06-.27-.24-.25s-.26,0-.38,0H113.19c-.21,0-.31,0-.31-.29q0-2.62,0-5.25c0-.25.1-.32.34-.31h3.26a9.33,9.33,0,0,0,2-.26,1.76,1.76,0,0,0,1.43-1.45,11,11,0,0,0,.26-2.63q0-10.31,0-20.61c0-2.29,0-4.57,0-6.86a11.52,11.52,0,0,0-.24-2.48,1.88,1.88,0,0,0-1.58-1.55,12.77,12.77,0,0,0-2.54-.23c-.82,0-1.64,0-2.46,0-.43,0-.43,0-.43-.45v-4.87c0-.56,0-.52.5-.52H125c.52,0,.52,0,.52-.51v-6.9c0-.12,0-.25,M
0-.38s.09-.25.26-.24h5.54c.56,0,.51-.06.51.5,0,2.32,0,4.63,0,6.95,0,.65,0,.58.58.58h5.3c.43,0,.43,0,.43-.46v-7c0-.11,0-.22,0-.33s.07-.26.25-.25h5.54c.55,0,.52-.08.52.54V446c0,.36,0,.35.37.38a30.6,30.6,0,0,1,5.63.91,16.49,16.49,0,0,1,3,1.11,8.5,8.5,0,0,1,4.65,5.6,13.15,13.15,0,0,1,.11,6.68,9.54,9.54,0,0,1-3.85,5.55,17,17,0,0,1-4.93,2.34C149.3,468.61,149.19,468.58,149.13,468.75Zm-17.31,11.44c0,2.55,0,5.1,0,7.66,0,.41,0,.41.41.41H135a40.14,40.14,0,0,0,5.9-.28,14.22,14.22,0,0,0,3.38-.86,5.83,5.83,0,0,0,3.5-3.84,11,11,0M
,0,0,.24-5.51,5.78,5.78,0,0,0-2.58-3.91,8.31,8.31,0,0,0-2.49-1,21.66,21.66,0,0,0-4.25-.6c-2.2-.13-4.41,0-6.62-.07-.23,0-.31.09-.29.3s0,.22,0,.33Q131.81,476.5,131.82,480.19Zm0-21v3.92q0,1.44,0,2.88c0,.23.05.35.31.34a62.82,62.82,0,0,0,7.13-.2,13.67,13.67,0,0,0,3.39-.83,5.13,5.13,0,0,0,3.18-3.67,10.6,10.6,0,0,0,.15-4.45,5,5,0,0,0-3.52-4.22,16.7,16.7,0,0,0-4.64-.82c-1.86-.09-3.72,0-5.58,0H132a.2.2,0,0,0-.22.23v.38Q131.81,456,131.81,459.19Z" transform="translate(4.96 5.26)" style="fill:#f79421" /></g><circle cx="897.68"M
 cy="478.42" r="61.24" style="fill:#f26227" /><circle cx="897.68" cy="478.42" r="53.6" style="fill:#d74b27" /><g><path d="M890.36,423.81h4.82a5.2,5.2,0,0,0,1,.07c1.4.12,2.79.27,4.18.48a48.5,48.5,0,0,1,9.62,2.52,49.52,49.52,0,0,1,29.69,31,47.6,47.6,0,0,1,2,9.2c.13,1.13.24,2.26.28,3.39a1.52,1.52,0,0,0,.07.76v4a1.4,1.4,0,0,0-.07.76,41.81,41.81,0,0,1-.48,4.74,47.88,47.88,0,0,1-5,15.23,49.44,49.44,0,0,1-40.51,26.54,47.59,47.59,0,0,1-7.36-.06,48.57,48.57,0,0,1-9.43-1.69,49.12,49.12,0,0,1-27.44-19.8,49.17,49.17,0,0,1-8.35M
-23.6,12.63,12.63,0,0,0-.15-1.74c0-.56,0-1.12,0-1.69,0-1,0-2,0-3a.62.62,0,0,0,.07-.37,47.11,47.11,0,0,1,.76-6.37,48.1,48.1,0,0,1,4.09-12.43,49.49,49.49,0,0,1,32.44-26.4,50.07,50.07,0,0,1,8.62-1.36A7.27,7.27,0,0,0,890.36,423.81Zm-38.79,49.37A41.17,41.17,0,1,0,892.72,432,41.14,41.14,0,0,0,851.57,473.18Z" transform="translate(4.96 5.26)" style="fill:#f79421" /><path d="M905.13,471.72a19.6,19.6,0,0,1,5,1.56,10.85,10.85,0,0,1,4.87,4.34,11,11,0,0,1,1.4,4.28,16.25,16.25,0,0,1-.25,5.73,10,10,0,0,1-6.28,7.39,23.28,23.28,0,0M
,1-5.33,1.41c-1.23.19-2.46.33-3.71.41-.43,0-.44,0-.44.47v7.33c0,.46,0,.47-.47.47h-5.35c-.52,0-.49,0-.49-.49v-7.09c0-.59,0-.53-.54-.53h-5.34c-.43,0-.43,0-.43.45,0,2.38,0,4.76,0,7.14,0,.54.05.52-.5.52H882c-.5,0-.51,0-.51-.53v-7.33c0-.17-.06-.26-.24-.25H869.19c-.21,0-.31-.05-.31-.28q0-2.62,0-5.25c0-.26.1-.32.34-.32h3.26a9.33,9.33,0,0,0,2-.26,1.76,1.76,0,0,0,1.43-1.45,11,11,0,0,0,.26-2.62q0-10.32,0-20.62c0-2.28,0-4.57,0-6.85a11.55,11.55,0,0,0-.24-2.49,1.88,1.88,0,0,0-1.58-1.55,12.77,12.77,0,0,0-2.54-.23h-2.46c-.43,0-.4M
3,0-.43-.45v-4.87c0-.55,0-.52.5-.52H881c.52,0,.52,0,.52-.5v-6.91c0-.12,0-.25,0-.37s.09-.26.26-.25h5.54c.56,0,.51-.05.51.5,0,2.32,0,4.64,0,6.95,0,.65-.05.58.58.58h5.3c.43,0,.43,0,.43-.45v-7c0-.11,0-.22,0-.33s.07-.26.25-.25h5.54c.55,0,.52-.07.52.55V449c0,.36,0,.36.37.38a30.62,30.62,0,0,1,5.63.92,16.45,16.45,0,0,1,3,1.1,8.5,8.5,0,0,1,4.65,5.6,13.19,13.19,0,0,1,.11,6.69,9.49,9.49,0,0,1-3.85,5.54,16.79,16.79,0,0,1-4.93,2.34C905.3,471.58,905.19,471.56,905.13,471.72Zm-17.31,11.44c0,2.55,0,5.11,0,7.66,0,.41,0,.41.41.41H891M
a40.14,40.14,0,0,0,5.9-.29,14.2,14.2,0,0,0,3.38-.85,5.85,5.85,0,0,0,3.5-3.85,11,11,0,0,0,.24-5.51,5.78,5.78,0,0,0-2.58-3.91,8.31,8.31,0,0,0-2.49-1,23.27,23.27,0,0,0-4.25-.6c-2.2-.13-4.41,0-6.62-.07-.23,0-.31.09-.29.31s0,.22,0,.33C887.81,478.25,887.81,480.7,887.82,483.16Zm0-21v3.92c0,1,0,1.92,0,2.89,0,.22.05.34.31.33a62.82,62.82,0,0,0,7.13-.2,13.67,13.67,0,0,0,3.39-.83,5.11,5.11,0,0,0,3.18-3.66,10.65,10.65,0,0,0,.15-4.46,5,5,0,0,0-3.52-4.22,16.68,16.68,0,0,0-4.64-.81c-1.86-.1-3.72,0-5.58-.05H888c-.15,0-.23.07-.22.23M
v.38Q887.8,458.92,887.81,462.16Z" transform="translate(4.96 5.26)" style="fill:#f79421" /></g></g><g id="Ears-2"><circle cx="133.72" cy="393.44" r="61.91" style="fill:#883a62" /><circle cx="154.36" cy="469.11" r="41.27" style="fill:#883a62" /><circle cx="181.87" cy="427.84" r="41.27" style="fill:#542f5f" /><g style="opacity:0.5700000000000001;mix-blend-mode:overlay"><line x1="126.08" y1="359.82" x2="194.87" y2="428.6" style="fill:none;stroke:#070707;stroke-miterlimit:10;stroke-width:3px" /><line x1="181.87" y1="436M
.67" x2="146.52" y2="472.03" style="fill:none;stroke:#070707;stroke-miterlimit:10;stroke-width:3px" /><line x1="155.36" y1="392.49" x2="128.85" y2="419" style="fill:none;stroke:#070707;stroke-miterlimit:10;stroke-width:3px" /><line x1="164.2" y1="401.32" x2="128.85" y2="436.67" style="fill:none;stroke:#070707;stroke-miterlimit:10;stroke-width:3px" /></g><circle cx="119.85" cy="534.05" r="53.19" style="fill:#f96020" /><circle cx="119.84" cy="534.05" r="46.55" style="fill:#d74816" /><circle cx="890.1" cy="392.85" r="M
61.91" style="fill:#883a62" /><circle cx="869.47" cy="468.51" r="41.27" style="fill:#883a62" /><circle cx="841.95" cy="427.24" r="41.27" style="fill:#542f5f" /><g style="opacity:0.5700000000000001;mix-blend-mode:overlay"><line x1="897.75" y1="359.22" x2="828.96" y2="428.01" style="fill:none;stroke:#070707;stroke-miterlimit:10;stroke-width:3px" /><line x1="841.95" y1="436.08" x2="877.31" y2="471.43" style="fill:none;stroke:#070707;stroke-miterlimit:10;stroke-width:3px" /><line x1="868.47" y1="391.89" x2="894.98" y2=M
"418.41" style="fill:none;stroke:#070707;stroke-miterlimit:10;stroke-width:3px" /><line x1="859.63" y1="400.73" x2="894.98" y2="436.08" style="fill:none;stroke:#070707;stroke-miterlimit:10;stroke-width:3px" /></g><circle cx="903.98" cy="533.46" r="53.19" style="fill:#f96020" /><circle cx="903.99" cy="533.46" r="46.55" style="fill:#d74816" /></g><g id="Mouth-5"><polyline points="528.78 551.11 214.79 551.11 336.9 673.22 528.78 673.22 528.78 551.11" style="fill:#4a2955" /><rect x="441.56" y="562.74" width="23.26" heigM
ht="29.07" style="fill:#fdf6de" /><rect x="470.63" y="562.74" width="23.26" height="29.07" style="fill:#fdf6de" /><polygon points="406.67 603.44 429.93 562.74 429.93 562.74 406.67 562.74 406.67 603.44" style="fill:#fdf6de" /><polygon points="331.08 664.5 389.23 562.74 389.23 562.74 331.08 562.74 331.08 664.5" style="fill:#fdf6de" /><polygon points="302.84 591.81 319.45 562.74 319.45 562.74 302.84 562.74 302.84 591.81" style="fill:#fdf6de" /><polyline points="480.08 550.62 794.06 550.62 671.96 672.72 480.08 672.72 4M
80.08 550.62" style="fill:#161f26" /><rect x="545.7" y="562.24" width="23.26" height="29.07" transform="translate(1112.99 1153.56) rotate(-180)" style="fill:#fdf6de" /><rect x="516.62" y="562.24" width="23.26" height="29.07" transform="translate(1054.85 1153.56) rotate(-180)" style="fill:#fdf6de" /><rect x="487.55" y="562.24" width="23.26" height="29.07" transform="translate(996.7 1153.56) rotate(-180)" style="fill:#fdf6de" /><polygon points="602.18 602.95 578.92 562.25 578.92 562.25 602.18 562.25 602.18 602.95" stM
yle="fill:#fdf6de" /><polygon points="677.77 664 619.63 562.25 619.63 562.25 677.77 562.25 677.77 664" style="fill:#fdf6de" /><polygon points="706.01 591.32 689.4 562.25 689.4 562.25 706.01 562.25 706.01 591.32" style="fill:#fdf6de" /><path d="M443.22,676.13a61.06,61.06,0,1,1,122.11,0" transform="translate(-1.66 0)" style="fill:#e63580" /></g><g id="Eyebrows-1">undefined</g><g id="Glasses-4">undefined</g><g id="Eyes-9"><polyline points="406.74 531.45 329.95 454.66 406.06 454.66" style="fill:#e1d4d1" /><polyline poiM
nts="609.46 531.45 686.25 454.66 609.06 454.66" style="fill:#aea4b2" /><path d="M773.72,413a85.24,85.24,0,1,0-170.48,0" transform="translate(0.34)" style="fill:#959acc" /><circle cx="668.36" cy="413.04" r="64.79" style="fill:#727fbd" /><circle cx="667.27" cy="413.04" r="25.85" style="fill:#213f7d" /><polyline points="648.81 394.58 611.88 424.12 648.81 424.12" style="fill:#213f7d" /><circle cx="667.27" cy="413.04" r="18.47" style="fill:#131640" /><path d="M581.29,429.05V368.69A103.31,103.31,0,0,1,684.6,265.38h19.45"M
 transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;opacity:0.49;mix-blend-mode:overlay" /><path d="M497.89,213.26" transform="translate(0.34)" style="fill:#f1f5fa" /><path d="M241.8,413a85.25,85.25,0,0,1,170.49,0" transform="translate(0.34)" style="fill:#d0bac3" /><circle cx="347.84" cy="413.04" r="64.79" style="fill:#aaaecc" /><polyline points="365.88 394.58 402.81 424.12 365.88 424.12" style="fill:#727fbd" /><circle cx="347.41" cy="413.04" r="25.85" style="fill:M
#727fbd" /><circle cx="347.41" cy="413.04" r="18.47" style="fill:#213f7d" /><circle cx="339.93" cy="409.35" r="4.39" style="fill:#eff3f9" /><path d="M431.26,427.83V367.47A103.3,103.3,0,0,0,328,264.16H308.51" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;mix-blend-mode:overlay" /><path d="M253.74,412.68a78.86,78.86,0,1,1,157.71,0" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;mix-blend-mode:overlay" /><patM
h d="M268.9,413.43a70.69,70.69,0,1,1,141.37,0" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;mix-blend-mode:overlay" /><path d="M296.55,413.15a57.12,57.12,0,0,1,114.24,0" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;opacity:0.58;mix-blend-mode:overlay" /><path d="M760.73,413.67a78.86,78.86,0,0,0-157.72,0" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:1M
0;opacity:0.49;mix-blend-mode:overlay" /><path d="M745.56,414.42a70.69,70.69,0,0,0-141.37,0" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;opacity:0.49;mix-blend-mode:overlay" /><path d="M717.91,414.15a57.12,57.12,0,1,0-114.24,0" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;opacity:0.49;mix-blend-mode:overlay" /><path d="M572.2,428V363.34A110.66,110.66,0,0,1,682.87,252.68h20.84" transform="translate(0.34M
)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;opacity:0.49;mix-blend-mode:overlay" /><path d="M552.15,428.56V354.18A127.29,127.29,0,0,1,679.43,226.9h24" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;opacity:0.49;mix-blend-mode:overlay" /><path d="M440.4,427.44V362.77A110.65,110.65,0,0,0,329.74,252.11H308.9" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;mix-blend-mode:overlayM
" /><path d="M460.46,428V353.61A127.29,127.29,0,0,0,333.18,226.33h-24" transform="translate(0.34)" style="fill:none;stroke:#e9dedb;stroke-linecap:round;stroke-miterlimit:10;mix-blend-mode:overlay" /><circle cx="659.4" cy="409.28" r="4.39" style="fill:#eff3f9" /></g><g id="Nose-1"><path d="M515.59,360.78h0A111.68,111.68,0,0,1,627.27,472.46V598.54a0,0,0,0,1,0,0H403.92a0,0,0,0,1,0,0V472.46A111.68,111.68,0,0,1,515.59,360.78Z" style="fill:#883a62;opacity:0.7000000000000001" /><path d="M458.09,527.5h59.68V427.43H476.51a2M
4.44,24.44,0,0,0-23,16.17l-18.42,51.17A24.45,24.45,0,0,0,458.09,527.5Z" transform="translate(9.03 13)" style="fill:#fa8cb2" /><circle cx="479.97" cy="487.27" r="18.01" style="fill:#542f5f" /><path d="M551.83,527.9H506.16V427.83h27.25a24.45,24.45,0,0,1,23,16.17l18.42,51.17A24.45,24.45,0,0,1,551.83,527.9Z" transform="translate(9.03 13)" style="fill:#f46461" /><circle cx="548.01" cy="486.55" r="18.01" style="fill:#172027" /></g><g id="Hat-3"><rect x="362" y="88" width="144" height="135" style="fill:#542f5f" /><rect x=L
"506" y="88" width="144" height="135" style="fill:#172027" /><rect x="254" y="214" width="513" height="18" style="fill:#172027" /></g></g></svg>h!
**************************************************
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
!22222222222222222222222222222222222222222222222222
filter: 0; jpegRotation: 90; fileterIntensity: 0.000000; filterMask: 0; module:1facing:0;
touch: (-1.0, -1.0);
AI_Scene: (-1, -1);
filter: 0; jpegRotation: 90; fileterInteM
nsity: 0.000000; filterMask: 0; module:1facing:0;
touch: (-1.0, -1.0);
AI_Scene: (-1, -1);
!22222222222222222222222222222222222222222222222222
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:GIMP="http://www.gimp.org/xmp/" xmlns:tiff="http://ns.adobe.com/tiff/1.0/" xmlns:xmp="http://ns.adobe.com/xap/1M
.0/" xmpMM:DocumentID="gimp:docid:gimp:8316bccc-2935-4a47-97f1-f21f2f7511e8" xmpMM:InstanceID="xmp.iid:28ad7955-1d0f-4fbc-bcb9-31bd60dd7812" xmpMM:OriginalDocumentID="xmp.did:55268173-c20b-48e2-b1f8-9017bbc1123a" dc:Format="image/webp" GIMP:API="2.0" GIMP:Platform="Windows" GIMP:TimeStamp="1675232775611897" GIMP:Version="2.10.30" tiff:Orientation="1" xmp:CreatorTool="GIMP 2.10"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="saved" stEvt:changed="/" stEvt:instanceID="xmp.iid:82f338de-3b92-418b-9fe3-827fdfb9b654" sM
tEvt:softwareAgent="Gimp 2.10 (Windows)" stEvt:when="2023-02-01T07:19:57"/> <rdf:li stEvt:action="saved" stEvt:changed="/" stEvt:instanceID="xmp.iid:ffbb490b-2e1f-4668-8b2d-a092335f6f8d" stEvt:softwareAgent="Gimp 2.10 (Windows)" stEvt:when="2023-02-01T07:26:15"/> </rdf:Seq> </xmpMM:History> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                          M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        MB
                                                                                                                                                                                                                                                                                                               <?xpacket end="w"?>h!
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
4j2DC-L5:wyJzxVNyQCr40trKQw5W+FNsq4WPDqI0o0uMj0OLIoY=
9j7+:BTC/BTC::bc1q3f787hr38pmal87yxtpq8tng09q60ljjqqd759:0
IjG=:BNB.TWT-8C2:bnb12w6plevt6kmjdhawzea0u8gjll2nuser5p5e0x:242784547:te:0
c/Foundry USA Pool #dropgold/
FjDOUT:3FD037F22CE424042BB411720B98286FAC6E020A83E9D6013978D2F2C8B72620
IjGREFUND:024EE60586980A9C6377B66335EDB5E4D2E7FD700B153B658005BF01FDFFC9BA
CjA=:ETH.ETH:0x09eeC9795f09342b8E364A5ed90B7B58057576b2:2591762:te:0
FjDOUT:9933C1878C9F90EA05ED40599FEF03C94BDD2FBE57720665F193456264205014
FjDOUT:0D13B6AAB253FB9D8D26EC64A3B53817EC43602D04D3A3BB1762FAA251597257
FjDOUT:0E16416FA49D4A73F48A3F1F01E703F8B9940194A6E2250BE15726F4EDD55F3B
FjDOUT:3BE8B6600F3DE4BBC31860CB7F50D1EC38B01E0C2DFF2B576D56411345C83D8C
FjDOUT:B1ED19234C9A42E00462A84F8BA59E748DC0312EDB91142B3F018BE40D7F988C
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-M
c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-M
01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:07:24+03:00" xmp:ModifyDate="2023-02-03T00:07:24+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:10302117-c060-314b-a620-8d00379ec6e5" xmpMM:DocumentID="adobe:docid:photoshop:d9ba050b-ede3-cb49-9a2a-3b3b4140153f" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-M
7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:9d78ffab-bc21-5740-a28e-1a9bdf78970f" stEvt:when="2023-02-03T00:07:24+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rM
df:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:10302117-c060-314b-a620-8d00379ec6e5" stEvt:when="2023-02-03T00:07:24+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:9d78ffab-bc21-5740-a28e-1aM
9bdf78970f" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                      M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                   <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:DescriptioM
n rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:05:24+03:00" xmp:ModifyDate="2023-02-03T00:05:24+03:00" dc:format="image/M
jpeg" xmpMM:InstanceID="xmp.iid:dcbbd076-90e3-714a-ad17-5e3aa8c29009" xmpMM:DocumentID="adobe:docid:photoshop:4b629e50-f7c3-b24e-9a19-ee62c555bbac" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:actioM
n="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:0104d6c5-35f3-0e45-a87d-5ffe488fae0f" stEvt:when="2023-02-03T00:05:24+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="deM
rived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:dcbbd076-90e3-714a-ad17-5e3aa8c29009" stEvt:when="2023-02-03T00:05:24+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:0104d6c5-35f3-0e45-a87d-5ffe488fae0f" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:865M
3de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                     M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                    <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http:/M
/www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:06:11+03:00" xmp:MM
odifyDate="2023-02-03T00:06:11+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:87f68be3-dd4b-2349-adc6-93cb6ff19d58" xmpMM:DocumentID="adobe:docid:photoshop:ab05481d-a4ab-ec48-9379-8b5f15ced756" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgentM
="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:8a22ee1f-0bb9-a544-a28a-666c77beb644" stEvt:when="2023-02-03T00:06:11+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adM
obe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:87f68be3-dd4b-2349-adc6-93cb6ff19d58" stEvt:when="2023-02-03T00:06:11+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:8a22ee1f-0bb9-a544-a28a-666c77beb644" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-8M
7e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                              M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                           <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.coM
m/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:03:36+03:00" xmp:ModifyDate="2023-02-03T00:03:36+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:ed709d07-309M
4-8241-b761-b5291cf565ed" xmpMM:DocumentID="adobe:docid:photoshop:efe1b116-b36e-144a-9454-8539f97dba60" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496M
-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:e96dedf3-4cfd-9448-8f08-a627edb36972" stEvt:when="2023-02-03T00:03:36+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from applM
ication/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:ed709d07-3094-8241-b761-b5291cf565ed" stEvt:when="2023-02-03T00:03:36+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:e96dedf3-4cfd-9448-8f08-a627edb36972" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photosM
hop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                 M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                        <?xpacket end="w"?>
yright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
iewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
FjDOUT:13151B37BB35BB9F7A38D91D4216928C060DF7EBD638F840A04405BE5D6D0907
FjDOUT:4080AFC2008608D6852DB07BC067C4FCD027C8FBE4DEDBBA764333FD5DB2976B
c/Foundry USA Pool #dropgold/
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <M
rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02M
-03T00:03:04+03:00" xmp:ModifyDate="2023-02-03T00:03:04+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:18905f51-745a-4c47-8460-219f1d59abe4" xmpMM:DocumentID="adobe:docid:photoshop:596e5cf2-93e5-3440-b90a-44c991b060c2" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+0M
3:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:9cf81fec-b00c-b941-8732-c91540fb6ec2" stEvt:when="2023-02-03T00:03:04+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parametersM
="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:18905f51-745a-4c47-8460-219f1d59abe4" stEvt:when="2023-02-03T00:03:04+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:9cf81fec-b00c-b941-8732-c91540fb6ec2" stRef:documentID="adobe:docid:photoM
shop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                     M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                    <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RM
GB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
DjB=:BNB.BNB:bnb1xehn2r9dhlac5x2q74ur046nknyr2cv9hnckdn:17881693:te:0
Ahttp://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.5.0"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" photoshop:ColorMode="3" photoshop:M
ICCProfile="sRGB IEC61966-2.1" xmp:ModifyDate="2023-02-02T18:27:45-05:00" xmp:MetadataDate="2023-02-02T18:27:45-05:00"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="produced" stEvt:softwareAgent="Affinity Photo 1.10.6" stEvt:when="2023-02-02T18:27:45-05:00"/> </rdf:Seq> </xmpMM:History> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                           M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                              <?xpacket end="w"?>
 .)10.)-,3:J>36F7,-@WAFLNRSR2M
&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
Ahttp://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.5.0"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" photoshop:ColorMode="3" photoshop:M
ICCProfile="sRGB IEC61966-2.1" xmp:ModifyDate="2023-02-02T18:24:24-05:00" xmp:MetadataDate="2023-02-02T18:24:24-05:00"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="produced" stEvt:softwareAgent="Affinity Photo 1.10.6" stEvt:when="2023-02-02T18:24:24-05:00"/> </rdf:Seq> </xmpMM:History> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                           M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                              <?xpacket end="w"?>
 .)10.)-,3:J>36F7,-@WAFLNRSR2M
&O5-5OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
zTXtRaw profile type exif
    "title": "The Basics",
    "description": "Basic HTML and JS Game Collection",
      "title": "Snake",
      "inscription": "6edf80efbbae537b554340c31496439b57bef65357a57f21cbb547bc6287d7bfi0"
      "title": "Tetris",
      "inscription": "d7f1917503abc4ee718e871acdd3a701cd383c9b8694692d587eebba434fb1c7i0"
      "title": "Frogger",
      "inscription": "d3c366b3605b1a212b7e648446eba21215dbdb826fd20a5dc51b7421989c35e0i0"
      "inscription": "c2b3eec36b0949dee2729265b8aa045d0dd8b24913847fb69e04946b28e68bc2i0"
      "title": "Sokoban",
      "inscription": "0eb7edf9d10e27f443d605c3fc986564df3c4914bb33cbaeabb114f5adbd47a9i0"
      "title": "Puzzle Bobble",
      "inscription": "64aba1641a97ec70ccd21bb9e99647cae7619900ad173b2d52214754bd9c0a9ei0"
      "title": "Bomberman",
      "inscription": "c10adaa4ee52306c8db381da3e136189192fab9c160de3e9f6c56b918afec141i0"
      "inscription": "6cc328043c8e8837a421e2b869026363010fb10a5e50f89005187cadc429a821i0"
      "title": "Missile Command",
      "inscription": "6a3e2377103969dedcdd58fa3d55a31901e6359e8446d97700a6e0a81b71bd24i0"
      "title": "Doodle Jump",
      "inscription": "f07e36f8d23758372d076ce17019a784b72046612fd19842d45a1182d382c3d8i0"
text/plain;charset=utf-8
/ViaBTC/Mined by nextone2/,
KjISWAPTX:0xda0464b36aacb6955fa7c1f9732b93e81d5de4d6548c22f3eabbc3a24d019dab
IjGREFUND:F7E0A1C6FD328DC8ACD55F4AA0F6D1036FF7DB0F5E71D6A352FE24B697F43189
EjC=:BNB.ETH-1C9:bnb1krqpk0d4t33uqkrajjfvgx8785tsz76axvgc8l:21290:te:0
Mined by AntPool958[
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
'#))'#&%,1?5,.;/%&6J7;ACFGF*4MRLDR?EFC
 C-&-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
",+7!!,ZZ`^^b/.<XX]
-;=O''8(%%TTYbbe**<<<I/0B328DEU23D423efl@ANXVOTRKEI]?AT1($|.
6&OMFNThRTbWaz*,Bpry
c/Foundry USA Pool #dropgold/
Bj@1fb878ce0ca08b1a4b8ba2e88b459710bf5afa2cfae0a88010466a6185159572
EjCs:LTC.LTC:ltc1qq6qse2etz6nk6ld3gmmdggwyydv37504fzt7rg:97473793:ss:0
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmM
eta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorToM
ol="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:05:13+03:00" xmp:ModifyDate="2023-02-03T00:05:13+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:1c80af2b-cce7-8d42-a1d6-e9008a86e4a4" xmpMM:DocumentID="adobe:docid:photoshop:39b59a96-c41e-f441-94f6-0f310e0bab75" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="crM
eated" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:7c566773-5e1c-374f-a2fe-76c79f68ef57" stEvt:when="2023-02-03T00:05:13+03:00" stEvt:softwareAgenM
t="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:1c80af2b-cce7-8d42-a1d6-e9008a86e4a4" stEvt:when="2023-02-03T00:05:13+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedM
From stRef:instanceID="xmp.iid:7c566773-5e1c-374f-a2fe-76c79f68ef57" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                             M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                            <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
CjA=:BNB.BNB:bnb1xehn2r9dhlac5x2q74ur046nknyr2cv9hnckdn:3072145:te:0
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:M
stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:03:19+03:00" xmp:ModifyDate="2023-02-03T00:03:19+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:cd82dfed-a484-bc4f-a105-fab2d276973b" xmpMM:DocumentID="adobe:docid:photoshop:851dbb5d-b5ce-924e-9f02-86c32bad17ef" xmpMM
M:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21M
.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:ef2a2553-7376-db40-881f-d277a7ae9815" stEvt:when="2023-02-03T00:03:19+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:cd82dfedM
-a484-bc4f-a105-fab2d276973b" stEvt:when="2023-02-03T00:03:19+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:ef2a2553-7376-db40-881f-d277a7ae9815" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DoM
cumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                             M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                            <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
KjISWAPTX:0xc2db3fe8bfc51988dc335a013c970910d91e65f74f68b7287aa6354afc971918Q
FjDOUT:8DB2E32CCAFE708B8A7EC5CF2B11D2A6B851B50CA18864A39B8081EFF69F69B9
FjDOUT:6DA7FBB369E6058B34DA69053488363904660F2FFDDA269D0E1CA0AC62E352E2
FjDOUT:FA5D8703AA6632BD34974F158F4640DE09E3D05332E3ED5DD5A58727EA17A953
LjJ=:ETH.USDC-B48:0x86a680ee2a0C4eed78664931AC9aeFD40E7575a8:195169989017:xdf
LjJ=:ETH.USDC-B48:0x86a680ee2a0C4eed78664931AC9aeFD40E7575a8:112509347596:xdf(}
text/plain;charset=utf-8
THE TRAGEDY OF ROMEO AND JULIET
by William Shakespeare
Scene I. A public place.
Scene III. Room in Capulet
Scene V. A Hall in Capulet
Scene I. An open place adjoining Capulet
Scene III. Friar Lawrence
Scene VI. Friar Lawrence
Scene I. A public Place.
ene II. A Room in Capulet
Scene III. Friar Lawrence
Scene IV. A Room in Capulet
Scene V. An open Gallery to Juliet
s Chamber, overlooking the Garden.
Scene I. Friar Lawrence
Scene II. Hall in Capulet
Scene IV. Hall in Capulet
s Chamber; Juliet on the bed.
Scene I. Mantua. A Street.
Scene II. Friar Lawrence
Scene III. A churchyard; in it a Monument belonging tM
ESCALUS, Prince of Verona.
MERCUTIO, kinsman to the Prince, and friend to Romeo.
PARIS, a young Nobleman, kinsman to the Prince.
MONTAGUE, head of a Veronese family at feud with the Capulets.
LADY MONTAGUE, wife to Montague.
ROMEO, son to Montague.
BENVOLIO, nephew to Montague, and friend to Romeo.
ABRAM, servant to Montague.
BALTHASAR, servant to Romeo.
CAPULET, head of a Veronese family at feud with the Montagues.
LADY CAPULET, wife to CM
JULIET, daughter to Capulet.
TYBALT, nephew to Lady Capulet.
S COUSIN, an old man.
PETER, servant to Juliet
SAMPSON, servant to Capulet.
GREGORY, servant to Capulet.
FRIAR LAWRENCE, a Franciscan.
FRIAR JOHN, of the same Order.
Citizens of Verona; several Men and Women, relations to both houses;
Maskers, Guards, Watchmen and Attendants.
SCENE. During the greater part of the Play in Verona;M
Fifth Act, at Mantua.
Two households, both alike in dignity,
In fair Verona, where we lay our scene,
From ancient grudge break to new mutiny,
Where civil blood makes civil hands unclean.
From forth the fatal loins of these two foes
A pair of star-cross
d lovers take their life;
d piteous overthrows
Doth with their death bury their parents
The fearful passage of their death-mark
And the continuance of tM
Which, but their children
s end, nought could remove,
Is now the two hours
 traffic of our stage;
The which, if you with patient ears attend,
What here shall miss, our toil shall strive to mend.
SCENE I. A public place.
 Enter Sampson and Gregory armed with swords and bucklers.
Gregory, on my word, we
No, for then we should be colliers.
I mean, if we be in choler, we
, while you live, draw your neck out o
I strike quickly, being moved.
But thou art not quickly moved to strike.
A dog of the house of Montague moves me.
To move is to stir; and to be valiant is to stand: therefore, if thou
art moved, thou runn
A dog of that house shall move me to stand.
I will take the wall of any man or maid of Montague
That shows thee a weak slave, for the weakest goes to the wall.
True, and therefore women, being the weaker vessels, are ever thrust to
the wall: therefore I will push Montague
s men from the wall, and
thrust his maids to the wall.
The quarrel is between our masters and us their men.
Tis all one, I will show myself a tyrant: when I have fought with the
men I will be civil with the maids, I will cut off their heads.
The heads of the maids?
Ay, the heads of the maids, or their maidenheads; take it in what sense
They must take it in sense that feel it.
Me they shall feel while I am able to stand: and
pretty piece of flesh.
Tis well thou art not fish; if thou hadst, thou hadst been poor John.
Draw thy tool; here comes of the house of Montagues.
 Enter Abram and Balthasar.
My naked weapon is out: quarrel, I will back thee.
How? Turn thy back and run?
No, marry; I fear thee!
Let us take the law of our sides; let them begin.
I will frown as I pass by, and let them take it as they list.
Nay, as they dare. I will bite my thumb at them, which is disgrace to
them if they bear it.
Do you bite your thumb at us, sir?
I do bite my thumb, sir.
Do you bite your thumb at us, sir?
Is the law of our side if I say ay?
No sir, I do not bite my thumb at you, sir; but I bite my thumb, sir.
Do you quarrel, sir?
Quarrel, sir? No, sir.
But if you do, sir, I am for you. I serve as good a man as you.
Say better; here comes one of my master
Draw, if you be men. Gregory, remember thy washing blow.
Part, fools! put up your swords, you know not what you do.
 [_Beats down their swords._]
What, art thou drawn among these heartless hinds?
Turn thee Benvolio, look upon thy death.
I do but keep the peace, put up thy sword,
Or manage it to part these men with me.
What, drawn, and talk of peace? I hate the word
As I hate hell, all Montagues, and thee:
Have at thee, coward.
 Enter three or four Citizens with clubs.
Clubs, bills and partisans! Strike! Beat them down!
Down with the Capulets! Down with the MonM
 Enter Capulet in his gown, and Lady Capulet.
What noise is this? Give me my long sword, ho!
A crutch, a crutch! Why call you for a sword?
My sword, I say! Old Montague is come,
And flourishes his blade in spite of me.
 Enter Montague and his Lady Montague.
Thou villain Capulet! Hold me not, let me go.
Thou shalt not stir one foot to seek a foe.
 Enter Prince Escalus, with Attendants.
Rebellious subjects, enemM
Profaners of this neighbour-stained steel,
Will they not hear? What, ho! You men, you beasts,
That quench the fire of your pernicious rage
With purple fountains issuing from your veins,
On pain of torture, from those bloody hands
Throw your mistemper
d weapons to the ground
And hear the sentence of your moved prince.
Three civil brawls, bred of an airy word,
By thee, old Capulet, and Montague,
d the quiet of our streets,
by their grave beseeming ornaments,
To wield old partisans, in hands as old,
d with peace, to part your canker
If ever you disturb our streets again,
Your lives shall pay the forfeit of the peace.
For this time all the rest depart away:
You, Capulet, shall go along with me,
And Montague, come you this afternoon,
To know our farther pleasure in this case,
To old Free-town, our common judgement-place.
Once more, on pain of death, all men depart.
 [_Exeunt Prince and Attendants; CapuletM
, Lady Capulet, Tybalt,
 Citizens and Servants._]
Who set this ancient quarrel new abroach?
Speak, nephew, were you by when it began?
Here were the servants of your adversary
And yours, close fighting ere I did approach.
I drew to part them, in the instant came
The fiery Tybalt, with his sword prepar
d defiance to my ears,
He swung about his head, and cut the winds,
Who nothing hurt withal, hiss
While we were interchanging thrusts andM
Came more and more, and fought on part and part,
Till the Prince came, who parted either part.
O where is Romeo, saw you him today?
Right glad I am he was not at this fray.
Madam, an hour before the worshipp
d forth the golden window of the east,
A troubled mind drave me to walk abroad,
Where underneath the grove of sycamore
That westward rooteth from this city side,
So early walking did I see your son.
Towards him I made, but he was ware of me,
tole into the covert of the wood.
I, measuring his affections by my own,
Which then most sought where most might not be found,
Being one too many by my weary self,
d my humour, not pursuing his,
d who gladly fled from me.
Many a morning hath he there been seen,
With tears augmenting the fresh morning
Adding to clouds more clouds with his deep sighs;
But all so soon as the all-cheering sun
Should in the farthest east begin to draw
The shady curtains from AuM
Away from light steals home my heavy son,
And private in his chamber pens himself,
Shuts up his windows, locks fair daylight out
And makes himself an artificial night.
Black and portentous must this humour prove,
Unless good counsel may the cause remove.
My noble uncle, do you know the cause?
I neither know it nor can learn of him.
Both by myself and many other friends;
But he, his own affections
I will not say how true
But to himself so secret and so close,
So far from sounding and discovery,
As is the bud bit with an envious worm
Ere he can spread his sweet leaves to the air,
Or dedicate his beauty to the sun.
Could we but learn from whence his sorrows grow,
We would as willingly give cure as know.
See, where he comes. So please you step aside;
ll know his grievance or be much denied.
I would thou wert so happy by thyM
To hear true shrift. Come, madam, let
 [_Exeunt Montague and Lady Montague._]
Good morrow, cousin.
Is the day so young?
But new struck nine.
Ay me, sad hours seem long.
Was that my father that went hence so fast?
It was. What sadness lengthens Romeo
Not having that which, having, makes them short.
Out of her favour where I am in love.
Alas that love so gentle in his view,
Should be so tyrannous and rough in proof.
Alas that love, whose view is muffled still,
Should, without eyes, see pathways to his will!
Where shall we dine? O me! What fray was here?
Yet tell me not, for I have heard it all.
s much to do with hate, but more with love:
Why, then, O brawling love! O loving hate!
O anything, of nothing first create!
O heavy lightness! serious vanity!
Misshapen chaos of well-seeming forms!
Feather of lead, briM
ght smoke, cold fire, sick health!
Still-waking sleep, that is not what it is!
This love feel I, that feel no love in this.
Dost thou not laugh?
No coz, I rather weep.
Good heart, at what?
Griefs of mine own lie heavy in my breast,
Which thou wilt propagate to have it prest
With more of thine. This love that thou hast shown
Doth add more grief to too much of mine own.
Love is a smoke made M
with the fume of sighs;
d, a fire sparkling in lovers
What is it else? A madness most discreet,
A choking gall, and a preserving sweet.
Soft! I will go along:
And if you leave me so, you do me wrong.
Tut! I have lost myself; I am not here.
This is not Romeo, he
Tell me in sadness who is that you love?
What, shall I groan and tellM
Groan! Why, no; but sadly tell me who.
Bid a sick man in sadness make his will,
d to one that is so ill.
In sadness, cousin, I do love a woman.
d so near when I suppos
A right good markman, and she
A right fair mark, fair coz, is soonest hit.
Well, in that hit you miss: she
s arrow, she hath Dian
And in strong proof of chastity well arM
s weak childish bow she lives uncharm
She will not stay the siege of loving terms
encounter of assailing eyes,
Nor ope her lap to saint-seducing gold:
s rich in beauty, only poor
That when she dies, with beauty dies her store.
Then she hath sworn that she will still live chaste?
She hath, and in that sparing makes huge waste;
d with her severity,
Cuts beauty off from all posterity.
She is too fair, too wise; wisely toM
To merit bliss by making me despair.
She hath forsworn to love, and in that vow
Do I live dead, that live to tell it now.
d by me, forget to think of her.
O teach me how I should forget to think.
By giving liberty unto thine eyes;
Examine other beauties.
To call hers, exquisite, in question more.
These happy masks that kiss fair ladies
Being black, puts us in mind they hide the fair;
He that is strucken blind cannot M
The precious treasure of his eyesight lost.
Show me a mistress that is passing fair,
What doth her beauty serve but as a note
Where I may read who pass
d that passing fair?
Farewell, thou canst not teach me to forget.
ll pay that doctrine, or else die in debt.
 Enter Capulet, Paris and Servant.
But Montague is bound as well as I,
In penalty alike; and
tis not hard, I think,
For men so old as we to keep the peace.
Of honourable reckoning are you both,
But now my lord, what say you to my suit?
er what I have said before.
My child is yet a stranger in the world,
She hath not seen the change of fourteen years;
Let two more summers wither in their pride
Ere we may think her ripe to be a bride.
Younger than she are happy mothers made.
d are those so early made.
The earth hath swallowed all my hopes but she,
She is the hopeful lady of my earth:
But woo her, gentle Paris, get her heart,
My will to her consent is but a part;
And she agree, within her scope of choice
Lies my consent and fair according voice.
This night I hold an old accustom
Whereto I have invited many a guest,
Such as I love, and you among the store,
One more, most welcome, makes my number more.
At my poor house look to behold this night
Earth-treading stars that make dark heaven light:
Such comfort as do lusty young men feel
Of limping winter treads, even such delight
Among fresh female buds shall you this night
Inherit at my house. Hear all, all see,
And like her most whose merit most shall be:
Which, on more view of many, mine, being one,
May stand in number, though in reckoning none.
Come, go with me. Go, sirrah, trudge about
Through fair Verona; find those persons out
Whose names are written there, [_gives a paper_] and to them say,
My house and welcome on their pleasure stay.
eunt Capulet and Paris._]
Find them out whose names are written here! It is written that the
shoemaker should meddle with his yard and the tailor with his last, the
fisher with his pencil, and the painter with his nets; but I am sent to
find those persons whose names are here writ, and can never find what
names the writing person hath here writ. I must to the learned. In good
 Enter Benvolio and Romeo.
Tut, man, one fire burns out another
Turn giddy, and be holp by backward turning;
One desperate grief cures with another
Take thou some new infection to thy eye,
And the rank poison of the old will die.
Your plantain leaf is excellent for that.
For what, I pray thee?
For your broken shin.
Why, Romeo, art thou mad?
Not mad, but bound more than a madman is:
Shut up in prison, kept without my food,
God-den, good fellow.
 go-den. I pray, sir, can you read?
Ay, mine own fortune in my misery.
Perhaps you have learned it without book.
But I pray, can you read anything you see?
Ay, If I know the letters and the language.
Ye say honestly, rest you merry!
Stay, fellow; I can read.
 [_He reads the letter._]
_Signior Martino and his wife and daughters;
County Anselmo and his beauteous sisters;
The lady widow of Utruvio;
Signior Placentio and his loveM
Mercutio and his brother Valentine;
Mine uncle Capulet, his wife, and daughters;
My fair niece Rosaline and Livia;
Signior Valentio and his cousin Tybalt;
Lucio and the lively Helena. _
A fair assembly. [_Gives back the paper_] Whither should they come?
Indeed I should have ask
ll tell you without asking. My master is M
the great rich Capulet,
and if you be not of the house of Montagues, I pray come and crush a
cup of wine. Rest you merry.
At this same ancient feast of Capulet
Sups the fair Rosaline whom thou so lov
With all the admired beauties of Verona.
Go thither and with unattainted eye,
Compare her face with some that I shall show,
And I will make thee think thy swan a crow.
When the devout religion of mine eye
Maintains such falsehood, then turn tears to fire;
ese who, often drown
Transparent heretics, be burnt for liars.
One fairer than my love? The all-seeing sun
er saw her match since first the world begun.
Tut, you saw her fair, none else being by,
d with herself in either eye:
But in that crystal scales let there be weigh
s love against some other maid
That I will show you shining at this feast,
And she shall scant show well that now shows best.
ll go along, no such sight M
But to rejoice in splendour of my own.
SCENE III. Room in Capulet
 Enter Lady Capulet and Nurse.
s my daughter? Call her forth to me.
Now, by my maidenhead, at twelve year old,
I bade her come. What, lamb! What ladybird!
s this girl? What, Juliet!
Madam, I am here. What is your will?
. Nurse, give leave awhile,
We must talk in secret. Nurse, come back again,
Thou knowest my daughter
Faith, I can tell her age unto an hour.
ll lay fourteen of my teeth,
And yet, to my teen be it spoken, I have but four,
She is not fourteen. How long is it now
A fortnight and odd days.
Even or odd, of all days in the year,
Lammas Eve at night shall she be fourteen.
God rest all Christian souls!
Were of an age. Well, Susan is with God;
She was too good for me. But as I said,
On Lammas Eve at night shall she be fourteen;
That shall she, marry; I remember it well.
Tis since the earthquake now eleven years;
I never shall forget it
Of all the days of the year, upon that day:
For I had then laid wormwood to my dug,
Sitting in the sun under the dovehouse wall;
My lord and you werM
Nay, I do bear a brain. But as I said,
When it did taste the wormwood on the nipple
Of my dug and felt it bitter, pretty fool,
To see it tetchy, and fall out with the dug!
Shake, quoth the dovehouse:
twas no need, I trow,
And since that time it is eleven years;
For then she could stand alone; nay, by th
She could have run and waddled all about;
For even the day before she broke her brow,
And then my husband,
God be with his soul!
dost thou fall upon thy face?
Thou wilt fall backward when thou hast more wit;
Wilt thou not, Jule?
 and, by my holidame,
The pretty wretch left crying, and said
To see now how a jest shall come about.
I warrant, and I should live a thousand years,
I never should forget it.
Wilt thou not, Jule?
And, pretty fool, it stinted, and said
Enough of this; I pray thee hold thy peace.
Yes, madam, yet I cannot choM
To think it should leave crying, and say
And yet I warrant it had upon it brow
A bump as big as a young cockerel
A perilous knock, and it cried bitterly.
Thou wilt fall backward when thou comest to age;
Wilt thou not, Jule?
 it stinted, and said
And stint thou too, I pray thee, Nurse, say I.
Peace, I have done. God mark thee to his grace
Thou wast the prettiest babe that e
And I might live to see thee married once, I have my wish.
Marry, that marry is the very theme
I came to talk of. Tell me, daughter Juliet,
How stands your disposition to be married?
It is an honour that I dream not of.
An honour! Were not I thine only nurse,
I would say thou hadst suck
d wisdom from thy teat.
Well, think of marriage now: younger than you,
Here in Verona, ladies of esteem,
Are made already mothers. By my count
other much upon these years
That you are now a maid. Thus, then, in brief;
The valiant Paris seeks you for his love.
A man, young lady! Lady, such a man
s summer hath not such a flower.
s a flower, in faith a very flower.
What say you, can you love the gentleman?
This night you shall behold him at our feast;
er the volume of young Paris
And find delight writ there with beaM
Examine every married lineament,
And see how one another lends content;
d in this fair volume lies,
Find written in the margent of his eyes.
This precious book of love, this unbound lover,
To beautify him, only lacks a cover:
The fish lives in the sea; and
For fair without the fair within to hide.
s eyes doth share the glory,
That in gold clasps locks in the golden story;
So shall you share all that he doth possess,
By having him, makiM
ng yourself no less.
No less, nay bigger. Women grow by men.
Speak briefly, can you like of Paris
ll look to like, if looking liking move:
But no more deep will I endart mine eye
Than your consent gives strength to make it fly.
Madam, the guests are come, supper served up, you called, my young lady
asked for, the Nurse cursed in the pantry, and everything in extremity.
I must hence to wait, I beseech you follow straight.
Juliet, the County stays.
Go, girl, seek happy nights to happy days.
 Enter Romeo, Mercutio, Benvolio, with five or six Maskers;
 Torch-bearers and others.
What, shall this speech be spoke for our excuse?
Or shall we on without apology?
The date is out of such prolixity:
ll have no Cupid hoodwink
s painted bow of lath,
 like a crow-keeper;
Nor no without-book prologue, faintly spoke
After the prompter, for our entrance:
But let them measure us by what they will,
ll measure them a measure, and be gone.
Give me a torch, I am not for this ambling;
Being but heavy I will bear the light.
Nay, gentle Romeo, we must have you dance.
Not I, believe me, you have dancing shoes,
With nimble soles, I have a soul of lead
So stakes me to the ground I cannot move.
You are a lover, borM
And soar with them above a common bound.
I am too sore enpierced with his shaft
To soar with his light feathers, and so bound,
I cannot bound a pitch above dull woe.
s heavy burden do I sink.
And, to sink in it, should you burden love;
Too great oppression for a tender thing.
Is love a tender thing? It is too rough,
Too rude, too boisterous; and it pricks like thorn.
If love be rough with you, be rough with love;
or pricking, and you beat love down.
Give me a case to put my visage in: [_Putting on a mask._]
A visor for a visor. What care I
What curious eye doth quote deformities?
Here are the beetle-brows shall blush for me.
Come, knock and enter; and no sooner in
But every man betake him to his legs.
A torch for me: let wantons, light of heart,
Tickle the senseless rushes with their heels;
d with a grandsire phrase,
ll be a candle-holder and look on,
er so fair, and I am done.
s the mouse, the constable
ll draw thee from the mire
Or save your reverence love, wherein thou stickest
Up to the ears. Come, we burn daylight, ho.
I mean sir, in delay
We waste our lights in vain, light lights by day.
Take our good meaning, for our judgment sits
Five times in that ere once in our five wits.
And we mean well in going to this mask;
I dreamt a dream tonight.
Well what was yours?
That dreamers often lie.
In bed asleep, while they do dream things true.
O, then, I see Queen Mab hath been with you.
 midwife, and she comes
In shape no bigger than an agate-stone
On the fore-finger of an alderman,
Drawn with a team of little atomies
s noses as they lie asleep:
Her waggon-spokes made M
The cover, of the wings of grasshoppers;
Her traces, of the smallest spider
The collars, of the moonshine
s bone; the lash, of film;
Her waggoner, a small grey-coated gnat,
Not half so big as a round little worm
d from the lazy finger of a maid:
Her chariot is an empty hazelnut,
Made by the joiner squirrel or old grub,
And in this state she gallops night by night
 brains, and then they dream of love;
 knees, that dream on curtsies straight;
 fingers, who straight dream on fees;
 lips, who straight on kisses dream,
Which oft the angry Mab with blisters plagues,
Because their breaths with sweetmeats tainted are:
Sometime she gallops o
And then dreams he of smelling out a suit;
And sometime comes she with a tithe-pig
s nose as a lies asleep,
 of another benefice:
Sometime she driveth o
And then dreams he of cutting foreign throats,
Of breaches, ambuscados, Spanish blades,
Of healths five fathom deep; and then anon
Drums in his ear, at which he starts and wakes;
And, being thus frighted, swears a prayer or two,
And sleeps again. This is that very Mab
That plats the manes of horses in the night;
And bakes the elf-locks in foul sluttish hairs,
Which, once untangled, much misfortune bodes:
This is the hag, when maids lieM
That presses them, and learns them first to bear,
Making them women of good carriage:
Peace, peace, Mercutio, peace,
True, I talk of dreams,
Which are the children of an idle brain,
Begot of nothing but vain fantasy,
Which is as thin of substance as the air,
And more inconstant than the wind, who wooes
Even now the frozen bosom of the north,
d, puffs away from thence,
Turning his side to the dew-droppiM
This wind you talk of blows us from ourselves:
Supper is done, and we shall come too late.
I fear too early: for my mind misgives
Some consequence yet hanging in the stars,
Shall bitterly begin his fearful date
s revels; and expire the term
Of a despised life, clos
By some vile forfeit of untimely death.
But he that hath the steerage of my course
Direct my suit. On, lusty gentlemen!
 Musicians waiting. Enter Servants.
s Potpan, that he helps not to take away?
He shift a trencher! He scrape a trencher!
When good manners shall lie all in one or two men
Away with the join-stools, remove the court-cupboard, look to the
plate. Good thou, save me a piece of marchpane; and as thou loves me,
let the porter let in Susan Grindstone and Nell. AntonM
You are looked for and called for, asked for and sought for, in the
We cannot be here and there too. Cheerly, boys. Be brisk awhile, and
the longer liver take all.
 Enter Capulet, &c. with the Guests and Gentlewomen to the Maskers.
Welcome, gentlemen, ladies that have their toes
d with corns will have a bout with you.
Ah my mistresses, which of you all
to dance? She that makes dainty,
ll swear hath corns. Am I come near ye now?
Welcome, gentlemen! I have seen the day
That I have worn a visor, and could tell
A whispering tale in a fair lady
Such as would please;
You are welcome, gentlemen! Come, musicians, play.
A hall, a hall, give room! And foot it, girls.
 [_Music plays, and they dance._]
More light, you knaves; and turn the tables up,
And quench the fire, the room is grown too hot.
d-for sport comes well.
Nay sit, nay sit, good cousin Capulet,
For you and I are past our dancing days;
t now since last yourself and I
r Lady, thirty years.
Tis since the nuptial of Lucentio,
Come Pentecost as quickly as it will,
Some five and twenty years; and then we mask
tis more, his son is elder, sir;
Will you tell me that?
His son was but a ward two years ago.
What lady is that, which doth enrich the hand
O, she doth teach the torches to burn bright!
It seems she hangs upon the cheek of night
As a rich jewel in an Ethiop
Beauty too rich for use, for earth too dear!
So shows a snowy dove trooping with crows
er her fellows shows.
ll watch her place of stand,
g hers, make blessed my rude hand.
Did my heart love till now? Forswear it, sight!
er saw true beauty till this night.
This by his voice, should be a Montague.
Fetch me my rapier, boy. What, dares the slave
d with an antic face,
To fleer and scorn at our solemnity?
Now by the stock and honour of my kin,
To strike him dead I hold it not a sin.
Why how now, kinsman!
Wherefore storm you so?
Uncle, this is a Montague, our foe;
is hither come in spite,
To scorn at our solemnity this night.
Tis he, that villain Romeo.
Content thee, gentle coz, let him alone,
A bears him like a portly gentleman;
And, to say truth, Verona brags of him
To be a virtuous and well-govern
I would not for the wealth of all the town
Here in my house do him disparagement.
Therefore be patient, take no note of him,
It is my will; the which if thou respect,
Show a fair presence and put ofM
An ill-beseeming semblance for a feast.
It fits when such a villain is a guest:
What, goodman boy! I say he shall, go to;
Am I the master here, or you? Go to.
ll not endure him! God shall mend my soul,
ll make a mutiny among my guests!
You will set cock-a-hoop, you
You are a saucy boy. Is
This trick may chance M
to scathe you, I know what.
You must contrary me! Marry,
Well said, my hearts!
You are a princox; go:
More light, more light!
ll make you quiet. What, cheerly, my hearts.
Patience perforce with wilful choler meeting
Makes my flesh tremble in their different greeting.
I will withdraw: but this intrusion shall,
Now seeming sweet, convert to bitter gall.
[_To Juliet._] If I profane with my unworthiest hand
This holy shrine, theM
 gentle sin is this,
My lips, two blushing pilgrims, ready stand
To smooth that rough touch with a tender kiss.
Good pilgrim, you do wrong your hand too much,
Which mannerly devotion shows in this;
For saints have hands that pilgrims
And palm to palm is holy palmers
Have not saints lips, and holy palmers too?
Ay, pilgrim, lips that they must use in prayer.
O, then, dear saint, let lips do what hands do:
They pray, grant thou, lest faithM
Saints do not move, though grant for prayers
Then move not while my prayer
Thus from my lips, by thine my sin is purg
Then have my lips the sin that they have took.
Sin from my lips? O trespass sweetly urg
Give me my sin again.
You kiss by the book.
Madam, your mother craves a word with you.
Her mother is the ladyM
And a good lady, and a wise and virtuous.
d her daughter that you talk
I tell you, he that can lay hold of her
Shall have the chinks.
O dear account! My life is my foe
Away, be gone; the sport is at the best.
Ay, so I fear; the more is my unrest.
Nay, gentlemen, prepare not to be gone,
We have a trifling foolish banquet towards.
en so? Why then, I thank you all;
I thank you, honest gentM
More torches here! Come on then, let
Ah, sirrah, by my fay, it waxes late,
 [_Exeunt all but Juliet and Nurse._]
Come hither, Nurse. What is yond gentleman?
The son and heir of old Tiberio.
s he that now is going out of door?
Marry, that I think be young Petruchio.
s he that follows here, that would not dance?
Go ask his name. If he be married,
is like to be my wedding bed.
His name is Romeo, and a Montague,
The only son of your great enemy.
My only love sprung from my only hate!
Too early seen unknown, and known too late!
Prodigious birth of love it is to me,
That I must love a loathed enemy.
 [_One calls within,
s away, the strangers all are gone.
Now old desire doth in his deathbed lie,
And young affection gapes to be his heir;
That fair for which love groan
d for and would die,
With tender Juliet match
Alike bewitched by the charm of looks;
But to his foe suppos
s sweet bait from fearful hooks:
Being held a foe, he may not have access
To breathe such vows as lovers use to swear;
And she as much in loM
ve, her means much less
To meet her new beloved anywhere.
But passion lends them power, time means, to meet,
Tempering extremities with extreme sweet.
SCENE I. An open place adjoining Capulet
Can I go forward when my heart is here?
Turn back, dull earth, and find thy centre out.
 [_He climbs the wall and leaps down within it._]
 Enter Benvolio and Mercutio.
Romeo! My cousin Romeo! Romeo!
And on my life hath sM
He ran this way, and leap
d this orchard wall:
Call, good Mercutio.
Romeo! Humours! Madman! Passion! Lover!
Appear thou in the likeness of a sigh,
Speak but one rhyme, and I am satisfied;
 Pronounce but Love and dove;
Speak to my gossip Venus one fair word,
One nickname for her purblind son and heir,
Young Abraham Cupid, he that shot so trim
When King Cophetua lov
He heareth not, he stiM
rreth not, he moveth not;
The ape is dead, and I must conjure him.
I conjure thee by Rosaline
By her high forehead and her scarlet lip,
By her fine foot, straight leg, and quivering thigh,
And the demesnes that there adjacent lie,
That in thy likeness thou appear to us.
An if he hear thee, thou wilt anger him.
This cannot anger him.
To raise a spirit in his mistress
Of some strange nature, letting it there stand
Till she had laid iM
That were some spite. My invocation
Is fair and honest, and, in his mistress
I conjure only but to raise up him.
Come, he hath hid himself among these trees
To be consorted with the humorous night.
Blind is his love, and best befits the dark.
If love be blind, love cannot hit the mark.
Now will he sit under a medlar tree,
And wish his mistress were that kind of fruit
As maids call medlars when they laugh alone.
O Romeo, that she were, O that sM
An open-arse and thou a poperin pear!
Romeo, good night. I
ll to my truckle-bed.
This field-bed is too cold for me to sleep.
To seek him here that means not to be found.
He jests at scars that never felt a wound.
 Juliet appears above at a window.
But soft, what light through yonder window breaks?
It is the east, and Juliet is the sun!
Arise fair sun and kiM
ll the envious moon,
Who is already sick and pale with grief,
That thou her maid art far more fair than she.
Be not her maid since she is envious;
Her vestal livery is but sick and green,
And none but fools do wear it; cast it off.
It is my lady, O it is my love!
O, that she knew she were!
She speaks, yet she says nothing. What of that?
Her eye discourses, I will answer it.
tis not to me she speaks.
Two of the fairest stars in all the heaven,
Having some business, do entreat her eyes
To twinkle in their spheres till they return.
What if her eyes were there, they in her head?
The brightness of her cheek would shame those stars,
As daylight doth a lamp; her eyes in heaven
Would through the airy region stream so bright
That birds would sing and think it were not night.
See how she leans her cheek upon her hand.
O that I were a glove upon that hand,
That I might touch that cheek.
O speak again bright angel, for thou art
As glorious to this night, M
As is a winged messenger of heaven
Unto the white-upturned wondering eyes
Of mortals that fall back to gaze on him
When he bestrides the lazy-puffing clouds
And sails upon the bosom of the air.
O Romeo, Romeo, wherefore art thou Romeo?
Deny thy father and refuse thy name.
Or if thou wilt not, be but sworn my love,
ll no longer be a Capulet.
[_Aside._] Shall I hear more, or shall I speak at this?
Tis but thy name that is my enemy;
thyself, though not a Montague.
s Montague? It is nor hand nor foot,
Nor arm, nor face, nor any other part
Belonging to a man. O be some other name.
s in a name? That which we call a rose
By any other name would smell as sweet;
So Romeo would, were he not Romeo call
Retain that dear perfection which he owes
Without that title. Romeo, doff thy name,
And for thy name, which is no part of thee,
I take thee at thy word.
Call me but love, and I
Henceforth I never will be Romeo.
What man art thou that, thus bescreen
So stumblest on my counsel?
I know not how to tell thee who I am:
My name, dear saint, is hateful to myself,
Because it is an enemy to thee.
Had I it written, I would tear the word.
My ears have yet not drunk a hundred words
s utterance, yet I know the sound.
Art thou not Romeo, and a Montague?
Neither, fair maid, if either thee dislike.
st thou hither, tell me, and wherefore?
The orchard walls are high and hard to climb,
And the place death, considering who thou art,
If any of my kinsmen find thee here.
s light wings did I o
erperch these walls,
For stony limits cannot hold love out,
And what love can do, that dares love attempt:
Therefore thy kinsmen are no stop to me.
If they do see thee, they will murder thee.
Alack, there lies more peril in thine eye
Than twenty of their swordM
s. Look thou but sweet,
And I am proof against their enmity.
I would not for the world they saw thee here.
s cloak to hide me from their eyes,
And but thou love me, let them find me here.
My life were better ended by their hate
Than death prorogued, wanting of thy love.
By whose direction found
st thou out this place?
By love, that first did prompt me to enquire;
He lent me counsel, and I lent him eyes.
I am no pilot; yet wert thou as far
d with the farthest sea,
I should adventure for such merchandise.
Thou knowest the mask of night is on my face,
Else would a maiden blush bepaint my cheek
For that which thou hast heard me speak tonight.
Fain would I dwell on form, fain, fain deny
What I have spoke; but farewell compliment.
Dost thou love me? I know thou wilt say Ay,
And I will take thy word. Yet, if thou swear
Thou mayst prove false. At lovers
They say Jove laughs. O gentle Romeo,
u dost love, pronounce it faithfully.
Or if thou thinkest I am too quickly won,
ll frown and be perverse, and say thee nay,
So thou wilt woo. But else, not for the world.
In truth, fair Montague, I am too fond;
And therefore thou mayst think my
But trust me, gentleman, I
Than those that have more cunning to be strange.
I should have been more strange, I must confess,
But that thou overheard
My true-love passion; therefore pardon me,
not impute this yielding to light love,
Which the dark night hath so discovered.
Lady, by yonder blessed moon I vow,
That tips with silver all these fruit-tree tops,
O swear not by the moon, th
That monthly changes in her circled orb,
Lest that thy love prove likewise variable.
What shall I swear by?
Do not swear at all.
Or if thou wilt, swear by thy gracious self,
Which is the god of my idolatry,
Well, do not swear. Although I joy in thee,
I have no joy of this contract tonight;
It is too rash, too unadvis
Too like the lightning, which doth cease to be
Ere one can say It lightens. Sweet, good night.
This bud of love, by summer
May prove a beauteous flower when next we meet.
Good night, good night. As sweet repose and rest
Come to thy heart as that within my breast.
O wilt thou leave me so unsatisfied?
 satisfaction canst thou have tonight?
exchange of thy love
s faithful vow for mine.
I gave thee mine before thou didst request it;
And yet I would it were to give again.
st thou withdraw it? For what purpose, love?
But to be frank and give it thee again.
And yet I wish but for the thing I have;
My bounty is as boundless as the sea,
My love as deep; the more I give to thee,
The more I have, for both are infinite.
I hear some noise within. Dear love,M
[_Nurse calls within._]
Sweet Montague be true.
Stay but a little, I will come again.
O blessed, blessed night. I am afeard,
Being in night, all this is but a dream,
Too flattering sweet to be substantial.
 Enter Juliet above.
Three words, dear Romeo, and good night indeed.
If that thy bent of love be honourable,
Thy purpose marriage, send me word tomorrow,
ll procure to come to thee,
Where and what time thou wilt perform tM
And all my fortunes at thy foot I
And follow thee my lord throughout the world.
 But if thou meanest not well,
To cease thy strife and leave me to my grief.
Tomorrow will I send.
A thousand times good night.
A thousand times the worse, to want thy light.
Love goes toward love as schoM
olboys from their books,
But love from love, towards school with heavy looks.
 [_Retiring slowly._]
 Re-enter Juliet, above.
Hist! Romeo, hist! O for a falconer
To lure this tassel-gentle back again.
Bondage is hoarse and may not speak aloud,
Else would I tear the cave where Echo lies,
And make her airy tongue more hoarse than mine
With repetition of my Romeo
It is my soul that calls upon my name.
How silver-sweet sound lovers
t music to attending ears.
Shall I send to thee?
By the hour of nine.
Tis twenty years till then.
I have forgot why I did call thee back.
Let me stand here till thou remember it.
I shall forget, to have thee still stand there,
Remembering how I love thy company.
ll still stay, to have thee still forget,
Forgetting any other home but this.
Tis almost morning; I would have thee gone,
And yet no farther than a wanton
That lets it hop a little from her hand,
Like a poor prisoner in his twisted gyves,
And with a silk thread plucks it back again,
So loving-jealous of his liberty.
I would I were thy bird.
Yet I should kill thee with much cherishing.
Good night, good night. Parting is such sweet sorrow
That I shall say good night till it be morrow.
Sleep dwell upon thine eyM
es, peace in thy breast.
Would I were sleep and peace, so sweet to rest.
d morn smiles on the frowning night,
Chequering the eastern clouds with streaks of light;
And darkness fleckled like a drunkard reels
s pathway, made by Titan
Hence will I to my ghostly Sire
His help to crave and my dear hap to tell.
SCENE III. Friar Lawrence
 Enter Friar Lawrence with a basket.
Now, ere the sun advance his burning eye,M
The day to cheer, and night
I must upfill this osier cage of ours
With baleful weeds and precious-juiced flowers.
s mother, is her tomb;
What is her burying grave, that is her womb:
And from her womb children of divers kind
We sucking on her natural bosom find.
Many for many virtues excellent,
None but for some, and yet all different.
O, mickle is the powerful grace that lies
In plants, herbs, stones, and their true qualities.
For naught so vile that on M
But to the earth some special good doth give;
Nor aught so good but, strain
d from that fair use,
Revolts from true birth, stumbling on abuse.
Virtue itself turns vice being misapplied,
s by action dignified.
Within the infant rind of this weak flower
Poison hath residence, and medicine power:
For this, being smelt, with that part cheers each part;
Being tasted, slays all senses with the heart.
Two such opposed kings encamp them still
grace and rude will;
And where the worser is predominant,
Full soon the canker death eats up that plant.
Good morrow, father.
What early tongue so sweet saluteth me?
Young son, it argues a distemper
So soon to bid good morrow to thy bed.
Care keeps his watch in every old man
And where care lodges sleep will never lie;
But where unbruised youth with unstuff
Doth couch his limbs, there golden sleep doth reign.
 thy earliness doth me assure
d with some distemperature;
Or if not so, then here I hit it right,
Our Romeo hath not been in bed tonight.
That last is true; the sweeter rest was mine.
God pardon sin. Wast thou with Rosaline?
With Rosaline, my ghostly father? No.
I have forgot that name, and that name
s my good son. But where hast thou been then?
ll tell thee ere thou ask it me again.
ing with mine enemy,
Where on a sudden one hath wounded me
s by me wounded. Both our remedies
Within thy help and holy physic lies.
I bear no hatred, blessed man; for lo,
My intercession likewise steads my foe.
Be plain, good son, and homely in thy drift;
Riddling confession finds but riddling shrift.
Then plainly know my heart
On the fair daughter of rich Capulet.
As mine on hers, so hers is set on mine;
d, save what thou must comM
By holy marriage. When, and where, and how
d, and made exchange of vow,
ll tell thee as we pass; but this I pray,
That thou consent to marry us today.
Holy Saint Francis! What a change is here!
Is Rosaline, that thou didst love so dear,
So soon forsaken? Young men
Not truly in their hearts, but in their eyes.
Jesu Maria, what a deal of brine
d thy sallow cheeks for Rosaline!
How much salt water thrown away in waste,
ve, that of it doth not taste.
The sun not yet thy sighs from heaven clears,
Thy old groans yet ring in mine ancient ears.
Lo here upon thy cheek the stain doth sit
Of an old tear that is not wash
If ere thou wast thyself, and these woes thine,
Thou and these woes were all for Rosaline,
d? Pronounce this sentence then,
Women may fall, when there
s no strength in men.
st me oft for loving Rosaline.
For doting, not for loving, pupM
To lay one in, another out to have.
I pray thee chide me not, her I love now
Doth grace for grace and love for love allow.
The other did not so.
Thy love did read by rote, that could not spell.
But come young waverer, come go with me,
ll thy assistant be;
For this alliance may so happy prove,
To turn your households
 rancour to pure love.
hence; I stand on sudden haste.
Wisely and slow; they stumble that run fast.
 Enter Benvolio and Mercutio.
Where the devil should this Romeo be? Came he not home tonight?
s; I spoke with his man.
Why, that same pale hard-hearted wench, that Rosaline, torments him so
that he will sure run mad.
Tybalt, the kinsman to old Capulet, hath sent a letter to his father
A challenge, on my life.
Romeo will answer it.
Any man that can write may answer a letter.
Nay, he will answer the letter
s master, how he dares, being dared.
Alas poor Romeo, he is already dead, stabbed with a white wench
eye; run through the ear with a love song, the very pin of his heart
cleft with the blind bow-boy
s butt-shaft. And is he a man to encounter
Why, what is Tybalt?
s the courageous captain of
compliments. He fights as you sing prick-song, keeps time, distance,
and proportion. He rests his minim rest, one, two, and the third in
your bosom: the very butcher of a silk button, a duellist, a duellist;
a gentleman of the very first house, of the first and second cause. Ah,
the immortal passado, the punto reverso, the hay.
The pox of such antic lisping, affecting phantasies; these new tuners
of accent. By Jesu, a very good M
blade, a very tall man, a very good
whore. Why, is not this a lamentable thing, grandsire, that we should
be thus afflicted with these strange flies, these fashion-mongers,
s, who stand so much on the new form that they cannot
sit at ease on the old bench? O their bones, their bones!
Here comes Romeo, here comes Romeo!
Without his roe, like a dried herring. O flesh, flesh, how art thou
fishified! Now is he for the numbers that Petrarch flowed in. LM
his lady, was but a kitchen wench,
marry, she had a better love to
berhyme her: Dido a dowdy; Cleopatra a gypsy; Helen and Hero hildings
and harlots; Thisbe a grey eye or so, but not to the purpose. Signior
Romeo, bonjour! There
s a French salutation to your French slop. You
gave us the counterfeit fairly last night.
Good morrow to you both. What counterfeit did I give you?
The slip sir, the slip; can you not conceive?
Pardon, good Mercutio, my business was greaM
t, and in such a case as
mine a man may strain courtesy.
s as much as to say, such a case as yours constrains a man to bow
Thou hast most kindly hit it.
A most courteous exposition.
Nay, I am the very pink of courtesy.
Why, then is my pump well flowered.
Sure wit, follow me this jest now, till thou hast worn out thy pump,
ingle sole of it is worn, the jest may remain after the
wearing, solely singular.
O single-soled jest, solely singular for the singleness!
Come between us, good Benvolio; my wits faint.
Swits and spurs, swits and spurs; or I
Nay, if thy wits run the wild-goose chase, I am done. For thou hast
more of the wild-goose in one of thy wits, than I am sure, I have in my
whole five. Was I with you there for the goose?
Thou wast never with me fM
or anything, when thou wast not there for the
I will bite thee by the ear for that jest.
Nay, good goose, bite not.
Thy wit is a very bitter sweeting, it is a most sharp sauce.
And is it not then well served in to a sweet goose?
s a wit of cheveril, that stretches from an inch narrow to an
I stretch it out for that word broad, which added to the goose, proves
thee far and wide a broad goose.
s not this better now than groaning for love? Now art thou
sociable, now art thou Romeo; not art thou what thou art, by art as
well as by nature. For this drivelling love is like a great natural,
that runs lolling up and down to hide his bauble in a hole.
Stop there, stop there.
Thou desirest me to stop in my tale against the hair.
Thou wouldst else have made thy tale large.
O, thou art deceived; I would have made it short, for I was come to the
h of my tale, and meant indeed to occupy the argument no
 Enter Nurse and Peter.
Two, two; a shirt and a smock.
Good Peter, to hide her face; for her fan
God ye good morrow, gentlemen.
God ye good-den, fair gentlewoman.
Tis no less, I tell ye; for the bawdy hand of the dial is nM
Out upon you! What a man are you?
One, gentlewoman, that God hath made for himself to mar.
By my troth, it is well said; for himself to mar, quoth a? Gentlemen,
can any of you tell me where I may find the young Romeo?
I can tell you: but young Romeo will be older when you have found him
than he was when you sought him. I am the youngest of that name, for
Yea, is the worst well? Very weM
faith; wisely, wisely.
If you be he, sir, I desire some confidence with you.
She will endite him to some supper.
A bawd, a bawd, a bawd! So ho!
What hast thou found?
No hare, sir; unless a hare, sir, in a lenten pie, that is something
stale and hoar ere it be spent.
    An old hare hoar,
    And an old hare hoar,
  Is very good meat in Lent;
    But a hare that is hoar
    Is too much for a score
  When it hoars ere it bM
Romeo, will you come to your father
ll to dinner thither.
Farewell, ancient lady; farewell, lady, lady, lady.
 [_Exeunt Mercutio and Benvolio._]
I pray you, sir, what saucy merchant was this that was so full of his
A gentleman, Nurse, that loves to hear himself talk, and will speak
more in a minute than he will stand to in a month.
And a speak anything against me, I
ll take him down, and a were lustier
han he is, and twenty such Jacks. And if I cannot, I
that shall. Scurvy knave! I am none of his flirt-gills; I am none of
And thou must stand by too and suffer every knave to
use me at his pleasure!
I saw no man use you at his pleasure; if I had, my weapon should
quickly have been out. I warrant you, I dare draw as soon as another
man, if I see occasion in a good quarrel, and the law on my side.
Now, afore God, I am so vexed that every part about me quiM
knave. Pray you, sir, a word: and as I told you, my young lady bid me
enquire you out; what she bade me say, I will keep to myself. But first
let me tell ye, if ye should lead her in a fool
say, it were a very gross kind of behaviour, as they say; for the
gentlewoman is young. And therefore, if you should deal double with
her, truly it were an ill thing to be offered to any gentlewoman, and
ROMEO. Nurse, commend me to thy lady and mistress. I protest uM
faith I will tell her as much. Lord, Lord, she will
What wilt thou tell her, Nurse? Thou dost not mark me.
I will tell her, sir, that you do protest, which, as I take it, is a
gentlemanlike offer.
Some means to come to shrift this afternoon,
And there she shall at Friar Lawrence
d and married. Here is for thy pains.
No truly, sir; not a penny.
This afternoon, sir? Well, she shall be there.
And stay, good Nurse, behind the abbey wall.
Within this hour my man shall be with thee,
And bring thee cords made like a tackled stair,
Which to the high topgallant of my joy
Must be my convoy in the secret night.
Farewell, be trusty, and I
Farewell; commend me to thy mistress.
Now God in heaven bless thee. Hark you, sir.
st thou, my dear Nurse?
Is your man secret? DidM
Two may keep counsel, putting one away?
I warrant thee my man
Well, sir, my mistress is the sweetest lady. Lord, Lord! When
little prating thing,
O, there is a nobleman in town, one Paris, that
would fain lay knife aboard; but she, good soul, had as lief see a
toad, a very toad, as see him. I anger her sometimes, and tell her that
Paris is the properer man, but I
ll warrant you, when I say so, she
looks as pale as any clout in thM
e versal world. Doth not rosemary and
Romeo begin both with a letter?
Ay, Nurse; what of that? Both with an R.
s name. R is for the
no, I know it begins
with some other letter, and she hath the prettiest sententious of it,
of you and rosemary, that it would do you good to hear it.
Commend me to thy lady.
Ay, a thousand times. Peter!
The clock struck nine when I did send the Nurse,
In half an hour she promised to return.
Perchance she cannot meet him. That
O, she is lame. Love
s heralds should be thoughts,
Which ten times faster glides than the sun
Driving back shadows over lowering hills:
Therefore do nimble-pinion
And therefore hath the wind-swift Cupid wings.
Now is the sun upon the highmost hill
s journey, and from nine till twelve
s three long hours, yet she is not come.
Had she affections and warm youthful blood,
d be as swift in motion as a ball;
My words would bandy her to my sweet love,
But old folks, many feign as they were dead;
Unwieldy, slow, heavy and pale as lead.
 Enter Nurse and Peter.
O God, she comes. O honey Nurse, what news?
Hast thou met with him? Send thy man away.
Peter, stay at the gate.
Now, good sweet Nurse,
hough news be sad, yet tell them merrily;
st the music of sweet news
By playing it to me with so sour a face.
I am aweary, give me leave awhile;
Fie, how my bones ache! What a jaunt have I had!
I would thou hadst my bones, and I thy news:
Nay come, I pray thee speak; good, good Nurse, speak.
Jesu, what haste? Can you not stay a while? Do you not see that I am
How art thou out of breath, when thou hast breath
To say to me that thM
ou art out of breath?
The excuse that thou dost make in this delay
Is longer than the tale thou dost excuse.
Is thy news good or bad? Answer to that;
ll stay the circumstance.
Let me be satisfied, is
Well, you have made a simple choice; you know not how to choose a man.
Romeo? No, not he. Though his face be better than any man
s, and for a hand and a foot, and a body, though
they be not to be talked on, yet they are past compaM
flower of courtesy, but I
ll warrant him as gentle as a lamb. Go thy
ways, wench, serve God. What, have you dined at home?
No, no. But all this did I know before.
What says he of our marriage? What of that?
Lord, how my head aches! What a head have I!
It beats as it would fall in twenty pieces.
Beshrew your heart for sending me about
To catch my death with jauncing up and down.
faith, I am sorry thatM
Sweet, sweet, sweet Nurse, tell me, what says my love?
Your love says like an honest gentleman,
And a courteous, and a kind, and a handsome,
And I warrant a virtuous,
Where is your mother?
Where is my mother? Why, she is within.
Where should she be? How oddly thou repliest.
Your love says, like an honest gentleman,
Where is your mother?
Are you so hot? Marry, come up, I trow.
Is this the poultice for my aching bones?
eforward do your messages yourself.
s such a coil. Come, what says Romeo?
Have you got leave to go to shrift today?
Then hie you hence to Friar Lawrence
There stays a husband to make you a wife.
Now comes the wanton blood up in your cheeks,
ll be in scarlet straight at any news.
Hie you to church. I must another way,
To fetch a ladder by the which your love
s nest soon when it is dark.
I am the drudge, and toil iM
But you shall bear the burden soon at night.
ll to dinner; hie you to the cell.
Hie to high fortune! Honest Nurse, farewell.
SCENE VI. Friar Lawrence
 Enter Friar Lawrence and Romeo.
So smile the heavens upon this holy act
That after-hours with sorrow chide us not.
Amen, amen, but come what sorrow can,
It cannot countervail the exchange of joy
That one short minute gives me in her sight.
Do thou but close our haM
nds with holy words,
Then love-devouring death do what he dare,
It is enough I may but call her mine.
These violent delights have violent ends,
And in their triumph die; like fire and powder,
Which as they kiss consume. The sweetest honey
Is loathsome in his own deliciousness,
And in the taste confounds the appetite.
Therefore love moderately: long love doth so;
Too swift arrives as tardy as too slow.
Here comes the lady. O, so light a foot
A lover may bestride the gossamers
That idles in the wanton summer air
And yet not fall; so light is vanity.
Good even to my ghostly confessor.
Romeo shall thank thee, daughter, for us both.
As much to him, else is his thanks too much.
Ah, Juliet, if the measure of thy joy
d like mine, and that thy skill be more
To blazon it, then sweeten with thy breath
This neighbour air, and let rich music
 happiness that both
Receive in either by this dear encounter.
Conceit more rich in matter than in words,
Brags of his substance, not of ornament.
They are but beggars that can count their worth;
But my true love is grown to such excess,
I cannot sum up sum of half my wealth.
Come, come with me, and we will make short work,
For, by your leaves, you shall not stay alone
Till holy church incorporate two in one.
SCENE I. A public Place.
 Mercutio, Benvolio, Page and Servants.
I pray thee, good Mercutio, let
The day is hot, the Capulets abroad,
And if we meet, we shall not scape a brawl,
For now these hot days, is the mad blood stirring.
Thou art like one of these fellows that, when he enters the confines of
a tavern, claps me his sword upon the table, and says
 and by the operation of the second cup draws him on the
drawer, when indeed there is no need.
m I like such a fellow?
Come, come, thou art as hot a Jack in thy mood as any in Italy; and as
soon moved to be moody, and as soon moody to be moved.
Nay, an there were two such, we should have none shortly, for one would
kill the other. Thou? Why, thou wilt quarrel with a man that hath a
hair more or a hair less in his beard than thou hast. Thou wilt quarrel
with a man for cracking nuts, having no other reason but because thou
hast hazel eyes. What eye buM
t such an eye would spy out such a quarrel?
Thy head is as full of quarrels as an egg is full of meat, and yet thy
head hath been beaten as addle as an egg for quarrelling. Thou hast
quarrelled with a man for coughing in the street, because he hath
wakened thy dog that hath lain asleep in the sun. Didst thou not fall
out with a tailor for wearing his new doublet before Easter? with
another for tying his new shoes with an old riband? And yet thou wilt
tutor me from quarrelling!
 to quarrel as thou art, any man should buy the fee
simple of my life for an hour and a quarter.
The fee simple! O simple!
 Enter Tybalt and others.
By my head, here comes the Capulets.
By my heel, I care not.
Follow me close, for I will speak to them.
Gentlemen, good-den: a word with one of you.
And but one word with one of us? Couple it with something; make it a
You shall find me apt enough to that, sir, and youM
Could you not take some occasion without giving?
Mercutio, thou consortest with Romeo.
Consort? What, dost thou make us minstrels? And thou make minstrels of
us, look to hear nothing but discords. Here
s my fiddlestick, here
that shall make you dance. Zounds, consort!
We talk here in the public haunt of men.
Either withdraw unto some private place,
And reason coldly of your grievances,
Or else depart; here all eyes gaze on us.M
s eyes were made to look, and let them gaze.
I will not budge for no man
Well, peace be with you, sir, here comes my man.
ll be hanged, sir, if he wear your livery.
Marry, go before to field, he
ll be your follower;
Your worship in that sense may call him man.
Romeo, the love I bear thee can afford
No better term than this: Thou art a villain.
Tybalt, the reason that I have to love thee
xcuse the appertaining rage
To such a greeting. Villain am I none;
Therefore farewell; I see thou know
Boy, this shall not excuse the injuries
That thou hast done me, therefore turn and draw.
I do protest I never injur
But love thee better than thou canst devise
Till thou shalt know the reason of my love.
And so good Capulet, which name I tender
As dearly as mine own, be satisfied.
O calm, dishonourable, vile submission!
[_Draws._] Alla stoccata caM
Tybalt, you rat-catcher, will you walk?
What wouldst thou have with me?
Good King of Cats, nothing but one of your nine lives; that I mean to
make bold withal, and, as you shall use me hereafter, dry-beat the rest
of the eight. Will you pluck your sword out of his pilcher by the ears?
Make haste, lest mine be about your ears ere it be out.
[_Drawing._] I am for you.
Gentle Mercutio, put thy rapier up.
Come, sir, your passado.
Draw, Benvolio; beat down their weapons.
Gentlemen, for shame, forbear this outrage,
Tybalt, Mercutio, the Prince expressly hath
Forbid this bandying in Verona streets.
Hold, Tybalt! Good Mercutio!
 [_Exeunt Tybalt with his Partizans._]
 both your houses. I am sped.
Is he gone, and hath nothing?
What, art thou hurt?
Ay, ay, a scratch, a scratch. Marry,
Where is my page? Go villain, fetch a surgeon.
Courage, man; the hurt cannot be much.
tis not so deep as a well, nor so wide as a church door, but
twill serve. Ask for me tomorrow, and you shall find me a
grave man. I am peppered, I warrant, for this world. A plague o
your houses. Zounds, a dog, a rat, a mouse, a cat, to scratch a man to
death. A braggart, a rogue, a villain, that fights by the book of
Why the devil came you between us? I was hurt under your
I thought all for the best.
Help me into some house, Benvolio,
Or I shall faint. A plague o
They have made worms
I have it, and soundly too. Your houses!
 [_Exeunt Mercutio and Benvolio._]
This gentleman, the Prince
My very friend, hath got his mortal hurt
In my behalf; my reputation stain
Tybalt, that an hour
Hath been my cousin. O sweet Juliet,
Thy beauty hath made me effeminate
O Romeo, Romeo, brave Mercutio
That gallant spirit hath aspir
Which too untimely here did scorn the earth.
s black fate on mo days doth depend;
This but begins the woe others must end.
Here comes the furious Tybalt back again.
Again in triumph, and Mercutio slain?
Away to heaven respective lenity,
d fury be my conduct now!
Is but a little way above our heads,
Staying for thine to keep him company.
Either thou or I, or both, must go with him.
Thou wretched boy, that didst consort him here,
Shalt with him hence.
This shall determine that.
 [_They fight; Tybalt falls._]
Romeo, away, be gone!
The citizens are up, and Tybalt slain.
d. The Prince will doom thee death
If thou art taken. HencM
Which way ran he that kill
Tybalt, that murderer, which way ran he?
There lies that Tybalt.
Up, sir, go with me.
I charge thee in the Prince
 Enter Prince, attended; Montague, Capulet, their Wives and others.
Where are the vile beginners of this fray?
O noble Prince, I can discoM
The unlucky manage of this fatal brawl.
There lies the man, slain by young Romeo,
That slew thy kinsman, brave Mercutio.
Tybalt, my cousin! O my brother
O Prince! O husband! O, the blood is spill
Of my dear kinsman! Prince, as thou art true,
For blood of ours shed blood of Montague.
Benvolio, who began this bloody fray?
Tybalt, here slain, whom Romeo
Romeo, that spoke him fair, bid him bethink
he quarrel was, and urg
Your high displeasure. All this uttered
With gentle breath, calm look, knees humbly bow
Could not take truce with the unruly spleen
Of Tybalt, deaf to peace, but that he tilts
With piercing steel at bold Mercutio
Who, all as hot, turns deadly point to point,
And, with a martial scorn, with one hand beats
Cold death aside, and with the other sends
It back to Tybalt, whose dexterity
Retorts it. Romeo he cries aloud,
Hold, friends! Friends, part!
swifter than his tongue,
His agile arm beats down their fatal points,
twixt them rushes; underneath whose arm
An envious thrust from Tybalt hit the life
Of stout Mercutio, and then Tybalt fled.
But by and by comes back to Romeo,
Who had but newly entertain
t they go like lightning; for, ere I
Could draw to part them was stout Tybalt slain;
And as he fell did Romeo turn and fly.
This is the truth, or let Benvolio die.
He is a kinsman to the Montague.
n makes him false, he speaks not true.
Some twenty of them fought in this black strife,
And all those twenty could but kill one life.
I beg for justice, which thou, Prince, must give;
Romeo slew Tybalt, Romeo must not live.
Romeo slew him, he slew Mercutio.
Who now the price of his dear blood doth owe?
Not Romeo, Prince, he was Mercutio
His fault concludes but what the law should end,
And for that offence
Immediately we do exile him henceM
I have an interest in your hate
My blood for your rude brawls doth lie a-bleeding.
ll amerce you with so strong a fine
That you shall all repent the loss of mine.
I will be deaf to pleading and excuses;
Nor tears nor prayers shall purchase out abuses.
Therefore use none. Let Romeo hence in haste,
Else, when he is found, that hour is his last.
Bear hence this body, and attend our will.
Mercy but murders, pardoning those that kill.
SCENE II. A Room in Capulet
Gallop apace, you fiery-footed steeds,
 lodging. Such a waggoner
As Phaeton would whip you to the west
And bring in cloudy night immediately.
Spread thy close curtain, love-performing night,
s eyes may wink, and Romeo
Leap to these arms, untalk
Lovers can see to do their amorous rites
By their own beauties: or, if love be blind,
It best agrees with night. Come, civil night,
Thou sober-suited matron, all in black,
d learn me how to lose a winning match,
d for a pair of stainless maidenhoods.
d blood, bating in my cheeks,
With thy black mantle, till strange love, grow bold,
Think true love acted simple modesty.
Come, night, come Romeo; come, thou day in night;
For thou wilt lie upon the wings of night
Whiter than new snow upon a raven
Come gentle night, come loving black-brow
Give me my Romeo, and when I shall die,
Take him and cut him out in little stars,
ke the face of heaven so fine
That all the world will be in love with night,
And pay no worship to the garish sun.
O, I have bought the mansion of a love,
d it; and though I am sold,
d. So tedious is this day
As is the night before some festival
To an impatient child that hath new robes
And may not wear them. O, here comes my Nurse,
And she brings news, and every tongue that speaks
s name speaks heavenly eloquence.
 Enter Nurse, with cords.
hat news? What hast thou there?
The cords that Romeo bid thee fetch?
 [_Throws them down._]
Ay me, what news? Why dost thou wring thy hands?
We are undone, lady, we are undone.
Can heaven be so envious?
Though heaven cannot. O Romeo, Romeo.
Who ever would have thought it? Romeo!
What devil art thou,M
 that dost torment me thus?
This torture should be roar
Hath Romeo slain himself? Say thou but Ay,
And that bare vowel I shall poison more
Than the death-darting eye of cockatrice.
I am not I if there be such an I;
Or those eyes shut that make thee answer Ay.
If he be slain, say Ay; or if not, No.
Brief sounds determine of my weal or woe.
I saw the wound, I saw it with mine eyes,
here on his manly breast.
A piteous corse, a bloody piteous corse;
ale as ashes, all bedaub
All in gore-blood. I swounded at the sight.
O, break, my heart. Poor bankrout, break at once.
Vile earth to earth resign; end motion here,
And thou and Romeo press one heavy bier.
O Tybalt, Tybalt, the best friend I had.
O courteous Tybalt, honest gentleman!
That ever I should live to see thee dead.
What storm is this that blows so contrary?
d and is Tybalt dead?
t cousin, and my dearer lord?
Then dreadful trumpet sound the general doom,
For who is living, if those two are gone?
Tybalt is gone, and Romeo banished,
d him, he is banished.
It did, it did; alas the day, it did.
O serpent heart, hid with a flowering face!
Did ever dragon keep so fair a cave?
Beautiful tyrant, fiend angelical,
d raven, wolvish-ravening lamb!
Despised substance of M
Just opposite to what thou justly seem
A damned saint, an honourable villain!
O nature, what hadst thou to do in hell
When thou didst bower the spirit of a fiend
In mortal paradise of such sweet flesh?
Was ever book containing such vile matter
So fairly bound? O, that deceit should dwell
In such a gorgeous palace.
No faith, no honesty in men. All perjur
All forsworn, all naught, all dissemblers.
s my man? Give me some aqua vitae.
 griefs, these woes, these sorrows make me old.
Shame come to Romeo.
For such a wish! He was not born to shame.
Upon his brow shame is asham
tis a throne where honour may be crown
Sole monarch of the universal earth.
O, what a beast was I to chide at him!
Will you speak well of him that kill
Shall I speak ill of him that is my husband?
Ah, poor my lord, what tongue shall smooth thy name,
When I thy three-houM
 wife have mangled it?
But wherefore, villain, didst thou kill my cousin?
That villain cousin would have kill
Back, foolish tears, back to your native spring,
Your tributary drops belong to woe,
Which you mistaking offer up to joy.
My husband lives, that Tybalt would have slain,
s dead, that would have slain my husband.
All this is comfort; wherefore weep I then?
Some word there was, worser than Tybalt
d me. I would forget it fain,
Like damned guilty deeds to sinners
Tybalt is dead, and Romeo banished.
Hath slain ten thousand Tybalts. Tybalt
Was woe enough, if it had ended there.
Or if sour woe delights in fellowship,
And needly will be rank
d with other griefs,
d not, when she said Tybalt
Thy father or thy mother, nay or both,
Which modern lamentation might have mov
But with a rear-ward following Tybalt
Is father, mother, Tybalt, Romeo, Juliet,
All slain, all dead. Romeo is banished,
There is no end, no limit, measure, bound,
s death, no words can that woe sound.
Where is my father and my mother, Nurse?
Weeping and wailing over Tybalt
Will you go to them? I will bring you thither.
Wash they his wounds with tears. Mine shall be spent,
When theirs are dry, for Romeo
Take up those cords. Poor ropes, M
Both you and I; for Romeo is exil
He made you for a highway to my bed,
But I, a maid, die maiden-widowed.
Come cords, come Nurse, I
ll to my wedding bed,
And death, not Romeo, take my maidenhead.
Hie to your chamber. I
To comfort you. I wot well where he is.
Hark ye, your Romeo will be here at night.
ll to him, he is hid at Lawrence
O find him, give this ring to my true knight,
And bid him come to take his last farewell.
SCENE III. Friar Lawrence
 Enter Friar Lawrence.
Romeo, come forth; come forth, thou fearful man.
Affliction is enanmour
And thou art wedded to calamity.
Father, what news? What is the Prince
What sorrow craves acquaintance at my hand,
That I yet know not?
Is my dear son with such sour company.
I bring thee tidings of the Prince
What less than doomsday is thM
A gentler judgment vanish
Ha, banishment? Be merciful, say death;
For exile hath more terror in his look,
Much more than death. Do not say banishment.
Hence from Verona art thou banished.
Be patient, for the world is broad and wide.
There is no world without Verona walls,
But purgatory, torture, hell itself.
Hence banished is banish
 exile is death. Then banished
d. Calling death banished,
st my head off with a golden axe,
And smilest upon the stroke that murders me.
O deadly sin, O rude unthankfulness!
Thy fault our law calls death, but the kind Prince,
Taking thy part, hath brush
d that black word death to banishment.
This is dear mercy, and thou see
Tis torture, and not mercy. Heaven is here
Where Juliet lives, and every cat aM
And little mouse, every unworthy thing,
Live here in heaven and may look on her,
But Romeo may not. More validity,
More honourable state, more courtship lives
In carrion flies than Romeo. They may seize
On the white wonder of dear Juliet
And steal immortal blessing from her lips,
Who, even in pure and vestal modesty
Still blush, as thinking their own kisses sin.
But Romeo may not, he is banished.
This may flies do, when I from this must fly.
They are free men but I am banished.
st thou yet that exile is not death?
Hadst thou no poison mix
d, no sharp-ground knife,
No sudden mean of death, though ne
But banished to kill me? Banished?
O Friar, the damned use that word in hell.
Howlings attends it. How hast thou the heart,
Being a divine, a ghostly confessor,
A sin-absolver, and my friend profess
To mangle me with that word banished?
Thou fond mad man, hear me speak a little,
O, thou wilt speak again of banishment.
ll give thee armour to keep off that word,
s sweet milk, philosophy,
To comfort thee, though thou art banished.
Yet banished? Hang up philosophy.
Unless philosophy can make a Juliet,
Displant a town, reverse a Prince
It helps not, it prevails not, talk no more.
O, then I see that mad men have no ears.
How should they, when that wise men have no eyes?
Let me dispute with thee of thy estate.
peak of that thou dost not feel.
Wert thou as young as I, Juliet thy love,
An hour but married, Tybalt murdered,
Doting like me, and like me banished,
Then mightst thou speak, then mightst thou tear thy hair,
And fall upon the ground as I do now,
Taking the measure of an unmade grave.
 [_Knocking within._]
Arise; one knocks. Good Romeo, hide thyself.
Not I, unless the breath of heartsick groans
Mist-like infold me from the search of eyes.
Hark, how they knock!
What simpleness is this.
Who knocks so hard? Whence come you, what
[_Within._] Let me come in, and you shall know my errand.
I come from Lady Juliet.
O holy Friar, O, tell me, holy Friar,
There on the ground, with his own tears made drunk.
O, he is even in my mistress
Just in her case! O woeful sympathy!
Piteous predicament. Even so lies she,
Blubbering and weeping, weeping and blubbering.
Stand up, stand up; stand, and you be a man.
s sake, for her sake, rise and stand.
Why should you fall into so deep an O?
Ah sir, ah sir, death
Spakest thou of Juliet? How is it withM
Doth not she think me an old murderer,
d the childhood of our joy
d but little from her own?
Where is she? And how doth she? And what says
d lady to our cancell
O, she says nothing, sir, but weeps and weeps;
And now falls on her bed, and then starts up,
And Tybalt calls, and then on Romeo cries,
And then down falls again.
Shot from the deadly level of a gun,
Did murder her, as that name
d her kinsman. O, tell me, Friar, tell me,
In what vile part of this anatomy
Doth my name lodge? Tell me, that I may sack
The hateful mansion.
 [_Drawing his sword._]
Hold thy desperate hand.
Art thou a man? Thy form cries out thou art.
Thy tears are womanish, thy wild acts denote
The unreasonable fury of a beast.
Unseemly woman in a seeming man,
And ill-beseeming beast in seeming both!
d me. By my holy order,
I thought thy disposition better temper
Hast thou slain Tybalt? Wilt thou slay thyself?
And slay thy lady, that in thy life lives,
By doing damned hate upon thyself?
st thou on thy birth, the heaven and earth?
Since birth, and heaven and earth, all three do meet
In thee at once; which thou at once wouldst lose.
st thy shape, thy love, thy wit,
Which, like a usurer, abound
And usest none in that true use indeed
Which should bedeck thy shape, thy love, thy wit.
Thy noble shape is but a form of wax,
Digressing from the valour of a man;
Thy dear love sworn but hollow perjury,
Killing that love which thou hast vow
Thy wit, that ornament to shape and love,
Misshapen in the conduct of them both,
Like powder in a skilless soldier
Is set afire by thine own ignorance,
d with thine own defence.
What, rouse thee, man. Thy Juliet is alive,
For whose dear sake thou wast but lately dead.
There art thou happy. Tybalt would kill thee,
The law that threaten
d death becomes thy friend,
And turns it to exile; there art thou happy.
A pack of blessings light upon thy back;
Happiness courts thee in her best array;
But like a misshaped and sullen wench,
st up thy Fortune and thy love.
Take heed, take heed, for such die miserable.
Go, get thee to thy love as was decreed,
Ascend her chamber, hence and comfort her.
But look thou stay not till the watch be set,
For then thou canst not pass to Mantua;
shalt live till we can find a time
To blaze your marriage, reconcile your friends,
Beg pardon of the Prince, and call thee back
With twenty hundred thousand times more joy
st forth in lamentation.
Go before, Nurse. Commend me to thy lady,
And bid her hasten all the house to bed,
Which heavy sorrow makes them apt unto.
O Lord, I could have stay
d here all the night
To hear good counsel. O, what learning is!
ll tell my lady you will come.
Do so, and bid my sweet prepare to chide.
Here sir, a ring she bid me give you, sir.
Hie you, make haste, for it grows very late.
How well my comfort is reviv
Go hence, good night, and here stands all your state:
Either be gone before the watch be set,
Or by the break of day disguis
Sojourn in Mantua. I
ll find out your man,
And he shall signify from time to time
Every good hap to you that chances here.
tis late; farewell; good night.
But that a joy past joy calls out on me,
It were a grief so brief to part with thee.
SCENE IV. A Room in Capulet
 Enter Capulet, Lady Capulet and Paris.
Things have fallen out, sir, so unluckily
That we have had no time to move our daughter.
d her kinsman Tybalt dearly,
And so did I. Well, we were born to die.
ll not come down tonight.
I promise you, but for your M
I would have been abed an hour ago.
These times of woe afford no tune to woo.
Madam, good night. Commend me to your daughter.
I will, and know her mind early tomorrow;
d up to her heaviness.
Sir Paris, I will make a desperate tender
s love. I think she will be rul
In all respects by me; nay more, I doubt it not.
Wife, go you to her ere you go to bed,
Acquaint her here of my son Paris
And bid her, mark you me,M
But, soft, what day is this?
Monday! Ha, ha! Well, Wednesday is too soon,
A Thursday let it be; a Thursday, tell her,
She shall be married to this noble earl.
Will you be ready? Do you like this haste?
ll keep no great ado,
For, hark you, Tybalt being slain so late,
It may be thought we held him carelessly,
Being our kinsman, if we revel much.
ll have some half a dozen friends,
And there an end. But what saM
My lord, I would that Thursday were tomorrow.
Well, get you gone. A Thursday be it then.
Go you to Juliet ere you go to bed,
Prepare her, wife, against this wedding day.
Light to my chamber, ho!
Afore me, it is so very very late that we
May call it early by and by. Good night.
SCENE V. An open Gallery to Juliet
s Chamber, overlooking the Garden.
 Enter Romeo and Juliet.
Wilt thou be gone? It is not yet near day.M
It was the nightingale, and not the lark,
d the fearful hollow of thine ear;
Nightly she sings on yond pomegranate tree.
Believe me, love, it was the nightingale.
It was the lark, the herald of the morn,
No nightingale. Look, love, what envious streaks
Do lace the severing clouds in yonder east.
s candles are burnt out, and jocund day
Stands tiptoe on the misty mountain tops.
I must be gone and live, or stay and die.
Yond light is not daylight, I know it, I.
 is some meteor that the sun exhales
To be to thee this night a torchbearer
And light thee on thy way to Mantua.
Therefore stay yet, thou need
en, let me be put to death,
I am content, so thou wilt have it so.
ll say yon grey is not the morning
Tis but the pale reflex of Cynthia
Nor that is not the lark whose notes do beat
The vaulty heaven so high above our heads.
I have more care to stay than will to go.
Come, death, and welcome. JM
s talk. It is not day.
It is, it is! Hie hence, be gone, away.
It is the lark that sings so out of tune,
Straining harsh discords and unpleasing sharps.
Some say the lark makes sweet division;
This doth not so, for she divideth us.
Some say the lark and loathed toad change eyes.
O, now I would they had chang
Since arm from arm that voice doth us affray,
Hunting thee hence with hunt
O now be gone, more light and liM
More light and light, more dark and dark our woes.
Your lady mother is coming to your chamber.
The day is broke, be wary, look about.
Then, window, let day in, and let life out.
Farewell, farewell, one kiss, and I
Art thou gone so? Love, lord, ay husband, friend,
I must hear from thee every day in the hour,
For in a minute there are many days.
O, by this count I shall be much in years
Ere I again behold my Romeo.
I will omit no opportunity
That may convey my greetings, love, to thee.
O thinkest thou we shall ever meet again?
I doubt it not, and all these woes shall serve
For sweet discourses in our time to come.
O God! I have an ill-divining soul!
Methinks I see thee, now thou art so low,
As one dead in the bottom of a tomb.
Either my eyesight fails, or thou look
ust me, love, in my eye so do you.
Dry sorrow drinks our blood. Adieu, adieu.
O Fortune, Fortune! All men call thee fickle,
If thou art fickle, what dost thou with him
d for faith? Be fickle, Fortune;
For then, I hope thou wilt not keep him long
[_Within._] Ho, daughter, are you up?
t that calls? Is it my lady mother?
Is she not down so late, or up so early?
d cause procures her hitherM
 Enter Lady Capulet.
Why, how now, Juliet?
Madam, I am not well.
Evermore weeping for your cousin
What, wilt thou wash him from his grave with tears?
And if thou couldst, thou couldst not make him live.
Therefore have done: some grief shows much of love,
But much of grief shows still some want of wit.
Yet let me weep for such a feeling loss.
So shall you feel the loss, but not the friend
Feeling so the loss,
I cannot choose but ever weep the friend.
Well, girl, thou weep
st not so much for his death
As that the villain lives which slaughter
What villain, madam?
That same villain Romeo.
Villain and he be many miles asunder.
God pardon him. I do, with all my heart.
And yet no man like he doth grieve my heart.
That is because the traitor murderer lives.
Ay madam, from the reach of these my hands.M
Would none but I might venge my cousin
We will have vengeance for it, fear thou not.
Then weep no more. I
ll send to one in Mantua,
Where that same banish
d runagate doth live,
Shall give him such an unaccustom
That he shall soon keep Tybalt company:
And then I hope thou wilt be satisfied.
Indeed I never shall be satisfied
With Romeo till I behold him
Is my poor heart so for a kinsman vex
Madam, if you could find out but a man
 poison, I would temper it,
That Romeo should upon receipt thereof,
Soon sleep in quiet. O, how my heart abhors
d, and cannot come to him,
To wreak the love I bore my cousin
Upon his body that hath slaughter
Find thou the means, and I
ll tell thee joyful tidings, girl.
And joy comes well in such a needy time.
What are they, I beseech your ladyship?
Well, well, thou hast a careful father, child;
ho to put thee from thy heaviness,
Hath sorted out a sudden day of joy,
That thou expects not, nor I look
Madam, in happy time, what day is that?
Marry, my child, early next Thursday morn
The gallant, young, and noble gentleman,
The County Paris, at Saint Peter
Shall happily make thee there a joyful bride.
s Church, and Peter too,
He shall not make me there a joyful bride.
I wonder at this haste, that I must wed
hat should be husband comes to woo.
I pray you tell my lord and father, madam,
I will not marry yet; and when I do, I swear
It shall be Romeo, whom you know I hate,
Rather than Paris. These are news indeed.
Here comes your father, tell him so yourself,
And see how he will take it at your hands.
 Enter Capulet and Nurse.
When the sun sets, the air doth drizzle dew;
But for the sunset of my brother
How now? A conduit, girl? What, still in tears?
vermore showering? In one little body
Thou counterfeits a bark, a sea, a wind.
For still thy eyes, which I may call the sea,
Do ebb and flow with tears; the bark thy body is,
Sailing in this salt flood, the winds, thy sighs,
Who raging with thy tears and they with them,
Without a sudden calm will overset
Thy tempest-tossed body. How now, wife?
d to her our decree?
Ay, sir; but she will none, she gives you thanks.
I would the fool were married to her grave.
Soft. Take me with you, take me with you, wife.
How, will she none? Doth she not give us thanks?
Is she not proud? Doth she not count her blest,
Unworthy as she is, that we have wrought
So worthy a gentleman to be her bridegroom?
Not proud you have, but thankful that you have.
Proud can I never be of what I hate;
But thankful even for hate that is meant love.
How now, how now, chopp
d logic? What is this?
Proud, and, I thank you, and I thank you not;
And yet not proud. Mistress miM
Thank me no thankings, nor proud me no prouds,
But fettle your fine joints
gainst Thursday next
To go with Paris to Saint Peter
Or I will drag thee on a hurdle thither.
Out, you green-sickness carrion! Out, you baggage!
Fie, fie! What, are you mad?
Good father, I beseech you on my knees,
Hear me with patience but to speak a word.
Hang thee young baggage, disobedient wretch!
get thee to church a Thursday,M
Or never after look me in the face.
Speak not, reply not, do not answer me.
My fingers itch. Wife, we scarce thought us blest
That God had lent us but this only child;
But now I see this one is one too much,
And that we have a curse in having her.
Out on her, hilding.
God in heaven bless her.
You are to blame, my lord, to rate her so.
And why, my lady wisdom? Hold your tongue,
Good prudence; smatter with your gossips, go.
Peace, you mumbling fool!
Utter your gravity o
For here we need it not.
s bread, it makes me mad!
Day, night, hour, ride, time, work, play,
Alone, in company, still my care hath been
d, and having now provided
A gentleman of noble parentage,
Of fair demesnes, youthful, and nobly allied,
d, as they say, with honourable parts,
And then to have a wretched puling fool,
A whining mammet, in her fortune
ll not wed, I cannot love,
I am too young, I pray you pardon me.
But, and you will not wed, I
Graze where you will, you shall not house with me.
t, I do not use to jest.
Thursday is near; lay hand on heart, advise.
ll give you to my friend;
And you be not, hang, beg, starve, die in the streets,
er acknowledge thee,
Nor what is mine shall never do thee good.
Is there no pity sitting in the clouds,
That sees into the bottom of my grief?
O sweet my mother, cast me not away,
Delay this marriage for a month, a week,
Or, if you do not, make the bridal bed
In that dim monument where Tybalt lies.
Talk not to me, for I
ll not speak a word.
Do as thou wilt, for I have done with thee.
O God! O Nurse, how shall this be prevented?
My husband is on earth, my faith in heaven.
How shall that faith return again to earth,
Unless that husband send it me from heaven
By leaving earth? Comfort me, counsel me.
Alack, alack, that heaven should practise stratagems
Upon so soft a subject as myself.
st thou? Hast thou not a word of joy?
Some comfort, Nurse.
Romeo is banished; and all the world to nothing
er come back to challenge you.
 he do, it needs must be by stealth.
Then, since the case so stands as now it doth,
I think it best you married with the County.
s a lovely gentleman.
s a dishclout to him. An eagle, madam,
Hath not so green, so quick, so fair an eye
As Paris hath. Beshrew my very heart,
I think you are happy in this second match,
For it excels your first: or if it did not,
Your first is dead, or
twere as good he were,
As living here and you no use of him.
Speakest thou from thy heart?
And from my soul too,
Or else beshrew them both.
Well, thou hast comforted me marvellous much.
Go in, and tell my lady I am gone,
d my father, to Lawrence
To make confession and to be absolv
Marry, I will; and this is wisely done.
Ancient damnation! O most wicked fiend!
Is it more sin to wish me thus forsworn,
Or to dispraise my lord with that same tongue
Which she hath prais
So many thousand times? Go, counsellor.
Thou and my bosom henceforth shall be twain.
ll to the Friar to know his remedy.
If all else fail, myself have power to die.
SCENE I. Friar Lawrence
 Enter Friar Lawrence and Paris.
On Thursday, sir? The time is very short.
My father Capulet will have it so;
And I am nothing slow to slack his haste.
You say you do not know the lady
urse; I like it not.
Immoderately she weeps for Tybalt
And therefore have I little talk
For Venus smiles not in a house of tears.
Now, sir, her father counts it dangerous
That she do give her sorrow so much sway;
And in his wisdom, hastes our marriage,
To stop the inundation of her tears,
Which, too much minded by herself alone,
May be put from her by society.
Now do you know the reason of this haste.
[_Aside._] I would I knew not why it should be slowM
Look, sir, here comes the lady toward my cell.
Happily met, my lady and my wife!
That may be, sir, when I may be a wife.
That may be, must be, love, on Thursday next.
What must be shall be.
Come you to make confession to this father?
To answer that, I should confess to you.
Do not deny to him that you love me.
I will confess to you that I love him.
So will ye, I am sure, that you love me.
If I do so, it will be of more price,
Being spoke behind your back than to your face.
Poor soul, thy face is much abus
The tears have got small victory by that;
For it was bad enough before their spite.
st it more than tears with that report.
That is no slander, sir, which is a truth,
And what I spake, I spake it to my face.
Thy face is mine, and thou hast slander
It may be so, for it is not mine own.
Are you at leisure, holy father, now,
Or shall I come to you at evening mass?
My leisure serves me, pensive daughter, now.
My lord, we must entreat the time alone.
God shield I should disturb devotion!
Juliet, on Thursday early will I rouse ye,
Till then, adieu; and keep this holy kiss.
O shut the door, and when thou hast done so,
Come weep with me, past hope, past cure, past help!
O Juliet, I already know thy grief;
It strains me past the compass of my wits.
I hear thou must, and nothing may prorogue it,
On Thursday next be married to this County.
Tell me not, Friar, that thou hear
Unless thou tell me how I may prevent it.
If in thy wisdom, thou canst give no help,
Do thou but call my resolution wise,
And with this knife I
ll help it presently.
d my heart and Romeo
And ere this hand, by thee to Romeo
Shall be the label to another deed,
Or my true heart with treacherous revolt
Turn to another, this shall slay them both.
Therefore, out of thy long-experienc
Give me some present counsel, or behold
Twixt my extremes and me this bloody knife
Shall play the empire, arbitrating that
Which the commission of thy years and art
Could to no issue of true honour bring.
Be not so long to speak. I long to die,
st speak not of remedy.
Hold, daughter. I do spy a kiM
Which craves as desperate an execution
As that is desperate which we would prevent.
If, rather than to marry County Paris
Thou hast the strength of will to slay thyself,
Then is it likely thou wilt undertake
A thing like death to chide away this shame,
st with death himself to scape from it.
ll give thee remedy.
O, bid me leap, rather than marry Paris,
From off the battlements of yonder tower,
Or walk in thievish ways, or bid me lurk
ents are. Chain me with roaring bears;
Or hide me nightly in a charnel-house,
d quite with dead men
With reeky shanks and yellow chapless skulls.
Or bid me go into a new-made grave,
And hide me with a dead man in his shroud;
Things that, to hear them told, have made me tremble,
And I will do it without fear or doubt,
d wife to my sweet love.
Hold then. Go home, be merry, give consent
To marry Paris. Wednesday is tomorrow;
 night look that thou lie alone,
Let not thy Nurse lie with thee in thy chamber.
Take thou this vial, being then in bed,
And this distilled liquor drink thou off,
When presently through all thy veins shall run
A cold and drowsy humour; for no pulse
Shall keep his native progress, but surcease.
No warmth, no breath shall testify thou livest,
The roses in thy lips and cheeks shall fade
To paly ashes; thy eyes
Like death when he shuts up the day of life.
Shall stiff and stark and cold appear like death.
d likeness of shrunk death
Thou shalt continue two and forty hours,
And then awake as from a pleasant sleep.
Now when the bridegroom in the morning comes
To rouse thee from thy bed, there art thou dead.
Then as the manner of our country is,
In thy best robes, uncover
Thou shalt be borne to that same ancient vault
Where all the kindred of the Capulets lie.
In the meantime, against thou shalt awake,
 by my letters know our drift,
And hither shall he come, and he and I
Will watch thy waking, and that very night
Shall Romeo bear thee hence to Mantua.
And this shall free thee from this present shame,
If no inconstant toy nor womanish fear
Abate thy valour in the acting it.
Give me, give me! O tell not me of fear!
Hold; get you gone, be strong and prosperous
ll send a friar with speed
To Mantua, with my letters to thy lord.
gth, and strength shall help afford.
Farewell, dear father.
SCENE II. Hall in Capulet
 Enter Capulet, Lady Capulet, Nurse and Servants.
So many guests invite as here are writ.
 [_Exit first Servant._]
Sirrah, go hire me twenty cunning cooks.
You shall have none ill, sir; for I
ll try if they can lick their
How canst thou try them so?
tis an ill cook that cannot lick his own fingers;
therefore he that cannot lick his fingers goes not with me.
 [_Exit second Servant._]
We shall be much unfurnish
What, is my daughter gone to Friar Lawrence?
Well, he may chance to do some good on her.
See where she comes from shrift with merry look.
How now, my headstrong. Where have you been gadding?
Where I have learnt me to repentM
Of disobedient opposition
To you and your behests; and am enjoin
By holy Lawrence to fall prostrate here,
To beg your pardon. Pardon, I beseech you.
Henceforward I am ever rul
Send for the County, go tell him of this.
ll have this knot knit up tomorrow morning.
I met the youthful lord at Lawrence
And gave him what becomed love I might,
er the bounds of modesty.
t. This is well. Stand up.
t should be. Let me see the County.
Ay, marry. Go, I say, and fetch him hither.
Now afore God, this reverend holy Friar,
All our whole city is much bound to him.
Nurse, will you go with me into my closet,
To help me sort such needful ornaments
As you think fit to furnish me tomorrow?
No, not till Thursday. There is time enough.
Go, Nurse, go with her. We
ll to church tomorrow.
 [_Exeunt Juliet and Nurse._]
We shall be short in our provisioM
Tush, I will stir about,
And all things shall be well, I warrant thee, wife.
Go thou to Juliet, help to deck up her.
ll not to bed tonight, let me alone.
ll play the housewife for this once.
They are all forth: well, I will walk myself
To County Paris, to prepare him up
Against tomorrow. My heart is wondrous light
Since this same wayward girl is so reclaim
 Enter Juliet and Nurse.
Ay, those attires are best. But, gentle Nurse,
I pray thee leave me to myself tonight;
For I have need of many orisons
To move the heavens to smile upon my state,
Which, well thou know
st, is cross and full of sin.
 Enter Lady Capulet.
What, are you busy, ho? Need you my help?
No, madam; we have cull
As are behoveful for our state tomorrow.
So please you, let me now be left alone,
And let the nurse this night sit up with you,
For I am sure you havM
e your hands full all
In this so sudden business.
Get thee to bed and rest, for thou hast need.
 [_Exeunt Lady Capulet and Nurse._]
Farewell. God knows when we shall meet again.
I have a faint cold fear thrills through my veins
That almost freezes up the heat of life.
ll call them back again to comfort me.
What should she do here?
My dismal scene I needs must act alone.
What if this mixture do not work at all?
Shall I be married then toM
No, No! This shall forbid it. Lie thou there.
 [_Laying down her dagger._]
What if it be a poison, which the Friar
Subtly hath minister
Lest in this marriage he should be dishonour
Because he married me before to Romeo?
I fear it is. And yet methinks it should not,
For he hath still been tried a holy man.
How if, when I am laid into the tomb,
I wake before the time that Romeo
Come to redeem me? There
Shall I not then be stifled in the vaM
To whose foul mouth no healthsome air breathes in,
And there die strangled ere my Romeo comes?
Or, if I live, is it not very like,
The horrible conceit of death and night,
Together with the terror of the place,
As in a vault, an ancient receptacle,
Where for this many hundred years the bones
Of all my buried ancestors are pack
Where bloody Tybalt, yet but green in earth,
Lies festering in his shroud; where, as they say,
At some hours in the night spirits resort
Alack, alack, is it not like M
So early waking, what with loathsome smells,
And shrieks like mandrakes torn out of the earth,
That living mortals, hearing them, run mad.
O, if I wake, shall I not be distraught,
Environed with all these hideous fears,
And madly play with my forefathers
And pluck the mangled Tybalt from his shroud?
And, in this rage, with some great kinsman
As with a club, dash out my desperate brains?
O look, methinks I see my cousin
Seeking out Romeo that did spit his body
s point. Stay, Tybalt, stay!
Romeo, Romeo, Romeo, here
s drink! I drink to thee.
 [_Throws herself on the bed._]
SCENE IV. Hall in Capulet
 Enter Lady Capulet and Nurse.
Hold, take these keys and fetch more spices, Nurse.
They call for dates and quinces in the pastry.
Come, stir, stir, stir! The second cock hath crow
The curfew bell hath rung,
d meats, good Angelica;
Go, you cot-quean, go,
Get you to bed; faith, you
No, not a whit. What! I have watch
All night for lesser cause, and ne
Ay, you have been a mouse-hunt in your time;
But I will watch you from such watching now.
 [_Exeunt Lady Capulet and Nurse._]
A jealous-hood, a jealous-hood!
 Enter Servants, with spits, logs and baskets.
Things for the cook, sir; but I know not what.
Make haste, make haste.
 [_Exit First Servant._]
Sirrah, fetch drier logs.
Call Peter, he will show thee where they are.
I have a head, sir, that will find out logs
And never trouble Peter for the matter.
Mass and well said; a merry whoreson, ha.
Thou shalt be loggerhead.
The County will be here with music straight,
For so he said he would. I hear him nearM
Nurse! Wife! What, ho! What, Nurse, I say!
Go waken Juliet, go and trim her up.
ll go and chat with Paris. Hie, make haste,
Make haste; the bridegroom he is come already.
s Chamber; Juliet on the bed.
Mistress! What, mistress! Juliet! Fast, I warrant her, she.
Why, lamb, why, lady, fie, you slug-abed!
Why, love, I say! Madam! Sweetheart! Why, bride!
What, not a word? You take M
your pennyworths now.
Sleep for a week; for the next night, I warrant,
The County Paris hath set up his rest
That you shall rest but little. God forgive me!
Marry and amen. How sound is she asleep!
I needs must wake her. Madam, madam, madam!
Ay, let the County take you in your bed,
faith. Will it not be?
d, and in your clothes, and down again?
I must needs wake you. Lady! Lady! Lady!
Alas, alas! Help, help! My lady
O, well-a-day that ever I was born.
me aqua vitae, ho! My lord! My lady!
 Enter Lady Capulet.
Look, look! O heavy day!
O me, O me! My child, my only life.
Revive, look up, or I will die with thee.
Help, help! Call help.
For shame, bring Juliet forth, her lord is come.
s dead; alack the day!
Ha! Let me see her. Out alas! She
Her blood is settled and her joints are stiff.
Life and these lips have long been separated.
Death lies on her like an untimely frost
Upon the sweetest flower of all the field.
en her hence to make me wail,
Ties up my tongue and will not let me speak.
 Enter Friar Lawrence and Paris with Musicians.
ride ready to go to church?
Ready to go, but never to return.
O son, the night before thy wedding day
Hath death lain with thy bride. There she lies,
Flower as she was, deflowered by him.
Death is my son-in-law, death is my heir;
My daughter he hath wedded. I will die.
And leave him all; life, living, all is death
Have I thought long to see this morning
And doth it give me such a sight as this?
d, unhappy, wretched, hateful day.
In lasting labour of his pilgrimage.
But one, poor one, one poor and loving child,
But one thing to rejoice and solace in,
And cruel death hath catch
O woe! O woeful, woeful, woeful day.
Most lamentable day, most woeful day
That ever, ever, I did yet behold!
O day, O day, O day, O hateful day.
Never was seen so black a day as this.
O woeful day, O woeful day.
d, divorced, wronged, spited, slain.
Most detestable death, by theeM
By cruel, cruel thee quite overthrown.
O love! O life! Not life, but love in death!
d, distressed, hated, martyr
Uncomfortable time, why cam
To murder, murder our solemnity?
O child! O child! My soul, and not my child,
Dead art thou. Alack, my child is dead,
And with my child my joys are buried.
Peace, ho, for shame. Confusion
In these confusions. Heaven and yourself
Had part in this fair maid, now heavenM
And all the better is it for the maid.
Your part in her you could not keep from death,
But heaven keeps his part in eternal life.
The most you sought was her promotion,
twas your heaven she should be advanc
And weep ye now, seeing she is advanc
Above the clouds, as high as heaven itself?
O, in this love, you love your child so ill
That you run mad, seeing that she is well.
s not well married that lives married long,
s best married that dies married young.
p your tears, and stick your rosemary
On this fair corse, and, as the custom is,
And in her best array bear her to church;
For though fond nature bids us all lament,
All things that we ordained festival
Turn from their office to black funeral:
Our instruments to melancholy bells,
Our wedding cheer to a sad burial feast;
Our solemn hymns to sullen dirges change;
Our bridal flowers serve for a buried corse,
And all things change them to the contrarM
Sir, go you in, and, madam, go with him,
And go, Sir Paris, everyone prepare
To follow this fair corse unto her grave.
The heavens do lower upon you for some ill;
Move them no more by crossing their high will.
 [_Exeunt Capulet, Lady Capulet, Paris and Friar._]
Faith, we may put up our pipes and be gone.
Honest good fellows, ah, put up, put up,
For well you know this is a pitiful case.
Ay, by my troth, the case may be amended.
Musicians, O, musicians,
will have me live, play
O musicians, because my heart itself plays
me some merry dump to comfort me.
tis no time to play now.
I will then give it you soundly.
No money, on my faith, but the gleek! I will give you the minstrel.
Then will I give you the serving-creature.
Then will I lay the serving-creature
s dagger on your pate. I will
carry no crotchets. I
ll fa you. Do you note me?
And you re us and fa us, you note us.
Pray you put up your dagger, and put out your wit.
Then have at you with my wit. I will dry-beat you with an iron wit, and
put up my iron dagger. Answer me like men.
When griping griefs the heart doth wound,
      And doleful dumps the mind oppress,
    Then music with her silver sound
music with her silver sound
Marry, sir, because silver hath a sweet sound.
Prates. What say you, Hugh Rebeck?
 because musicians sound for silver.
Prates too! What say you, James SoundpoM
Faith, I know not what to say.
O, I cry you mercy, you are the singer. I will say for you. It is
music with her silver sound
 because musicians have no gold for
Then music with her silver sound
      With speedy help doth lend redress.
What a pestilent knave is this same!
Hang him, Jack. Come, we
ll in here, tarry for the mourners, and stay
If I may trust the flattering eye of sleep,
My dreams presage some joyful news at hand.
s lord sits lightly in his throne;
And all this day an unaccustom
Lifts me above the ground with cheerful thoughts.
I dreamt my lady came and found me dead,
Strange dream, that gives a dead man leave to think!
d such life with kisses in my lips,
d, and was an emperor.
Ah me, how sweet is love itself possess
s shadows are so rich in joy.
News from Verona! How now, Balthasar?
Dost thou not bring me letters from the Friar?
How doth my lady? Is my father well?
How fares my Juliet? That I ask again;
For nothing can be ill if she be well.
Then she is well, and nothing can be ill.
Her body sleeps in Capel
And her immortal part with angels lives.
I saw her laid low in her kindred
And presently took post to tell it you.
O pardon me for bringing thesM
Since you did leave it for my office, sir.
Is it even so? Then I defy you, stars!
st my lodging. Get me ink and paper,
And hire post-horses. I will hence tonight.
I do beseech you sir, have patience.
Your looks are pale and wild, and do import
Tush, thou art deceiv
Leave me, and do the thing I bid thee do.
Hast thou no letters to me from the Friar?
No matter. Get thee gone,
ll be with thee straight.
 [_Exit Balthasar._]
Well, Juliet, I will lie with thee tonight.
s see for means. O mischief thou art swift
To enter in the thoughts of desperate men.
I do remember an apothecary,
And hereabouts he dwells,
d weeds, with overwhelming brows,
Culling of simples, meagre were his looks,
Sharp misery had worn him to the bones;
And in his needy shop a tortoise hung,
 fishes; and about his shelves
A beggarly account of empty boxes,
Green earthen pots, bladders, and musty seeds,
Remnants of packthread, and old cakes of roses
d, to make up a show.
Noting this penury, to myself I said,
And if a man did need a poison now,
Whose sale is present death in Mantua,
Here lives a caitiff wretch would sell it him.
O, this same thought did but forerun my need,
And this same needy man must sell it me.
As I remember, this should be the house.
What, ho! Apothecary!
Come hither, man. I see that thou art poor.
Hold, there is forty ducats. Let me have
A dram of poison, such soon-speeding gear
As will disperse itself through all the veins,
That the life-weary taker may fall dead,
And that the trunk may be discharg
As violently as hasty powder fir
Doth hurry from the fatal cannon
Such mortal drugs I have, but MantM
Is death to any he that utters them.
Art thou so bare and full of wretchedness,
st to die? Famine is in thy cheeks,
Need and oppression starveth in thine eyes,
Contempt and beggary hangs upon thy back.
The world is not thy friend, nor the world
The world affords no law to make thee rich;
Then be not poor, but break it and take this.
My poverty, but not my will consents.
I pay thy poverty, and not thy will.
And drink it off; and, if you had the strength
Of twenty men, it would despatch you straight.
There is thy gold, worse poison to men
Doing more murder in this loathsome world
Than these poor compounds that thou mayst not sell.
I sell thee poison, thou hast sold me none.
Farewell, buy food, and get thyself in flesh.
Come, cordial and not poison, go with me
s grave, for there must I use thee.
SCENE II. Friar Lawrence
Holy Franciscan Friar! Brother, ho!
 Enter Friar Lawrence.
This same should be the voice of Friar John.
Welcome from Mantua. What says Romeo?
Or, if his mind be writ, give me his letter.
Going to find a barefoot brother out,
One of our order, to associate me,
Here in this city visiting the sick,
And finding him, the searchers of the town,
Suspecting that we both were in a house
Where the infectious pestilence did reign,
, and would not let us forth,
So that my speed to Mantua there was stay
Who bare my letter then to Romeo?
I could not send it,
Nor get a messenger to bring it thee,
So fearful were they of infection.
Unhappy fortune! By my brotherhood,
The letter was not nice, but full of charge,
Of dear import, and the neglecting it
May do much danger. Friar John, go hence,
Get me an iron crow and bring it straight
ll go and bring it thee.
Now must I to the monument alone.
Within this three hours will fair Juliet wake.
She will beshrew me much that Romeo
Hath had no notice of these accidents;
But I will write again to Mantua,
And keep her at my cell till Romeo come.
Poor living corse, clos
SCENE III. A churchyard; in it a Monument belonging to the Capulets.
 Enter Paris, and his Page bearing flowers and a torch.
Give me thy torch, boy. Hence and stand aloof.
Yet put it out, for I would not be seen.
Under yond yew tree lay thee all along,
Holding thy ear close to the hollow ground;
So shall no foot upon the churchyard tread,
Being loose, unfirm, with digging up of graves,
But thou shalt hear it. Whistle then to me,
As signal that thou hear
st something approach.
Give me those flowers. Do as I bid thee, go.
[_Aside._] I am almost afraid to stand alone
Here in the churchyard; yet I will adventure.
Sweet flower, with flowers thy bridal bed I strew.
O woe, thy canopy is dust and stones,
Which with sweet water nightly I will dew,
Or wanting that, with tears distill
The obsequies that I for thee will keep,
Nightly shall be to strew thy grave and weep.
 [_The Page whistles._]
The boy gives warning something doth approach.
What cursed foot wanders this way tonight,
To cross my obsequies and true love
What, with a torch! Muffle me, night, awhile.
 Enter Romeo and Balthasar with a torch, mattock, &c.
Give me that mattock and the wrenching iron.
Hold, take this letter; early in the morning
See thou deliver it to my lord and father.
Give me the light; upon thy life I charge thee,
st or seest, stand all aloof
And do not interrupt me in my course.
Why I descend into this bed of death
Is partly to behold my lady
But chiefly to take thence from her dead finger
A precious ring, a ring that I must use
In dear employment. Therefore hence, be gone.
But if thou jealous dost return to pry
In what I further shall intend to do,
By heaven I will tear thee joint by joint,
And strew this hungry churchyard with thy limbs.
The time and my intents are savage-wild;
More fierce and more inexorable far
Than empty tigers or the roaring sea.
I will be gone, sir, and not trouble you.
So shalt thou show me friendship. Take thou that.
Live, and be prosperous, and farewell, good fellow.
For all this same, I
ll hide me hereabout.
His looks I fear, and his intents I doubt.
Thou detestable maw, thou womb of death,
d with the dearest morsel of the earth,
Thus I enforce thy rotten jaws to open,
 [_Breaking open the door of the monument._]
ll cram thee with more food.
It is supposed, the fair creature died,
 to do some villanous shame
To the dead bodies. I will apprehend him.
d toil, vile Montague.
Can vengeance be pursu
d further than death?
Condemned villain, I do apprehend thee.
Obey, and go with me, for thou must die.
I must indeed; and therefore came I hither.
Good gentle youth, tempt not a desperate man.
Fly hence and leave me. Think upon these gone;
Let them affright thee. I beseech thee, youth,
Put not another sin upon my head
By urging me to fury.M
By heaven I love thee better than myself;
For I come hither arm
Stay not, be gone, live, and hereafter say,
s mercy bid thee run away.
I do defy thy conjuration,
And apprehend thee for a felon here.
Wilt thou provoke me? Then have at thee, boy!
O lord, they fight! I will go call the watch.
O, I am slain! [_Falls._] If thou be merciful,
Open the tomb, lay me with Juliet.
In faith, I will. Let me peruse this face.
s kinsman, noble County Paris!
What said my man, when my betossed soul
Did not attend him as we rode? I think
He told me Paris should have married Juliet.
Said he not so? Or did I dream it so?
Or am I mad, hearing him talk of Juliet,
To think it was so? O, give me thy hand,
One writ with me in sour misfortune
ll bury thee in a triumphant grave.
A grave? O no, a lantern, slaught
For here lies Juliet, and her beauty makes
This vault a feasting presence full of light.
Death, lie thou there, by a dead man interr
 [_Laying Paris in the monument._]
How oft when men are at the point of death
Have they been merry! Which their keepers call
A lightning before death. O, how may I
Call this a lightning? O my love, my wife,
Death that hath suck
d the honey of thy breath,
Hath had no power yet upon thy beauty.
Thou art not conquer
Is crimson in thy lips and in thy cheeks,
 is not advanced there.
Tybalt, liest thou there in thy bloody sheet?
O, what more favour can I do to thee
Than with that hand that cut thy youth in twain
To sunder his that was thine enemy?
Forgive me, cousin. Ah, dear Juliet,
Why art thou yet so fair? Shall I believe
That unsubstantial death is amorous;
And that the lean abhorred monster keeps
Thee here in dark to be his paramour?
For fear of that I still will stay with thee,
And never from this palace of dim night
Depart again. Here, here will I remaM
With worms that are thy chambermaids. O, here
Will I set up my everlasting rest;
And shake the yoke of inauspicious stars
From this world-wearied flesh. Eyes, look your last.
Arms, take your last embrace! And, lips, O you
The doors of breath, seal with a righteous kiss
A dateless bargain to engrossing death.
Come, bitter conduct, come, unsavoury guide.
Thou desperate pilot, now at once run on
The dashing rocks thy sea-sick weary bark.
s to my love! [_Drinks._] O true apothecary!
quick. Thus with a kiss I die.
 Enter, at the other end of the Churchyard, Friar Lawrence, with a
 lantern, crow, and spade.
Saint Francis be my speed. How oft tonight
Have my old feet stumbled at graves? Who
Who is it that consorts, so late, the dead?
s one, a friend, and one that knows you well.
Bliss be upon you. Tell me, good my friend,
What torch is yond that vainly lends his light
To grubs and eyeless skulls? As I dM
It burneth in the Capels
It doth so, holy sir, and there
How long hath he been there?
Go with me to the vault.
My master knows not but I am gone hence,
And fearfully did menace me with death
If I did stay to look on his intents.
ll go alone. Fear comeM
O, much I fear some ill unlucky thing.
As I did sleep under this yew tree here,
I dreamt my master and another fought,
And that my master slew him.
Romeo! [_Advances._]
Alack, alack, what blood is this which stains
The stony entrance of this sepulchre?
What mean these masterless and gory swords
d by this place of peace?
 [_Enters the monument._]
Romeo! O, pale! Who else? What, Paris too?
d in blood? Ah what an unkind hour
 guilty of this lamentable chance?
 [_Juliet wakes and stirs._]
O comfortable Friar, where is my lord?
I do remember well where I should be,
And there I am. Where is my Romeo?
I hear some noise. Lady, come from that nest
Of death, contagion, and unnatural sleep.
A greater power than we can contradict
Hath thwarted our intents. Come, come away.
Thy husband in thy bosom there lies dead;
And Paris too. Come, I
a sisterhood of holy nuns.
Stay not to question, for the watch is coming.
Come, go, good Juliet. I dare no longer stay.
Go, get thee hence, for I will not away.
 [_Exit Friar Lawrence._]
Poison, I see, hath been his timeless end.
O churl. Drink all, and left no friendly drop
To help me after? I will kiss thy lips.
Haply some poison yet doth hang on them,
To make me die with a restorative.
[_Within._] Lead, boy. Which way?
ll be brief. O happy dagger.
This is thy sheath. [_stabs herself_] There rest, and let me die.
 Enter Watch with the Page of Paris.
This is the place. There, where the torch doth burn.
The ground is bloody. Search about the churchyard.
Go, some of you, whoe
 [_Exeunt some of the Watch._]
t! Here lies the County slain,
And Juliet bleeding, warm, and newly dead,
Who here hath lain this two days buried.
Go tell the Prince; run to the Capulets.
Raise up the Montagues, some others search.
 [_Exeunt others of the Watch._]
We see the ground whereon these woes do lie,
But the true ground of all these piteous woes
We cannot without circumstance descry.
 Re-enter some of the Watch with Balthasar.
s man. We found him in the churchyard.
m in safety till the Prince come hither.
 Re-enter others of the Watch with Friar Lawrence.
THIRD WATCH. Here is a Friar that trembles, sighs, and weeps.
We took this mattock and this spade from him
As he was coming from this churchyard side.
A great suspicion. Stay the Friar too.
 Enter the Prince and Attendants.
What misadventure is so early up,
That calls our person from our morning
 Enter Capulet, Lady Capulet and others.
What should it be that M
they so shriek abroad?
O the people in the street cry Romeo,
Some Juliet, and some Paris, and all run
With open outcry toward our monument.
What fear is this which startles in our ears?
Sovereign, here lies the County Paris slain,
And Romeo dead, and Juliet, dead before,
Search, seek, and know how this foul murder comes.
Here is a Friar, and slaughter
With instruments upon them fit to open
O heaven! O wife, look how our daughter bleeds!
This dagger hath mista
en, for lo, his house
Is empty on the back of Montague,
And it mis-sheathed in my daughter
O me! This sight of death is as a bell
That warns my old age to a sepulchre.
 Enter Montague and others.
Come, Montague, for thou art early up,
To see thy son and heir more early down.
Alas, my liege, my wife is dead tonight.
What further woe conspires against mine age?
Look, and thou shalt see.
O thou untaught! What manners is in this,
To press before thy father to a grave?
Seal up the mouth of outrage for a while,
Till we can clear these ambiguities,
And know their spring, their head, their true descent,
And then will I be general of your woes,
And lead you even to death. Meantime forbear,
And let mischance be slave to patience.
Bring forth the parties of suspicion.
I am the greatest, able to do least,
Yet most suspected, as the time and place
Doth make against me, of this direful murder.
And here I stand, both to impeach and purge
Myself condemned and myself excus
Then say at once what thou dost know in this.
I will be brief, for my short date of breath
Is not so long as is a tedious tale.
Romeo, there dead, was husband to that Juliet,
And she, there dead, that Romeo
I married them; and their M
s doomsday, whose untimely death
d the new-made bridegroom from this city;
For whom, and not for Tybalt, Juliet pin
You, to remove that siege of grief from her,
d, and would have married her perforce
To County Paris. Then comes she to me,
And with wild looks, bid me devise some means
To rid her from this second marriage,
Or in my cell there would she kill herself.
Then gave I her, so tutored by my art,
A sleeping potion, which so took effect
I intended, for it wrought on her
The form of death. Meantime I writ to Romeo
That he should hither come as this dire night
To help to take her from her borrow
Being the time the potion
s force should cease.
But he which bore my letter, Friar John,
d by accident; and yesternight
d my letter back. Then all alone
At the prefixed hour of her waking
Came I to take her from her kindred
Meaning to keep her closely at my cell
Till I conveniently could send to Romeo.
But when I came, some minute ere the time
Of her awaking, here untimely lay
The noble Paris and true Romeo dead.
She wakes; and I entreated her come forth
And bear this work of heaven with patience.
But then a noise did scare me from the tomb;
And she, too desperate, would not go with me,
But, as it seems, did violence on herself.
All this I know; and to the marriage
Her Nurse is privy. And if ought in this
Miscarried by my fault, let my old life
d, some hour before his time,
We still have known thee for a holy man.
s man? What can he say to this?
I brought my master news of Juliet
And then in post he came from Mantua
To this same place, to this same monument.
This letter he early bid me give his father,
d me with death, going in the vault,
If I departed not, and left him there.
Give me the letter, I will look on it.
 what made your master in this place?
He came with flowers to strew his lady
And bid me stand aloof, and so I did.
Anon comes one with light to ope the tomb,
And by and by my master drew on him,
And then I ran away to call the watch.
This letter doth make good the Friar
Their course of love, the tidings of her death.
And here he writes that he did buy a poison
pothecary, and therewithal
Came to this vault to die, and lie with Juliet.
nemies? Capulet, Montague,
See what a scourge is laid upon your hate,
That heaven finds means to kill your joys with love!
And I, for winking at your discords too,
Have lost a brace of kinsmen. All are punish
O brother Montague, give me thy hand.
s jointure, for no more
But I can give thee more,
For I will raise her statue in pure gold,
That whiles Verona by that name is known,
There shall no figure at such rate be set
As that of true andM
Poor sacrifices of our enmity.
A glooming peace this morning with it brings;
The sun for sorrow will not show his head.
Go hence, to have more talk of these sad things.
Some shall be pardon
d, and some punished,
For never was a story of more woe
Than this of Juliet and her Romeo.
*** END OF THE PROJECT GUTENBERG EBOOK ROMEO AND JULIET ***
Updated editions will replace the previous one--the oldM
Creating the works from print editions not protected by U.S. copyright
law means that no one owns a United States copyright in these works,
so the Foundation (and you!) can copy and distribute it in the
United States without permission and without paying copyright
royalties. Special rules, set forth in the General Terms of Use part
of this license, apply to copying and distributing Project
Gutenberg-tm electronic works to protect the PROJECT GUTENBERG-tm
concept and trademark. M
Project Gutenberg is a registered trademark,
and may not be used if you charge for an eBook, except by following
the terms of the trademark license, including paying royalties for use
of the Project Gutenberg trademark. If you do not charge anything for
copies of this eBook, complying with the trademark license is very
easy. You may use this eBook for nearly any purpose such as creation
of derivative works, reports, performances and research. Project
Gutenberg eBooks may be modified and printed and given awaM
do practically ANYTHING in the United States with eBooks not protected
by U.S. copyright law. Redistribution is subject to the trademark
license, especially commercial redistribution.
THE FULL PROJECT GUTENBERG LICENSE
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK
To protect the Project Gutenberg-tm mission of promoting the free
distribution of electronic works, by using or distributing this work
(or any other work associated in any way with the phrase "ProjecM
Gutenberg"), you agree to comply with all the terms of the Full
Project Gutenberg-tm License available with this file or online at
www.gutenberg.org/license.
Section 1. General Terms of Use and Redistributing Project
Gutenberg-tm electronic works
1.A. By reading or using any part of this Project Gutenberg-tm
electronic work, you indicate that you have read, understand, agree to
and accept all the terms of this license and intellectual property
(trademark/copyright) agreement. If you do not agree to aM
the terms of this agreement, you must cease using and return or
destroy all copies of Project Gutenberg-tm electronic works in your
possession. If you paid a fee for obtaining a copy of or access to a
Project Gutenberg-tm electronic work and you do not agree to be bound
by the terms of this agreement, you may obtain a refund from the
person or entity to whom you paid the fee as set forth in paragraph
1.B. "Project Gutenberg" is a registered trademark. It may only be
used on or associatM
ed in any way with an electronic work by people who
agree to be bound by the terms of this agreement. There are a few
things that you can do with most Project Gutenberg-tm electronic works
even without complying with the full terms of this agreement. See
paragraph 1.C below. There are a lot of things you can do with Project
Gutenberg-tm electronic works if you follow the terms of this
agreement and help preserve free future access to Project Gutenberg-tm
electronic works. See paragraph 1.E below.
 Project Gutenberg Literary Archive Foundation ("the
Foundation" or PGLAF), owns a compilation copyright in the collection
of Project Gutenberg-tm electronic works. Nearly all the individual
works in the collection are in the public domain in the United
States. If an individual work is unprotected by copyright law in the
United States and you are located in the United States, we do not
claim a right to prevent you from copying, distributing, performing,
displaying or creating derivative works based on the woM
all references to Project Gutenberg are removed. Of course, we hope
that you will support the Project Gutenberg-tm mission of promoting
free access to electronic works by freely sharing Project Gutenberg-tm
works in compliance with the terms of this agreement for keeping the
Project Gutenberg-tm name associated with the work. You can easily
comply with the terms of this agreement by keeping this work in the
same format with its attached full Project Gutenberg-tm License when
ut charge with others.
1.D. The copyright laws of the place where you are located also govern
what you can do with this work. Copyright laws in most countries are
in a constant state of change. If you are outside the United States,
check the laws of your country in addition to the terms of this
agreement before downloading, copying, displaying, performing,
distributing or creating derivative works based on this work or any
other Project Gutenberg-tm work. The Foundation makes no
representations concerningM
 the copyright status of any work in any
country other than the United States.
1.E. Unless you have removed all references to Project Gutenberg:
1.E.1. The following sentence, with active links to, or other
immediate access to, the full Project Gutenberg-tm License must appear
prominently whenever any copy of a Project Gutenberg-tm work (any work
on which the phrase "Project Gutenberg" appears, or with which the
phrase "Project Gutenberg" is associated) is accessed, displayed,
performed, viewed, copied M
  This eBook is for the use of anyone anywhere in the United States and
  most other parts of the world at no cost and with almost no
  restrictions whatsoever. You may copy it, give it away or re-use it
  under the terms of the Project Gutenberg License included with this
  eBook or online at www.gutenberg.org. If you are not located in the
  United States, you will have to check the laws of the country where
  you are located before using this eBook.
1.E.2. If an individual Project GutM
enberg-tm electronic work is
derived from texts not protected by U.S. copyright law (does not
contain a notice indicating that it is posted with permission of the
copyright holder), the work can be copied and distributed to anyone in
the United States without paying any fees or charges. If you are
redistributing or providing access to a work with the phrase "Project
Gutenberg" associated with or appearing on the work, you must comply
either with the requirements of paragraphs 1.E.1 through 1.E.7 or
ermission for the use of the work and the Project Gutenberg-tm
trademark as set forth in paragraphs 1.E.8 or 1.E.9.
1.E.3. If an individual Project Gutenberg-tm electronic work is posted
with the permission of the copyright holder, your use and distribution
must comply with both paragraphs 1.E.1 through 1.E.7 and any
additional terms imposed by the copyright holder. Additional terms
will be linked to the Project Gutenberg-tm License for all works
posted with the permission of the copyright holder found at M
beginning of this work.
1.E.4. Do not unlink or detach or remove the full Project Gutenberg-tm
License terms from this work, or any files containing a part of this
work or any other work associated with Project Gutenberg-tm.
1.E.5. Do not copy, display, perform, distribute or redistribute this
electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1 with
active links or immediate access to the full terms of the Project
1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form, including
any word processing or hypertext form. However, if you provide access
to or distribute copies of a Project Gutenberg-tm work in a format
other than "Plain Vanilla ASCII" or other format used in the official
version posted on the official Project Gutenberg-tm website
(www.gutenberg.org), you must, at no additional cost, fee or expense
to the user, provide a copyM
, a means of exporting a copy, or a means
of obtaining a copy upon request, of the work in its original "Plain
Vanilla ASCII" or other form. Any alternate format must include the
full Project Gutenberg-tm License as specified in paragraph 1.E.1.
1.E.7. Do not charge a fee for access to, viewing, displaying,
performing, copying or distributing any Project Gutenberg-tm works
unless you comply with paragraph 1.E.8 or 1.E.9.
1.E.8. You may charge a reasonable fee for copies of or providing
ributing Project Gutenberg-tm electronic works
* You pay a royalty fee of 20% of the gross profits you derive from
  the use of Project Gutenberg-tm works calculated using the method
  you already use to calculate your applicable taxes. The fee is owed
  to the owner of the Project Gutenberg-tm trademark, but he has
  agreed to donate royalties under this paragraph to the Project
  Gutenberg Literary Archive Foundation. Royalty payments must be paid
  within 60 days following each date on wM
hich you prepare (or are
  legally required to prepare) your periodic tax returns. Royalty
  payments should be clearly marked as such and sent to the Project
  Gutenberg Literary Archive Foundation at the address specified in
  Section 4, "Information about donations to the Project Gutenberg
  Literary Archive Foundation."
* You provide a full refund of any money paid by a user who notifies
  you in writing (or by e-mail) within 30 days of receipt that s/he
  does not agree to the terms of the full ProjeM
  License. You must require such a user to return or destroy all
  copies of the works possessed in a physical medium and discontinue
  all use of and all access to other copies of Project Gutenberg-tm
* You provide, in accordance with paragraph 1.F.3, a full refund of
  any money paid for a work or a replacement copy, if a defect in the
  electronic work is discovered and reported to you within 90 days of
  receipt of the work.
* You comply with all other terms of this agreemeM
  distribution of Project Gutenberg-tm works.
1.E.9. If you wish to charge a fee or distribute a Project
Gutenberg-tm electronic work or group of works on different terms than
are set forth in this agreement, you must obtain permission in writing
from the Project Gutenberg Literary Archive Foundation, the manager of
the Project Gutenberg-tm trademark. Contact the Foundation as set
forth in Section 3 below.
1.F.1. Project Gutenberg volunteers and employees expend considerable
to identify, do copyright research on, transcribe and proofread
works not protected by U.S. copyright law in creating the Project
Gutenberg-tm collection. Despite these efforts, Project Gutenberg-tm
electronic works, and the medium on which they may be stored, may
contain "Defects," such as, but not limited to, incomplete, inaccurate
or corrupt data, transcription errors, a copyright or other
intellectual property infringement, a defective or damaged disk or
other medium, a computer virus, or computer codes M
cannot be read by your equipment.
1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the "Right
of Replacement or Refund" described in paragraph 1.F.3, the Project
Gutenberg Literary Archive Foundation, the owner of the Project
Gutenberg-tm trademark, and any other party distributing a Project
Gutenberg-tm electronic work under this agreement, disclaim all
liability to you for damages, costs and expenses, including legal
fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRM
LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE
PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE THAT THE FOUNDATION, THE
TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE
LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR
INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH
1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a
defect in this electronic work within 90 days of receiving it, you can
receive a refund of M
the money (if any) you paid for it by sending a
written explanation to the person you received the work from. If you
received the work on a physical medium, you must return the medium
with your written explanation. The person or entity that provided you
with the defective work may elect to provide a replacement copy in
lieu of a refund. If you received the work electronically, the person
or entity providing it to you may choose to give you a second
opportunity to receive the work electronically in lieu of a M
the second copy is also defective, you may demand a refund in writing
without further opportunities to fix the problem.
1.F.4. Except for the limited right of replacement or refund set forth
in paragraph 1.F.3, this work is provided to you 'AS-IS', WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.
1.F.5. Some states do not allow disclaimers of certain implied
warranties or the exclusion or limitatioM
n of certain types of
damages. If any disclaimer or limitation set forth in this agreement
violates the law of the state applicable to this agreement, the
agreement shall be interpreted to make the maximum disclaimer or
limitation permitted by the applicable state law. The invalidity or
unenforceability of any provision of this agreement shall not void the
remaining provisions.
1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the
trademark owner, any agent or employee of the Foundation, M
providing copies of Project Gutenberg-tm electronic works in
accordance with this agreement, and any volunteers associated with the
production, promotion and distribution of Project Gutenberg-tm
electronic works, harmless from all liability, costs and expenses,
including legal fees, that arise directly or indirectly from any of
the following which you do or cause to occur: (a) distribution of this
or any Project Gutenberg-tm work, (b) alteration, modification, or
additions or deletions to any ProjectM
 Gutenberg-tm work, and (c) any
Section 2. Information about the Mission of Project Gutenberg-tm
Project Gutenberg-tm is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new computers. It
exists because of the efforts of hundreds of volunteers and donations
from people in all walks of life.
Volunteers and financial support to provide volunteers with the
assistance they need are cM
ritical to reaching Project Gutenberg-tm's
goals and ensuring that the Project Gutenberg-tm collection will
remain freely available for generations to come. In 2001, the Project
Gutenberg Literary Archive Foundation was created to provide a secure
and permanent future for Project Gutenberg-tm and future
generations. To learn more about the Project Gutenberg Literary
Archive Foundation and how your efforts and donations can help, see
Sections 3 and 4 and the Foundation information page at
Section 3. Information about the Project Gutenberg Literary
The Project Gutenberg Literary Archive Foundation is a non-profit
501(c)(3) educational corporation organized under the laws of the
state of Mississippi and granted tax exempt status by the Internal
Revenue Service. The Foundation's EIN or federal tax identification
number is 64-6221541. Contributions to the Project Gutenberg Literary
Archive Foundation are tax deductible to the full extent permitted by
U.S. federal laws and M
The Foundation's business office is located at 809 North 1500 West,
Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up
to date contact information can be found at the Foundation's website
and official page at www.gutenberg.org/contact
Section 4. Information about Donations to the Project Gutenberg
Literary Archive Foundation
Project Gutenberg-tm depends upon and cannot survive without
widespread public support and donations to carry out its mission of
he number of public domain and licensed works that can be
freely distributed in machine-readable form accessible by the widest
array of equipment including outdated equipment. Many small donations
($1 to $5,000) are particularly important to maintaining tax exempt
status with the IRS.
The Foundation is committed to complying with the laws regulating
charities and charitable donations in all 50 states of the United
States. Compliance requirements are not uniform and it takes a
considerable effort, much papM
erwork and many fees to meet and keep up
with these requirements. We do not solicit donations in locations
where we have not received written confirmation of compliance. To SEND
DONATIONS or determine the status of compliance for any particular
state visit www.gutenberg.org/donate
While we cannot and do not solicit contributions from states where we
have not met the solicitation requirements, we know of no prohibition
against accepting unsolicited donations from donors in such states who
International donations are gratefully accepted, but we cannot make
any statements concerning tax treatment of donations received from
outside the United States. U.S. laws alone swamp our small staff.
Please check the Project Gutenberg web pages for current donation
methods and addresses. Donations are accepted in a number of other
ways including checks, online payments and credit card donations. To
donate, please visit: www.gutenberg.org/donate
Section 5. General Information About PM
roject Gutenberg-tm electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg-tm concept of a library of electronic works that could be
freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg-tm eBooks with only a loose network of
Project Gutenberg-tm eBooks are often created from several printed
editions, all of which are confirmed as not protected by copyright in
the U.S. unless a copyright notice is included. Thus, we dM
necessarily keep eBooks in compliance with any particular paper
Most people start at our website which has the main PG search
facility: www.gutenberg.org
This website includes information about Project Gutenberg-tm,
including how to make donations to the Project Gutenberg Literary
Archive Foundation, how to help produce our new eBooks, and how to
subscribe to our email newsletter to hear about new eBooks.
c/Foundry USA Pool #dropgold/
FjDOUT:7BF1FAD6FDEBFA72D20CB6384B16D5166D4A07C93CED511D24B1CA5D69AD8AFE
FjD=:THOR.RUNE:thor1wx5av89rghsmgh2vh40aknx7csvs7xj2cr474n:774358562945C
6j4ion:1.QmVxDfFuMKLwtJmRpQYhHAdzk1zMFXiWygN9nRU1TSrbEH-t
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlM
ns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:02:50+03:00" xmp:ModifyDate="2023-02-03T00:02:50+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:f377a2a8-f9ad-a14c-a4d3-a446d7a02e3d" xmpMM:DocumentID="adobe:docid:photoshop:3a180004-e65b-a44c-81c5-2680754e9cf2" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5M
110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saveM
d" stEvt:instanceID="xmp.iid:7ea87814-4f22-8640-9d50-acee20e71059" stEvt:when="2023-02-03T00:02:50+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:f377a2a8-f9ad-a14c-a4d3-a446d7a02e3d" stEvt:when="2023-02-03T00:02:5M
0+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:7ea87814-4f22-8640-9d50-acee20e71059" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta> M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
CjA=:BNB.BNB:bnb13cmkeluypa7ap5qcssfs502pr7pdmswh7nzgkj:2780918:te:0
CjA=:BNB.BNB:bnb1g4yz96ggkzrg9x94m9j9wuydsrcrcrkc6d3yuz:1159043:te:0
CjA=:ETH.ETH:0xA58f588133FE1b40C0daC8d2eE95157309b46648:7343745:te:0
*<5?>;5:9CK`QCGZH9:SqTZcfklk@Pv~th}`ikg
1gE:Egggggggggggggggggggggggggggggggggggggggggggggggggg
IjGREFUND:4A7C3395F779196991F38BB8F1CFE686F1E7AF9B8F46305E54E81B9651DE5DF5
c/Foundry USA Pool #dropgold/
iTXtXML:com.adobe.xmp
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
            xmlns:GIMP="http://www.giM
            xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
            xmlns:dc="http://purl.org/dc/elements/1.1/"
            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <xmp:CreatorTool>GIMP 2.10.32</xmp:CreatorTool>
         <xmp:MetadataDate>2023:02:02T19:50:40-05:00</xmp:MetadataDate>
         <xmp:ModifyDate>2023-02-02T19:50:40</xmp:ModifyDate>
         <GIMP:Version>2.10.32</GIMP:Version>
         <GIMP:Platform>Mac OS</GIMP:Platform>
         <GIMP:TimeStamp>1675385444320041</GIMP:TimeStamp>
         <tiff:ResolutionUnit>3</tiff:ResolutionUnit>
         <tiff:Orientation>1</tiff:Orientation>
         <tiff:YResolution>300</tiff:YResolution>
         <tiff:XResolution>300</tiff:XResolution>
         <dc:description>
            <rdf:Alt>
               <rdf:li xml:lang="x-default">Created with GIMP</rdf:li>
            </rdf:Alt>
   </dc:description>
         <dc:Format>image/png</dc:Format>
         <xmpMM:History>
            <rdf:Seq>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:changed>/</stEvt:changed>
                  <stEvt:softwareAgent>Gimp 2.10 (Mac OS)</stEvt:softwareAgent>
                  <stEvt:when>2023-02-02T19:50:44-05:00</stEvt:when>
                  <stEvt:instanceID>xmp.iid:e5718189-0424-40bb-a9f8-36d2ce4eab4a</stEvt:instanceID>
                  <stEvt:action>saved</stEvt:action>
            </rdf:Seq>
         </xmpMM:History>
         <xmpMM:OriginalDocumentID>xmp.did:c94998d8-2630-434e-a45c-65a3a57fc3fc</xmpMM:OriginalDocumentID>
         <xmpMM:InstanceID>xmp.iid:a583b2cd-e010-4bc7-928d-6560c67ba966</xmpMM:InstanceID>
         <xmpMM:DocumentID>gimp:docid:gimp:395961ab-3b1a-477e-80f0-70509eef8325</xmpMM:DocumentID>
         <exif:ColorSpace>1</exif:ColorSpace>
         <exif:UserComment>
            <rdf:Alt>
               <rdf:li xml:lang="x-default">Created with GIMPM
            </rdf:Alt>
         </exif:UserComment>
      </rdf:Description>
c/Foundry USA Pool #dropgold/
FjD=:BNB.ETH-1C9:bnb1pwluj70zmyhq0qg0uvdsrv76ltrwal24ugvh73:412685:te:0
c/Foundry USA Pool #dropgold/
7j5+:BTC.BTC:thor1swcvf06tsytaalk7y6t3urnwyv435gu8fg6jgch
FjDOUT:C9ED7ADA559145FC5F4C39861E79F9585A30ABF72C580D8A3D6E914A16CDB2F8
FjDOUT:62F7C91C85EB60FFE75B1AFCF7C69FB52091A4D6BDB83973C007177D0A2A357A
HjF=:THOR.RUNE:thor1q29n2ysvgj9suf4p64g897n9vng9tn2efnhyzf:6157635489:xdf/
/ViaBTC/Mined by pryor2/,
FjDOUT:4104A5CF89CA1BA77B1AB968C41DBB3B7E8EA64B051AA964835BC853AB9DAB5B
FjDOUT:354067A70D7A1EA7072F3040C3C73FA2C8BFAECF04E0DFF9EDE04BDB67B20AA1
FjDOUT:53B081DFCA7ECBF9EA774239299FAD09FD21BEB940C67FA4623648513D4A09AB
FjDOUT:8AD3CD08A0E884009BFEDBDFD7C599C77634224038AAD886964CB8176809C2BE
FjDOUT:1A3FF9A2810A56756EB7BEB4AF50F865DD636958AFBCDDE185A458C993F725F6
FjDOUT:4AFE949A2E66C3EB553FC8B54BB23EE5085F597E4177D5BB15DCC7CEE95EBEFA
4j2DC-L5:jGUdxA0bP2RHjprVegNM9xqeu78+i+KAo1ovV6jhaAE=
Mined by AntPool958[
FjDOUT:3B38D8481DA133BF71DD262DF503BD35ECD16F727A93A0E9650DB793450AE7D7
EjC=:ETH.ETH:0x209053265e81db305151f9ec4f3b1ddb6cd6a109:140250063:t:30
6j4ion:4.Qmeo4b2Ghsrg3SWgyt3QNXCvMj33tH7KqSjRsmZyCkLGfoC]
Bj@=:BNB.BNB:bnb13s75wzln0wmtpt9eadtxuffmvm90ccnp5zyaxa:897385:te:0
DjB=:ETH.ETH:0x1ba368fDd7237C4cE77678e0d84991b7038012d0:11580272:te:0
KjI=:BNB.BUSD-BD1:bnb19he5gu4m27lndqsflvjfphh4xg3pd8a6n0qty0:4561915599:te:0
c/Foundry USA Pool #dropgold/
EjC=:ETH.ETH:0x209053265e81db305151f9ec4f3b1ddb6cd6a109:393677585:t:30
FjDOUT:BEE3A27337D74B8470E4116BD69BA846A3A6A9668DC3A90E1EB6E828C9DBEDF3
FjDOUT:1BB6F8347345DB0F986FE9FF01CD0BB286214612D13058B8DD1DD27EB8CF518A
CjA=:BNB.BNB:bnb1c667cxycg4cgjt7ae4c3cgj9agtmzdrnw3la90:5385690:te:0
 9cb54f84e4779cc375bedc55b7724d7aG0D
 f32fb6862e5394dd156f2fa3f93c811cH0E
Adobe Photoshop 21.0 (Windows)
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xapM
/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:51:15+03:00" xmp:ModifyDate="2023-02-02T23:51:15+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:07335f47-16eb-4941-aed9-4112db30de78" xmpMM:DocumentID="adobe:docid:photoshop:cc1e9353-ec23-f243-a7d2-190643df2ab3" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" pM
hotoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:a9faM
b889-07b2-2b4b-9a4c-87e079b6cffb" stEvt:when="2023-02-02T23:51:15+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:07335f47-16eb-4941-aed9-4112db30de78" stEvt:when="2023-02-02T23:51:15+03:00" stEvt:softwareAgent="AdoM
be Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:a9fab889-07b2-2b4b-9a4c-87e079b6cffb" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                       <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
text/html;charset=utf-8
<html><head><title>FREEDOM TO TRANSACT</title><script src="https://hv4gxzchk24cqfezebn3ujjz6oy2kbtztv5vghn6kpbkjc3vg4rq.arweave.net/LwoYxA0u8husyQUnezc7A5x4EU-rzYNfLnHtICXCBzc"></script><script src="data:text/javascript;base64,dmFyIGxvZ287CnZhciBiZzsKdmFyIHggPSAwOwp2YXIgeSA9IDA7CnZhciBzc3BlZWQgPSAzCnZhciB4ZGlyID0gMTsKdmFyIHlkaXIgPSAxOwp2YXIgZmxpcHNwZWVkID0gMC4wMQoKZnVuY3Rpb24gcHJlbG9hZCgpIHsKICBsb2dvID0gbG9hZEltYWdlKCJodHRwczovL3g0ZDVhNXlxNDRxd29mZDJlbzZoZHpwaG5qZG51bTU0NG1mNnJ5dmV0Y2htYndpcTR5d2EuYXJ3ZWF2ZS5uZXQvdM
ndmUWR4RG5JV2NVZWlPOGNlWG5ha2JhTTd6akMtamlwSmlPd05rUTVpdyIpOwogIGJnID0gbG9hZEltYWdlKCJodHRwczovL2Fyd2VhdmUubmV0L2xZVUZXLXZSVU5ZWkMwTWx3NDVfdXVhXzlLekNGNHZ3RTMtYVJVLTVTVkkiKTsKICBzcGVlZCA9IHJhbmRvbSgxLDUpOwogIGZsaXBzcGVlZCA9IGZsaXBzcGVlZCAqIHJhbmRvbSgyLDgpOwp9CgpmdW5jdGlvbiBzZXR1cCgpIHsKICBjcmVhdGVDYW52YXMoNjQ4LCA5NDksIFdFQkdMKTsKfQoKZnVuY3Rpb24gZHJhdygpIHsKICBiYWNrZ3JvdW5kKDIwMCk7CiAgaW1hZ2UoYmcsIC0zMjQsIC00NzQsIHdpZHRoLCBoZWlnaHQpOyAgCiAgbm9TdHJva2UoKTsKICAKICB4ID0geCArIHNzcGVlZCAqIHhkaXI7CiAgeSA9IHkgKyBzc3BlZWQgKMy
iB5ZGlyOwogIAogIGlmICh4ID4gMzI0IC0gMjQwIHx8IHggPCAtMzI0LSAxMjUpIHsKICAgIHhkaXIgPSAteGRpcjsKICB9CiAgaWYgKHkgPiA0NzQgLTQwIHx8IHkgPCAtNDc0KyAxMDApIHsKICAgIHlkaXIgPSAteWRpcjsKICB9CiAgCiAgcHVzaCgpOwogIHRyYW5zbGF0ZSh4LCB5LCA2NCk7CiAgcm90YXRlWChmcmFtZUNvdW50ICogZmxpcHNwZWVkKTsKICB0ZXh0dXJlKGxvZ28pOwogIGNpcmNsZSgyMDAsIDEsIDEyMCk7CiAgcG9wKCk7Cn0"></script></head><body></body></html>
TUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUa
AUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
FPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
TUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUa
AUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
FPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
-=-157:::#+?D?8C49:7
%77777777777777777777777777777777777777777777777777
EDDEULDDDDEDDDDDDDEDDDDDDDU
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww,x
FFnFFFFFnFFFFFFFFnFFB23r=70\Y
-=-157:::#+?D?8C49:7
%77777777777777777777777777777777777777777777777777
6t[6t[6t[6t[6t[6t[6t[6t[6t[6t[6t[6t[6t[6tQ
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:sM
tEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:54:06+03:00" xmp:ModifyDate="2023-02-02T23:54:06+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:9f3a26db-23bc-dd4b-a512-5cd8740720ca" xmpMM:DocumentID="adobe:docid:photoshop:2eee3dd7-b1fd-c642-bc56-456b9816b23e" xmpMMM
:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.M
0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:a4d6113d-3915-e74e-8722-c2cb14030300" stEvt:when="2023-02-02T23:54:06+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:9f3a26db-M
23bc-dd4b-a512-5cd8740720ca" stEvt:when="2023-02-02T23:54:06+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:a4d6113d-3915-e74e-8722-c2cb14030300" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocM
umentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                              M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                           <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:M
RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02TM
23:52:18+03:00" xmp:ModifyDate="2023-02-02T23:52:18+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:7cfe2aee-67e1-2f40-bff1-e1ea0deb3c39" xmpMM:DocumentID="adobe:docid:photoshop:5bbc60b8-85d3-9a44-85f0-23fb366c60d0" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00M
" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:8e57fc9d-b22e-574d-bc4b-b36fa9e58227" stEvt:when="2023-02-02T23:52:18+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="frM
om application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:7cfe2aee-67e1-2f40-bff1-e1ea0deb3c39" stEvt:when="2023-02-02T23:52:18+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:8e57fc9d-b22e-574d-bc4b-b36fa9e58227" stRef:documentID="adobe:docid:photoshopM
:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                         M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB cM
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
FjDOUT:8C972A17ED87893EA29AF95AD948315AE182F5A21A82E4ECCEBF39EF2627FA8C
CjA=:BNB.BNB:bnb1c667cxycg4cgjt7ae4c3cgj9agtmzdrnw3la90:4247275:te:0
CjA=:ETH.ETH:0xCBe879c445DDdE04A71a1b58892E26f3A27A43F7:5802230:te:0
<svg width='1024' height='1024' id='token-0' xmlns='http://www.w3.org/2000/svg'> <style>#token-0{shape-rendering: crispedges;} rect{width:32px;height:32px}.a{fill:#7739d1}.b{fill:#7ec292}.c{fill:#22133d}.d{fill:#e14d9c}.w{fill:#ffffff}</style><rect x='0' y='0' class='a'/><rect x='32' y='0' class='a'/><rect x='64' y='0' class='a'/><rect x='96' y='0' class='a'/><rect x='128' y='0' class='a'/><rect x='160' y='0' class='a'/><rect x='192' y='0' class='a'/><rect x='224' y='0' class='a'/><rect x='256' y='0' class='a'/><reM
ct x='288' y='0' class='a'/><rect x='320' y='0' class='a'/><rect x='352' y='0' class='b'/><rect x='384' y='0' class='b'/><rect x='416' y='0' class='b'/><rect x='448' y='0' class='b'/><rect x='480' y='0' class='b'/><rect x='512' y='0' class='b'/><rect x='544' y='0' class='b'/><rect x='576' y='0' class='b'/><rect x='608' y='0' class='b'/><rect x='640' y='0' class='b'/><rect x='672' y='0' class='b'/><rect x='704' y='0' class='b'/><rect x='736' y='0' class='b'/><rect x='768' y='0' class='b'/><rect x='800' y='0' class='M
b'/><rect x='832' y='0' class='b'/><rect x='864' y='0' class='b'/><rect x='896' y='0' class='b'/><rect x='928' y='0' class='b'/><rect x='960' y='0' class='b'/><rect x='992' y='0' class='b'/><rect x='0' y='32' class='a'/><rect x='32' y='32' class='a'/><rect x='64' y='32' class='a'/><rect x='96' y='32' class='a'/><rect x='128' y='32' class='a'/><rect x='160' y='32' class='a'/><rect x='192' y='32' class='a'/><rect x='224' y='32' class='a'/><rect x='256' y='32' class='a'/><rect x='288' y='32' class='a'/><rect x='320' yM
='32' class='a'/><rect x='352' y='32' class='a'/><rect x='384' y='32' class='a'/><rect x='416' y='32' class='a'/><rect x='448' y='32' class='a'/><rect x='480' y='32' class='a'/><rect x='512' y='32' class='a'/><rect x='544' y='32' class='a'/><rect x='576' y='32' class='a'/><rect x='608' y='32' class='a'/><rect x='640' y='32' class='a'/><rect x='672' y='32' class='w'/><rect x='704' y='32' class='a'/><rect x='736' y='32' class='b'/><rect x='768' y='32' class='b'/><rect x='800' y='32' class='b'/><rect x='832' y='32' clM
ass='b'/><rect x='864' y='32' class='b'/><rect x='896' y='32' class='b'/><rect x='928' y='32' class='b'/><rect x='960' y='32' class='b'/><rect x='992' y='32' class='b'/><rect x='0' y='64' class='b'/><rect x='32' y='64' class='b'/><rect x='64' y='64' class='b'/><rect x='96' y='64' class='b'/><rect x='128' y='64' class='b'/><rect x='160' y='64' class='b'/><rect x='192' y='64' class='b'/><rect x='224' y='64' class='b'/><rect x='256' y='64' class='a'/><rect x='288' y='64' class='a'/><rect x='320' y='64' class='a'/><recM
t x='352' y='64' class='a'/><rect x='384' y='64' class='a'/><rect x='416' y='64' class='c'/><rect x='448' y='64' class='c'/><rect x='480' y='64' class='c'/><rect x='512' y='64' class='c'/><rect x='544' y='64' class='c'/><rect x='576' y='64' class='c'/><rect x='608' y='64' class='c'/><rect x='640' y='64' class='c'/><rect x='672' y='64' class='a'/><rect x='704' y='64' class='a'/><rect x='736' y='64' class='a'/><rect x='768' y='64' class='a'/><rect x='800' y='64' class='a'/><rect x='832' y='64' class='a'/><rect x='864M
' y='64' class='a'/><rect x='896' y='64' class='a'/><rect x='928' y='64' class='a'/><rect x='960' y='64' class='a'/><rect x='992' y='64' class='a'/><rect x='0' y='96' class='b'/><rect x='32' y='96' class='b'/><rect x='64' y='96' class='b'/><rect x='96' y='96' class='b'/><rect x='128' y='96' class='b'/><rect x='160' y='96' class='b'/><rect x='192' y='96' class='b'/><rect x='224' y='96' class='b'/><rect x='256' y='96' class='b'/><rect x='288' y='96' class='b'/><rect x='320' y='96' class='b'/><rect x='352' y='96' clasM
s='c'/><rect x='384' y='96' class='c'/><rect x='416' y='96' class='c'/><rect x='448' y='96' class='c'/><rect x='480' y='96' class='c'/><rect x='512' y='96' class='c'/><rect x='544' y='96' class='c'/><rect x='576' y='96' class='c'/><rect x='608' y='96' class='w'/><rect x='640' y='96' class='c'/><rect x='672' y='96' class='c'/><rect x='704' y='96' class='c'/><rect x='736' y='96' class='a'/><rect x='768' y='96' class='a'/><rect x='800' y='96' class='a'/><rect x='832' y='96' class='a'/><rect x='864' y='96' class='a'/><M
rect x='896' y='96' class='a'/><rect x='928' y='96' class='a'/><rect x='960' y='96' class='a'/><rect x='992' y='96' class='a'/><rect x='0' y='128' class='a'/><rect x='32' y='128' class='w'/><rect x='64' y='128' class='a'/><rect x='96' y='128' class='a'/><rect x='128' y='128' class='b'/><rect x='160' y='128' class='b'/><rect x='192' y='128' class='b'/><rect x='224' y='128' class='b'/><rect x='256' y='128' class='b'/><rect x='288' y='128' class='b'/><rect x='320' y='128' class='c'/><rect x='352' y='128' class='c'/><rM
ect x='384' y='128' class='c'/><rect x='416' y='128' class='c'/><rect x='448' y='128' class='c'/><rect x='480' y='128' class='c'/><rect x='512' y='128' class='c'/><rect x='544' y='128' class='c'/><rect x='576' y='128' class='c'/><rect x='608' y='128' class='c'/><rect x='640' y='128' class='c'/><rect x='672' y='128' class='c'/><rect x='704' y='128' class='c'/><rect x='736' y='128' class='b'/><rect x='768' y='128' class='b'/><rect x='800' y='128' class='b'/><rect x='832' y='128' class='b'/><rect x='864' y='128' classM
='b'/><rect x='896' y='128' class='b'/><rect x='928' y='128' class='b'/><rect x='960' y='128' class='a'/><rect x='992' y='128' class='a'/><rect x='0' y='160' class='a'/><rect x='32' y='160' class='a'/><rect x='64' y='160' class='a'/><rect x='96' y='160' class='a'/><rect x='128' y='160' class='a'/><rect x='160' y='160' class='a'/><rect x='192' y='160' class='a'/><rect x='224' y='160' class='a'/><rect x='256' y='160' class='a'/><rect x='288' y='160' class='a'/><rect x='320' y='160' class='c'/><rect x='352' y='160' clM
ass='c'/><rect x='384' y='160' class='c'/><rect x='416' y='160' class='c'/><rect x='448' y='160' class='c'/><rect x='480' y='160' class='c'/><rect x='512' y='160' class='c'/><rect x='544' y='160' class='c'/><rect x='576' y='160' class='c'/><rect x='608' y='160' class='c'/><rect x='640' y='160' class='c'/><rect x='672' y='160' class='w'/><rect x='704' y='160' class='c'/><rect x='736' y='160' class='c'/><rect x='768' y='160' class='b'/><rect x='800' y='160' class='b'/><rect x='832' y='160' class='b'/><rect x='864' y=M
'160' class='b'/><rect x='896' y='160' class='b'/><rect x='928' y='160' class='b'/><rect x='960' y='160' class='b'/><rect x='992' y='160' class='b'/><rect x='0' y='192' class='a'/><rect x='32' y='192' class='a'/><rect x='64' y='192' class='a'/><rect x='96' y='192' class='a'/><rect x='128' y='192' class='a'/><rect x='160' y='192' class='a'/><rect x='192' y='192' class='a'/><rect x='224' y='192' class='a'/><rect x='256' y='192' class='a'/><rect x='288' y='192' class='c'/><rect x='320' y='192' class='c'/><rect x='352'M
 y='192' class='c'/><rect x='384' y='192' class='c'/><rect x='416' y='192' class='c'/><rect x='448' y='192' class='c'/><rect x='480' y='192' class='c'/><rect x='512' y='192' class='c'/><rect x='544' y='192' class='c'/><rect x='576' y='192' class='c'/><rect x='608' y='192' class='c'/><rect x='640' y='192' class='c'/><rect x='672' y='192' class='c'/><rect x='704' y='192' class='c'/><rect x='736' y='192' class='c'/><rect x='768' y='192' class='a'/><rect x='800' y='192' class='a'/><rect x='832' y='192' class='w'/><rectM
 x='864' y='192' class='b'/><rect x='896' y='192' class='b'/><rect x='928' y='192' class='b'/><rect x='960' y='192' class='b'/><rect x='992' y='192' class='b'/><rect x='0' y='224' class='b'/><rect x='32' y='224' class='b'/><rect x='64' y='224' class='b'/><rect x='96' y='224' class='b'/><rect x='128' y='224' class='b'/><rect x='160' y='224' class='b'/><rect x='192' y='224' class='b'/><rect x='224' y='224' class='b'/><rect x='256' y='224' class='b'/><rect x='288' y='224' class='c'/><rect x='320' y='224' class='c'/><rM
ect x='352' y='224' class='c'/><rect x='384' y='224' class='c'/><rect x='416' y='224' class='c'/><rect x='448' y='224' class='c'/><rect x='480' y='224' class='c'/><rect x='512' y='224' class='c'/><rect x='544' y='224' class='c'/><rect x='576' y='224' class='c'/><rect x='608' y='224' class='c'/><rect x='640' y='224' class='c'/><rect x='672' y='224' class='c'/><rect x='704' y='224' class='c'/><rect x='736' y='224' class='w'/><rect x='768' y='224' class='c'/><rect x='800' y='224' class='a'/><rect x='832' y='224' classM
='a'/><rect x='864' y='224' class='a'/><rect x='896' y='224' class='a'/><rect x='928' y='224' class='a'/><rect x='960' y='224' class='a'/><rect x='992' y='224' class='a'/><rect x='0' y='256' class='b'/><rect x='32' y='256' class='b'/><rect x='64' y='256' class='b'/><rect x='96' y='256' class='b'/><rect x='128' y='256' class='b'/><rect x='160' y='256' class='b'/><rect x='192' y='256' class='b'/><rect x='224' y='256' class='b'/><rect x='256' y='256' class='b'/><rect x='288' y='256' class='c'/><rect x='320' y='256' clM
ass='c'/><rect x='352' y='256' class='c'/><rect x='384' y='256' class='a'/><rect x='416' y='256' class='a'/><rect x='448' y='256' class='a'/><rect x='480' y='256' class='a'/><rect x='512' y='256' class='c'/><rect x='544' y='256' class='c'/><rect x='576' y='256' class='c'/><rect x='608' y='256' class='c'/><rect x='640' y='256' class='c'/><rect x='672' y='256' class='c'/><rect x='704' y='256' class='w'/><rect x='736' y='256' class='c'/><rect x='768' y='256' class='c'/><rect x='800' y='256' class='a'/><rect x='832' y=M
'256' class='a'/><rect x='864' y='256' class='a'/><rect x='896' y='256' class='a'/><rect x='928' y='256' class='a'/><rect x='960' y='256' class='a'/><rect x='992' y='256' class='a'/><rect x='0' y='288' class='a'/><rect x='32' y='288' class='a'/><rect x='64' y='288' class='a'/><rect x='96' y='288' class='a'/><rect x='128' y='288' class='a'/><rect x='160' y='288' class='a'/><rect x='192' y='288' class='a'/><rect x='224' y='288' class='a'/><rect x='256' y='288' class='b'/><rect x='288' y='288' class='c'/><rect x='320'M
 y='288' class='c'/><rect x='352' y='288' class='b'/><rect x='384' y='288' class='b'/><rect x='416' y='288' class='b'/><rect x='448' y='288' class='a'/><rect x='480' y='288' class='a'/><rect x='512' y='288' class='a'/><rect x='544' y='288' class='a'/><rect x='576' y='288' class='c'/><rect x='608' y='288' class='c'/><rect x='640' y='288' class='c'/><rect x='672' y='288' class='c'/><rect x='704' y='288' class='c'/><rect x='736' y='288' class='c'/><rect x='768' y='288' class='c'/><rect x='800' y='288' class='b'/><rectM
 x='832' y='288' class='b'/><rect x='864' y='288' class='b'/><rect x='896' y='288' class='b'/><rect x='928' y='288' class='b'/><rect x='960' y='288' class='b'/><rect x='992' y='288' class='b'/><rect x='0' y='320' class='a'/><rect x='32' y='320' class='a'/><rect x='64' y='320' class='a'/><rect x='96' y='320' class='w'/><rect x='128' y='320' class='a'/><rect x='160' y='320' class='a'/><rect x='192' y='320' class='a'/><rect x='224' y='320' class='a'/><rect x='256' y='320' class='a'/><rect x='288' y='320' class='c'/><rM
ect x='320' y='320' class='b'/><rect x='352' y='320' class='b'/><rect x='384' y='320' class='b'/><rect x='416' y='320' class='b'/><rect x='448' y='320' class='b'/><rect x='480' y='320' class='b'/><rect x='512' y='320' class='a'/><rect x='544' y='320' class='a'/><rect x='576' y='320' class='a'/><rect x='608' y='320' class='c'/><rect x='640' y='320' class='c'/><rect x='672' y='320' class='c'/><rect x='704' y='320' class='c'/><rect x='736' y='320' class='c'/><rect x='768' y='320' class='c'/><rect x='800' y='320' classM
='w'/><rect x='832' y='320' class='b'/><rect x='864' y='320' class='b'/><rect x='896' y='320' class='b'/><rect x='928' y='320' class='b'/><rect x='960' y='320' class='b'/><rect x='992' y='320' class='b'/><rect x='0' y='352' class='b'/><rect x='32' y='352' class='b'/><rect x='64' y='352' class='b'/><rect x='96' y='352' class='b'/><rect x='128' y='352' class='a'/><rect x='160' y='352' class='a'/><rect x='192' y='352' class='a'/><rect x='224' y='352' class='a'/><rect x='256' y='352' class='a'/><rect x='288' y='352' clM
ass='c'/><rect x='320' y='352' class='b'/><rect x='352' y='352' class='b'/><rect x='384' y='352' class='b'/><rect x='416' y='352' class='b'/><rect x='448' y='352' class='b'/><rect x='480' y='352' class='b'/><rect x='512' y='352' class='b'/><rect x='544' y='352' class='b'/><rect x='576' y='352' class='a'/><rect x='608' y='352' class='c'/><rect x='640' y='352' class='c'/><rect x='672' y='352' class='c'/><rect x='704' y='352' class='c'/><rect x='736' y='352' class='c'/><rect x='768' y='352' class='c'/><rect x='800' y=M
'352' class='a'/><rect x='832' y='352' class='a'/><rect x='864' y='352' class='a'/><rect x='896' y='352' class='a'/><rect x='928' y='352' class='a'/><rect x='960' y='352' class='a'/><rect x='992' y='352' class='b'/><rect x='0' y='384' class='b'/><rect x='32' y='384' class='b'/><rect x='64' y='384' class='b'/><rect x='96' y='384' class='b'/><rect x='128' y='384' class='b'/><rect x='160' y='384' class='b'/><rect x='192' y='384' class='b'/><rect x='224' y='384' class='b'/><rect x='256' y='384' class='b'/><rect x='288'M
 y='384' class='c'/><rect x='320' y='384' class='b'/><rect x='352' y='384' class='b'/><rect x='384' y='384' class='w'/><rect x='416' y='384' class='b'/><rect x='448' y='384' class='b'/><rect x='480' y='384' class='b'/><rect x='512' y='384' class='b'/><rect x='544' y='384' class='b'/><rect x='576' y='384' class='b'/><rect x='608' y='384' class='c'/><rect x='640' y='384' class='c'/><rect x='672' y='384' class='c'/><rect x='704' y='384' class='c'/><rect x='736' y='384' class='c'/><rect x='768' y='384' class='c'/><rectM
 x='800' y='384' class='a'/><rect x='832' y='384' class='a'/><rect x='864' y='384' class='a'/><rect x='896' y='384' class='a'/><rect x='928' y='384' class='w'/><rect x='960' y='384' class='a'/><rect x='992' y='384' class='a'/><rect x='0' y='416' class='a'/><rect x='32' y='416' class='b'/><rect x='64' y='416' class='b'/><rect x='96' y='416' class='b'/><rect x='128' y='416' class='b'/><rect x='160' y='416' class='b'/><rect x='192' y='416' class='b'/><rect x='224' y='416' class='b'/><rect x='256' y='416' class='d'/><rM
ect x='288' y='416' class='d'/><rect x='320' y='416' class='d'/><rect x='352' y='416' class='d'/><rect x='384' y='416' class='d'/><rect x='416' y='416' class='d'/><rect x='448' y='416' class='d'/><rect x='480' y='416' class='d'/><rect x='512' y='416' class='d'/><rect x='544' y='416' class='d'/><rect x='576' y='416' class='d'/><rect x='608' y='416' class='c'/><rect x='640' y='416' class='c'/><rect x='672' y='416' class='c'/><rect x='704' y='416' class='c'/><rect x='736' y='416' class='c'/><rect x='768' y='416' classM
='c'/><rect x='800' y='416' class='b'/><rect x='832' y='416' class='b'/><rect x='864' y='416' class='a'/><rect x='896' y='416' class='a'/><rect x='928' y='416' class='a'/><rect x='960' y='416' class='a'/><rect x='992' y='416' class='a'/><rect x='0' y='448' class='a'/><rect x='32' y='448' class='a'/><rect x='64' y='448' class='a'/><rect x='96' y='448' class='a'/><rect x='128' y='448' class='a'/><rect x='160' y='448' class='a'/><rect x='192' y='448' class='a'/><rect x='224' y='448' class='w'/><rect x='256' y='448' clM
ass='d'/><rect x='288' y='448' class='c'/><rect x='320' y='448' class='b'/><rect x='352' y='448' class='c'/><rect x='384' y='448' class='w'/><rect x='416' y='448' class='c'/><rect x='448' y='448' class='w'/><rect x='480' y='448' class='c'/><rect x='512' y='448' class='d'/><rect x='544' y='448' class='b'/><rect x='576' y='448' class='b'/><rect x='608' y='448' class='c'/><rect x='640' y='448' class='c'/><rect x='672' y='448' class='c'/><rect x='704' y='448' class='c'/><rect x='736' y='448' class='c'/><rect x='768' y=M
'448' class='c'/><rect x='800' y='448' class='w'/><rect x='832' y='448' class='b'/><rect x='864' y='448' class='b'/><rect x='896' y='448' class='b'/><rect x='928' y='448' class='b'/><rect x='960' y='448' class='b'/><rect x='992' y='448' class='b'/><rect x='0' y='480' class='a'/><rect x='32' y='480' class='w'/><rect x='64' y='480' class='a'/><rect x='96' y='480' class='a'/><rect x='128' y='480' class='a'/><rect x='160' y='480' class='a'/><rect x='192' y='480' class='a'/><rect x='224' y='480' class='a'/><rect x='256'M
 y='480' class='d'/><rect x='288' y='480' class='b'/><rect x='320' y='480' class='c'/><rect x='352' y='480' class='d'/><rect x='384' y='480' class='d'/><rect x='416' y='480' class='d'/><rect x='448' y='480' class='c'/><rect x='480' y='480' class='b'/><rect x='512' y='480' class='d'/><rect x='544' y='480' class='b'/><rect x='576' y='480' class='b'/><rect x='608' y='480' class='c'/><rect x='640' y='480' class='c'/><rect x='672' y='480' class='c'/><rect x='704' y='480' class='c'/><rect x='736' y='480' class='c'/><rectM
 x='768' y='480' class='w'/><rect x='800' y='480' class='b'/><rect x='832' y='480' class='b'/><rect x='864' y='480' class='b'/><rect x='896' y='480' class='b'/><rect x='928' y='480' class='b'/><rect x='960' y='480' class='b'/><rect x='992' y='480' class='b'/><rect x='0' y='512' class='b'/><rect x='32' y='512' class='b'/><rect x='64' y='512' class='b'/><rect x='96' y='512' class='b'/><rect x='128' y='512' class='b'/><rect x='160' y='512' class='b'/><rect x='192' y='512' class='b'/><rect x='224' y='512' class='b'/><rM
ect x='256' y='512' class='d'/><rect x='288' y='512' class='d'/><rect x='320' y='512' class='d'/><rect x='352' y='512' class='d'/><rect x='384' y='512' class='b'/><rect x='416' y='512' class='d'/><rect x='448' y='512' class='d'/><rect x='480' y='512' class='d'/><rect x='512' y='512' class='d'/><rect x='544' y='512' class='b'/><rect x='576' y='512' class='b'/><rect x='608' y='512' class='c'/><rect x='640' y='512' class='c'/><rect x='672' y='512' class='c'/><rect x='704' y='512' class='c'/><rect x='736' y='512' classM
='c'/><rect x='768' y='512' class='c'/><rect x='800' y='512' class='a'/><rect x='832' y='512' class='a'/><rect x='864' y='512' class='a'/><rect x='896' y='512' class='a'/><rect x='928' y='512' class='a'/><rect x='960' y='512' class='a'/><rect x='992' y='512' class='a'/><rect x='0' y='544' class='b'/><rect x='32' y='544' class='b'/><rect x='64' y='544' class='b'/><rect x='96' y='544' class='b'/><rect x='128' y='544' class='b'/><rect x='160' y='544' class='b'/><rect x='192' y='544' class='b'/><rect x='224' y='544' clM
ass='b'/><rect x='256' y='544' class='b'/><rect x='288' y='544' class='c'/><rect x='320' y='544' class='b'/><rect x='352' y='544' class='b'/><rect x='384' y='544' class='b'/><rect x='416' y='544' class='b'/><rect x='448' y='544' class='b'/><rect x='480' y='544' class='b'/><rect x='512' y='544' class='b'/><rect x='544' y='544' class='b'/><rect x='576' y='544' class='b'/><rect x='608' y='544' class='c'/><rect x='640' y='544' class='c'/><rect x='672' y='544' class='c'/><rect x='704' y='544' class='c'/><rect x='736' y=M
'544' class='c'/><rect x='768' y='544' class='c'/><rect x='800' y='544' class='a'/><rect x='832' y='544' class='a'/><rect x='864' y='544' class='a'/><rect x='896' y='544' class='a'/><rect x='928' y='544' class='a'/><rect x='960' y='544' class='a'/><rect x='992' y='544' class='a'/><rect x='0' y='576' class='a'/><rect x='32' y='576' class='a'/><rect x='64' y='576' class='a'/><rect x='96' y='576' class='a'/><rect x='128' y='576' class='b'/><rect x='160' y='576' class='b'/><rect x='192' y='576' class='b'/><rect x='224'M
 y='576' class='b'/><rect x='256' y='576' class='b'/><rect x='288' y='576' class='c'/><rect x='320' y='576' class='b'/><rect x='352' y='576' class='a'/><rect x='384' y='576' class='a'/><rect x='416' y='576' class='a'/><rect x='448' y='576' class='b'/><rect x='480' y='576' class='b'/><rect x='512' y='576' class='b'/><rect x='544' y='576' class='b'/><rect x='576' y='576' class='c'/><rect x='608' y='576' class='c'/><rect x='640' y='576' class='c'/><rect x='672' y='576' class='c'/><rect x='704' y='576' class='c'/><rectM
 x='736' y='576' class='c'/><rect x='768' y='576' class='c'/><rect x='800' y='576' class='b'/><rect x='832' y='576' class='b'/><rect x='864' y='576' class='b'/><rect x='896' y='576' class='b'/><rect x='928' y='576' class='b'/><rect x='960' y='576' class='w'/><rect x='992' y='576' class='a'/><rect x='0' y='608' class='a'/><rect x='32' y='608' class='a'/><rect x='64' y='608' class='a'/><rect x='96' y='608' class='a'/><rect x='128' y='608' class='a'/><rect x='160' y='608' class='a'/><rect x='192' y='608' class='w'/><rM
ect x='224' y='608' class='a'/><rect x='256' y='608' class='a'/><rect x='288' y='608' class='c'/><rect x='320' y='608' class='b'/><rect x='352' y='608' class='b'/><rect x='384' y='608' class='b'/><rect x='416' y='608' class='b'/><rect x='448' y='608' class='b'/><rect x='480' y='608' class='b'/><rect x='512' y='608' class='b'/><rect x='544' y='608' class='c'/><rect x='576' y='608' class='c'/><rect x='608' y='608' class='c'/><rect x='640' y='608' class='c'/><rect x='672' y='608' class='c'/><rect x='704' y='608' classM
='c'/><rect x='736' y='608' class='w'/><rect x='768' y='608' class='w'/><rect x='800' y='608' class='b'/><rect x='832' y='608' class='b'/><rect x='864' y='608' class='b'/><rect x='896' y='608' class='b'/><rect x='928' y='608' class='b'/><rect x='960' y='608' class='b'/><rect x='992' y='608' class='b'/><rect x='0' y='640' class='b'/><rect x='32' y='640' class='a'/><rect x='64' y='640' class='a'/><rect x='96' y='640' class='a'/><rect x='128' y='640' class='a'/><rect x='160' y='640' class='a'/><rect x='192' y='640' clM
ass='a'/><rect x='224' y='640' class='c'/><rect x='256' y='640' class='c'/><rect x='288' y='640' class='c'/><rect x='320' y='640' class='c'/><rect x='352' y='640' class='b'/><rect x='384' y='640' class='b'/><rect x='416' y='640' class='b'/><rect x='448' y='640' class='b'/><rect x='480' y='640' class='c'/><rect x='512' y='640' class='w'/><rect x='544' y='640' class='c'/><rect x='576' y='640' class='w'/><rect x='608' y='640' class='c'/><rect x='640' y='640' class='c'/><rect x='672' y='640' class='c'/><rect x='704' y=M
'640' class='c'/><rect x='736' y='640' class='c'/><rect x='768' y='640' class='c'/><rect x='800' y='640' class='c'/><rect x='832' y='640' class='a'/><rect x='864' y='640' class='b'/><rect x='896' y='640' class='b'/><rect x='928' y='640' class='b'/><rect x='960' y='640' class='b'/><rect x='992' y='640' class='b'/><rect x='0' y='672' class='b'/><rect x='32' y='672' class='b'/><rect x='64' y='672' class='b'/><rect x='96' y='672' class='w'/><rect x='128' y='672' class='b'/><rect x='160' y='672' class='b'/><rect x='192'M
 y='672' class='c'/><rect x='224' y='672' class='w'/><rect x='256' y='672' class='c'/><rect x='288' y='672' class='c'/><rect x='320' y='672' class='c'/><rect x='352' y='672' class='c'/><rect x='384' y='672' class='c'/><rect x='416' y='672' class='c'/><rect x='448' y='672' class='c'/><rect x='480' y='672' class='c'/><rect x='512' y='672' class='c'/><rect x='544' y='672' class='c'/><rect x='576' y='672' class='c'/><rect x='608' y='672' class='c'/><rect x='640' y='672' class='c'/><rect x='672' y='672' class='c'/><rectM
 x='704' y='672' class='c'/><rect x='736' y='672' class='c'/><rect x='768' y='672' class='c'/><rect x='800' y='672' class='c'/><rect x='832' y='672' class='c'/><rect x='864' y='672' class='a'/><rect x='896' y='672' class='a'/><rect x='928' y='672' class='a'/><rect x='960' y='672' class='a'/><rect x='992' y='672' class='a'/><rect x='0' y='704' class='b'/><rect x='32' y='704' class='b'/><rect x='64' y='704' class='b'/><rect x='96' y='704' class='b'/><rect x='128' y='704' class='b'/><rect x='160' y='704' class='c'/><rM
ect x='192' y='704' class='c'/><rect x='224' y='704' class='c'/><rect x='256' y='704' class='c'/><rect x='288' y='704' class='c'/><rect x='320' y='704' class='c'/><rect x='352' y='704' class='w'/><rect x='384' y='704' class='c'/><rect x='416' y='704' class='c'/><rect x='448' y='704' class='c'/><rect x='480' y='704' class='c'/><rect x='512' y='704' class='c'/><rect x='544' y='704' class='c'/><rect x='576' y='704' class='c'/><rect x='608' y='704' class='c'/><rect x='640' y='704' class='c'/><rect x='672' y='704' classM
='c'/><rect x='704' y='704' class='c'/><rect x='736' y='704' class='c'/><rect x='768' y='704' class='c'/><rect x='800' y='704' class='c'/><rect x='832' y='704' class='c'/><rect x='864' y='704' class='c'/><rect x='896' y='704' class='a'/><rect x='928' y='704' class='a'/><rect x='960' y='704' class='a'/><rect x='992' y='704' class='a'/><rect x='0' y='736' class='a'/><rect x='32' y='736' class='a'/><rect x='64' y='736' class='a'/><rect x='96' y='736' class='a'/><rect x='128' y='736' class='c'/><rect x='160' y='736' clM
ass='c'/><rect x='192' y='736' class='c'/><rect x='224' y='736' class='c'/><rect x='256' y='736' class='c'/><rect x='288' y='736' class='c'/><rect x='320' y='736' class='c'/><rect x='352' y='736' class='w'/><rect x='384' y='736' class='c'/><rect x='416' y='736' class='c'/><rect x='448' y='736' class='c'/><rect x='480' y='736' class='c'/><rect x='512' y='736' class='c'/><rect x='544' y='736' class='c'/><rect x='576' y='736' class='c'/><rect x='608' y='736' class='c'/><rect x='640' y='736' class='c'/><rect x='672' y=M
'736' class='c'/><rect x='704' y='736' class='c'/><rect x='736' y='736' class='c'/><rect x='768' y='736' class='c'/><rect x='800' y='736' class='c'/><rect x='832' y='736' class='c'/><rect x='864' y='736' class='c'/><rect x='896' y='736' class='w'/><rect x='928' y='736' class='b'/><rect x='960' y='736' class='b'/><rect x='992' y='736' class='b'/><rect x='0' y='768' class='a'/><rect x='32' y='768' class='a'/><rect x='64' y='768' class='a'/><rect x='96' y='768' class='c'/><rect x='128' y='768' class='w'/><rect x='160'M
 y='768' class='c'/><rect x='192' y='768' class='c'/><rect x='224' y='768' class='c'/><rect x='256' y='768' class='c'/><rect x='288' y='768' class='c'/><rect x='320' y='768' class='c'/><rect x='352' y='768' class='c'/><rect x='384' y='768' class='c'/><rect x='416' y='768' class='c'/><rect x='448' y='768' class='c'/><rect x='480' y='768' class='c'/><rect x='512' y='768' class='c'/><rect x='544' y='768' class='c'/><rect x='576' y='768' class='c'/><rect x='608' y='768' class='c'/><rect x='640' y='768' class='c'/><rectM
 x='672' y='768' class='c'/><rect x='704' y='768' class='c'/><rect x='736' y='768' class='c'/><rect x='768' y='768' class='c'/><rect x='800' y='768' class='c'/><rect x='832' y='768' class='c'/><rect x='864' y='768' class='c'/><rect x='896' y='768' class='c'/><rect x='928' y='768' class='b'/><rect x='960' y='768' class='b'/><rect x='992' y='768' class='b'/><rect x='0' y='800' class='b'/><rect x='32' y='800' class='b'/><rect x='64' y='800' class='b'/><rect x='96' y='800' class='c'/><rect x='128' y='800' class='c'/><rM
ect x='160' y='800' class='c'/><rect x='192' y='800' class='c'/><rect x='224' y='800' class='c'/><rect x='256' y='800' class='c'/><rect x='288' y='800' class='w'/><rect x='320' y='800' class='a'/><rect x='352' y='800' class='c'/><rect x='384' y='800' class='c'/><rect x='416' y='800' class='c'/><rect x='448' y='800' class='c'/><rect x='480' y='800' class='w'/><rect x='512' y='800' class='c'/><rect x='544' y='800' class='c'/><rect x='576' y='800' class='c'/><rect x='608' y='800' class='c'/><rect x='640' y='800' classM
='c'/><rect x='672' y='800' class='w'/><rect x='704' y='800' class='c'/><rect x='736' y='800' class='c'/><rect x='768' y='800' class='c'/><rect x='800' y='800' class='c'/><rect x='832' y='800' class='c'/><rect x='864' y='800' class='c'/><rect x='896' y='800' class='c'/><rect x='928' y='800' class='a'/><rect x='960' y='800' class='a'/><rect x='992' y='800' class='b'/><rect x='0' y='832' class='b'/><rect x='32' y='832' class='b'/><rect x='64' y='832' class='c'/><rect x='96' y='832' class='c'/><rect x='128' y='832' clM
ass='c'/><rect x='160' y='832' class='c'/><rect x='192' y='832' class='c'/><rect x='224' y='832' class='c'/><rect x='256' y='832' class='w'/><rect x='288' y='832' class='a'/><rect x='320' y='832' class='c'/><rect x='352' y='832' class='c'/><rect x='384' y='832' class='c'/><rect x='416' y='832' class='c'/><rect x='448' y='832' class='c'/><rect x='480' y='832' class='c'/><rect x='512' y='832' class='c'/><rect x='544' y='832' class='c'/><rect x='576' y='832' class='c'/><rect x='608' y='832' class='c'/><rect x='640' y=M
'832' class='c'/><rect x='672' y='832' class='w'/><rect x='704' y='832' class='c'/><rect x='736' y='832' class='c'/><rect x='768' y='832' class='c'/><rect x='800' y='832' class='c'/><rect x='832' y='832' class='c'/><rect x='864' y='832' class='c'/><rect x='896' y='832' class='c'/><rect x='928' y='832' class='c'/><rect x='960' y='832' class='a'/><rect x='992' y='832' class='a'/><rect x='0' y='864' class='a'/><rect x='32' y='864' class='b'/><rect x='64' y='864' class='c'/><rect x='96' y='864' class='c'/><rect x='128'M
 y='864' class='c'/><rect x='160' y='864' class='c'/><rect x='192' y='864' class='c'/><rect x='224' y='864' class='c'/><rect x='256' y='864' class='c'/><rect x='288' y='864' class='a'/><rect x='320' y='864' class='w'/><rect x='352' y='864' class='c'/><rect x='384' y='864' class='c'/><rect x='416' y='864' class='c'/><rect x='448' y='864' class='c'/><rect x='480' y='864' class='c'/><rect x='512' y='864' class='c'/><rect x='544' y='864' class='c'/><rect x='576' y='864' class='c'/><rect x='608' y='864' class='c'/><rectM
 x='640' y='864' class='c'/><rect x='672' y='864' class='c'/><rect x='704' y='864' class='c'/><rect x='736' y='864' class='c'/><rect x='768' y='864' class='c'/><rect x='800' y='864' class='c'/><rect x='832' y='864' class='c'/><rect x='864' y='864' class='c'/><rect x='896' y='864' class='c'/><rect x='928' y='864' class='w'/><rect x='960' y='864' class='a'/><rect x='992' y='864' class='a'/><rect x='0' y='896' class='a'/><rect x='32' y='896' class='a'/><rect x='64' y='896' class='w'/><rect x='96' y='896' class='c'/><rM
ect x='128' y='896' class='c'/><rect x='160' y='896' class='c'/><rect x='192' y='896' class='c'/><rect x='224' y='896' class='c'/><rect x='256' y='896' class='a'/><rect x='288' y='896' class='c'/><rect x='320' y='896' class='c'/><rect x='352' y='896' class='c'/><rect x='384' y='896' class='c'/><rect x='416' y='896' class='c'/><rect x='448' y='896' class='c'/><rect x='480' y='896' class='c'/><rect x='512' y='896' class='c'/><rect x='544' y='896' class='c'/><rect x='576' y='896' class='c'/><rect x='608' y='896' classM
='a'/><rect x='640' y='896' class='w'/><rect x='672' y='896' class='c'/><rect x='704' y='896' class='c'/><rect x='736' y='896' class='c'/><rect x='768' y='896' class='c'/><rect x='800' y='896' class='w'/><rect x='832' y='896' class='c'/><rect x='864' y='896' class='c'/><rect x='896' y='896' class='c'/><rect x='928' y='896' class='c'/><rect x='960' y='896' class='b'/><rect x='992' y='896' class='w'/><rect x='0' y='928' class='a'/><rect x='32' y='928' class='c'/><rect x='64' y='928' class='c'/><rect x='96' y='928' clM
ass='c'/><rect x='128' y='928' class='c'/><rect x='160' y='928' class='c'/><rect x='192' y='928' class='c'/><rect x='224' y='928' class='c'/><rect x='256' y='928' class='c'/><rect x='288' y='928' class='c'/><rect x='320' y='928' class='c'/><rect x='352' y='928' class='c'/><rect x='384' y='928' class='c'/><rect x='416' y='928' class='c'/><rect x='448' y='928' class='c'/><rect x='480' y='928' class='c'/><rect x='512' y='928' class='c'/><rect x='544' y='928' class='c'/><rect x='576' y='928' class='c'/><rect x='608' y=M
'928' class='a'/><rect x='640' y='928' class='c'/><rect x='672' y='928' class='c'/><rect x='704' y='928' class='c'/><rect x='736' y='928' class='c'/><rect x='768' y='928' class='c'/><rect x='800' y='928' class='c'/><rect x='832' y='928' class='c'/><rect x='864' y='928' class='c'/><rect x='896' y='928' class='c'/><rect x='928' y='928' class='c'/><rect x='960' y='928' class='c'/><rect x='992' y='928' class='b'/><rect x='0' y='960' class='b'/><rect x='32' y='960' class='c'/><rect x='64' y='960' class='c'/><rect x='96'M
 y='960' class='c'/><rect x='128' y='960' class='c'/><rect x='160' y='960' class='c'/><rect x='192' y='960' class='c'/><rect x='224' y='960' class='c'/><rect x='256' y='960' class='c'/><rect x='288' y='960' class='c'/><rect x='320' y='960' class='c'/><rect x='352' y='960' class='c'/><rect x='384' y='960' class='c'/><rect x='416' y='960' class='c'/><rect x='448' y='960' class='c'/><rect x='480' y='960' class='c'/><rect x='512' y='960' class='c'/><rect x='544' y='960' class='c'/><rect x='576' y='960' class='c'/><rectM
 x='608' y='960' class='a'/><rect x='640' y='960' class='c'/><rect x='672' y='960' class='w'/><rect x='704' y='960' class='c'/><rect x='736' y='960' class='c'/><rect x='768' y='960' class='c'/><rect x='800' y='960' class='c'/><rect x='832' y='960' class='c'/><rect x='864' y='960' class='c'/><rect x='896' y='960' class='c'/><rect x='928' y='960' class='c'/><rect x='960' y='960' class='c'/><rect x='992' y='960' class='a'/><rect x='0' y='992' class='b'/><rect x='32' y='992' class='c'/><rect x='64' y='992' class='c'/><M
rect x='96' y='992' class='c'/><rect x='128' y='992' class='c'/><rect x='160' y='992' class='c'/><rect x='192' y='992' class='c'/><rect x='224' y='992' class='c'/><rect x='256' y='992' class='c'/><rect x='288' y='992' class='c'/><rect x='320' y='992' class='w'/><rect x='352' y='992' class='c'/><rect x='384' y='992' class='c'/><rect x='416' y='992' class='c'/><rect x='448' y='992' class='c'/><rect x='480' y='992' class='c'/><rect x='512' y='992' class='c'/><rect x='544' y='992' class='c'/><rect x='576' y='992' classM
='c'/><rect x='608' y='992' class='a'/><rect x='640' y='992' class='c'/><rect x='672' y='992' class='c'/><rect x='704' y='992' class='c'/><rect x='736' y='992' class='c'/><rect x='768' y='992' class='c'/><rect x='800' y='992' class='c'/><rect x='832' y='992' class='c'/><rect x='864' y='992' class='c'/><rect x='896' y='992' class='c'/><rect x='928' y='992' class='c'/><rect x='960' y='992' class='c'/><rect x='992' y='992' class='a'/></svg>h!
FjDOUT:316745776DAC98DBDDBA55452770A9873F50CB616BBF46035947A7C9047DDC78
FjDOUT:CF0AEEBF11ED85F053B30A00A9387C525F6AC1B04E7F9F5B414E1EE2B7AD731B
FjDOUT:793615EA4A28FEEDE4434958328BC339F0B118336CE9B5EADC154BD82788D066
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobM
e.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:02:05+03:00" xmp:ModifyDate="2023-02-03T00:02:05+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:45cabdffM
-4207-df4b-b6b3-6c233d7e2621" xmpMM:DocumentID="adobe:docid:photoshop:005f273f-e699-e54f-b5a4-7ba86f0904f4" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4M
a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:0a4573c8-a0cf-9343-80b3-cb89ab2d704c" stEvt:when="2023-02-03T00:02:05+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from M
application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:45cabdff-4207-df4b-b6b3-6c233d7e2621" stEvt:when="2023-02-03T00:02:05+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:0a4573c8-a0cf-9343-80b3-cb89ab2d704c" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <phM
otoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                             M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                            <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
ce Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/M
1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:52:03+03:00" xmp:ModifyDate="2023-02-02T23:52:03+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:e89826ca-a5b9-ab4a-b718-a76e97afe4c5" xmpMM:DocumentID="adobe:docid:photoshop:f7806049-f914-bc4f-95b3-738M
bf5680d34" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="AdoM
be Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:32e4ff7e-b6bc-384e-9b53-e727cb28e034" stEvt:when="2023-02-02T23:52:03+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xM
mp.iid:e89826ca-a5b9-ab4a-b718-a76e97afe4c5" stEvt:when="2023-02-02T23:52:03+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:32e4ff7e-b6bc-384e-9b53-e727cb28e034" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag>M
 </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                              M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                           <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xapM
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"M
 xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:02:19+03:00" xmp:ModifyDate="2023-02-03T00:02:19+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:8bcb3def-477b-3e4b-bbea-62463269e8b2" xmpMM:DocumentID="adobe:docid:photoshop:206f96d2-41f1-7843-9267-7dc2fa4f60d1" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGM
B IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:20cc94cd-c79c-3a4e-be73-c2c3M
7b13ed63" stEvt:when="2023-02-03T00:02:19+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:8bcb3def-477b-3e4b-bbea-62463269e8b2" stEvt:when="2023-02-03T00:02:19+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (WindoM
ws)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:20cc94cd-c79c-3a4e-be73-c2c37b13ed63" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                          M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                               <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
/ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sTM
ype/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:06:54+03:00" xmp:ModifyDate="2023-02-03T00:06:54+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:e3727b60-c3b9-1f47-90c6-ae59e006a04d" xmpMM:DocumentID="adobe:docid:photoshop:9582e418-4564-804b-8292-1a3598f268df" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshoM
p:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:45502dde-f7M
da-614c-97fc-866ba557b96d" stEvt:when="2023-02-03T00:06:54+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:e3727b60-c3b9-1f47-90c6-ae59e006a04d" stEvt:when="2023-02-03T00:06:54+03:00" stEvt:softwareAgent="Adobe PhotM
oshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:45502dde-f7da-614c-97fc-866ba557b96d" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                         M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
c/Foundry USA Pool #dropgold/
FjDOUT:2F70FAA86C1797B51BFD88047E55253CBA975691F53158942F12A28131ADD7CA
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.M
org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:54:23+03:00" xmp:ModifyDatM
e="2023-02-02T23:54:23+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:72b5c9e2-410c-6844-a7aa-c82e789f9d04" xmpMM:DocumentID="adobe:docid:photoshop:ccab23d6-067b-ba40-86b3-a87678e6db8f" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe M
Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:6c7aa775-90d6-f84c-b8b9-c5851e284c44" stEvt:when="2023-02-02T23:54:23+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photM
oshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:72b5c9e2-410c-6844-a7aa-c82e789f9d04" stEvt:when="2023-02-02T23:54:23+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:6c7aa775-90d6-f84c-b8b9-c5851e284c44" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecM
b72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                      M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                   <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:metM
a/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 M
(Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:57:17+03:00" xmp:ModifyDate="2023-02-02T23:57:17+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:300f3f52-f940-3942-b7ec-0181f605c5b7" xmpMM:DocumentID="adobe:docid:photoshop:39b9dc53-c08d-2d41-9625-029be6fe7725" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="M
xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:05e029ec-82d4-334b-853d-585c8f79c8d9" stEvt:when="2023-02-02T23:57:17+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (M
Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:300f3f52-f940-3942-b7ec-0181f605c5b7" stEvt:when="2023-02-02T23:57:17+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmM
p.iid:05e029ec-82d4-334b-853d-585c8f79c8d9" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                      M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                   <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlnsM
:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:53:50+M
03:00" xmp:ModifyDate="2023-02-02T23:53:50+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:345891fc-b1fd-ea4f-b4b3-9e11605e4e06" xmpMM:DocumentID="adobe:docid:photoshop:7a36ea52-4076-fa46-93ab-bd36f4c3bef2" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:sM
oftwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:8f9614ab-aa73-3b49-8a09-1b51fe5ea7bc" stEvt:when="2023-02-02T23:53:50+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from applicM
ation/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:345891fc-b1fd-ea4f-b4b3-9e11605e4e06" stEvt:when="2023-02-02T23:53:50+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:8f9614ab-aa73-3b49-8a09-1b51fe5ea7bc" stRef:documentID="adobe:docid:photoshop:6564fe94M
-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                       <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour spaM
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-0M
1:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MeM
tadataDate="2023-02-02T23:55:24+03:00" xmp:ModifyDate="2023-02-02T23:55:24+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:3f013ffb-0418-3247-9f7a-8182fa170d54" xmpMM:DocumentID="adobe:docid:photoshop:c62cea25-cacd-a549-8c2d-bb049acf81f6" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="20M
23-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:5a664466-4488-4b43-b232-426af7b439bd" stEvt:when="2023-02-02T23:55:24+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converteM
d" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3f013ffb-0418-3247-9f7a-8182fa170d54" stEvt:when="2023-02-02T23:55:24+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:5a664466-4488-4b43-b232-426af7b439bd" stRef:documentIDM
="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                       <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:nM
s:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop M
21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:58:56+03:00" xmp:ModifyDate="2023-02-02T23:58:56+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:c750450a-f0dc-8845-9293-0018795bb15b" xmpMM:DocumentID="adobe:docid:photoshop:56d76642-317f-7944-a707-d256cf7051a6" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instancM
eID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:66937cef-872c-1a47-8bd7-bcfd12b7e710" stEvt:when="2023-02-02T23:58:56+03:00" stEvt:softwareAgent="Adobe Photoshop 2M
1.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:c750450a-f0dc-8845-9293-0018795bb15b" stEvt:when="2023-02-02T23:58:56+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceIM
D="xmp.iid:66937cef-872c-1a47-8bd7-bcfd12b7e710" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                 M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                        <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.comM
/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:00:59+03:00" xmp:ModifyDate="2023-02-03T00:00:59+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:37756a80-1bffM
-7e4c-ab67-2067a635bcfa" xmpMM:DocumentID="adobe:docid:photoshop:991ffd88-3c75-264c-88e3-a12ae24e6c22" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-M
9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:280d0e31-6393-4749-91f1-afd8f349d987" stEvt:when="2023-02-03T00:00:59+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from appliM
cation/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:37756a80-1bff-7e4c-ab67-2067a635bcfa" stEvt:when="2023-02-03T00:00:59+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:280d0e31-6393-4749-91f1-afd8f349d987" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshM
op:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                       <?xpacket end="w"?>
right (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
ewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rM
df:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-M
03T00:06:33+03:00" xmp:ModifyDate="2023-02-03T00:06:33+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:f2af3ff0-524e-4e45-b3e6-1dc9143a98bf" xmpMM:DocumentID="adobe:docid:photoshop:841f19f2-7238-2c49-801f-d15b0b3040ae" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03M
:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:599ad2d2-b7c4-6947-b2cd-bfc6be93bb71" stEvt:when="2023-02-03T00:06:33+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters=M
"from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:f2af3ff0-524e-4e45-b3e6-1dc9143a98bf" stEvt:when="2023-02-03T00:06:33+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:599ad2d2-b7c4-6947-b2cd-bfc6be93bb71" stRef:documentID="adobe:docid:photosM
hop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                      M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                   <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGM
B colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvtM
="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:52:51+03:00" xmp:ModifyDate="2023-02-02T23:52:51+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:dfcd1683-a3cf-6640-af66-1390d523d847" xmpMM:DocumentID="adobe:docid:photoshop:eb1a31ba-f8a7-dd4d-8957-40f9ecf59e58" xmpMM:OriM
ginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (WM
indows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:f2e5ebba-5c49-ed4d-add8-67d5bdc9c690" stEvt:when="2023-02-02T23:52:51+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:dfcd1683-a3cfM
-6640-af66-1390d523d847" stEvt:when="2023-02-02T23:52:51+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:f2e5ebba-5c49-ed4d-add8-67d5bdc9c690" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumenM
tAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                       <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceM
Event#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:43:29+03:00" xmp:ModifyDate="2023-02-02T23:43:29+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:12f65ef3-690b-9b43-9519-708015e4abf3" xmpMM:DocumentID="adobe:docid:photoshop:8b809d31-273a-464d-b84c-2ac820d51294" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-M
ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:aM
ction="saved" stEvt:instanceID="xmp.iid:1f6ebb91-4de9-b047-b6f6-1e619c243cc4" stEvt:when="2023-02-02T23:43:29+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:12f65ef3-690b-9b43-9519-708015e4abf3" stEvt:when="2023-02M
-02T23:43:29+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:1f6ebb91-4de9-b047-b6f6-1e619c243cc4" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </M
x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-sM
yntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:59:12+03:00" xmp:ModifyDate="2023-02-02T23:59:M
12+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:98d90746-80e9-5f40-9618-ce0fdd1075e2" xmpMM:DocumentID="adobe:docid:photoshop:d8b9a132-d22f-0e4c-a351-96f97d08cec6" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (WindM
ows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:158f808b-4dd7-2e4c-a3bc-3aef1a659719" stEvt:when="2023-02-02T23:59:12+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"M
/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:98d90746-80e9-5f40-9618-ce0fdd1075e2" stEvt:when="2023-02-02T23:59:12+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:158f808b-4dd7-2e4c-a3bc-3aef1a659719" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:origM
inalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                          M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                               <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 DefauM
lt RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1M
/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:59:29+03:00" xmp:ModifyDate="2023-02-02T23:59:29+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:bf96df4e-d1a0-7c48-b182-43e212eab950" xmpMM:DocumentID="adobe:docM
id:photoshop:f36cb407-b10e-e448-803c-d28ba26208c6" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31TM
21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:988a3851-5c73-7e43-a5c6-d8ffcad57c98" stEvt:when="2023-02-02T23:59:29+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li M
stEvt:action="saved" stEvt:instanceID="xmp.iid:bf96df4e-d1a0-7c48-b182-43e212eab950" stEvt:when="2023-02-02T23:59:29+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:988a3851-5c73-7e43-a5c6-d8ffcad57c98" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DAM
26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                      M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                   <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
 Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.M
com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:58:34+03:00" xmp:ModifyDate="2023-02-02T23:58:34+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:3e358e3d-8628-784f-ae01-e685a6828b49" xmpMM:DocumentID="adobe:docid:photoshop:61142c2f-d925-0b49-M
acaf-9508d5f41426" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgM
ent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:c8131d5c-00c5-b54c-b7b8-bd2deac80eb5" stEvt:when="2023-02-02T23:58:34+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instaM
nceID="xmp.iid:3e358e3d-8628-784f-ae01-e685a6828b49" stEvt:when="2023-02-02T23:58:34+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:c8131d5c-00c5-b54c-b7b8-bd2deac80eb5" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </M
rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                      M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                   <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2M
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">M
 <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:54:42+03:00" xmp:ModifyDate="2023-02-02T23:54:42+03:00" dM
c:format="image/jpeg" xmpMM:InstanceID="xmp.iid:711a4496-d8c1-6f42-bafb-75311d59e100" xmpMM:DocumentID="adobe:docid:photoshop:87f964d3-5dbf-d349-8708-65028cfbd658" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdM
f:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:4717a7cd-7d84-7d47-933d-09cf2f28ba0b" stEvt:when="2023-02-02T23:54:42+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li M
stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:711a4496-d8c1-6f42-bafb-75311d59e100" stEvt:when="2023-02-02T23:54:42+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:4717a7cd-7d84-7d47-933d-09cf2f28ba0b" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumenM
tID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                     M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                    <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB coloM
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="httM
p://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:01:39+03:00" xmp:ModifyDate="2023-02-03T00:01:39+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iM
id:758bcf87-913c-9f48-9c0a-610b755de106" xmpMM:DocumentID="adobe:docid:photoshop:2ae77fd8-d2eb-fd41-81ed-17bda9ddb505" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xM
mp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:14cc0a9e-c7e9-a448-b8f2-fbca8cc39566" stEvt:when="2023-02-03T00:01:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="convM
erted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:758bcf87-913c-9f48-9c0a-610b755de106" stEvt:when="2023-02-03T00:01:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:14cc0a9e-c7e9-a448-b8f2-fbca8cc39566" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf511M
0288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                       <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/RM
esourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:58:09+03:00" xmp:ModifyDate="2023-02-02T23:58:09+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:ba43e5dc-cb0d-5945-99a2-017a15cf54d5" xmpMM:DocumentID="adobe:docid:photoshop:93018a75-a72e-8042-8b40-7bb27c47aac2" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCM
Profile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:0d05fed8-3b7e-93M
4c-b022-b0991e20cb52" stEvt:when="2023-02-02T23:58:09+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:ba43e5dc-cb0d-5945-99a2-017a15cf54d5" stEvt:when="2023-02-02T23:58:09+03:00" stEvt:softwareAgent="Adobe PhotoshopM
 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:0d05fed8-3b7e-934c-b022-b0991e20cb52" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                              M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                           <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://M
ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:56:02+03:00" xmp:ModifyDate="2023-02-02T23:56:02+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:259811d4-aae9-2f43-a591-5ba2b1c96f83" xmpMM:DocumentID="adobe:docid:photoshop:e98e238f-b276-0e42-bbe2-effa610a90e5" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshopM
:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceM
ID="xmp.iid:57273942-ce1c-e043-aa1b-363ddc6693da" stEvt:when="2023-02-02T23:56:02+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:259811d4-aae9-2f43-a591-5ba2b1c96f83" stEvt:when="2023-02-02T23:56:02+03:00" stEvt:soM
ftwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:57273942-ce1c-e043-aa1b-363ddc6693da" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-nsM
#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:55:40+03:00" xmp:ModifyDate="2023-02-02T23:55:40+03:00M
" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:b23a486a-67c6-8447-85ec-c0bcd8ab0c09" xmpMM:DocumentID="adobe:docid:photoshop:ffb50835-367b-c04a-8f7f-3346e5badcc5" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> M
<rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:28cc80d7-ea53-564d-947d-292151663727" stEvt:when="2023-02-02T23:55:40+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:M
li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:b23a486a-67c6-8447-85ec-c0bcd8ab0c09" stEvt:when="2023-02-02T23:55:40+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:28cc80d7-ea53-564d-947d-292151663727" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocuM
mentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                       <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB cM
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0M
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlM
ns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:44:04+03:00" xmp:ModifyDate="2023-02-02T23:44:04+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:fc9c8046-f0e2-5749-b6da-0ba6886eb704" xmpMM:DocumentID="adobe:docid:photoshop:45ba5af2-272a-2d47-a98a-29e815a19bc0" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEM
C61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:f41ff474-efb9-764c-884b-10bd7253M
a03c" stEvt:when="2023-02-02T23:44:04+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:fc9c8046-f0e2-5749-b6da-0ba6886eb704" stEvt:when="2023-02-02T23:44:04+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"M
 stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:f41ff474-efb9-764c-884b-10bd7253a03c" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                              M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                           <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/M
ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:50:53+03:00" xmp:ModifyDate="2023-02-02T23:50:53+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:f769e145-7cb5-cd42-af6f-0cd3d8a15aa6" xmpMM:DocumentID="adobe:docid:photoshop:7a1d50ce-8133-d746-a215-77cbdf590b51" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICM
CProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:662bc714-d276-7M
343-a114-c99b13d7850f" stEvt:when="2023-02-02T23:50:53+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:f769e145-7cb5-cd42-af6f-0cd3d8a15aa6" stEvt:when="2023-02-02T23:50:53+03:00" stEvt:softwareAgent="Adobe PhotoshoM
p 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:662bc714-d276-7343-a114-c99b13d7850f" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                             M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                            <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourcM
eEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:59:47+03:00" xmp:ModifyDate="2023-02-02T23:59:47+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:26f7f70c-15d3-6d49-9f60-7a50058abcac" xmpMM:DocumentID="adobe:docid:photoshop:dfe68c1f-fb67-2845-b689-273581857813" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643M
-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:M
action="saved" stEvt:instanceID="xmp.iid:00c6253b-d8f7-7242-9c76-e326f7a0c831" stEvt:when="2023-02-02T23:59:47+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:26f7f70c-15d3-6d49-9f60-7a50058abcac" stEvt:when="2023-0M
2-02T23:59:47+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:00c6253b-d8f7-7242-9c76-e326f7a0c831" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> <M
/x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResoM
urceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:02:38+03:00" xmp:ModifyDate="2023-02-03T00:02:38+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:0c2b5b65-3469-ad4b-8018-01322b81e22d" xmpMM:DocumentID="adobe:docid:photoshop:5385fd80-af35-7049-975f-6cd32d406d90" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProM
file="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:13281450-52c7-4240-M
b6a3-62ce81f0d62a" stEvt:when="2023-02-03T00:02:38+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:0c2b5b65-3469-ad4b-8018-01322b81e22d" stEvt:when="2023-02-03T00:02:38+03:00" stEvt:softwareAgent="Adobe Photoshop 21M
.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:13281450-52c7-4240-b6a3-62ce81f0d62a" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                 M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                        <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sTyM
pe/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:01:22+03:00" xmp:ModifyDate="2023-02-03T00:01:22+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:8e2a4b23-920e-f44f-a855-cf46bece9459" xmpMM:DocumentID="adobe:docid:photoshop:c767911c-8382-a24a-b670-8e6d1440beab" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshopM
:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:49f32109-a10M
e-e941-b5e4-2cfa757792b3" stEvt:when="2023-02-03T00:01:22+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:8e2a4b23-920e-f44f-a855-cf46bece9459" stEvt:when="2023-02-03T00:01:22+03:00" stEvt:softwareAgent="Adobe PhotoM
shop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:49f32109-a10e-e941-b5e4-2cfa757792b3" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                          M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                               <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sM
Type/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:57:44+03:00" xmp:ModifyDate="2023-02-02T23:57:44+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:b85c81db-79a0-b745-877e-bc8bb1059680" xmpMM:DocumentID="adobe:docid:photoshop:563cdac9-6491-f344-9990-e3588ba9f4b3" xmpMM:OriginalDocumentID="xmp.did:8653deM
18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rM
df:li stEvt:action="saved" stEvt:instanceID="xmp.iid:430c7380-9e80-b343-9410-efcb0efa7eeb" stEvt:when="2023-02-02T23:57:44+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:b85c81db-79a0-b745-877e-bc8bb1059680" stEvt:M
when="2023-02-02T23:57:44+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:430c7380-9e80-b343-9410-efcb0efa7eeb" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> M
</rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <?xpackeM
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1

Mined by AntPool958[
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobM
e.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:53:30+03:00" xmp:ModifyDate="2023-02-02T23:53:30+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:7cf43313M
-f245-4c40-b5e8-23257f11c382" xmpMM:DocumentID="adobe:docid:photoshop:d5a23159-0ab2-da46-958f-414525789fdc" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4M
a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:92ce1660-b9b8-2146-b9a9-4c74905dda48" stEvt:when="2023-02-02T23:53:30+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from M
application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:7cf43313-f245-4c40-b5e8-23257f11c382" stEvt:when="2023-02-02T23:53:30+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:92ce1660-b9b8-2146-b9a9-4c74905dda48" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <phM
otoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                             M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                            <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
ce Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmM
lns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:55:05+03:00" xmp:ModifyDate="2023-02-02T23:55:05+03:00" dc:format="image/jpeg" xmpMM:InstaM
nceID="xmp.iid:307af74e-1fff-5d45-aa88-2c82ec0f80fe" xmpMM:DocumentID="adobe:docid:photoshop:52014a0f-adcf-0044-93b3-2329f0f45e6f" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:iM
nstanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:250bf60e-1e54-1d43-88fe-3c0461ee951a" stEvt:when="2023-02-02T23:55:05+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:paraM
meters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:307af74e-1fff-5d45-aa88-2c82ec0f80fe" stEvt:when="2023-02-02T23:55:05+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:250bf60e-1e54-1d43-88fe-3c0461ee951a" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-aM
c05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                      M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                   <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/eleM
ments/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:51:47+03:00" xmp:ModifyDate="2023-02-02T23:51:47+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:2d284bd5-7419-e64f-b850-51c728a0b5b1" xmpMM:DocumentID="M
adobe:docid:photoshop:c9307d57-c715-524c-a3f7-5e3961863ef9" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="20M
23-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:4177826a-1b3c-d24f-8ce6-8be982cee24b" stEvt:when="2023-02-02T23:51:47+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/>M
 <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:2d284bd5-7419-e64f-b850-51c728a0b5b1" stEvt:when="2023-02-02T23:51:47+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:4177826a-1b3c-d24f-8ce6-8be982cee24b" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CM
D41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                             M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                            <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
Reference Viewing Condition in IEC61966-2.1
c/Foundry USA Pool #dropgold/!
KjI=:BNB.BUSD-BD1:bnb1c667cxycg4cgjt7ae4c3cgj9agtmzdrnw3la90:1360015365:te:0
FjDOUT:8513733D2F3272B455D05FF4BE690759B1F0AF75F56E14030F66376280694301
FjDOUT:88C70FFF989C930F94E82BF24F2933FA4EE87B5DD7156D7673AE9FB9AC321FE6
iTXtXML:com.adobe.xmp
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
            xmlns:GIMP="http://www.giM
            xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
            xmlns:dc="http://purl.org/dc/elements/1.1/"
            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
            xmlns:exif="http://ns.adobe.com/exif/1.0/">
         <xmp:CreatorTool>GIMP 2.10.32</xmp:CreatorTool>
         <xmp:MetadataDate>2023:02:02T22:29:40-05:00</xmp:MetadataDate>
         <xmp:ModifyDate>2023-02-02T22:29:40</xmp:ModifyDate>
         <GIMP:Version>2.10.32</GIMP:Version>
         <GIMP:Platform>Mac OS</GIMP:Platform>
         <GIMP:TimeStamp>1675394983316255</GIMP:TimeStamp>
         <tiff:ResolutionUnit>3</tiff:ResolutionUnit>
         <tiff:Orientation>1</tiff:Orientation>
         <tiff:YResolution>300</tiff:YResolution>
         <tiff:XResolution>300</tiff:XResolution>
         <dc:description>
            <rdf:Alt>
               <rdf:li xml:lang="x-default">Created with GIMP</rdf:li>
            </rdf:Alt>
   </dc:description>
         <dc:Format>image/png</dc:Format>
         <xmpMM:History>
            <rdf:Seq>
               <rdf:li rdf:parseType="Resource">
                  <stEvt:changed>/</stEvt:changed>
                  <stEvt:softwareAgent>Gimp 2.10 (Mac OS)</stEvt:softwareAgent>
                  <stEvt:when>2023-02-02T22:29:43-05:00</stEvt:when>
                  <stEvt:instanceID>xmp.iid:3bd39d47-e1d5-4912-a1b9-3080716bbd88</stEvt:instanceID>
                  <stEvt:action>saved</stEvt:action>
            </rdf:Seq>
         </xmpMM:History>
         <xmpMM:OriginalDocumentID>xmp.did:26bdec4f-7856-442b-be21-d59d7eeeb323</xmpMM:OriginalDocumentID>
         <xmpMM:InstanceID>xmp.iid:36cbb0fe-daf7-4304-873e-cc0175b2fb5b</xmpMM:InstanceID>
         <xmpMM:DocumentID>gimp:docid:gimp:b87b518a-f04b-4ba0-b6b1-071cfa9e0cd4</xmpMM:DocumentID>
         <exif:ColorSpace>1</exif:ColorSpace>
         <exif:UserComment>
            <rdf:Alt>
               <rdf:li xml:lang="x-default">Created with GIMPM
            </rdf:Alt>
         </exif:UserComment>
      </rdf:Description>
text/html;charset=utf-8
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>FREEDOM TO TRANSACT</title><script src="https://hv4gxzchk24cqfezebn3ujjz6oy2kbtztv5vghn6kpbkjc3vg4rq.arweave.net/LwoYxA0u8husyQUnezc7A5x4EU-rzYNfLnHtICXCBzc"></script><script src="data:text/javascript;base64,dmFyIGxvZ287CnZhciBiZzsKdmFyIHggPSAwOwp2YXIgeSA9IDA7CnZhciBzc3BlZWQgPSAzCnZhciB4ZGlyID0gMTsKdmFyIHlkaXIgPSAxOwp2YXIgZmxpcHNwZWVkID0gMC4wMQoKZnVuY3Rpb24gcHJlbG9hZCgpIHsKICBsb2dvID0gbG9hZEltYWdlKCJodHRwczovL3g0ZDVM
hNXlxNDRxd29mZDJlbzZoZHpwaG5qZG51bTU0NG1mNnJ5dmV0Y2htYndpcTR5d2EuYXJ3ZWF2ZS5uZXQvdndmUWR4RG5JV2NVZWlPOGNlWG5ha2JhTTd6akMtamlwSmlPd05rUTVpdyIpOwogIGJnID0gbG9hZEltYWdlKCJodHRwczovL2Fyd2VhdmUubmV0L2xZVUZXLXZSVU5ZWkMwTWx3NDVfdXVhXzlLekNGNHZ3RTMtYVJVLTVTVkkiKTsKICBzcGVlZCA9IHJhbmRvbSgxLDUpOwogIGZsaXBzcGVlZCA9IGZsaXBzcGVlZCAqIHJhbmRvbSgyLDgpOwp9CgpmdW5jdGlvbiBzZXR1cCgpIHsKICBjcmVhdGVDYW52YXMoNjQ4LCA5NDksIFdFQkdMKTsKfQoKZnVuY3Rpb24gZHJhdygpIHsKICBiYWNrZ3JvdW5kKDIwMCk7CiAgaW1hZ2UoYmcsIC0zMjQsIC00NzQsIHdpZHRoLCBoZWlnaHQpOyAM
gCiAgbm9TdHJva2UoKTsKICAKICB4ID0geCArIHNzcGVlZCAqIHhkaXI7CiAgeSA9IHkgKyBzc3BlZWQgKiB5ZGlyOwogIAogIGlmICh4ID4gMzI0IC0gMjQwIHx8IHggPCAtMzI0LSAxMjUpIHsKICAgIHhkaXIgPSAteGRpcjsKICB9CiAgaWYgKHkgPiA0NzQgLTQwIHx8IHkgPCAtNDc0KyAxMDApIHsKICAgIHlkaXIgPSAteWRpcjsKICB9CiAgCiAgcHVzaCgpOwogIHRyYW5zbGF0ZSh4LCB5LCA2NCk7CiAgcm90YXRlWChmcmFtZUNvdW50ICogZmxpcHNwZWVkKTsKICB0ZXh0dXJlKGxvZ28pOwogIGNpcmNsZSgyMDAsIDEsIDEyMCk7CiAgcG9wKCk7Cn0"></script></head><body></body></html>
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://M
ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:52:33+03:00" xmp:ModifyDate="2023-02-02T23:52:33+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:5414536d-98dc-9649-8e56-525aa9029c54" xmpMM:DocumentID="adobe:docid:photoshop:704f48c4-ad26-a34d-a33a-13d845c5315f" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshopM
:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceM
ID="xmp.iid:d1d451fe-ef31-0b4e-a892-a7d7e3c90329" stEvt:when="2023-02-02T23:52:33+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:5414536d-98dc-9649-8e56-525aa9029c54" stEvt:when="2023-02-02T23:52:33+03:00" stEvt:soM
ftwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:d1d451fe-ef31-0b4e-a892-a7d7e3c90329" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
hiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/phM
otoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-02T23:56:56+03:00" xmp:ModifyDate="2023-02-02T23:56:56+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:25e78c1e-f867-b94b-a5c5-1ff5349d788e" xmpMM:DocumentID="adobe:docid:photoshop:4c00ebc6-2c85-1044-9569-547ce0f7eefe" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:SeM
q> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:4512ea08-c005-fa41-b551-22f0a19d8fe5" stEvt:when="2023-02-02T23:56:5M
6+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:25e78c1e-f867-b94b-a5c5-1ff5349d788e" stEvt:when="2023-02-02T23:56:56+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmM
pMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:4512ea08-c005-fa41-b551-22f0a19d8fe5" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                  M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                       <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
FjD=:THOR.RUNE:thor1pwdwh5x2080epw989x6wmh2e2yj3f2ch7vw9pa:1361320035:t'
#%'+-/357:<>BDFHLNPTUW[]_cegkmortvz|~
LAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
ULAME3.100UUUUUUUUUUUUM
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU|
LAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
LAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
NhELAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUh
0}LAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUXu
4ALAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUH
100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
LAME3.100UUUUUUUUUUUUUU
ULAME3.100UUUUUUUUUUUUUUU
ULAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
LAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
sLAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUM
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
LAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUM
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUULAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUULAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUM
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUULAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUh!
0G#UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU0
UUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUY(i
UUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUM
~UUUUUUUUUUUUUUUUUUU
rqUUUUUUUUUUUUUUUUUU
JrqUUUUUUUUUUUUUUUUUU
ff\rqUUUUUUUUUUUUUUUU
 UUUUUUUUUUUUUUUUUUU
E3.98UUUUUUUUUUUUUUU
rqUUUUUUUUUUUUUUUUUU
\rqUUUUUUUUUUUUUUUUU
82L"UUUUUUUUUUUUUUUUUUUU
CUUUUUUUUUUUUUUUUUUUU
f\rqUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU:
GqUUUUUUUUUUUUUUUUUUUU
KrUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUnY#
f\rqUUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUR
UUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU
KLAME3.98UUUUUUUUUUUUM
GrUUUUUUUUUUUUUUUUUUU
GYUUUUUUUUUUUUUUUUUUUU	rH
UUUUUUUUUUUUUUUUUUUUUUUUUUU
9UUUUUUUUUUUUUUUUUUUv
f\rqUUUUUUUUUUUUUUUUUUUUUU
VUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU".
TUUUUUUUUUUUUUUUUUUU
SqUUUUUUUUUUUUUUUUUUUU
VUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU
[UUUUUUUUUUUUUUUUUUUU
LAME3.98UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
GrUUUUUUUUUUUUUUUUUUU
SsUUUUUUUUUUUUUUUUUUUU
f\rqUUUUUUUUUUUUUUUUUUU
XUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUU
MmUUUUUUUUUUUUUUUUUUUU
QQUUUUUUUUUUUUUUUUUUU
MTUUUUUUUUUUUUUUUUUUU
f\rqUUUUUUUUUUUUUUUUU
SwUUUUUUUUUUUUUUUUUUU
8UUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU
Ms8UUUUUUUUUUUUUUUUUUUo
MvUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
ZUUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU
UUUUUUUUUUUUUUUUUUUU
-=-157:::#+?D?8C49:7
%77777777777777777777777777777777777777777777777777
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntaM
x-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T00:07:10+03:00" xmp:ModifyDate="2023-02-03T00:07:10+0M
3:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:c1285253-4a7e-7649-9feb-5d382bb5fdfe" xmpMM:DocumentID="adobe:docid:photoshop:272eaaaa-b262-1b41-9821-a308bee336dc" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)M
"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:d1bb25e2-91e2-ea45-b185-aa072cd39ecc" stEvt:when="2023-02-03T00:07:10+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <M
rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:c1285253-4a7e-7649-9feb-5d382bb5fdfe" stEvt:when="2023-02-03T00:07:10+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:d1bb25e2-91e2-ea45-b185-aa072cd39ecc" stRef:documentID="adobe:docid:photoshop:6564fe94-253e-b74d-87e1-5aecb72f57e0" stRef:originalM
DocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                              M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                           <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RM
GB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
-=-157:::#+?D?8C49:7
%77777777777777777777777777777777777777777777777777
**************************************************
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
c/Foundry USA Pool #dropgold/
7j5+:BTC.BTC:thor1pwdwh5x2080epw989x6wmh2e2yj3f2ch7vw9pa
:http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.5.0"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" photoshop:ColorMode="3" photoshop:ICCProfile="M
Display P3" xmp:ModifyDate="2023-02-02T22:41:55-05:00" xmp:MetadataDate="2023-02-02T22:41:55-05:00"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="produced" stEvt:softwareAgent="Affinity Photo 1.10.6" stEvt:when="2023-02-02T22:41:55-05:00"/> </rdf:Seq> </xmpMM:History> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                              M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                           <?xpacket end="w"?>
 (B+(%%(Q:=0B`Ued_U][jx
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.comM
/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:38:18+03:00" xmp:ModifyDate="2023-02-03T06:38:18+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:866271e1-27f4-a14b-988a-23da8ca1ee00" xmpMM:DocumentID="adobe:docid:photoshop:bb95b76a-271d-1440-b7db-770a5bc441e6" xmpMM:OriginalDocumentID="xmp.M
did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changeM
d="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:760b500e-ae25-3a4a-a92e-3e1a3b0983ce" stEvt:when="2023-02-03T06:38:18+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:866271e1-27f4-a14b-988a-23da8ca1eeM
00" stEvt:when="2023-02-03T06:38:18+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:760b500e-ae25-3a4a-a92e-3e1a3b0983ce" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:DesM
cription> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
  <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.M
com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:38:53+03:00" xmp:ModifyDate="2023-02-03T06:38:53+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:29b0be4c-5M
d64-9040-b0ac-f8362c9e6c3c" xmpMM:DocumentID="adobe:docid:photoshop:0c413839-96f8-684a-bf3e-881dc95d1a18" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a4M
96-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:717a847b-8139-174b-a4bf-a630b355c9bc" stEvt:when="2023-02-03T06:38:53+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from apM
plication/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:29b0be4c-5d64-9040-b0ac-f8362c9e6c3c" stEvt:when="2023-02-03T06:38:53+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:717a847b-8139-174b-a4bf-a630b355c9bc" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photM
oshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                               M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                          <?xpacket end="w"?>
opyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
 Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmetM
a xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorToolM
="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:35:47+03:00" xmp:ModifyDate="2023-02-03T06:35:47+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:1b892532-d4ac-ee42-be47-b3b86a85c825" xmpMM:DocumentID="adobe:docid:photoshop:dd536a55-2f9a-0744-8d01-5bc101df1997" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="creaM
ted" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:506a3fb5-7807-5940-946c-8a7ac096fcd6" stEvt:when="2023-02-03T06:35:47+03:00" stEvt:softwareAgent=M
"Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:1b892532-d4ac-ee42-be47-b3b86a85c825" stEvt:when="2023-02-03T06:35:47+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrM
om stRef:instanceID="xmp.iid:506a3fb5-7807-5940-946c-8a7ac096fcd6" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                               M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                          <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobeM
:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe PhotoshoM
p 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:38:34+03:00" xmp:ModifyDate="2023-02-03T06:38:34+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:78f6a023-58b0-4842-871a-99fcda45817a" xmpMM:DocumentID="adobe:docid:photoshop:231e4c4e-c199-774d-9d59-a74075502ec1" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instaM
nceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:ccf585da-b06b-f443-9a31-0d1fcbd5336e" stEvt:when="2023-02-03T06:38:34+03:00" stEvt:softwareAgent="Adobe PhotoshopM
 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:78f6a023-58b0-4842-871a-99fcda45817a" stEvt:when="2023-02-03T06:38:34+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instancM
eID="xmp.iid:ccf585da-b06b-f443-9a31-0d1fcbd5336e" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                               M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                          <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
-=-157:::#+?D?8C49:7
%77777777777777777777777777777777777777777777777777
Z&jINE.E.E.E.E.E.E.E-
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.M
com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:39:29+03:00" xmp:ModifyDate="2023-02-03T06:39:29+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:2045d1b8-798a-2344-8fba-e9d305342676" xmpMM:DocumentID="adobe:docid:photoshop:5e457855-5097-184c-9e55-007b22260f54" xmpMM:OriginalDocumentID="xM
mp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:chaM
nged="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:f335aa63-54ed-494c-b3c3-e998fd960e11" stEvt:when="2023-02-03T06:39:29+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:2045d1b8-798a-2344-8fba-e9d3053M
42676" stEvt:when="2023-02-03T06:39:29+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:f335aa63-54ed-494c-b3c3-e998fd960e11" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:M
Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
     <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="htM
tp://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:36:48+03:00" xmp:ModifyDate="2023-02-03T06:36:48+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:2776fc6c-3e74-0642-a805-e69a7329556a" xmpMM:DocumentID="adobe:docid:photoshop:9e197M
735-69cc-8844-abe4-da716c3a4837" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stM
Evt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:96e91e6c-2ed6-4146-bb92-c47869790001" stEvt:when="2023-02-03T06:36:48+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saveM
d" stEvt:instanceID="xmp.iid:2776fc6c-3e74-0642-a805-e69a7329556a" stEvt:when="2023-02-03T06:36:48+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:96e91e6c-2ed6-4146-bb92-c47869790001" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733M
F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                 <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing ConditionM
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/RM
esourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:37:03+03:00" xmp:ModifyDate="2023-02-03T06:37:03+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:4cbe6b62-1a68-5d40-bfdc-82f8b7d94068" xmpMM:DocumentID="adobe:docid:photoshop:b388ec5b-eb0b-b843-886f-041d50c9a32b" xmpMM:OriginalDocumentID="xmp.did:8653de18-59bM
9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li M
stEvt:action="saved" stEvt:instanceID="xmp.iid:3a64df4c-03cb-d84b-9cd0-b6bfd0e4201c" stEvt:when="2023-02-03T06:37:03+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:4cbe6b62-1a68-5d40-bfdc-82f8b7d94068" stEvt:when="M
2023-02-03T06:37:03+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:3a64df4c-03cb-d84b-9cd0-b6bfd0e4201c" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:M
RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          <?xpacket end=M
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adoM
be.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:37:44+03:00" xmp:ModifyDate="2023-02-03T06:37:44+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:f44efd61-97b8-aa41-a68f-736ce5dd0b0a" xmpMM:DocumentID="adobe:docid:photoshop:5f852445-801b-0aM
41-b8b7-9b826c66b132" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwarM
eAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:b00dc16f-2967-014d-ae95-4ceb6cb02a74" stEvt:when="2023-02-03T06:37:44+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:inM
stanceID="xmp.iid:f44efd61-97b8-aa41-a68f-736ce5dd0b0a" stEvt:when="2023-02-03T06:37:44+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:b00dc16f-2967-014d-ae95-4ceb6cb02a74" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li>M
 </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                   M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                      <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC6196M
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/M
" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (WM
indows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:37:23+03:00" xmp:ModifyDate="2023-02-03T06:37:23+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:971b94ce-8c57-214b-800d-ff6aa998e5a5" xmpMM:DocumentID="adobe:docid:photoshop:9706f5b8-be84-d344-9302-619d0ab33de9" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmM
p.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:ea0d8694-4b95-2740-8ab7-2810937c31ea" stEvt:when="2023-02-03T06:37:23+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (WiM
ndows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:971b94ce-8c57-214b-800d-ff6aa998e5a5" stEvt:when="2023-02-03T06:37:23+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.M
iid:ea0d8694-4b95-2740-8ab7-2810937c31ea" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                 <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
text/plain;charset=utf-8
#############################################
### Announcing the Rare Ordinal Directory ###
#                                           #
# Directory: http://rareordinal.directory   #
# Telegram: https://t.me/+qIdmbUk_m6ZmZTgx  #
# Twitter: https://twitter.com/RareOrdinals #
#                                           #
#   Submit Here Your Rare Ordinals Today    #
# -> http://rareordinal.directory/submit <- #
#############################################h!
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elM
ements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:40:24+03:00" xmp:ModifyDate="2023-02-03T06:40:24+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:2123933d-1492-b04e-b8c1-af1b6c6fa0b8" xmpMM:DocumentID=M
"adobe:docid:photoshop:a86a9f28-8a98-7241-a0f5-81290e93c2f2" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2M
023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:703298d2-9559-e049-9c4b-c86c1fdf2de8" stEvt:when="2023-02-03T06:40:24+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/M
> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:2123933d-1492-b04e-b8c1-af1b6c6fa0b8" stEvt:when="2023-02-03T06:40:24+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:703298d2-9559-e049-9c4b-c86c1fdf2de8" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72M
CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                            M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                             <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036M
, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26M
+03:00" xmp:MetadataDate="2023-02-03T06:39:45+03:00" xmp:ModifyDate="2023-02-03T06:39:45+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:c9e09a4f-a3a2-3c4e-8056-daf7978965a7" xmpMM:DocumentID="adobe:docid:photoshop:fe1a9504-ddfa-3043-8cca-73409949309d" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" M
stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:49f1d22a-4050-8e4c-9e1c-3b46091b904c" stEvt:when="2023-02-03T06:39:45+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:acM
tion="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:c9e09a4f-a3a2-3c4e-8056-daf7978965a7" stEvt:when="2023-02-03T06:39:45+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:49f1d22a-4050-8e4c-9e1c-3b46091b904c" stM
Ref:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                    M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                     <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/M
sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:42:14+03:00" xmp:ModifyDate="2023-02-03T06:42:14+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:2a285d8e-af91-7843-9eb0-13c3ff3d7e77" xmpMM:DocumentID="adobe:docid:photoshop:114882fe-22d3-6040-a7ae-b378e1deead5" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photosM
hop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:08dbc7d2-M
d9f3-fc4e-99d3-82f2b7cf9940" stEvt:when="2023-02-03T06:42:14+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:2a285d8e-af91-7843-9eb0-13c3ff3d7e77" stEvt:when="2023-02-03T06:42:14+03:00" stEvt:softwareAgent="Adobe PhM
otoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:08dbc7d2-d9f3-fc4e-99d3-82f2b7cf9940" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                       M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                  <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://puM
rl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:42:37+03:00" xmp:ModifyDate="2023-02-03T06:42:37+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:ad95f6f8-f0e9-334b-9933-129e37534ce9" xmpMMM
:DocumentID="adobe:docid:photoshop:115c38c6-7a83-8949-967f-dd39db2b9693" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" sM
tEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:967396ea-3204-c64c-aa3b-d24c47b61a89" stEvt:when="2023-02-03T06:42:37+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to M
image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:ad95f6f8-f0e9-334b-9933-129e37534ce9" stEvt:when="2023-02-03T06:42:37+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:967396ea-3204-c64c-aa3b-d24c47b61a89" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:BagM
> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                         <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-PackardM
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.M
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlM
ns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:40:09+03:00" xmp:ModifyDate="2023-02-03T06:40:09+03:00" dc:format="image/jpeg" xmpMM:InstanM
ceID="xmp.iid:1a30e2b8-7d9b-0841-adc8-10c52a07a582" xmpMM:DocumentID="adobe:docid:photoshop:ee195b12-b90c-204f-bc07-e7b21a7c4d7d" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:inM
stanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:8f12ea3d-f6f6-3c40-9e19-d92fe2ee1bba" stEvt:when="2023-02-03T06:40:09+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:paramM
eters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:1a30e2b8-7d9b-0841-adc8-10c52a07a582" stEvt:when="2023-02-03T06:40:09+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:8f12ea3d-f6f6-3c40-9e19-d92fe2ee1bba" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-acM
05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                       M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                  <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adM
obe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:39:58+03:00" xmp:ModifyDate="2023-02-03T06:39:58+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:24dfa88b-3169-4949-98d4-e83bc4914377" xmpMM:DocumentID="adobe:docid:photoshop:90ad8cde-dfce-3e44-8663-ecaaf25bcbe5" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:HistorM
y> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:5789b27e-df10-bb4b-958b-a123971e56bb" stEvt:when="2023-02-M
03T06:39:58+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:24dfa88b-3169-4949-98d4-e83bc4914377" stEvt:when="2023-02-03T06:39:58+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdfM
:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:5789b27e-df10-bb4b-958b-a123971e56bb" stRef:documentID="adobe:docid:photoshop:3eda5629-51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                 <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour space - sRGB
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
Adobe Photoshop 21.0 (Windows)
cropWhenPrintingbool
http://ns.adobe.com/xap/1.0/
" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c148 79.164036, 2019/08/13-01:06:57        "> <rdf:RDF xmlns:M
rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmp:CreatorTool="Adobe Photoshop 21.0 (Windows)" xmp:CreateDate="2023-01-31T19:01:26+03:00" xmp:MetadataDate="2023-02-03T06:41:13+0M
3:00" xmp:ModifyDate="2023-02-03T06:41:13+03:00" dc:format="image/jpeg" xmpMM:InstanceID="xmp.iid:d5e466fc-49f2-6548-abb5-9d3996892f57" xmpMM:DocumentID="adobe:docid:photoshop:6cd5ae32-a44c-6d4b-83a4-0bcc36d3818c" xmpMM:OriginalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="created" stEvt:instanceID="xmp.iid:8653de18-59b9-7643-ac05-7a8bf5110288" stEvt:when="2023-01-31T19:01:26+03:00" stEvt:soM
ftwareAgent="Adobe Photoshop 21.0 (Windows)"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:3be4a496-9a2e-5b43-b9e4-aa2e09192e28" stEvt:when="2023-01-31T21:56:39+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:815468ae-7084-5b49-b30b-518083629483" stEvt:when="2023-02-03T06:41:13+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from applicaM
tion/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/jpeg"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:d5e466fc-49f2-6548-abb5-9d3996892f57" stEvt:when="2023-02-03T06:41:13+03:00" stEvt:softwareAgent="Adobe Photoshop 21.0 (Windows)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:815468ae-7084-5b49-b30b-518083629483" stRef:documentID="adobe:docid:photoshop:3eda5629-M
51f1-de48-8662-170ca4a0cd94" stRef:originalDocumentID="xmp.did:8653de18-59b9-7643-ac05-7a8bf5110288"/> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>72CD41DEE1DA26104D97BB46D1E733F2</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                   M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        M
                                                                                                                                                                                                                                                      <?xpacket end="w"?>
Copyright (c) 1998 Hewlett-Packard Company
IEC http://www.iec.ch
IEC http://www.iec.ch
.IEC 61966-2.1 Default RGB colour spacM
.IEC 61966-2.1 Default RGB colour space - sRGB
,Reference Viewing Condition in IEC61966-2.1
,Reference Viewing Condition in IEC61966-2.1
6j4ion:2.QmSfiXBHE2WetDMpKmrxfBFLWAG3bmruVRW8SmsQeVbpWYZF
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
/ViaBTC/Mined by hashcloud/,
**************************************************
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
I=5L<,L@>UG5UIAW;.X/
c/Foundry USA Pool #dropgold/
Mined by AntPool960J
6j4ion:3.QmNNZiYAdMPtadhME8JqEHKc5nNJfPjWxdZn28uRY64f2vq/
 584c631b1bdb70775b6ffd56653428c8H0E
 8686c0d1d13b60f308178ba8bb3eaf34H0E
 203c6da29c7649e5faea624a1aa0ea92H0E
c/Foundry USA Pool #dropgold/
7j5+:BTC.BTC:thor1h8txnahwctgw96ryl3ahlwk27f7a0gpz225st2I
4j2DC-L5:i86rV/UdWykSV3X+9Xjyz91wpdJyrc+9+T4VdSEw2Qg=
FjDOUT:15CB61C6180E0BF7EB0489A98CF70DEBFAA6187828D539D2B89A94E2CA8F5B62
Bj@=:ETH.ETH:0x5BE75Eb25fd73adD2696BF8Db3Cd25e83388FBb3:782207:te:0
Bj@=:BNB.BNB:bnb16qnuncx9p79c2dpylmqpjzjqsyn3du3wpuq0hk:617090:te:0
EjC=:BNB.BNB:bnb1rjf4z8wnzz6p2ahxl7azhluhtrf62dx88mqtkp:141978589:te:0
c/Foundry USA Pool #dropgold/
FjDOUT:BB19409EE48BE060BF5A6AF12BCA71302BBBA6A5277B32BC00DE072676DF6CE1
FjDOUT:8321CA108AA1AE8E03AF5E6CAF647B251CBE2EA70D85B46CCD4FF6DBA75B04AB
FjDOUT:7C20ED9EDD090AF18A8B7913853679D5C1F5869772F39AF99CDAF9924E15D304
FjDOUT:27959554207220531846022250D4E4FF8579BF1415B348C5BC786895F3568C6A
FjDOUT:A0C8C80E18C4FB68A3DB574A36C9BA00E890416F4B9ECC8C54D4D0D3431857A1
FjDOUT:134C324E9C5E7EBB6E27AF5ABA35E3B3A3BFFA43D9A67A67C664BDEF59A96A61
c/Foundry USA Pool #dropgold/!

blk00000.txt blk00001.txt blk00002.txt blk00003.txt blk00004.txt blk00005.txt blk00006.txt blk00007.txt blk00008.txt blk00009.txt blk00010.txt blk00011.txt blk00012.txt blk00013.txt blk00014.txt blk00015.txt blk00016.txt blk00017.txt blk00018.txt blk00019.txt blk00020.txt blk00021.txt blk00022.txt blk00023.txt blk00024.txt blk00025.txt blk00026.txt blk00027.txt blk00028.txt blk00029.txt blk00030.txt blk00031.txt blk00032.txt blk00033.txt blk00034.txt blk00035.txt blk00036.txt blk00037.txt blk00038.txt blk00039.txt blk00040.txt blk00041.txt blk00042.txt blk00043.txt blk00044.txt blk00045.txt blk00046.txt blk00047.txt blk00048.txt blk00049.txt blk00050.txt blk00051.txt blk00052.txt blk00053.txt blk00054.txt blk00055.txt blk00056.txt blk00057.txt blk00058.txt blk00059.txt blk00060.txt blk00061.txt blk00062.txt blk00063.txt blk00064.txt blk00065.txt blk00066.txt blk00067.txt blk00068.txt blk00069.txt blk00070.txt blk00071.txt blk00072.txt blk00073.txt blk00074.txt blk00075.txt blk00076.txt blk00077.txt blk00078.txt blk00079.txt blk00080.txt blk00081.txt blk00082.txt blk00083.txt blk00084.txt blk00085.txt blk00086.txt blk00087.txt blk00088.txt blk00089.txt blk00090.txt blk00091.txt blk00092.txt blk00093.txt blk00094.txt blk00095.txt blk00096.txt blk00097.txt blk00098.txt blk00099.txt blk00100.txt blk00101.txt blk00102.txt blk00103.txt blk00104.txt blk00105.txt blk00106.txt blk00107.txt blk00108.txt blk00109.txt blk00110.txt blk00111.txt blk00112.txt blk00113.txt blk00114.txt blk00115.txt blk00116.txt blk00117.txt blk00118.txt blk00119.txt blk00120.txt blk00121.txt blk00122.txt blk00123.txt blk00124.txt blk00125.txt blk00126.txt blk00127.txt blk00128.txt blk00129.txt blk00130.txt blk00131.txt blk00132.txt blk00133.txt blk00134.txt blk00135.txt blk00136.txt blk00137.txt blk00138.txt blk00139.txt blk00140.txt blk00141.txt blk00142.txt blk00143.txt blk00144.txt blk00145.txt blk00146.txt blk00147.txt blk00148.txt blk00149.txt blk00150.txt blk00151.txt blk00152.txt blk00153.txt blk00154.txt blk00155.txt blk00156.txt blk00157.txt blk00158.txt blk00159.txt blk00160.txt blk00161.txt blk00162.txt blk00163.txt blk00164.txt blk00165.txt blk00166.txt blk00167.txt blk00168.txt blk00169.txt blk00170.txt blk00171.txt blk00172.txt blk00173.txt blk00174.txt blk00175.txt blk00176.txt blk00177.txt blk00178.txt blk00179.txt blk00180.txt blk00181.txt blk00182.txt blk00183.txt blk00184.txt blk00185.txt blk00186.txt blk00187.txt blk00188.txt blk00189.txt blk00190.txt blk00191.txt blk00192.txt blk00193.txt blk00194.txt blk00195.txt blk00196.txt blk00197.txt blk00198.txt blk00199.txt blk00200.txt blk00201.txt blk00202.txt blk00203.txt blk00204.txt blk00205.txt blk00206.txt blk00207.txt blk00208.txt blk00209.txt blk00210.txt blk00211.txt blk00212.txt blk00213.txt blk00214.txt blk00215.txt blk00216.txt blk00217.txt blk00218.txt blk00219.txt blk00220.txt blk00221.txt blk00222.txt blk00223.txt blk00224.txt blk00225.txt blk00226.txt blk00227.txt blk00228.txt blk00229.txt blk00230.txt blk00231.txt blk00232.txt blk00233.txt blk00234.txt blk00235.txt blk00236.txt blk00237.txt blk00238.txt blk00239.txt blk00240.txt blk00241.txt blk00242.txt blk00243.txt blk00244.txt blk00245.txt blk00246.txt blk00247.txt blk00248.txt blk00249.txt blk00250.txt blk00251.txt blk00252.txt blk00253.txt blk00254.txt blk00255.txt blk00256.txt blk00257.txt blk00258.txt blk00259.txt blk00260.txt blk00261.txt blk00262.txt blk00263.txt blk00264.txt blk00265.txt blk00266.txt blk00267.txt blk00268.txt blk00269.txt blk00270.txt blk00271.txt blk00272.txt blk00273.txt blk00274.txt blk00275.txt blk00276.txt blk00277.txt blk00278.txt blk00279.txt blk00280.txt blk00281.txt blk00282.txt blk00283.txt blk00284.txt blk00285.txt blk00286.txt blk00287.txt blk00288.txt blk00289.txt blk00290.txt blk00291.txt blk00292.txt blk00293.txt blk00294.txt blk00295.txt blk00296.txt blk00297.txt blk00298.txt blk00299.txt blk00300.txt blk00301.txt blk00302.txt blk00303.txt blk00304.txt blk00305.txt blk00306.txt blk00307.txt blk00308.txt blk00309.txt blk00310.txt blk00311.txt blk00312.txt blk00313.txt blk00314.txt blk00315.txt blk00316.txt blk00317.txt blk00318.txt blk00319.txt blk00320.txt blk00321.txt blk00322.txt blk00323.txt blk00324.txt blk00325.txt blk00326.txt blk00327.txt blk00328.txt blk00329.txt blk00330.txt blk00331.txt blk00332.txt blk00333.txt blk00334.txt blk00335.txt blk00336.txt blk00337.txt blk00338.txt blk00339.txt blk00340.txt blk00341.txt blk00342.txt blk00343.txt blk00344.txt blk00345.txt blk00346.txt blk00347.txt blk00348.txt blk00349.txt blk00350.txt blk00351.txt blk00352.txt blk00353.txt blk00354.txt blk00355.txt blk00356.txt blk00357.txt blk00358.txt blk00359.txt blk00360.txt blk00361.txt blk00362.txt blk00363.txt blk00364.txt blk00365.txt blk00366.txt blk00367.txt blk00368.txt blk00369.txt blk00370.txt blk00371.txt blk00372.txt blk00373.txt blk00374.txt blk00375.txt blk00376.txt blk00377.txt blk00378.txt blk00379.txt blk00380.txt blk00381.txt blk00382.txt blk00383.txt blk00384.txt blk00385.txt blk00386.txt blk00387.txt blk00388.txt blk00389.txt blk00390.txt blk00391.txt blk00392.txt blk00393.txt blk00394.txt blk00395.txt blk00396.txt blk00397.txt blk00398.txt blk00399.txt blk00400.txt blk00401.txt blk00402.txt blk00403.txt blk00404.txt blk00405.txt blk00406.txt blk00407.txt blk00408.txt blk00409.txt blk00410.txt blk00411.txt blk00412.txt blk00413.txt blk00414.txt blk00415.txt blk00416.txt blk00417.txt blk00418.txt blk00419.txt blk00420.txt blk00421.txt blk00422.txt blk00423.txt blk00424.txt blk00425.txt blk00426.txt blk00427.txt blk00428.txt blk00429.txt blk00430.txt blk00431.txt blk00432.txt blk00433.txt blk00434.txt blk00435.txt blk00436.txt blk00437.txt blk00438.txt blk00439.txt blk00440.txt blk00441.txt blk00442.txt blk00443.txt blk00444.txt blk00445.txt blk00446.txt blk00447.txt blk00448.txt blk00449.txt blk00450.txt blk00451.txt blk00452.txt blk00453.txt blk00454.txt blk00455.txt blk00456.txt blk00457.txt blk00458.txt blk00459.txt blk00460.txt blk00461.txt blk00462.txt blk00463.txt blk00464.txt blk00465.txt blk00466.txt blk00467.txt blk00468.txt blk00469.txt blk00470.txt blk00471.txt blk00472.txt blk00473.txt blk00474.txt blk00475.txt blk00476.txt blk00477.txt blk00478.txt blk00479.txt blk00480.txt blk00481.txt blk00482.txt blk00483.txt blk00484.txt blk00485.txt blk00486.txt blk00487.txt blk00488.txt blk00489.txt blk00490.txt blk00491.txt blk00492.txt blk00493.txt blk00494.txt blk00495.txt blk00496.txt blk00497.txt blk00498.txt blk00499.txt blk00500.txt blk00501.txt blk00502.txt blk00503.txt blk00504.txt blk00505.txt blk00506.txt blk00507.txt blk00508.txt blk00509.txt blk00510.txt blk00511.txt blk00512.txt blk00513.txt blk00514.txt blk00515.txt blk00516.txt blk00517.txt blk00518.txt blk00519.txt blk00520.txt blk00521.txt blk00522.txt blk00523.txt blk00524.txt blk00525.txt blk00526.txt blk00527.txt blk00528.txt blk00529.txt blk00530.txt blk00531.txt blk00532.txt blk00533.txt blk00534.txt blk00535.txt blk00536.txt blk00537.txt blk00538.txt blk00539.txt blk00540.txt blk00541.txt blk00542.txt blk00543.txt blk00544.txt blk00545.txt blk00546.txt blk00547.txt blk00548.txt blk00549.txt blk00550.txt blk00551.txt blk00552.txt blk00553.txt blk00554.txt blk00555.txt blk00556.txt blk00557.txt blk00558.txt blk00559.txt blk00560.txt blk00561.txt blk00562.txt blk00563.txt blk00564.txt blk00565.txt blk00566.txt blk00567.txt blk00568.txt blk00569.txt blk00570.txt blk00571.txt blk00572.txt blk00573.txt blk00574.txt blk00575.txt blk00576.txt blk00577.txt blk00578.txt blk00579.txt blk00580.txt blk00581.txt blk00582.txt blk00583.txt blk00584.txt blk00585.txt blk00586.txt blk00587.txt blk00588.txt blk00589.txt blk00590.txt blk00591.txt blk00592.txt blk00593.txt blk00594.txt blk00595.txt blk00596.txt blk00597.txt blk00598.txt blk00599.txt blk00600.txt blk00601.txt blk00602.txt blk00603.txt blk00604.txt blk00605.txt blk00606.txt blk00607.txt blk00608.txt blk00609.txt blk00610.txt blk00611.txt blk00612.txt blk00613.txt blk00614.txt blk00615.txt blk00616.txt blk00617.txt blk00618.txt blk00619.txt blk00620.txt blk00621.txt blk00622.txt blk00623.txt blk00624.txt blk00625.txt blk00626.txt blk00627.txt blk00628.txt blk00629.txt blk00630.txt blk00631.txt blk00632.txt blk00633.txt blk00634.txt blk00635.txt blk00636.txt blk00637.txt blk00638.txt blk00639.txt blk00640.txt blk00641.txt blk00642.txt blk00643.txt blk00644.txt blk00645.txt blk00646.txt blk00647.txt blk00648.txt blk00649.txt blk00650.txt blk00651.txt blk00652.txt blk00653.txt blk00654.txt blk00655.txt blk00656.txt blk00657.txt blk00658.txt blk00659.txt blk00660.txt blk00661.txt blk00662.txt blk00663.txt blk00664.txt blk00665.txt blk00666.txt blk00667.txt blk00668.txt blk00669.txt blk00670.txt blk00671.txt blk00672.txt blk00673.txt blk00674.txt blk00675.txt blk00676.txt blk00677.txt blk00678.txt blk00679.txt blk00680.txt blk00681.txt blk00682.txt blk00683.txt blk00684.txt blk00685.txt blk00686.txt blk00687.txt blk00688.txt blk00689.txt blk00690.txt blk00691.txt blk00692.txt blk00693.txt blk00694.txt blk00695.txt blk00696.txt blk00697.txt blk00698.txt blk00699.txt blk00700.txt blk00701.txt blk00702.txt blk00703.txt blk00704.txt blk00705.txt blk00706.txt blk00707.txt blk00708.txt blk00709.txt blk00710.txt blk00711.txt blk00712.txt blk00713.txt blk00714.txt blk00715.txt blk00716.txt blk00717.txt blk00718.txt blk00719.txt blk00720.txt blk00721.txt blk00722.txt blk00723.txt blk00724.txt blk00725.txt blk00726.txt blk00727.txt blk00728.txt blk00729.txt blk00730.txt blk00731.txt blk00732.txt blk00733.txt blk00734.txt blk00735.txt blk00736.txt blk00737.txt blk00738.txt blk00739.txt blk00740.txt blk00741.txt blk00742.txt blk00743.txt blk00744.txt blk00745.txt blk00746.txt blk00747.txt blk00748.txt blk00749.txt blk00750.txt blk00751.txt blk00752.txt blk00753.txt blk00754.txt blk00755.txt blk00756.txt blk00757.txt blk00758.txt blk00759.txt blk00760.txt blk00761.txt blk00762.txt blk00763.txt blk00764.txt blk00765.txt blk00766.txt blk00767.txt blk00768.txt blk00769.txt blk00770.txt blk00771.txt blk00772.txt blk00773.txt blk00774.txt blk00775.txt blk00776.txt blk00777.txt blk00778.txt blk00779.txt blk00780.txt blk00781.txt blk00782.txt blk00783.txt blk00784.txt blk00785.txt blk00786.txt blk00787.txt blk00788.txt blk00789.txt blk00790.txt blk00791.txt blk00792.txt blk00793.txt blk00794.txt blk00795.txt blk00796.txt blk00797.txt blk00798.txt blk00799.txt blk00800.txt blk00801.txt blk00802.txt blk00803.txt blk00804.txt blk00805.txt blk00806.txt blk00807.txt blk00808.txt blk00809.txt blk00810.txt blk00811.txt blk00812.txt blk00813.txt blk00814.txt blk00815.txt blk00816.txt blk00817.txt blk00818.txt blk00819.txt blk00820.txt blk00821.txt blk00822.txt blk00823.txt blk00824.txt blk00825.txt blk00826.txt blk00827.txt blk00828.txt blk00829.txt blk00830.txt blk00831.txt blk00832.txt blk00833.txt blk00834.txt blk00835.txt blk00836.txt blk00837.txt blk00838.txt blk00839.txt blk00840.txt blk00841.txt blk00842.txt blk00843.txt blk00844.txt blk00845.txt blk00846.txt blk00847.txt blk00848.txt blk00849.txt blk00850.txt blk00851.txt blk00852.txt blk00853.txt blk00854.txt blk00855.txt blk00856.txt blk00857.txt blk00858.txt blk00859.txt blk00860.txt blk00861.txt blk00862.txt blk00863.txt blk00864.txt blk00865.txt blk00866.txt blk00867.txt blk00868.txt blk00869.txt blk00870.txt blk00871.txt blk00872.txt blk00873.txt blk00874.txt blk00875.txt blk00876.txt blk00877.txt blk00878.txt blk00879.txt blk00880.txt blk00881.txt blk00882.txt blk00883.txt blk00884.txt blk00885.txt blk00886.txt blk00887.txt blk00888.txt blk00889.txt blk00890.txt blk00891.txt blk00892.txt blk00893.txt blk00894.txt blk00895.txt blk00896.txt blk00897.txt blk00898.txt blk00899.txt blk00900.txt blk00901.txt blk00902.txt blk00903.txt blk00904.txt blk00905.txt blk00906.txt blk00907.txt blk00908.txt blk00909.txt blk00910.txt blk00911.txt blk00912.txt blk00913.txt blk00914.txt blk00915.txt blk00916.txt blk00917.txt blk00918.txt blk00919.txt blk00920.txt blk00921.txt blk00922.txt blk00923.txt blk00924.txt blk00925.txt blk00926.txt blk00927.txt blk00928.txt blk00929.txt blk00930.txt blk00931.txt blk00932.txt blk00933.txt blk00934.txt blk00935.txt blk00936.txt blk00937.txt blk00938.txt blk00939.txt blk00940.txt blk00941.txt blk00942.txt blk00943.txt blk00944.txt blk00945.txt blk00946.txt blk00947.txt blk00948.txt blk00949.txt blk00950.txt blk00951.txt blk00952.txt blk00953.txt blk00954.txt blk00955.txt blk00956.txt blk00957.txt blk00958.txt blk00959.txt blk00960.txt blk00961.txt blk00962.txt blk00963.txt blk00964.txt blk00965.txt blk00966.txt blk00967.txt blk00968.txt blk00969.txt blk00970.txt blk00971.txt blk00972.txt blk00973.txt blk00974.txt blk00975.txt blk00976.txt blk00977.txt blk00978.txt blk00979.txt blk00980.txt blk00981.txt blk00982.txt blk00983.txt blk00984.txt blk00985.txt blk00986.txt blk00987.txt blk00988.txt blk00989.txt blk00990.txt blk00991.txt blk00992.txt blk00993.txt blk00994.txt blk00995.txt blk00996.txt blk00997.txt blk00998.txt blk00999.txt blk01000.txt blk01001.txt blk01002.txt blk01003.txt blk01004.txt blk01005.txt blk01006.txt blk01007.txt blk01008.txt blk01009.txt blk01010.txt blk01011.txt blk01012.txt blk01013.txt blk01014.txt blk01015.txt blk01016.txt blk01017.txt blk01018.txt blk01019.txt blk01020.txt blk01021.txt blk01022.txt blk01023.txt blk01024.txt blk01025.txt blk01026.txt blk01027.txt blk01028.txt blk01029.txt blk01030.txt blk01031.txt blk01032.txt blk01033.txt blk01034.txt blk01035.txt blk01036.txt blk01037.txt blk01038.txt blk01039.txt blk01040.txt blk01041.txt blk01042.txt blk01043.txt blk01044.txt blk01045.txt blk01046.txt blk01047.txt blk01048.txt blk01049.txt blk01050.txt blk01051.txt blk01052.txt blk01053.txt blk01054.txt blk01055.txt blk01056.txt blk01057.txt blk01058.txt blk01059.txt blk01060.txt blk01061.txt blk01062.txt blk01063.txt blk01064.txt blk01065.txt blk01066.txt blk01067.txt blk01068.txt blk01069.txt blk01070.txt blk01071.txt blk01072.txt blk01073.txt blk01074.txt blk01075.txt blk01076.txt blk01077.txt blk01078.txt blk01079.txt blk01080.txt blk01081.txt blk01082.txt blk01083.txt blk01084.txt blk01085.txt blk01086.txt blk01087.txt blk01088.txt blk01089.txt blk01090.txt blk01091.txt blk01092.txt blk01093.txt blk01094.txt blk01095.txt blk01096.txt blk01097.txt blk01098.txt blk01099.txt blk01100.txt blk01101.txt blk01102.txt blk01103.txt blk01104.txt blk01105.txt blk01106.txt blk01107.txt blk01108.txt blk01109.txt blk01110.txt blk01111.txt blk01112.txt blk01113.txt blk01114.txt blk01115.txt blk01116.txt blk01117.txt blk01118.txt blk01119.txt blk01120.txt blk01121.txt blk01122.txt blk01123.txt blk01124.txt blk01125.txt blk01126.txt blk01127.txt blk01128.txt blk01129.txt blk01130.txt blk01131.txt blk01132.txt blk01133.txt blk01134.txt blk01135.txt blk01136.txt blk01137.txt blk01138.txt blk01139.txt blk01140.txt blk01141.txt blk01142.txt blk01143.txt blk01144.txt blk01145.txt blk01146.txt blk01147.txt blk01148.txt blk01149.txt blk01150.txt blk01151.txt blk01152.txt blk01153.txt blk01154.txt blk01155.txt blk01156.txt blk01157.txt blk01158.txt blk01159.txt blk01160.txt blk01161.txt blk01162.txt blk01163.txt blk01164.txt blk01165.txt blk01166.txt blk01167.txt blk01168.txt blk01169.txt blk01170.txt blk01171.txt blk01172.txt blk01173.txt blk01174.txt blk01175.txt blk01176.txt blk01177.txt blk01178.txt blk01179.txt blk01180.txt blk01181.txt blk01182.txt blk01183.txt blk01184.txt blk01185.txt blk01186.txt blk01187.txt blk01188.txt blk01189.txt blk01190.txt blk01191.txt blk01192.txt blk01193.txt blk01194.txt blk01195.txt blk01196.txt blk01197.txt blk01198.txt blk01199.txt blk01200.txt blk01201.txt blk01202.txt blk01203.txt blk01204.txt blk01205.txt blk01206.txt blk01207.txt blk01208.txt blk01209.txt blk01210.txt blk01211.txt blk01212.txt blk01213.txt blk01214.txt blk01215.txt blk01216.txt blk01217.txt blk01218.txt blk01219.txt blk01220.txt blk01221.txt blk01222.txt blk01223.txt blk01224.txt blk01225.txt blk01226.txt blk01227.txt blk01228.txt blk01229.txt blk01230.txt blk01231.txt blk01232.txt blk01233.txt blk01234.txt blk01235.txt blk01236.txt blk01237.txt blk01238.txt blk01239.txt blk01240.txt blk01241.txt blk01242.txt blk01243.txt blk01244.txt blk01245.txt blk01246.txt blk01247.txt blk01248.txt blk01249.txt blk01250.txt blk01251.txt blk01252.txt blk01253.txt blk01254.txt blk01255.txt blk01256.txt blk01257.txt blk01258.txt blk01259.txt blk01260.txt blk01261.txt blk01262.txt blk01263.txt blk01264.txt blk01265.txt blk01266.txt blk01267.txt blk01268.txt blk01269.txt blk01270.txt blk01271.txt blk01272.txt blk01273.txt blk01274.txt blk01275.txt blk01276.txt blk01277.txt blk01278.txt blk01279.txt blk01280.txt blk01281.txt blk01282.txt blk01283.txt blk01284.txt blk01285.txt blk01286.txt blk01287.txt blk01288.txt blk01289.txt blk01290.txt blk01291.txt blk01292.txt blk01293.txt blk01294.txt blk01295.txt blk01296.txt blk01297.txt blk01298.txt blk01299.txt blk01300.txt blk01301.txt blk01302.txt blk01303.txt blk01304.txt blk01305.txt blk01306.txt blk01307.txt blk01308.txt blk01309.txt blk01310.txt blk01311.txt blk01312.txt blk01313.txt blk01314.txt blk01315.txt blk01316.txt blk01317.txt blk01318.txt blk01319.txt blk01320.txt blk01321.txt blk01322.txt blk01323.txt blk01324.txt blk01325.txt blk01326.txt blk01327.txt blk01328.txt blk01329.txt blk01330.txt blk01331.txt blk01332.txt blk01333.txt blk01334.txt blk01335.txt blk01336.txt blk01337.txt blk01338.txt blk01339.txt blk01340.txt blk01341.txt blk01342.txt blk01343.txt blk01344.txt blk01345.txt blk01346.txt blk01347.txt blk01348.txt blk01349.txt blk01350.txt blk01351.txt blk01352.txt blk01353.txt blk01354.txt blk01355.txt blk01356.txt blk01357.txt blk01358.txt blk01359.txt blk01360.txt blk01361.txt blk01362.txt blk01363.txt blk01364.txt blk01365.txt blk01366.txt blk01367.txt blk01368.txt blk01369.txt blk01370.txt blk01371.txt blk01372.txt blk01373.txt blk01374.txt blk01375.txt blk01376.txt blk01377.txt blk01378.txt blk01379.txt blk01380.txt blk01381.txt blk01382.txt blk01383.txt blk01384.txt blk01385.txt blk01386.txt blk01387.txt blk01388.txt blk01389.txt blk01390.txt blk01391.txt blk01392.txt blk01393.txt blk01394.txt blk01395.txt blk01396.txt blk01397.txt blk01398.txt blk01399.txt blk01400.txt blk01401.txt blk01402.txt blk01403.txt blk01404.txt blk01405.txt blk01406.txt blk01407.txt blk01408.txt blk01409.txt blk01410.txt blk01411.txt blk01412.txt blk01413.txt blk01414.txt blk01415.txt blk01416.txt blk01417.txt blk01418.txt blk01419.txt blk01420.txt blk01421.txt blk01422.txt blk01423.txt blk01424.txt blk01425.txt blk01426.txt blk01427.txt blk01428.txt blk01429.txt blk01430.txt blk01431.txt blk01432.txt blk01433.txt blk01434.txt blk01435.txt blk01436.txt blk01437.txt blk01438.txt blk01439.txt blk01440.txt blk01441.txt blk01442.txt blk01443.txt blk01444.txt blk01445.txt blk01446.txt blk01447.txt blk01448.txt blk01449.txt blk01450.txt blk01451.txt blk01452.txt blk01453.txt blk01454.txt blk01455.txt blk01456.txt blk01457.txt blk01458.txt blk01459.txt blk01460.txt blk01461.txt blk01462.txt blk01463.txt blk01464.txt blk01465.txt blk01466.txt blk01467.txt blk01468.txt blk01469.txt blk01470.txt blk01471.txt blk01472.txt blk01473.txt blk01474.txt blk01475.txt blk01476.txt blk01477.txt blk01478.txt blk01479.txt blk01480.txt blk01481.txt blk01482.txt blk01483.txt blk01484.txt blk01485.txt blk01486.txt blk01487.txt blk01488.txt blk01489.txt blk01490.txt blk01491.txt blk01492.txt blk01493.txt blk01494.txt blk01495.txt blk01496.txt blk01497.txt blk01498.txt blk01499.txt blk01500.txt blk01501.txt blk01502.txt blk01503.txt blk01504.txt blk01505.txt blk01506.txt blk01507.txt blk01508.txt blk01509.txt blk01510.txt blk01511.txt blk01512.txt blk01513.txt blk01514.txt blk01515.txt blk01516.txt blk01517.txt blk01518.txt blk01519.txt blk01520.txt blk01521.txt blk01522.txt blk01523.txt blk01524.txt blk01525.txt blk01526.txt blk01527.txt blk01528.txt blk01529.txt blk01530.txt blk01531.txt blk01532.txt blk01533.txt blk01534.txt blk01535.txt blk01536.txt blk01537.txt blk01538.txt blk01539.txt blk01540.txt blk01541.txt blk01542.txt blk01543.txt blk01544.txt blk01545.txt blk01546.txt blk01547.txt blk01548.txt blk01549.txt blk01550.txt blk01551.txt blk01552.txt blk01553.txt blk01554.txt blk01555.txt blk01556.txt blk01557.txt blk01558.txt blk01559.txt blk01560.txt blk01561.txt blk01562.txt blk01563.txt blk01564.txt blk01565.txt blk01566.txt blk01567.txt blk01568.txt blk01569.txt blk01570.txt blk01571.txt blk01572.txt blk01573.txt blk01574.txt blk01575.txt blk01576.txt blk01577.txt blk01578.txt blk01579.txt blk01580.txt blk01581.txt blk01582.txt blk01583.txt blk01584.txt blk01585.txt blk01586.txt blk01587.txt blk01588.txt blk01589.txt blk01590.txt blk01591.txt blk01592.txt blk01593.txt blk01594.txt blk01595.txt blk01596.txt blk01597.txt blk01598.txt blk01599.txt blk01600.txt blk01601.txt blk01602.txt blk01603.txt blk01604.txt blk01605.txt blk01606.txt blk01607.txt blk01608.txt blk01609.txt blk01610.txt blk01611.txt blk01612.txt blk01613.txt blk01614.txt blk01615.txt blk01616.txt blk01617.txt blk01618.txt blk01619.txt blk01620.txt blk01621.txt blk01622.txt blk01623.txt blk01624.txt blk01625.txt blk01626.txt blk01627.txt blk01628.txt blk01629.txt blk01630.txt blk01631.txt blk01632.txt blk01633.txt blk01634.txt blk01635.txt blk01636.txt blk01637.txt blk01638.txt blk01639.txt blk01640.txt blk01641.txt blk01642.txt blk01643.txt blk01644.txt blk01645.txt blk01646.txt blk01647.txt blk01648.txt blk01649.txt blk01650.txt blk01651.txt blk01652.txt blk01653.txt blk01654.txt blk01655.txt blk01656.txt blk01657.txt blk01658.txt blk01659.txt blk01660.txt blk01661.txt blk01662.txt blk01663.txt blk01664.txt blk01665.txt blk01666.txt blk01667.txt blk01668.txt blk01669.txt blk01670.txt blk01671.txt blk01672.txt blk01673.txt blk01674.txt blk01675.txt blk01676.txt blk01677.txt blk01678.txt blk01679.txt blk01680.txt blk01681.txt blk01682.txt blk01683.txt blk01684.txt blk01685.txt blk01686.txt blk01687.txt blk01688.txt blk01689.txt blk01690.txt blk01691.txt blk01692.txt blk01693.txt blk01694.txt blk01695.txt blk01696.txt blk01697.txt blk01698.txt blk01699.txt blk01700.txt blk01701.txt blk01702.txt blk01703.txt blk01704.txt blk01705.txt blk01706.txt blk01707.txt blk01708.txt blk01709.txt blk01710.txt blk01711.txt blk01712.txt blk01713.txt blk01714.txt blk01715.txt blk01716.txt blk01717.txt blk01718.txt blk01719.txt blk01720.txt blk01721.txt blk01722.txt blk01723.txt blk01724.txt blk01725.txt blk01726.txt blk01727.txt blk01728.txt blk01729.txt blk01730.txt blk01731.txt blk01732.txt blk01733.txt blk01734.txt blk01735.txt blk01736.txt blk01737.txt blk01738.txt blk01739.txt blk01740.txt blk01741.txt blk01742.txt blk01743.txt blk01744.txt blk01745.txt blk01746.txt blk01747.txt blk01748.txt blk01749.txt blk01750.txt blk01751.txt blk01752.txt blk01753.txt blk01754.txt blk01755.txt blk01756.txt blk01757.txt blk01758.txt blk01759.txt blk01760.txt blk01761.txt blk01762.txt blk01763.txt blk01764.txt blk01765.txt blk01766.txt blk01767.txt blk01768.txt blk01769.txt blk01770.txt blk01771.txt blk01772.txt blk01773.txt blk01774.txt blk01775.txt blk01776.txt blk01777.txt blk01778.txt blk01779.txt blk01780.txt blk01781.txt blk01782.txt blk01783.txt blk01784.txt blk01785.txt blk01786.txt blk01787.txt blk01788.txt blk01789.txt blk01790.txt blk01791.txt blk01792.txt blk01793.txt blk01794.txt blk01795.txt blk01796.txt blk01797.txt blk01798.txt blk01799.txt blk01800.txt blk01801.txt blk01802.txt blk01803.txt blk01804.txt blk01805.txt blk01806.txt blk01807.txt blk01808.txt blk01809.txt blk01810.txt blk01811.txt blk01812.txt blk01813.txt blk01814.txt blk01815.txt blk01816.txt blk01817.txt blk01818.txt blk01819.txt blk01820.txt blk01821.txt blk01822.txt blk01823.txt blk01824.txt blk01825.txt blk01826.txt blk01827.txt blk01828.txt blk01829.txt blk01830.txt blk01831.txt blk01832.txt blk01833.txt blk01834.txt blk01835.txt blk01836.txt blk01837.txt blk01838.txt blk01839.txt blk01840.txt blk01841.txt blk01842.txt blk01843.txt blk01844.txt blk01845.txt blk01846.txt blk01847.txt blk01848.txt blk01849.txt blk01850.txt blk01851.txt blk01852.txt blk01853.txt blk01854.txt blk01855.txt blk01856.txt blk01857.txt blk01858.txt blk01859.txt blk01860.txt blk01861.txt blk01862.txt blk01863.txt blk01864.txt blk01865.txt blk01866.txt blk01867.txt blk01868.txt blk01869.txt blk01870.txt blk01871.txt blk01872.txt blk01873.txt blk01874.txt blk01875.txt blk01876.txt blk01877.txt blk01878.txt blk01879.txt blk01880.txt blk01881.txt blk01882.txt blk01883.txt blk01884.txt blk01885.txt blk01886.txt blk01887.txt blk01888.txt blk01889.txt blk01890.txt blk01891.txt blk01892.txt blk01893.txt blk01894.txt blk01895.txt blk01896.txt blk01897.txt blk01898.txt blk01899.txt blk01900.txt blk01901.txt blk01902.txt blk01903.txt blk01904.txt blk01905.txt blk01906.txt blk01907.txt blk01908.txt blk01909.txt blk01910.txt blk01911.txt blk01912.txt blk01913.txt blk01914.txt blk01915.txt blk01916.txt blk01917.txt blk01918.txt blk01919.txt blk01920.txt blk01921.txt blk01922.txt blk01923.txt blk01924.txt blk01925.txt blk01926.txt blk01927.txt blk01928.txt blk01929.txt blk01930.txt blk01931.txt blk01932.txt blk01933.txt blk01934.txt blk01935.txt blk01936.txt blk01937.txt blk01938.txt blk01939.txt blk01940.txt blk01941.txt blk01942.txt blk01943.txt blk01944.txt blk01945.txt blk01946.txt blk01947.txt blk01948.txt blk01949.txt blk01950.txt blk01951.txt blk01952.txt blk01953.txt blk01954.txt blk01955.txt blk01956.txt blk01957.txt blk01958.txt blk01959.txt blk01960.txt blk01961.txt blk01962.txt blk01963.txt blk01964.txt blk01965.txt blk01966.txt blk01967.txt blk01968.txt blk01969.txt blk01970.txt blk01971.txt blk01972.txt blk01973.txt blk01974.txt blk01975.txt blk01976.txt blk01977.txt blk01978.txt blk01979.txt blk01980.txt blk01981.txt blk01982.txt blk01983.txt blk01984.txt blk01985.txt blk01986.txt blk01987.txt blk01988.txt blk01989.txt blk01990.txt blk01991.txt blk01992.txt blk01993.txt blk01994.txt blk01995.txt blk01996.txt blk01997.txt blk01998.txt blk01999.txt blk02000.txt blk02001.txt blk02002.txt blk02003.txt blk02004.txt blk02005.txt blk02006.txt blk02007.txt blk02008.txt blk02009.txt blk02010.txt blk02011.txt blk02012.txt blk02013.txt blk02014.txt blk02015.txt blk02016.txt blk02017.txt blk02018.txt blk02019.txt blk02020.txt blk02021.txt blk02022.txt blk02023.txt blk02024.txt blk02025.txt blk02026.txt blk02027.txt blk02028.txt blk02029.txt blk02030.txt blk02031.txt blk02032.txt blk02033.txt blk02034.txt blk02035.txt blk02036.txt blk02037.txt blk02038.txt blk02039.txt blk02040.txt blk02041.txt blk02042.txt blk02043.txt blk02044.txt blk02045.txt blk02046.txt blk02047.txt blk02048.txt blk02049.txt blk02050.txt blk02051.txt blk02052.txt blk02053.txt blk02054.txt blk02055.txt blk02056.txt blk02057.txt blk02058.txt blk02059.txt blk02060.txt blk02061.txt blk02062.txt blk02063.txt blk02064.txt blk02065.txt blk02066.txt blk02067.txt blk02068.txt blk02069.txt blk02070.txt blk02071.txt blk02072.txt blk02073.txt blk02074.txt blk02075.txt blk02076.txt blk02077.txt blk02078.txt blk02079.txt blk02080.txt blk02081.txt blk02082.txt blk02083.txt blk02084.txt blk02085.txt blk02086.txt blk02087.txt blk02088.txt blk02089.txt blk02090.txt blk02091.txt blk02092.txt blk02093.txt blk02094.txt blk02095.txt blk02096.txt blk02097.txt blk02098.txt blk02099.txt blk02100.txt blk02101.txt blk02102.txt blk02103.txt blk02104.txt blk02105.txt blk02106.txt blk02107.txt blk02108.txt blk02109.txt blk02110.txt blk02111.txt blk02112.txt blk02113.txt blk02114.txt blk02115.txt blk02116.txt blk02117.txt blk02118.txt blk02119.txt blk02120.txt blk02121.txt blk02122.txt blk02123.txt blk02124.txt blk02125.txt blk02126.txt blk02127.txt blk02128.txt blk02129.txt blk02130.txt blk02131.txt blk02132.txt blk02133.txt blk02134.txt blk02135.txt blk02136.txt blk02137.txt blk02138.txt blk02139.txt blk02140.txt blk02141.txt blk02142.txt blk02143.txt blk02144.txt blk02145.txt blk02146.txt blk02147.txt blk02148.txt blk02149.txt blk02150.txt blk02151.txt blk02152.txt blk02153.txt blk02154.txt blk02155.txt blk02156.txt blk02157.txt blk02158.txt blk02159.txt blk02160.txt blk02161.txt blk02162.txt blk02163.txt blk02164.txt blk02165.txt blk02166.txt blk02167.txt blk02168.txt blk02169.txt blk02170.txt blk02171.txt blk02172.txt blk02173.txt blk02174.txt blk02175.txt blk02176.txt blk02177.txt blk02178.txt blk02179.txt blk02180.txt blk02181.txt blk02182.txt blk02183.txt blk02184.txt blk02185.txt blk02186.txt blk02187.txt blk02188.txt blk02189.txt blk02190.txt blk02191.txt blk02192.txt blk02193.txt blk02194.txt blk02195.txt blk02196.txt blk02197.txt blk02198.txt blk02199.txt blk02200.txt blk02201.txt blk02202.txt blk02203.txt blk02204.txt blk02205.txt blk02206.txt blk02207.txt blk02208.txt blk02209.txt blk02210.txt blk02211.txt blk02212.txt blk02213.txt blk02214.txt blk02215.txt blk02216.txt blk02217.txt blk02218.txt blk02219.txt blk02220.txt blk02221.txt blk02222.txt blk02223.txt blk02224.txt blk02225.txt blk02226.txt blk02227.txt blk02228.txt blk02229.txt blk02230.txt blk02231.txt blk02232.txt blk02233.txt blk02234.txt blk02235.txt blk02236.txt blk02237.txt blk02238.txt blk02239.txt blk02240.txt blk02241.txt blk02242.txt blk02243.txt blk02244.txt blk02245.txt blk02246.txt blk02247.txt blk02248.txt blk02249.txt blk02250.txt blk02251.txt blk02252.txt blk02253.txt blk02254.txt blk02255.txt blk02256.txt blk02257.txt blk02258.txt blk02259.txt blk02260.txt blk02261.txt blk02262.txt blk02263.txt blk02264.txt blk02265.txt blk02266.txt blk02267.txt blk02268.txt blk02269.txt blk02270.txt blk02271.txt blk02272.txt blk02273.txt blk02274.txt blk02275.txt blk02276.txt blk02277.txt blk02278.txt blk02279.txt blk02280.txt blk02281.txt blk02282.txt blk02283.txt blk02284.txt blk02285.txt blk02286.txt blk02287.txt blk02288.txt blk02289.txt blk02290.txt blk02291.txt blk02292.txt blk02293.txt blk02294.txt blk02295.txt blk02296.txt blk02297.txt blk02298.txt blk02299.txt blk02300.txt blk02301.txt blk02302.txt blk02303.txt blk02304.txt blk02305.txt blk02306.txt blk02307.txt blk02308.txt blk02309.txt blk02310.txt blk02311.txt blk02312.txt blk02313.txt blk02314.txt blk02315.txt blk02316.txt blk02317.txt blk02318.txt blk02319.txt blk02320.txt blk02321.txt blk02322.txt blk02323.txt blk02324.txt blk02325.txt blk02326.txt blk02327.txt blk02328.txt blk02329.txt blk02330.txt blk02331.txt blk02332.txt blk02333.txt blk02334.txt blk02335.txt blk02336.txt blk02337.txt blk02338.txt blk02339.txt blk02340.txt blk02341.txt blk02342.txt blk02343.txt blk02344.txt blk02345.txt blk02346.txt blk02347.txt blk02348.txt blk02349.txt blk02350.txt blk02351.txt blk02352.txt blk02353.txt blk02354.txt blk02355.txt blk02356.txt blk02357.txt blk02358.txt blk02359.txt blk02360.txt blk02361.txt blk02362.txt blk02363.txt blk02364.txt blk02365.txt blk02366.txt blk02367.txt blk02368.txt blk02369.txt blk02370.txt blk02371.txt blk02372.txt blk02373.txt blk02374.txt blk02375.txt blk02376.txt blk02377.txt blk02378.txt blk02379.txt blk02380.txt blk02381.txt blk02382.txt blk02383.txt blk02384.txt blk02385.txt blk02386.txt blk02387.txt blk02388.txt blk02389.txt blk02390.txt blk02391.txt blk02392.txt blk02393.txt blk02394.txt blk02395.txt blk02396.txt blk02397.txt blk02398.txt blk02399.txt blk02400.txt blk02401.txt blk02402.txt blk02403.txt blk02404.txt blk02405.txt blk02406.txt blk02407.txt blk02408.txt blk02409.txt blk02410.txt blk02411.txt blk02412.txt blk02413.txt blk02414.txt blk02415.txt blk02416.txt blk02417.txt blk02418.txt blk02419.txt blk02420.txt blk02421.txt blk02422.txt blk02423.txt blk02424.txt blk02425.txt blk02426.txt blk02427.txt blk02428.txt blk02429.txt blk02430.txt blk02431.txt blk02432.txt blk02433.txt blk02434.txt blk02435.txt blk02436.txt blk02437.txt blk02438.txt blk02439.txt blk02440.txt blk02441.txt blk02442.txt blk02443.txt blk02444.txt blk02445.txt blk02446.txt blk02447.txt blk02448.txt blk02449.txt blk02450.txt blk02451.txt blk02452.txt blk02453.txt blk02454.txt blk02455.txt blk02456.txt blk02457.txt blk02458.txt blk02459.txt blk02460.txt blk02461.txt blk02462.txt blk02463.txt blk02464.txt blk02465.txt blk02466.txt blk02467.txt blk02468.txt blk02469.txt blk02470.txt blk02471.txt blk02472.txt blk02473.txt blk02474.txt blk02475.txt blk02476.txt blk02477.txt blk02478.txt blk02479.txt blk02480.txt blk02481.txt blk02482.txt blk02483.txt blk02484.txt blk02485.txt blk02486.txt blk02487.txt blk02488.txt blk02489.txt blk02490.txt blk02491.txt blk02492.txt blk02493.txt blk02494.txt blk02495.txt blk02496.txt blk02497.txt blk02498.txt blk02499.txt blk02500.txt blk02501.txt blk02502.txt blk02503.txt blk02504.txt blk02505.txt blk02506.txt blk02507.txt blk02508.txt blk02509.txt blk02510.txt blk02511.txt blk02512.txt blk02513.txt blk02514.txt blk02515.txt blk02516.txt blk02517.txt blk02518.txt blk02519.txt blk02520.txt blk02521.txt blk02522.txt blk02523.txt blk02524.txt blk02525.txt blk02526.txt blk02527.txt blk02528.txt blk02529.txt blk02530.txt blk02531.txt blk02532.txt blk02533.txt blk02534.txt blk02535.txt blk02536.txt blk02537.txt blk02538.txt blk02539.txt blk02540.txt blk02541.txt blk02542.txt blk02543.txt blk02544.txt blk02545.txt blk02546.txt blk02547.txt blk02548.txt blk02549.txt blk02550.txt blk02551.txt blk02552.txt blk02553.txt blk02554.txt blk02555.txt blk02556.txt blk02557.txt blk02558.txt blk02559.txt blk02560.txt blk02561.txt blk02562.txt blk02563.txt blk02564.txt blk02565.txt blk02566.txt blk02567.txt blk02568.txt blk02569.txt blk02570.txt blk02571.txt blk02572.txt blk02573.txt blk02574.txt blk02575.txt blk02576.txt blk02577.txt blk02578.txt blk02579.txt blk02580.txt blk02581.txt blk02582.txt blk02583.txt blk02584.txt blk02585.txt blk02586.txt blk02587.txt blk02588.txt blk02589.txt blk02590.txt blk02591.txt blk02592.txt blk02593.txt blk02594.txt blk02595.txt blk02596.txt blk02597.txt blk02598.txt blk02599.txt blk02600.txt blk02601.txt blk02602.txt blk02603.txt blk02604.txt blk02605.txt blk02606.txt blk02607.txt blk02608.txt blk02609.txt blk02610.txt blk02611.txt blk02612.txt blk02613.txt blk02614.txt blk02615.txt blk02616.txt blk02617.txt blk02618.txt blk02619.txt blk02620.txt blk02621.txt blk02622.txt blk02623.txt blk02624.txt blk02625.txt blk02626.txt blk02627.txt blk02628.txt blk02629.txt blk02630.txt blk02631.txt blk02632.txt blk02633.txt blk02634.txt blk02635.txt blk02636.txt blk02637.txt blk02638.txt blk02639.txt blk02640.txt blk02641.txt blk02642.txt blk02643.txt blk02644.txt blk02645.txt blk02646.txt blk02647.txt blk02648.txt blk02649.txt blk02650.txt blk02651.txt blk02652.txt blk02653.txt blk02654.txt blk02655.txt blk02656.txt blk02657.txt blk02658.txt blk02659.txt blk02660.txt blk02661.txt blk02662.txt blk02663.txt blk02664.txt blk02665.txt blk02666.txt blk02667.txt blk02668.txt blk02669.txt blk02670.txt blk02671.txt blk02672.txt blk02673.txt blk02674.txt blk02675.txt blk02676.txt blk02677.txt blk02678.txt blk02679.txt blk02680.txt blk02681.txt blk02682.txt blk02683.txt blk02684.txt blk02685.txt blk02686.txt blk02687.txt blk02688.txt blk02689.txt blk02690.txt blk02691.txt blk02692.txt blk02693.txt blk02694.txt blk02695.txt blk02696.txt blk02697.txt blk02698.txt blk02699.txt blk02700.txt blk02701.txt blk02702.txt blk02703.txt blk02704.txt blk02705.txt blk02706.txt blk02707.txt blk02708.txt blk02709.txt blk02710.txt blk02711.txt blk02712.txt blk02713.txt blk02714.txt blk02715.txt blk02716.txt blk02717.txt blk02718.txt blk02719.txt blk02720.txt blk02721.txt blk02722.txt blk02723.txt blk02724.txt blk02725.txt blk02726.txt blk02727.txt blk02728.txt blk02729.txt blk02730.txt blk02731.txt blk02732.txt blk02733.txt blk02734.txt blk02735.txt blk02736.txt blk02737.txt blk02738.txt blk02739.txt blk02740.txt blk02741.txt blk02742.txt blk02743.txt blk02744.txt blk02745.txt blk02746.txt blk02747.txt blk02748.txt blk02749.txt blk02750.txt blk02751.txt blk02752.txt blk02753.txt blk02754.txt blk02755.txt blk02756.txt blk02757.txt blk02758.txt blk02759.txt blk02760.txt blk02761.txt blk02762.txt blk02763.txt blk02764.txt blk02765.txt blk02766.txt blk02767.txt blk02768.txt blk02769.txt blk02770.txt blk02771.txt blk02772.txt blk02773.txt blk02774.txt blk02775.txt blk02776.txt blk02777.txt blk02778.txt blk02779.txt blk02780.txt blk02781.txt blk02782.txt blk02783.txt blk02784.txt blk02785.txt blk02786.txt blk02787.txt blk02788.txt blk02789.txt blk02790.txt blk02791.txt blk02792.txt blk02793.txt blk02794.txt blk02795.txt blk02796.txt blk02797.txt blk02798.txt blk02799.txt blk02800.txt blk02801.txt blk02802.txt blk02803.txt blk02804.txt blk02805.txt blk02806.txt blk02807.txt blk02808.txt blk02809.txt blk02810.txt blk02811.txt blk02812.txt blk02813.txt blk02814.txt blk02815.txt blk02816.txt blk02817.txt blk02818.txt blk02819.txt blk02820.txt blk02821.txt blk02822.txt blk02823.txt blk02824.txt blk02825.txt blk02826.txt blk02827.txt blk02828.txt blk02829.txt blk02830.txt blk02831.txt blk02832.txt blk02833.txt blk02834.txt blk02835.txt blk02836.txt blk02837.txt blk02838.txt blk02839.txt blk02840.txt blk02841.txt blk02842.txt blk02843.txt blk02844.txt blk02845.txt blk02846.txt blk02847.txt blk02848.txt blk02849.txt blk02850.txt blk02851.txt blk02852.txt blk02853.txt blk02854.txt blk02855.txt blk02856.txt blk02857.txt blk02858.txt blk02859.txt blk02860.txt blk02861.txt blk02862.txt blk02863.txt blk02864.txt blk02865.txt blk02866.txt blk02867.txt blk02868.txt blk02869.txt blk02870.txt blk02871.txt blk02872.txt blk02873.txt blk02874.txt blk02875.txt blk02876.txt blk02877.txt blk02878.txt blk02879.txt blk02880.txt blk02881.txt blk02882.txt blk02883.txt blk02884.txt blk02885.txt blk02886.txt blk02887.txt blk02888.txt blk02889.txt blk02890.txt blk02891.txt blk02892.txt blk02893.txt blk02894.txt blk02895.txt blk02896.txt blk02897.txt blk02898.txt blk02899.txt blk02900.txt blk02901.txt blk02902.txt blk02903.txt blk02904.txt blk02905.txt blk02906.txt blk02907.txt blk02908.txt blk02909.txt blk02910.txt blk02911.txt blk02912.txt blk02913.txt blk02914.txt blk02915.txt blk02916.txt blk02917.txt blk02918.txt blk02919.txt blk02920.txt blk02921.txt blk02922.txt blk02923.txt blk02924.txt blk02925.txt blk02926.txt blk02927.txt blk02928.txt blk02929.txt blk02930.txt blk02931.txt blk02932.txt blk02933.txt blk02934.txt blk02935.txt blk02936.txt blk02937.txt blk02938.txt blk02939.txt blk02940.txt blk02941.txt blk02942.txt blk02943.txt blk02944.txt blk02945.txt blk02946.txt blk02947.txt blk02948.txt blk02949.txt blk02950.txt blk02951.txt blk02952.txt blk02953.txt blk02954.txt blk02955.txt blk02956.txt blk02957.txt blk02958.txt blk02959.txt blk02960.txt blk02961.txt blk02962.txt blk02963.txt blk02964.txt blk02965.txt blk02966.txt blk02967.txt blk02968.txt blk02969.txt blk02970.txt blk02971.txt blk02972.txt blk02973.txt blk02974.txt blk02975.txt blk02976.txt blk02977.txt blk02978.txt blk02979.txt blk02980.txt blk02981.txt blk02982.txt blk02983.txt blk02984.txt blk02985.txt blk02986.txt blk02987.txt blk02988.txt blk02989.txt blk02990.txt blk02991.txt blk02992.txt blk02993.txt blk02994.txt blk02995.txt blk02996.txt blk02997.txt blk02998.txt blk02999.txt blk03000.txt blk03001.txt blk03002.txt blk03003.txt blk03004.txt blk03005.txt blk03006.txt blk03007.txt blk03008.txt blk03009.txt blk03010.txt blk03011.txt blk03012.txt blk03013.txt blk03014.txt blk03015.txt blk03016.txt blk03017.txt blk03018.txt blk03019.txt blk03020.txt blk03021.txt blk03022.txt blk03023.txt blk03024.txt blk03025.txt blk03026.txt blk03027.txt blk03028.txt blk03029.txt blk03030.txt blk03031.txt blk03032.txt blk03033.txt blk03034.txt blk03035.txt blk03036.txt blk03037.txt blk03038.txt blk03039.txt blk03040.txt blk03041.txt blk03042.txt blk03043.txt blk03044.txt blk03045.txt blk03046.txt blk03047.txt blk03048.txt blk03049.txt blk03050.txt blk03051.txt blk03052.txt blk03053.txt blk03054.txt blk03055.txt blk03056.txt blk03057.txt blk03058.txt blk03059.txt blk03060.txt blk03061.txt blk03062.txt blk03063.txt blk03064.txt blk03065.txt blk03066.txt blk03067.txt blk03068.txt blk03069.txt blk03070.txt blk03071.txt blk03072.txt blk03073.txt blk03074.txt blk03075.txt blk03076.txt blk03077.txt blk03078.txt blk03079.txt blk03080.txt blk03081.txt blk03082.txt blk03083.txt blk03084.txt blk03085.txt blk03086.txt blk03087.txt blk03088.txt blk03089.txt blk03090.txt blk03091.txt blk03092.txt blk03093.txt blk03094.txt blk03095.txt blk03096.txt blk03097.txt blk03098.txt blk03099.txt blk03100.txt blk03101.txt blk03102.txt blk03103.txt blk03104.txt blk03105.txt blk03106.txt blk03107.txt blk03108.txt blk03109.txt blk03110.txt blk03111.txt blk03112.txt blk03113.txt blk03114.txt blk03115.txt blk03116.txt blk03117.txt blk03118.txt blk03119.txt blk03120.txt blk03121.txt blk03122.txt blk03123.txt blk03124.txt blk03125.txt blk03126.txt blk03127.txt blk03128.txt blk03129.txt blk03130.txt blk03131.txt blk03132.txt blk03133.txt blk03134.txt blk03135.txt blk03136.txt blk03137.txt blk03138.txt blk03139.txt blk03140.txt blk03141.txt blk03142.txt blk03143.txt blk03144.txt blk03145.txt blk03146.txt blk03147.txt blk03148.txt blk03149.txt blk03150.txt blk03151.txt blk03152.txt blk03153.txt blk03154.txt blk03155.txt blk03156.txt blk03157.txt blk03158.txt blk03159.txt blk03160.txt blk03161.txt blk03162.txt blk03163.txt blk03164.txt blk03165.txt blk03166.txt blk03167.txt blk03168.txt blk03169.txt blk03170.txt blk03171.txt blk03172.txt blk03173.txt blk03174.txt blk03175.txt blk03176.txt blk03177.txt blk03178.txt blk03179.txt blk03180.txt blk03181.txt blk03182.txt blk03183.txt blk03184.txt blk03185.txt blk03186.txt blk03187.txt blk03188.txt blk03189.txt blk03190.txt blk03191.txt blk03192.txt blk03193.txt blk03194.txt blk03195.txt blk03196.txt blk03197.txt blk03198.txt blk03199.txt blk03200.txt blk03201.txt blk03202.txt blk03203.txt blk03204.txt blk03205.txt blk03206.txt blk03207.txt blk03208.txt blk03209.txt blk03210.txt blk03211.txt blk03212.txt blk03213.txt blk03214.txt blk03215.txt blk03216.txt blk03217.txt blk03218.txt blk03219.txt blk03220.txt blk03221.txt blk03222.txt blk03223.txt blk03224.txt blk03225.txt blk03226.txt blk03227.txt blk03228.txt blk03229.txt blk03230.txt blk03231.txt blk03232.txt blk03233.txt blk03234.txt blk03235.txt blk03236.txt blk03237.txt blk03238.txt blk03239.txt blk03240.txt blk03241.txt blk03242.txt blk03243.txt blk03244.txt blk03245.txt blk03246.txt blk03247.txt blk03248.txt blk03249.txt blk03250.txt blk03251.txt blk03252.txt blk03253.txt blk03254.txt blk03255.txt blk03256.txt blk03257.txt blk03258.txt blk03259.txt blk03260.txt blk03261.txt blk03262.txt blk03263.txt blk03264.txt blk03265.txt blk03266.txt blk03267.txt blk03268.txt blk03269.txt blk03270.txt blk03271.txt blk03272.txt blk03273.txt blk03274.txt blk03275.txt blk03276.txt blk03277.txt blk03278.txt blk03279.txt blk03280.txt blk03281.txt blk03282.txt blk03283.txt blk03284.txt blk03285.txt blk03286.txt blk03287.txt blk03288.txt blk03289.txt blk03290.txt blk03291.txt blk03292.txt blk03293.txt blk03294.txt blk03295.txt blk03296.txt blk03297.txt blk03298.txt blk03299.txt blk03300.txt blk03301.txt blk03302.txt blk03303.txt blk03304.txt blk03305.txt blk03306.txt blk03307.txt blk03308.txt blk03309.txt blk03310.txt blk03311.txt blk03312.txt blk03313.txt blk03314.txt blk03315.txt blk03316.txt blk03317.txt blk03318.txt blk03319.txt blk03320.txt blk03321.txt blk03322.txt blk03323.txt blk03324.txt blk03325.txt blk03326.txt blk03327.txt blk03328.txt blk03329.txt blk03330.txt blk03331.txt blk03332.txt blk03333.txt blk03334.txt blk03335.txt blk03336.txt blk03337.txt blk03338.txt blk03339.txt blk03340.txt blk03341.txt blk03342.txt blk03343.txt blk03344.txt blk03345.txt blk03346.txt blk03347.txt blk03348.txt blk03349.txt blk03350.txt blk03351.txt blk03352.txt blk03353.txt blk03354.txt blk03355.txt blk03356.txt blk03357.txt blk03358.txt blk03359.txt blk03360.txt blk03361.txt blk03362.txt blk03363.txt blk03364.txt blk03365.txt blk03366.txt blk03367.txt blk03368.txt blk03369.txt blk03370.txt blk03371.txt blk03372.txt blk03373.txt blk03374.txt blk03375.txt blk03376.txt blk03377.txt blk03378.txt blk03379.txt blk03380.txt blk03381.txt blk03382.txt blk03383.txt blk03384.txt blk03385.txt blk03386.txt blk03387.txt blk03388.txt blk03389.txt blk03390.txt blk03391.txt blk03392.txt blk03393.txt blk03394.txt blk03395.txt blk03396.txt blk03397.txt blk03398.txt blk03399.txt blk03400.txt blk03401.txt blk03402.txt blk03403.txt blk03404.txt blk03405.txt blk03406.txt blk03407.txt blk03408.txt blk03409.txt blk03410.txt blk03411.txt blk03412.txt blk03413.txt blk03414.txt blk03415.txt blk03416.txt blk03417.txt blk03418.txt blk03419.txt blk03420.txt blk03421.txt blk03422.txt blk03423.txt blk03424.txt blk03425.txt blk03426.txt blk03427.txt blk03428.txt blk03429.txt blk03430.txt blk03431.txt blk03432.txt blk03433.txt blk03434.txt blk03435.txt blk03436.txt blk03437.txt blk03438.txt blk03439.txt blk03440.txt blk03441.txt blk03442.txt blk03443.txt blk03444.txt blk03445.txt blk03446.txt blk03447.txt blk03448.txt blk03449.txt blk03450.txt blk03451.txt blk03452.txt blk03453.txt blk03454.txt blk03455.txt blk03456.txt blk03457.txt blk03458.txt blk03459.txt blk03460.txt blk03461.txt blk03462.txt blk03463.txt blk03464.txt blk03465.txt blk03466.txt blk03467.txt blk03468.txt blk03469.txt blk03470.txt blk03471.txt blk03472.txt blk03473.txt blk03474.txt blk03475.txt blk03476.txt blk03477.txt blk03478.txt blk03479.txt blk03480.txt blk03481.txt blk03482.txt blk03483.txt blk03484.txt blk03485.txt blk03486.txt blk03487.txt blk03488.txt blk03489.txt blk03490.txt blk03491.txt blk03492.txt blk03493.txt blk03494.txt blk03495.txt blk03496.txt blk03497.txt blk03498.txt blk03499.txt blk03500.txt blk03501.txt blk03502.txt blk03503.txt blk03504.txt blk03505.txt blk03506.txt blk03507.txt blk03508.txt blk03509.txt blk03510.txt blk03511.txt blk03512.txt blk03513.txt blk03514.txt blk03515.txt blk03516.txt blk03517.txt blk03518.txt blk03519.txt blk03520.txt blk03521.txt blk03522.txt blk03523.txt blk03524.txt blk03525.txt blk03526.txt blk03527.txt blk03528.txt blk03529.txt blk03530.txt blk03531.txt blk03532.txt blk03533.txt blk03534.txt blk03535.txt blk03536.txt blk03537.txt blk03538.txt blk03539.txt blk03540.txt blk03541.txt blk03542.txt blk03543.txt blk03544.txt blk03545.txt blk03546.txt blk03547.txt blk03548.txt blk03549.txt blk03550.txt blk03551.txt blk03552.txt blk03553.txt blk03554.txt blk03555.txt blk03556.txt blk03557.txt blk03558.txt blk03559.txt blk03560.txt blk03561.txt blk03562.txt blk03563.txt blk03564.txt blk03565.txt blk03566.txt blk03567.txt blk03568.txt blk03569.txt blk03570.txt blk03571.txt blk03572.txt blk03573.txt blk03574.txt blk03575.txt blk03576.txt blk03577.txt blk03578.txt blk03579.txt blk03580.txt blk03581.txt blk03582.txt blk03583.txt blk03584.txt blk03585.txt blk03586.txt blk03587.txt blk03588.txt blk03589.txt blk03590.txt blk03591.txt blk03592.txt blk03593.txt blk03594.txt blk03595.txt blk03596.txt blk03597.txt blk03598.txt blk03599.txt blk03600.txt blk03601.txt blk03602.txt blk03603.txt blk03604.txt blk03605.txt blk03606.txt blk03607.txt blk03608.txt blk03609.txt blk03610.txt blk03611.txt blk03612.txt blk03613.txt blk03614.txt blk03615.txt blk03616.txt blk03617.txt blk03618.txt blk03619.txt blk03620.txt blk03621.txt blk03622.txt blk03623.txt blk03624.txt blk03625.txt blk03626.txt blk03627.txt blk03628.txt blk03629.txt blk03630.txt blk03631.txt blk03632.txt blk03633.txt blk03634.txt blk03635.txt blk03636.txt blk03637.txt blk03638.txt blk03639.txt blk03640.txt blk03641.txt blk03642.txt blk03643.txt blk03644.txt blk03645.txt blk03646.txt blk03647.txt blk03648.txt blk03649.txt blk03650.txt blk03651.txt blk03652.txt blk03653.txt blk03654.txt blk03655.txt blk03656.txt blk03657.txt blk03658.txt blk03659.txt blk03660.txt blk03661.txt blk03662.txt blk03663.txt blk03664.txt blk03665.txt blk03666.txt blk03667.txt blk03668.txt blk03669.txt blk03670.txt blk03671.txt blk03672.txt blk03673.txt blk03674.txt blk03675.txt blk03676.txt blk03677.txt blk03678.txt blk03679.txt blk03680.txt blk03681.txt blk03682.txt blk03683.txt blk03684.txt blk03685.txt blk03686.txt blk03687.txt blk03688.txt blk03689.txt blk03690.txt blk03691.txt blk03692.txt blk03693.txt blk03694.txt blk03695.txt blk03696.txt blk03697.txt blk03698.txt blk03699.txt blk03700.txt blk03701.txt blk03702.txt blk03703.txt blk03704.txt blk03705.txt blk03706.txt blk03707.txt blk03708.txt blk03709.txt blk03710.txt blk03711.txt blk03712.txt blk03713.txt blk03714.txt blk03715.txt blk03716.txt blk03717.txt blk03718.txt blk03719.txt blk03720.txt blk03721.txt blk03722.txt blk03723.txt blk03724.txt blk03725.txt blk03726.txt blk03727.txt blk03728.txt blk03729.txt blk03730.txt blk03731.txt blk03732.txt blk03733.txt blk03734.txt blk03735.txt blk03736.txt blk03737.txt blk03738.txt blk03739.txt blk03740.txt blk03741.txt blk03742.txt blk03743.txt blk03744.txt blk03745.txt blk03746.txt blk03747.txt blk03748.txt blk03749.txt blk03750.txt blk03751.txt blk03752.txt blk03753.txt blk03754.txt blk03755.txt blk03756.txt blk03757.txt blk03758.txt blk03759.txt blk03760.txt blk03761.txt blk03762.txt blk03763.txt blk03764.txt blk03765.txt blk03766.txt blk03767.txt blk03768.txt blk03769.txt blk03770.txt blk03771.txt blk03772.txt blk03773.txt blk03774.txt blk03775.txt blk03776.txt blk03777.txt blk03778.txt blk03779.txt blk03780.txt blk03781.txt blk03782.txt blk03783.txt blk03784.txt blk03785.txt blk03786.txt blk03787.txt blk03788.txt blk03789.txt blk03790.txt blk03791.txt blk03792.txt blk03793.txt blk03794.txt blk03795.txt blk03796.txt blk03797.txt blk03798.txt blk03799.txt blk03800.txt blk03801.txt blk03802.txt blk03803.txt blk03804.txt blk03805.txt blk03806.txt blk03807.txt blk03808.txt blk03809.txt blk03810.txt blk03811.txt blk03812.txt blk03813.txt blk03814.txt blk03815.txt blk03816.txt blk03817.txt blk03818.txt blk03819.txt blk03820.txt blk03821.txt blk03822.txt blk03823.txt blk03824.txt blk03825.txt blk03826.txt blk03827.txt blk03828.txt blk03829.txt blk03830.txt blk03831.txt blk03832.txt blk03833.txt blk03834.txt blk03835.txt blk03836.txt blk03837.txt blk03838.txt blk03839.txt blk03840.txt blk03841.txt blk03842.txt blk03843.txt blk03844.txt blk03845.txt blk03846.txt blk03847.txt blk03848.txt blk03849.txt blk03850.txt blk03851.txt blk03852.txt blk03853.txt blk03854.txt blk03855.txt blk03856.txt blk03857.txt blk03858.txt blk03859.txt blk03860.txt blk03861.txt blk03862.txt blk03863.txt blk03864.txt blk03865.txt blk03866.txt blk03867.txt blk03868.txt blk03869.txt blk03870.txt blk03871.txt blk03872.txt blk03873.txt blk03874.txt blk03875.txt blk03876.txt blk03877.txt blk03878.txt blk03879.txt blk03880.txt blk03881.txt blk03882.txt blk03883.txt blk03884.txt blk03885.txt blk03886.txt blk03887.txt blk03888.txt blk03889.txt blk03890.txt blk03891.txt blk03892.txt blk03893.txt blk03894.txt blk03895.txt blk03896.txt blk03897.txt blk03898.txt blk03899.txt blk03900.txt blk03901.txt blk03902.txt blk03903.txt blk03904.txt blk03905.txt blk03906.txt blk03907.txt blk03908.txt blk03909.txt blk03910.txt blk03911.txt blk03912.txt blk03913.txt blk03914.txt blk03915.txt blk03916.txt blk03917.txt blk03918.txt blk03919.txt blk03920.txt blk03921.txt blk03922.txt blk03923.txt blk03924.txt blk03925.txt blk03926.txt blk03927.txt blk03928.txt blk03929.txt blk03930.txt blk03931.txt blk03932.txt blk03933.txt blk03934.txt blk03935.txt blk03936.txt blk03937.txt blk03938.txt blk03939.txt blk03940.txt blk03941.txt blk03942.txt blk03943.txt blk03944.txt blk03945.txt blk03946.txt blk03947.txt blk03948.txt blk03949.txt blk03950.txt blk03951.txt blk03952.txt blk03953.txt blk03954.txt blk03955.txt blk03956.txt blk03957.txt blk03958.txt blk03959.txt blk03960.txt blk03961.txt blk03962.txt blk03963.txt blk03964.txt blk03965.txt blk03966.txt blk03967.txt blk03968.txt blk03969.txt blk03970.txt blk03971.txt blk03972.txt blk03973.txt blk03974.txt blk03975.txt blk03976.txt blk03977.txt blk03978.txt blk03979.txt blk03980.txt blk03981.txt blk03982.txt blk03983.txt blk03984.txt blk03985.txt blk03986.txt blk03987.txt blk03988.txt blk03989.txt blk03990.txt blk03991.txt blk03992.txt blk03993.txt blk03994.txt blk03995.txt blk03996.txt blk03997.txt blk03998.txt blk03999.txt blk04000.txt blk04001.txt blk04002.txt blk04003.txt blk04004.txt blk04005.txt blk04006.txt blk04007.txt blk04008.txt blk04009.txt blk04010.txt blk04011.txt blk04012.txt blk04013.txt blk04014.txt blk04015.txt blk04016.txt blk04017.txt blk04018.txt blk04019.txt blk04020.txt blk04021.txt blk04022.txt blk04023.txt blk04024.txt blk04025.txt blk04026.txt blk04027.txt blk04028.txt blk04029.txt blk04030.txt blk04031.txt blk04032.txt blk04033.txt blk04034.txt blk04035.txt blk04036.txt blk04037.txt blk04038.txt blk04039.txt blk04040.txt blk04041.txt blk04042.txt blk04043.txt blk04044.txt blk04045.txt blk04046.txt blk04047.txt blk04048.txt blk04049.txt blk04050.txt blk04051.txt blk04052.txt blk04053.txt blk04054.txt blk04055.txt blk04056.txt blk04057.txt blk04058.txt blk04059.txt blk04060.txt blk04061.txt blk04062.txt blk04063.txt blk04064.txt blk04065.txt blk04066.txt blk04067.txt blk04068.txt blk04069.txt blk04070.txt blk04071.txt blk04072.txt blk04073.txt blk04074.txt blk04075.txt blk04076.txt blk04077.txt blk04078.txt blk04079.txt blk04080.txt blk04081.txt blk04082.txt blk04083.txt blk04084.txt blk04085.txt blk04086.txt blk04087.txt blk04088.txt blk04089.txt blk04090.txt blk04091.txt blk04092.txt blk04093.txt blk04094.txt blk04095.txt blk04096.txt blk04097.txt blk04098.txt blk04099.txt blk04100.txt blk04101.txt blk04102.txt blk04103.txt blk04104.txt blk04105.txt blk04106.txt blk04107.txt blk04108.txt blk04109.txt blk04110.txt blk04111.txt blk04112.txt blk04113.txt blk04114.txt blk04115.txt blk04116.txt blk04117.txt blk04118.txt blk04119.txt blk04120.txt blk04121.txt blk04122.txt blk04123.txt blk04124.txt blk04125.txt blk04126.txt blk04127.txt blk04128.txt blk04129.txt blk04130.txt blk04131.txt blk04132.txt blk04133.txt blk04134.txt blk04135.txt blk04136.txt blk04137.txt blk04138.txt blk04139.txt blk04140.txt blk04141.txt blk04142.txt blk04143.txt blk04144.txt blk04145.txt blk04146.txt blk04147.txt blk04148.txt blk04149.txt blk04150.txt blk04151.txt blk04152.txt blk04153.txt blk04154.txt blk04155.txt blk04156.txt blk04157.txt blk04158.txt blk04159.txt blk04160.txt blk04161.txt blk04162.txt blk04163.txt blk04164.txt blk04165.txt blk04166.txt blk04167.txt blk04168.txt blk04169.txt blk04170.txt blk04171.txt blk04172.txt blk04173.txt blk04174.txt blk04175.txt blk04176.txt blk04177.txt Show all files
Advertisement: