1: #include <X/mit-copyright.h> 2: 3: /* 4: * XPR - process xwd(1) files for the LN03 or LA100 printer 5: * 6: * Author: Michael R. Gretzinger, MIT Project Athena 7: * Copyright (C) 1985, Massachusetts Institute of Technology 8: */ 9: 10: #ifndef lint 11: static char *rcsid_xpr_c = "$Header: xpr.c,v 10.4 86/02/01 16:03:38 tony Rel $"; 12: #endif 13: 14: #include <sys/types.h> 15: #include <sys/file.h> 16: #include <sys/uio.h> 17: #include <stdio.h> 18: #include "lncmd.h" 19: #include "XWDFile.h" 20: 21: int debug = 0; 22: 23: enum device {LN01, LN03, LA100}; 24: enum orientation {PORTRAIT, LANDSCAPE}; 25: 26: #define W_MAX 2400 27: #define H_MAX 3150 28: #define W_MARGIN 75 29: #define H_MARGIN 37 30: #define W_PAGE 2550 31: #define H_PAGE 3225 32: 33: #ifdef NOINLINE 34: #define min(x,y) (((x)<(y))?(x):(y)) 35: #endif NOINLINE 36: 37: #define F_PORTRAIT 1 38: #define F_LANDSCAPE 2 39: #define F_DUMP 4 40: #define F_NOSIXOPT 8 41: #define F_APPEND 16 42: #define F_NOFF 32 43: #define F_REPORT 64 44: 45: 46: main(argc, argv) 47: char **argv; 48: { 49: XWDFileHeader win; 50: register unsigned char (*sixmap)[]; 51: register int i; 52: register int iw; 53: register int ih; 54: register int sixel_count; 55: char *w_name; 56: char *filename; 57: char *output_filename; 58: int scale, width, height, flags, split; 59: int left, top; 60: int top_margin, left_margin; 61: int wpad, hpad; 62: char *header, *trailer; 63: enum orientation orientation; 64: enum device device; 65: 66: parse_args (argc, argv, &scale, &width, &height, &left, &top, &device, 67: &flags, &split, &header, &trailer); 68: 69: /* read in window header */ 70: read(0, &win, sizeof win); 71: w_name = (char *)malloc(win.header_size - sizeof win); 72: read(0, w_name, win.header_size - sizeof win); 73: 74: /* calculate orientation and scale */ 75: setup_layout(device, win.pixmap_width, win.pixmap_height, flags, width, 76: height, header, trailer, &scale, &orientation); 77: 78: /* calculate w and h cell count */ 79: wpad = (16 - (win.pixmap_width & 15)) & 15; 80: iw = win.pixmap_width; 81: ih = (win.pixmap_height + 5) / 6; 82: hpad = (ih * 6) - win.pixmap_height; 83: 84: /* build pixcells from input file */ 85: sixel_count = iw * ih; 86: sixmap = (unsigned char (*)[])malloc(sixel_count); 87: build_sixmap(iw, ih, sixmap, wpad, hpad); 88: 89: /* output commands and sixel graphics */ 90: if (device == LN03) { 91: /* ln03_grind_fonts(sixmap, iw, ih, scale, &pixmap); */ 92: ln03_setup(iw, ih, orientation, scale, left, top, 93: &left_margin, &top_margin, flags, header, trailer); 94: ln03_output_sixels(sixmap, iw, ih, (flags & F_NOSIXOPT), split, 95: scale, top_margin, left_margin); 96: ln03_finish(); 97: } else if (device == LA100) { 98: la100_setup(iw, ih, scale); 99: la100_output_sixels(sixmap, iw, ih, (flags & F_NOSIXOPT)); 100: la100_finish(); 101: } else { 102: fprintf(stderr, "xwd2: device not supported\n"); 103: } 104: 105: /* print some statistics */ 106: if (flags & F_REPORT) { 107: fprintf(stderr, "Name: %s\n", w_name); 108: fprintf(stderr, "Width: %d, Height: %d\n", win.pixmap_width, 109: win.pixmap_height); 110: fprintf(stderr, "Orientation: %s, Scale: %d\n", 111: (orientation==PORTRAIT) ? "Portrait" : "Landscape", scale); 112: } 113: if (flags & F_DUMP) dump_sixmap(sixmap, iw, ih); 114: } 115: 116: parse_args(argc, argv, scale, width, height, left, top, device, flags, 117: split, header, trailer) 118: register int argc; 119: register char **argv; 120: int *scale; 121: int *width; 122: int *height; 123: int *left; 124: int *top; 125: enum device *device; 126: int *flags; 127: int *split; 128: char **header; 129: char **trailer; 130: { 131: register char *output_filename; 132: register int f; 133: register int len; 134: register int pos; 135: double atof(); 136: int atoi(); 137: 138: output_filename = NULL; 139: *device = LN03; /* default */ 140: *flags = 0; 141: *split = 1; 142: *width = -1; 143: *height = -1; 144: *top = -1; 145: *left = -1; 146: *header = NULL; 147: *trailer = NULL; 148: 149: argc--; 150: argv++; 151: 152: while (argc > 0 && argv[0][0] == '-') { 153: len = strlen(*argv); 154: switch (argv[0][1]) { 155: case 'a': /* -append <filename> */ 156: if (!bcmp(*argv, "-append", len)) { 157: argc--; argv++; 158: output_filename = *argv; 159: *flags |= F_APPEND; 160: } 161: break; 162: 163: case 'd': /* -device {ln03 | la100} | -dump */ 164: if (len <= 2) { 165: fprintf(stderr, "xwd2: ambiguous option: \"%s\"\n", *argv); 166: exit(1); 167: } 168: if (!bcmp(*argv, "-device", len)) { 169: argc--; argv++; 170: len = strlen(*argv); 171: if (!bcmp(*argv, "ln03", len)) { 172: *device = LN03; 173: } else if (!bcmp(*argv, "la100", len)) { 174: *device = LA100; 175: } else { 176: fprintf(stderr, 177: "xwd2: device \"%s\" not supported\n", *argv); 178: exit(1); 179: } 180: } else if (!bcmp(*argv, "-dump", len)) { 181: *flags |= F_DUMP; 182: } 183: break; 184: 185: case 'h': /* -height <inches> */ 186: if (len <= 3) { 187: fprintf(stderr, "xwd2: ambiguous option: \"%s\"\n", *argv); 188: exit(1); 189: } 190: if (!bcmp(*argv, "-height", len)) { 191: argc--; argv++; 192: *height = (int)(300.0 * atof(*argv)); 193: } else if (!bcmp(*argv, "-header", len)) { 194: argc--; argv++; 195: *header = *argv; 196: } 197: break; 198: 199: case 'l': /* -landscape | -left <inches> */ 200: if (!bcmp(*argv, "-landscape", len)) { 201: *flags |= F_LANDSCAPE; 202: } else if (!bcmp(*argv, "-left", len)) { 203: argc--; argv++; 204: *left = (int)(300.0 * atof(*argv)); 205: } 206: break; 207: 208: case 'n': /* -nosixopt | -noff */ 209: if (len <= 3) { 210: fprintf(stderr, "xwd2: ambiguous option: \"%s\"\n", *argv); 211: exit(1); 212: } 213: if (!bcmp(*argv, "-nosixopt", len)) { 214: *flags |= F_NOSIXOPT; 215: } else if (!bcmp(*argv, "-noff", len)) { 216: *flags |= F_NOFF; 217: } 218: break; 219: 220: case 'o': /* -output <filename> */ 221: if (!bcmp(*argv, "-output", len)) { 222: argc--; argv++; 223: output_filename = *argv; 224: } 225: break; 226: 227: case 'p': /* -portrait */ 228: if (!bcmp(*argv, "-portrait", len)) { 229: *flags |= F_PORTRAIT; 230: } 231: break; 232: 233: case 'r': /* -report */ 234: if (!bcmp(*argv, "-report", len)) { 235: *flags |= F_REPORT; 236: } 237: break; 238: 239: case 's': /* -scale <scale> | -split <n-pages> */ 240: if (!bcmp(*argv, "-scale", len)) { 241: argc--; argv++; 242: *scale = atoi(*argv); 243: } else if (!bcmp(*argv, "-split", len)) { 244: argc--; argv++; 245: *split = atoi(*argv); 246: } 247: break; 248: 249: case 't': /* -top <inches> */ 250: if (len <= 2) { 251: fprintf(stderr, "xwd2: ambigous option: \"%s\"\n", *argv); 252: exit(1); 253: } 254: if (!bcmp(*argv, "-top", len)) { 255: argc--; argv++; 256: *top = (int)(300.0 * atof(*argv)); 257: } else if (!bcmp(*argv, "-trailer", len)) { 258: argc--; argv++; 259: *trailer = *argv; 260: } 261: break; 262: 263: case 'w': /* -width <inches> */ 264: if (!bcmp(*argv, "-width", len)) { 265: argc--; argv++; 266: *width = (int)(300.0 * atof(*argv)); 267: } 268: break; 269: 270: } 271: argc--; argv++; 272: } 273: 274: if (argc > 0) { 275: f = open(*argv, O_RDONLY, 0); 276: if (f < 0) { 277: fprintf(stderr, "xwd2: error opening \"%s\" for input\n", *argv); 278: perror(""); 279: exit(1); 280: } 281: dup2(f, 0); 282: close(f); 283: /* if (output_filename == NULL) { 284: output_filename = (char *)malloc(strlen(*argv)+10); 285: build_output_filename(*argv, *device, output_filename); 286: } */ 287: } 288: 289: if (output_filename != NULL) { 290: if (!(*flags & F_APPEND)) { 291: f = open(output_filename, O_CREAT|O_WRONLY|O_TRUNC, 0664); 292: } else { 293: f = open(output_filename, O_WRONLY, 0); 294: } 295: if (f < 0) { 296: fprintf(stderr, "xwd2: error opening \"%s\" for output\n", 297: output_filename); 298: perror("xwd2"); 299: exit(1); 300: } 301: if (*flags & F_APPEND) { 302: pos = lseek(f, 0, 2); /* get eof position */ 303: if (*flags & F_NOFF) pos -= 3; /* set position before trailing */ 304: /* formfeed and reset */ 305: lseek(f, pos, 0); /* set pointer */ 306: } 307: dup2(f, 1); 308: close(f); 309: } 310: } 311: 312: setup_layout(device, win_width, win_height, flags, width, height, 313: header, trailer, scale, orientation) 314: enum device device; 315: int win_width; 316: int win_height; 317: int flags; 318: int width; 319: int height; 320: char *header; 321: char *trailer; 322: int *scale; 323: enum orientation *orientation; 324: { 325: register int w_scale; 326: register int h_scale; 327: register int iscale = *scale; 328: register int w_max; 329: register int h_max; 330: 331: if (header != NULL) win_height += 75; 332: if (trailer != NULL) win_height += 75; 333: 334: /* check maximum width and height; set orientation and scale*/ 335: if (device == LN03) { 336: if ((win_width < win_height || (flags & F_PORTRAIT)) && 337: !(flags & F_LANDSCAPE)) { 338: *orientation = PORTRAIT; 339: w_max = (width > 0)? width : W_MAX; 340: h_max = (height > 0)? height : H_MAX; 341: w_scale = w_max / win_width; 342: h_scale = h_max / win_height; 343: *scale = min(w_scale, h_scale); 344: } else { 345: *orientation = LANDSCAPE; 346: w_max = (width > 0)? width : H_MAX; 347: h_max = (height > 0)? height : W_MAX; 348: w_scale = w_max / win_width; 349: h_scale = h_max / win_height; 350: *scale = min(w_scale, h_scale); 351: } 352: } else { /* device == LA100 */ 353: *orientation = PORTRAIT; 354: *scale = W_MAX / win_width; 355: } 356: if (*scale == 0) *scale = 1; 357: if (*scale > 6) *scale = 6; 358: if (iscale > 0 && iscale < *scale) *scale = iscale; 359: } 360: 361: dump_sixmap(sixmap, iw, ih) 362: register unsigned char (*sixmap)[]; 363: int iw; 364: int ih; 365: { 366: register int i, j; 367: register unsigned char *c; 368: 369: c = (unsigned char *)sixmap; 370: fprintf(stderr, "Sixmap:\n"); 371: for (i = 0; i < ih; i++) { 372: for (j = 0; j < iw; j++) { 373: fprintf(stderr, "%02X ", *c++); 374: } 375: fprintf(stderr, "\n\n"); 376: } 377: } 378: 379: build_sixmap(iw, ih, sixmap, wpad, hpad) 380: int ih; 381: int iw; 382: unsigned char (*sixmap)[]; 383: int wpad; 384: int hpad; 385: { 386: int iwb, iww; 387: int rsize, cc; 388: int w, maxw; 389: struct iovec linevec[6]; 390: unsigned char line[6][150]; 391: register unsigned char *c; 392: register int i, j, k, m; 393: register int sixel; 394: static int mask[] = {~1, ~2, ~4, ~8, ~16, ~32, ~64, ~128}; 395: 396: c = (unsigned char *)sixmap; 397: iwb = (iw + wpad) / 8; 398: 399: for (i = 0; i <= 5; i++) { 400: linevec[i].iov_base = (caddr_t)line[i]; 401: linevec[i].iov_len = iwb; 402: } 403: 404: while (--ih >= 0) { 405: if (ih > 0 || hpad == 0) { 406: rsize = iwb * 6; 407: while (rsize > 0) { 408: cc = readv(0, linevec, 6); 409: if (cc == 0) break; 410: rsize -= cc; 411: } 412: } else { 413: i = 6 - hpad; 414: rsize = iwb * i; 415: while (rsize > 0) { 416: cc = readv(0, linevec, i); 417: if (cc == 0) break; 418: rsize -= cc; 419: } 420: for (; i < 6; i++) 421: for (j = 0; j < iwb; j++) line[i][j] = 0xFF; 422: } 423: 424: #ifndef NOINLINE 425: for (i = 0; i < iw; i++) { 426: sixel = extzv(line[0], i, 1); 427: sixel |= extzv(line[1], i, 1) << 1; 428: sixel |= extzv(line[2], i, 1) << 2; 429: sixel |= extzv(line[3], i, 1) << 3; 430: sixel |= extzv(line[4], i, 1) << 4; 431: sixel |= extzv(line[5], i, 1) << 5; 432: *c++ = sixel; 433: } 434: #else 435: for (i = 0, w = iw; w > 0; i++) { 436: for (j = 0; j <= 7; j++) { 437: m = mask[j]; 438: k = -j; 439: sixel = ((line[0][i] & ~m) << k++); 440: sixel |= ((line[1][i] & ~m) << k++); 441: sixel |= ((line[2][i] & ~m) << k++); 442: sixel |= ((line[3][i] & ~m) << k++); 443: sixel |= ((line[4][i] & ~m) << k++); 444: sixel |= ((line[5][i] & ~m) << k); 445: *c++ = sixel; 446: if (--w == 0) break; 447: } 448: } 449: #endif 450: } 451: } 452: 453: build_output_filename(name, device, oname) 454: register char *name, *oname; 455: enum device device; 456: { 457: while (*name && *name != '.') *oname++ = *name++; 458: switch (device) { 459: case LN03: bcopy(".ln03", oname, 6); break; 460: case LA100: bcopy(".la100", oname, 7); break; 461: } 462: } 463: 464: 465: ln03_grind_fonts(sixmap, iw, ih, scale, pixmap) 466: unsigned char (*sixmap)[]; 467: int iw; 468: int ih; 469: int scale; 470: struct pixmap (**pixmap)[]; 471: { 472: } 473: 474: 475: ln03_setup(iw, ih, orientation, scale, left, top, left_margin, top_margin, 476: flags, header, trailer) 477: int iw; 478: int ih; 479: enum orientation orientation; 480: int scale; 481: int left; 482: int top; 483: int *left_margin; 484: int *top_margin; 485: int flags; 486: char *header; 487: char *trailer; 488: { 489: register int i; 490: register int lm, tm, xm; 491: char fontname[6]; 492: char buf[256]; 493: register char *bp = buf; 494: 495: if (!(flags & F_APPEND)) { 496: sprintf(bp, LN_RIS); bp += 2; 497: sprintf(bp, LN_SSU, 7); bp += 5; 498: sprintf(bp, LN_PUM_SET); bp += sizeof LN_PUM_SET - 1; 499: } 500: 501: if (orientation == PORTRAIT) { 502: lm = (left > 0)? left : (((W_MAX - scale * iw) / 2) + W_MARGIN); 503: tm = (top > 0)? top : (((H_MAX - scale * ih * 6) / 2) + H_MARGIN); 504: sprintf(bp, LN_PFS, "?20"); bp += 7; 505: sprintf(bp, LN_DECOPM_SET); bp += sizeof LN_DECOPM_SET - 1; 506: sprintf(bp, LN_DECSLRM, lm, W_PAGE - lm); bp += strlen(bp); 507: } else { 508: lm = (left > 0)? left : (((H_MAX - scale * iw) / 2) + H_MARGIN); 509: tm = (top > 0)? top : (((W_MAX - scale * ih * 6) / 2) + W_MARGIN); 510: sprintf(bp, LN_PFS, "?21"); bp += 7; 511: sprintf(bp, LN_DECOPM_SET); bp += sizeof LN_DECOPM_SET - 1; 512: sprintf(bp, LN_DECSLRM, lm, H_PAGE - lm); bp += strlen(bp); 513: } 514: 515: if (header != NULL) { 516: sprintf(bp, LN_VPA, tm - 100); bp += strlen(bp); 517: i = strlen(header); 518: xm = (((scale * iw) - (i * 30)) / 2) + lm; 519: sprintf(bp, LN_HPA, xm); bp += strlen(bp); 520: sprintf(bp, LN_SGR, 3); bp += strlen(bp); 521: bcopy(header, bp, i); 522: bp += i; 523: } 524: if (trailer != NULL) { 525: sprintf(bp, LN_VPA, tm + (scale * ih * 6) + 75); bp += strlen(bp); 526: i = strlen(trailer); 527: xm = (((scale * iw) - (i * 30)) / 2) + lm; 528: sprintf(bp, LN_HPA, xm); bp += strlen(bp); 529: sprintf(bp, LN_SGR, 3); bp += strlen(bp); 530: bcopy(trailer, bp, i); 531: bp += i; 532: } 533: 534: sprintf(bp, LN_HPA, lm); bp += strlen(bp); 535: sprintf(bp, LN_VPA, tm); bp += strlen(bp); 536: sprintf(bp, LN_SIXEL_GRAPHICS, 9, 0, scale); bp += strlen(bp); 537: sprintf(bp, "\"1;1"); bp += 4; /* Pixel aspect ratio */ 538: write(1, buf, bp-buf); 539: *top_margin = tm; 540: *left_margin = lm; 541: } 542: 543: #define LN03_RESET "\033c" 544: 545: ln03_finish() 546: { 547: write(1, LN03_RESET, sizeof LN03_RESET - 1); 548: } 549: 550: la100_setup(iw, ih, scale) 551: { 552: unsigned char buf[256]; 553: register unsigned char *bp; 554: int lm, tm; 555: 556: bp = buf; 557: lm = ((80 - (int)((double)iw / 6.6)) / 2) - 1; 558: if (lm < 1) lm = 1; 559: tm = ((66 - (int)((double)ih / 2)) / 2) - 1; 560: if (tm < 1) tm = 1; 561: sprintf(bp, "\033[%d;%ds", lm, 81-lm); bp += strlen(bp); 562: sprintf(bp, "\033[?7l"); bp += 5; 563: sprintf(bp, "\033[%dd", tm); bp += strlen(bp); 564: sprintf(bp, "\033[%d`", lm); bp += strlen(bp); 565: sprintf(bp, "\033P0q"); bp += 4; 566: write(1, buf, bp-buf); 567: } 568: 569: #define LA100_RESET "\033[1;80s\033[?7h" 570: 571: la100_finish() 572: { 573: write(1, LA100_RESET, sizeof LA100_RESET - 1); 574: } 575: 576: ln03_alter_background(sixmap, iw, ih) 577: unsigned char (*sixmap)[]; 578: int iw; 579: int ih; 580: { 581: register int size; 582: register unsigned char *c, *stopc; 583: register unsigned char *startc; 584: register int n; 585: 586: c = (unsigned char *)sixmap; 587: stopc = c + (iw * ih); 588: n = 0; 589: while (c < stopc) { 590: switch (*c) { 591: case 0x08: case 0x11: case 0x04: case 0x22: 592: case 0x20: case 0x21: case 0x24: case 0x00: 593: if (n == 0) startc = c; 594: n++; 595: break; 596: 597: default: 598: if (n >= 2) { 599: while (n-- > 0) *startc++ = 0x00; 600: } else { 601: n = 0; 602: } 603: break; 604: } 605: c++; 606: } 607: } 608: 609: ln03_output_sixels(sixmap, iw, ih, nosixopt, split, scale, top_margin, 610: left_margin) 611: unsigned char (*sixmap)[]; 612: int iw; 613: int ih; 614: int nosixopt; 615: int split; 616: int top_margin; 617: int left_margin; 618: { 619: unsigned char *buf; 620: register unsigned char *bp; 621: int i; 622: int j; 623: register int k; 624: register unsigned char *c; 625: register int lastc; 626: register int count; 627: char snum[6]; 628: register char *snp; 629: 630: bp = (unsigned char *)malloc(iw*ih+512); 631: buf = bp; 632: count = 0; 633: lastc = -1; 634: c = (unsigned char *)sixmap; 635: split = ih / split; /* number of lines per page */ 636: 637: iw--; /* optimization */ 638: for (i = 0; i < ih; i++) { 639: for (j = 0; j <= iw; j++) { 640: if (!nosixopt) { 641: if (*c == lastc && j < iw) { 642: count++; 643: c++; 644: continue; 645: } 646: if (count >= 3) { 647: bp--; 648: count++; 649: *bp++ = '!'; 650: snp = snum; 651: while (count > 0) { 652: k = count / 10; 653: *snp++ = count - (k * 10) + '0'; 654: count = k; 655: } 656: while (--snp >= snum) *bp++ = *snp; 657: *bp++ = (~lastc & 0x3F) + 0x3F; 658: } else if (count > 0) { 659: lastc = (~lastc & 0x3F) + 0x3F; 660: do { 661: *bp++ = lastc; 662: } while (--count > 0); 663: } 664: } 665: lastc = *c++; 666: *bp++ = (~lastc & 0x3F) + 0x3F; 667: } 668: *bp++ = '-'; /* New line */ 669: lastc = -1; 670: if ((i % split) == 0 && i != 0) { 671: sprintf(bp, LN_ST); bp += sizeof LN_ST - 1; 672: *bp++ = '\f'; 673: sprintf(bp, LN_VPA, top_margin + (i * 6 * scale)); bp += strlen(bp); 674: sprintf(bp, LN_HPA, left_margin); bp += strlen(bp); 675: sprintf(bp, LN_SIXEL_GRAPHICS, 9, 0, scale); bp += strlen(bp); 676: sprintf(bp, "\"1;1"); bp += 4; 677: } 678: } 679: 680: sprintf(bp, LN_ST); bp += sizeof LN_ST - 1; 681: *bp++ = '\f'; 682: write(1, buf, bp-buf); 683: } 684: 685: la100_output_sixels(sixmap, iw, ih) 686: unsigned char (*sixmap)[]; 687: int iw; 688: int ih; 689: { 690: unsigned char *buf; 691: register unsigned char *bp; 692: int i; 693: register int j, k; 694: register unsigned char *c; 695: register int lastc; 696: register int count; 697: char snum[6]; 698: 699: bp = (unsigned char *)malloc(iw*ih+512); 700: buf = bp; 701: count = 0; 702: lastc = -1; 703: c = (unsigned char *)sixmap; 704: 705: for (i = 0; i < ih; i++) { 706: for (j = 0; j < iw; j++) { 707: if (*c == lastc && (j+1) < iw) { 708: count++; 709: c++; 710: continue; 711: } 712: if (count >= 2) { 713: bp -= 2; 714: count = 2 * (count + 1); 715: *bp++ = '!'; 716: k = 0; 717: while (count > 0) { 718: snum[k++] = (count % 10) + '0'; 719: count /= 10; 720: } 721: while (--k >= 0) *bp++ = snum[k]; 722: *bp++ = (~lastc & 0x3F) + 0x3F; 723: count = 0; 724: } else if (count > 0) { 725: lastc = (~lastc & 0x3F) + 0x3F; 726: do { 727: *bp++ = lastc; 728: *bp++ = lastc; 729: } while (--count > 0); 730: } 731: lastc = (~*c & 0x3F) + 0x3F; 732: *bp++ = lastc; 733: *bp++ = lastc; 734: lastc = *c++; 735: } 736: *bp++ = '-'; /* New line */ 737: lastc = -1; 738: } 739: 740: sprintf(bp, LN_ST); bp += sizeof LN_ST - 1; 741: *bp++ = '\f'; 742: write(1, buf, bp-buf); 743: }