[BACK]Return to wprinter.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot / win

Annotation of OpenXM_contrib/gnuplot/win/wprinter.c, Revision 1.1.1.2

1.1       maekawa     1: #ifndef lint
1.1.1.2 ! maekawa     2: static char *RCSid = "$Id: wprinter.c,v 1.1.1.2 1998/04/15 19:23:55 lhecking Exp $";
1.1       maekawa     3: #endif
                      4:
                      5: /* GNUPLOT - win/wprinter.c */
                      6: /*[
                      7:  * Copyright 1992, 1993, 1998   Maurice Castro, Russell Lang
                      8:  *
                      9:  * Permission to use, copy, and distribute this software and its
                     10:  * documentation for any purpose with or without fee is hereby granted,
                     11:  * provided that the above copyright notice appear in all copies and
                     12:  * that both that copyright notice and this permission notice appear
                     13:  * in supporting documentation.
                     14:  *
                     15:  * Permission to modify the software is granted, but not the right to
                     16:  * distribute the complete modified source code.  Modifications are to
                     17:  * be distributed as patches to the released version.  Permission to
                     18:  * distribute binaries produced by compiling modified sources is granted,
                     19:  * provided you
                     20:  *   1. distribute the corresponding source modifications from the
                     21:  *    released version in the form of a patch file along with the binaries,
                     22:  *   2. add special version identification to distinguish your version
                     23:  *    in addition to the base release version number,
                     24:  *   3. provide your name and address as the primary contact for the
                     25:  *    support of your modified version, and
                     26:  *   4. retain our contact information in regard to use of the base
                     27:  *    software.
                     28:  * Permission to distribute the released version of the source code along
                     29:  * with corresponding source modifications in the form of a patch file is
                     30:  * granted with same provisions 2 through 4 for binary distributions.
                     31:  *
                     32:  * This software is provided "as is" without express or implied warranty
                     33:  * to the extent permitted by applicable law.
                     34: ]*/
                     35:
                     36: /*
                     37:  * AUTHORS
                     38:  *
                     39:  *   Maurice Castro
                     40:  *   Russell Lang
                     41:  *
                     42:  * Send your comments or suggestions to
                     43:  *  info-gnuplot@dartmouth.edu.
                     44:  * This is a mailing list; to join it send a note to
                     45:  *  majordomo@dartmouth.edu.
                     46:  * Send bug reports to
                     47:  *  bug-gnuplot@dartmouth.edu.
                     48:  */
                     49:
                     50: /* Dump a file to the printer */
                     51:
                     52: #define STRICT
                     53: #include <windows.h>
                     54: #include <windowsx.h>
                     55: #if WINVER >= 0x030a
                     56: #include <commdlg.h>
                     57: #endif
                     58: #ifdef WIN32
                     59: #include <stdio.h>
                     60: #include <stdlib.h>
                     61: #endif
                     62: #ifdef __MSC__
                     63: #include <memory.h>
                     64: #else
                     65: #include <mem.h>
                     66: #endif
                     67: #include "wgnuplib.h"
                     68: #include "wresourc.h"
                     69: #include "wcommon.h"
                     70:
                     71: LPPRINT prlist = NULL;
                     72:
                     73: BOOL CALLBACK WINEXPORT PrintSizeDlgProc(HWND hdlg, UINT wmsg, WPARAM wparam, LPARAM lparam);
                     74: BOOL CALLBACK WINEXPORT
                     75: PrintSizeDlgProc(HWND hdlg, UINT wmsg, WPARAM wparam, LPARAM lparam)
                     76: {
                     77:        char buf[8];
                     78:        LPPRINT lpr;
                     79:        lpr = (LPPRINT)GetWindowLong(GetParent(hdlg), 4);
                     80:
                     81:        switch (wmsg) {
                     82:                case WM_INITDIALOG:
                     83:                        wsprintf(buf,"%d",lpr->pdef.x);
                     84:                        SetDlgItemText(hdlg, PSIZE_DEFX, buf);
                     85:                        wsprintf(buf,"%d",lpr->pdef.y);
                     86:                        SetDlgItemText(hdlg, PSIZE_DEFY, buf);
                     87:                        wsprintf(buf,"%d",lpr->poff.x);
                     88:                        SetDlgItemText(hdlg, PSIZE_OFFX, buf);
                     89:                        wsprintf(buf,"%d",lpr->poff.y);
                     90:                        SetDlgItemText(hdlg, PSIZE_OFFY, buf);
                     91:                        wsprintf(buf,"%d",lpr->psize.x);
                     92:                        SetDlgItemText(hdlg, PSIZE_X, buf);
                     93:                        wsprintf(buf,"%d",lpr->psize.y);
                     94:                        SetDlgItemText(hdlg, PSIZE_Y, buf);
                     95:                        CheckDlgButton(hdlg, PSIZE_DEF, TRUE);
                     96:                        EnableWindow(GetDlgItem(hdlg, PSIZE_X), FALSE);
                     97:                        EnableWindow(GetDlgItem(hdlg, PSIZE_Y), FALSE);
                     98:                        return TRUE;
                     99:                case WM_COMMAND:
                    100:                        switch (wparam) {
                    101:                                case PSIZE_DEF:
                    102:                                        EnableWindow(GetDlgItem(hdlg, PSIZE_X), FALSE);
                    103:                                        EnableWindow(GetDlgItem(hdlg, PSIZE_Y), FALSE);
                    104:                                        return FALSE;
                    105:                                case PSIZE_OTHER:
                    106:                                        EnableWindow(GetDlgItem(hdlg, PSIZE_X), TRUE);
                    107:                                        EnableWindow(GetDlgItem(hdlg, PSIZE_Y), TRUE);
                    108:                                        return FALSE;
                    109:                                case IDOK:
                    110:                                        if (SendDlgItemMessage(hdlg, PSIZE_OTHER, BM_GETCHECK, 0, 0L)) {
                    111:                                                SendDlgItemMessage(hdlg, PSIZE_X, WM_GETTEXT, 7, (LPARAM)((LPSTR)buf));
                    112:                                                GetInt(buf, (LPINT)&lpr->psize.x);
                    113:                                                SendDlgItemMessage(hdlg, PSIZE_Y, WM_GETTEXT, 7, (LPARAM)((LPSTR)buf));
                    114:                                                GetInt(buf, (LPINT)&lpr->psize.y);
                    115:                                        }
                    116:                                        else {
                    117:                                                lpr->psize.x = lpr->pdef.x;
                    118:                                                lpr->psize.y = lpr->pdef.y;
                    119:                                        }
                    120:                                        SendDlgItemMessage(hdlg, PSIZE_OFFX, WM_GETTEXT, 7, (LPARAM)((LPSTR)buf));
                    121:                                        GetInt(buf, (LPINT)&lpr->poff.x);
                    122:                                        SendDlgItemMessage(hdlg, PSIZE_OFFY, WM_GETTEXT, 7, (LPARAM)((LPSTR)buf));
                    123:                                        GetInt(buf, (LPINT)&lpr->poff.y);
                    124:
                    125:                                        if (lpr->psize.x <= 0)
                    126:                                                lpr->psize.x = lpr->pdef.x;
                    127:                                        if (lpr->psize.y <= 0)
                    128:                                                lpr->psize.y = lpr->pdef.y;
                    129:
                    130:                                        EndDialog(hdlg, IDOK);
                    131:                                        return TRUE;
                    132:                                case IDCANCEL:
                    133:                                        EndDialog(hdlg, IDCANCEL);
                    134:                                        return TRUE;
                    135:                        }
                    136:                        break;
                    137:        }
                    138:        return FALSE;
                    139: }
                    140:
                    141:
                    142:
                    143: /* GetWindowLong(hwnd, 4) must be available for use */
                    144: BOOL
                    145: PrintSize(HDC printer, HWND hwnd, LPRECT lprect)
                    146: {
                    147: HDC hdc;
                    148: DLGPROC lpfnPrintSizeDlgProc ;
                    149: BOOL status = FALSE;
                    150: PRINT pr;
                    151:
                    152:        SetWindowLong(hwnd, 4, (LONG)((LPPRINT)&pr));
                    153:        pr.poff.x = 0;
                    154:        pr.poff.y = 0;
                    155:        pr.psize.x = GetDeviceCaps(printer, HORZSIZE);
                    156:        pr.psize.y = GetDeviceCaps(printer, VERTSIZE);
                    157:        hdc = GetDC(hwnd);
                    158:        GetClientRect(hwnd,lprect);
                    159:        pr.pdef.x = MulDiv(lprect->right-lprect->left, 254, 10*GetDeviceCaps(hdc, LOGPIXELSX));
                    160:        pr.pdef.y = MulDiv(lprect->bottom-lprect->top, 254, 10*GetDeviceCaps(hdc, LOGPIXELSX));
                    161:        ReleaseDC(hwnd,hdc);
                    162: #ifdef WIN32
                    163:        if (DialogBox (hdllInstance, "PrintSizeDlgBox", hwnd, PrintSizeDlgProc)
                    164: #else
                    165: #ifdef __DLL__
                    166:        lpfnPrintSizeDlgProc = (DLGPROC)GetProcAddress(hdllInstance, "PrintSizeDlgProc");
                    167: #else
                    168:        lpfnPrintSizeDlgProc = (DLGPROC)MakeProcInstance((FARPROC)PrintSizeDlgProc, hdllInstance);
                    169: #endif
                    170:        if (DialogBox (hdllInstance, "PrintSizeDlgBox", hwnd, lpfnPrintSizeDlgProc)
                    171: #endif
                    172:                == IDOK) {
                    173:                lprect->left = MulDiv(pr.poff.x*10, GetDeviceCaps(printer, LOGPIXELSX), 254);
                    174:                lprect->top = MulDiv(pr.poff.y*10, GetDeviceCaps(printer, LOGPIXELSY), 254);
                    175:                lprect->right = lprect->left + MulDiv(pr.psize.x*10, GetDeviceCaps(printer, LOGPIXELSX), 254);
                    176:                lprect->bottom = lprect->top + MulDiv(pr.psize.y*10, GetDeviceCaps(printer, LOGPIXELSY), 254);
                    177:                status = TRUE;
                    178:        }
                    179: #ifndef WIN32
                    180: #ifndef __DLL__
                    181:        FreeProcInstance((FARPROC)lpfnPrintSizeDlgProc);
                    182: #endif
                    183: #endif
                    184:        SetWindowLong(hwnd, 4, (LONG)(0L));
                    185:
                    186:        return status;
                    187: }
                    188:
                    189: #ifdef WIN32
                    190: /* Win32 doesn't support OpenJob() etc. so we must use some old code
                    191:  * which attempts to sneak the output through a Windows printer driver */
                    192: void
                    193: PrintRegister(LPPRINT lpr)
                    194: {
                    195:        LPPRINT next;
                    196:        next = prlist;
                    197:        prlist = lpr;
                    198:        lpr->next = next;
                    199: }
                    200:
                    201: LPPRINT
                    202: PrintFind(HDC hdc)
                    203: {
                    204:        LPPRINT this;
                    205:        this = prlist;
                    206:        while (this && (this->hdcPrn!=hdc)) {
                    207:                this = this->next;
                    208:        }
                    209:        return this;
                    210: }
                    211:
                    212: void
                    213: PrintUnregister(LPPRINT lpr)
                    214: {
                    215:        LPPRINT this, prev;
                    216:        prev = (LPPRINT)NULL;
                    217:        this = prlist;
                    218:        while (this && (this!=lpr)) {
                    219:                prev = this;
                    220:                this = this->next;
                    221:        }
                    222:        if (this && (this == lpr)) {
                    223:                /* unhook it */
                    224:                if (prev)
                    225:                        prev->next = this->next;
                    226:                else
                    227:                        prlist = this->next;
                    228:        }
                    229: }
                    230:
                    231:
                    232: /* GetWindowLong(GetParent(hDlg), 4) must be available for use */
                    233: BOOL CALLBACK WINEXPORT
                    234: PrintDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
                    235: {
                    236:        LPPRINT lpr;
                    237:        lpr = (LPPRINT)GetWindowLong(GetParent(hDlg), 4);
                    238:
                    239:        switch(message) {
                    240:                case WM_INITDIALOG:
                    241:                        lpr->hDlgPrint = hDlg;
                    242:                        SetWindowText(hDlg,(LPSTR)lParam);
                    243:                        EnableMenuItem(GetSystemMenu(hDlg,FALSE),SC_CLOSE,MF_GRAYED);
                    244:                        return TRUE;
                    245:                case WM_COMMAND:
                    246:                        lpr->bUserAbort = TRUE;
                    247:                        lpr->hDlgPrint = 0;
                    248:                        EnableWindow(GetParent(hDlg),TRUE);
                    249:                        EndDialog(hDlg, FALSE);
                    250:                        return TRUE;
                    251:        }
                    252:        return FALSE;
                    253: }
                    254:
                    255:
                    256: BOOL CALLBACK WINEXPORT
                    257: PrintAbortProc(HDC hdcPrn, int code)
                    258: {
                    259:     MSG msg;
                    260:     LPPRINT lpr;
                    261:     lpr = PrintFind(hdcPrn);
                    262:
                    263:     while (!lpr->bUserAbort && PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
                    264:                if (!lpr->hDlgPrint || !IsDialogMessage(lpr->hDlgPrint,&msg)) {
                    265:                TranslateMessage(&msg);
                    266:                DispatchMessage(&msg);
                    267:                }
                    268:     }
                    269:     return(!lpr->bUserAbort);
                    270: }
                    271:
                    272:
                    273: /* GetWindowLong(hwnd, 4) must be available for use */
                    274: void WDPROC
                    275: DumpPrinter(HWND hwnd, LPSTR szAppName, LPSTR szFileName)
                    276: {
                    277: HDC printer;
                    278: PRINTDLG pd;
                    279: PRINT pr;
                    280: DOCINFO di;
                    281: char *buf;
                    282: WORD *bufcount;
                    283: int count;
                    284: FILE *f;
                    285: long lsize;
                    286: long ldone;
                    287: char pcdone[10];
                    288:
                    289:        memset(&pd, 0, sizeof(PRINTDLG));
                    290:        pd.lStructSize = sizeof(PRINTDLG);
                    291:        pd.hwndOwner = hwnd;
                    292:        pd.Flags = PD_PRINTSETUP | PD_RETURNDC;
                    293:
                    294:        if ((f = fopen(szFileName, "rb")) == (FILE *)NULL)
                    295:           return;
                    296:        fseek(f, 0L, SEEK_END);
                    297:        lsize = ftell(f);
                    298:        if (lsize <= 0)
                    299:            lsize = 1;
                    300:        fseek(f, 0L, SEEK_SET);
                    301:        ldone = 0;
                    302:
                    303:        if (PrintDlg(&pd)) {
                    304:        printer = pd.hDC;
                    305:        if (printer != (HDC)NULL) {
                    306:          pr.hdcPrn = printer;
                    307:          SetWindowLong(hwnd, 4, (LONG)((LPPRINT)&pr));
                    308:          PrintRegister((LPPRINT)&pr);
                    309:          if ( (buf = malloc(4096+2)) != (char *)NULL ) {
                    310:                bufcount = (WORD *)buf;
                    311:                EnableWindow(hwnd,FALSE);
                    312:                pr.bUserAbort = FALSE;
                    313: /* is parent set correctly */
                    314:                pr.hDlgPrint = CreateDialogParam(hdllInstance,"CancelDlgBox",hwnd,PrintDlgProc,(LPARAM)szAppName);
                    315:                SetAbortProc(printer, PrintAbortProc);
                    316:                di.cbSize = sizeof(DOCINFO);
                    317:                di.lpszDocName = szAppName;
                    318:                di.lpszOutput = NULL;
                    319:                if (StartDoc(printer, &di) > 0) {
                    320:                    while ( pr.hDlgPrint && !pr.bUserAbort
                    321:                        && (count = fread(buf+2, 1, 4096, f)) != 0 ) {
                    322:                        *bufcount = count;
                    323:                        Escape(printer, PASSTHROUGH, count+2, (LPSTR)buf, NULL);
                    324:                        ldone += count;
                    325:                        sprintf(pcdone, "%d%% done", (int)(ldone * 100 / lsize));
                    326:                        SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE), pcdone);
                    327:                        if (pr.bUserAbort)
                    328:                            AbortDoc(printer);
                    329:                        else
                    330:                            EndDoc(printer);
                    331:                    }
                    332:                    if (!pr.bUserAbort) {
                    333:                        EnableWindow(hwnd,TRUE);
                    334:                        DestroyWindow(pr.hDlgPrint);
                    335:                    }
                    336:                    free(buf);
                    337:                }
                    338:          }
                    339:          DeleteDC(printer);
                    340:          SetWindowLong(hwnd, 4, (LONG)(0L));
                    341:          PrintUnregister((LPPRINT)&pr);
                    342:        }
                    343:        }
                    344:        fclose(f);
                    345: }
                    346:
                    347:
                    348: #else  /* !WIN32 */
                    349: /* documented in Device Driver Adaptation Guide */
                    350: /* Prototypes taken from print.h */
                    351: DECLARE_HANDLE(HPJOB);
                    352:
                    353: HPJOB   WINAPI OpenJob(LPSTR, LPSTR, HPJOB);
                    354: int     WINAPI StartSpoolPage(HPJOB);
                    355: int     WINAPI EndSpoolPage(HPJOB);
                    356: int     WINAPI WriteSpool(HPJOB, LPSTR, int);
                    357: int     WINAPI CloseJob(HPJOB);
                    358: int     WINAPI DeleteJob(HPJOB, int);
                    359: int     WINAPI WriteDialog(HPJOB, LPSTR, int);
                    360: int     WINAPI DeleteSpoolPage(HPJOB);
                    361:
                    362: /* Modeless dialog box - Cancel printing */
                    363: BOOL CALLBACK WINEXPORT
                    364: CancelDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
                    365: {
                    366:     switch(message) {
                    367:        case WM_INITDIALOG:
                    368:            SetWindowText(hDlg,(LPSTR)lParam);
                    369:            return TRUE;
                    370:        case WM_COMMAND:
                    371:            switch(LOWORD(wParam)) {
                    372:                case IDCANCEL:
                    373:                    DestroyWindow(hDlg);
                    374:                    return TRUE;
                    375:            }
                    376:     }
                    377:     return FALSE;
                    378: }
                    379:
                    380:
                    381:
                    382: /* Dialog box to select printer port */
                    383: BOOL CALLBACK WINEXPORT
                    384: SpoolDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
                    385: {
                    386: LPSTR entry;
                    387:     switch(message) {
                    388:        case WM_INITDIALOG:
                    389:            entry = (LPSTR)lParam;
                    390:            while (*entry) {
                    391:                SendDlgItemMessage(hDlg, SPOOL_PORT, LB_ADDSTRING, 0, (LPARAM)entry);
                    392:                entry += lstrlen(entry)+1;
                    393:            }
                    394:            SendDlgItemMessage(hDlg, SPOOL_PORT, LB_SETCURSEL, 0, (LPARAM)0);
                    395:            return TRUE;
                    396:        case WM_COMMAND:
                    397:            switch(LOWORD(wParam)) {
                    398:                case SPOOL_PORT:
                    399:                    if (HIWORD(lParam) == LBN_DBLCLK)
                    400:                        PostMessage(hDlg, WM_COMMAND, IDOK, 0L);
                    401:                    return FALSE;
                    402:                case IDOK:
                    403:                    EndDialog(hDlg, 1+(int)SendDlgItemMessage(hDlg, SPOOL_PORT, LB_GETCURSEL, 0, 0L));
                    404:                    return TRUE;
                    405:                case IDCANCEL:
                    406:                    EndDialog(hDlg, 0);
                    407:                    return TRUE;
                    408:            }
                    409:     }
                    410:     return FALSE;
                    411: }
                    412:
                    413: /* Print File to port */
                    414: void WDPROC
                    415: DumpPrinter(HWND hwnd, LPSTR szAppName, LPSTR szFileName)
                    416: {
                    417: #define PRINT_BUF_SIZE 4096
                    418: char *buffer;
                    419: char *portname;
                    420: int i, iport;
                    421: DLGPROC lpfnSpoolProc;
                    422: HPJOB hJob;
                    423: UINT count;
                    424: HFILE hf;
                    425: int error = FALSE;
                    426: DLGPROC lpfnCancelProc;
                    427: long lsize;
                    428: long ldone;
                    429: char pcdone[10];
                    430: MSG msg;
                    431: HWND hDlgModeless;
                    432:
                    433:        if ((buffer = LocalAllocPtr(LHND, PRINT_BUF_SIZE)) == (char *)NULL)
                    434:            return;
                    435:        /* get list of ports */
                    436:        GetProfileString("ports", NULL, "", buffer, PRINT_BUF_SIZE);
                    437:        /* select a port */
                    438:        lpfnSpoolProc = (DLGPROC)MakeProcInstance((FARPROC)SpoolDlgProc, hdllInstance);
                    439:        iport = DialogBoxParam(hdllInstance, "SpoolDlgBox", hwnd, lpfnSpoolProc, (LPARAM)buffer);
                    440:        FreeProcInstance((FARPROC)lpfnSpoolProc);
                    441:        if (!iport) {
                    442:                LocalFreePtr((void NEAR *)buffer);
                    443:                return;
                    444:        }
                    445:        portname = buffer;
                    446:        for (i=1; i<iport && lstrlen(portname)!=0; i++)
                    447:                portname += lstrlen(portname)+1;
                    448:
                    449:        /* open file and get length */
                    450:        hf = _lopen(szFileName, OF_READ);
                    451:        if (hf == HFILE_ERROR) {
                    452:            LocalFreePtr((void NEAR *)buffer);
                    453:            return;
                    454:        }
                    455:        lsize = _llseek(hf, 0L, 2);
                    456:        (void)_llseek(hf, 0L, 0);
                    457:        if (lsize <= 0)
                    458:            lsize = 1;
                    459:
                    460:        hJob = OpenJob(portname, szFileName, (HDC)NULL);
                    461:        switch ((int)hJob) {
                    462:            case SP_APPABORT:
                    463:            case SP_ERROR:
                    464:            case SP_OUTOFDISK:
                    465:            case SP_OUTOFMEMORY:
                    466:            case SP_USERABORT:
                    467:                _lclose(hf);
                    468:                LocalFreePtr((void NEAR *)buffer);
                    469:                return;
                    470:        }
                    471:        if (StartSpoolPage(hJob) < 0)
                    472:            error = TRUE;
                    473:
                    474:        ldone = 0;
                    475:        lpfnCancelProc = (DLGPROC)MakeProcInstance((FARPROC)CancelDlgProc, hdllInstance);
                    476:        hDlgModeless = CreateDialogParam(hdllInstance, "CancelDlgBox", hwnd, lpfnCancelProc, (LPARAM)szAppName);
                    477:
                    478:        while (!error && hDlgModeless && IsWindow(hDlgModeless)
                    479:           && ((count = _lread(hf, buffer, PRINT_BUF_SIZE))!= 0) ) {
                    480:            wsprintf(pcdone, "%d%% done", (int)(ldone * 100 / lsize));
                    481:            SetWindowText(GetDlgItem(hDlgModeless, CANCEL_PCDONE), pcdone);
                    482:            if (WriteSpool(hJob, buffer, count) < 0)
                    483:                error = TRUE;
                    484:            ldone += count;
                    485:            while (IsWindow(hDlgModeless) && PeekMessage(&msg, hDlgModeless, 0, 0, PM_REMOVE)) {
                    486:                if (!IsDialogMessage(hDlgModeless, &msg)) {
                    487:                    TranslateMessage(&msg);
                    488:                    DispatchMessage(&msg);
                    489:                }
                    490:            }
                    491:        }
                    492:        LocalFreePtr((void NEAR *)buffer);
                    493:        _lclose(hf);
                    494:
                    495:        if (!hDlgModeless || !IsWindow(hDlgModeless))
                    496:            error=TRUE;
                    497:        if (IsWindow(hDlgModeless))
                    498:            DestroyWindow(hDlgModeless);
                    499:        hDlgModeless = 0;
                    500:        FreeProcInstance((FARPROC)lpfnCancelProc);
                    501:        EndSpoolPage(hJob);
                    502:        if (error)
                    503:            DeleteJob(hJob, 0);
                    504:        else
                    505:            CloseJob(hJob);
                    506: }
                    507: #endif /* !WIN32 */
                    508:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>