text:
//
//  ramchainapi.c
//  crypto777
//
//  Created by James on 4/9/15.
//  Copyright (c) 2015 jl777. All rights reserved.
//

#ifdef DEFINES_ONLY
#ifndef crypto777_ramchainapi_h
#define crypto777_ramchainapi_h
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "cJSON.h"
#include "huff.c"
#include "NXT777.c"
#include "blocks.c"
#include "../coins/msig.c"

char *ramstatus(char *origargstr,char *sender,char *previpaddr,char *coin);
char *rampyramid(char *NXTaddr,char *origargstr,char *sender,char *previpaddr,char *coin,uint32_t blocknum,char *typestr);
char *ramstring(char *origargstr,char *sender,char *previpaddr,char *coin,char *typestr,uint32_t rawind);
char *ramrawind(char *origargstr,char *sender,char *previpaddr,char *coin,char *typestr,char *str);
char *ramblock(char *NXTaddr,char *origargstr,char *sender,char *previpaddr,char *coin,uint32_t blocknum);
char *ramcompress(char *origargstr,char *sender,char *previpaddr,char *coin,char *ramhex);
char *ramexpand(char *origargstr,char *sender,char *previpaddr,char *coin,char *bitstream);
char *ramscript(char *origargstr,char *sender,char *previpaddr,char *coin,char *txidstr,int32_t tx_vout,struct address_entry *bp);
char *ramtxlist(char *origargstr,char *sender,char *previpaddr,char *coin,char *coinaddr,int32_t unspentflag);
char *ramrichlist(char *origargstr,char *sender,char *previpaddr,char *coin,int32_t numwhales,int32_t recalcflag);
char *rambalances(char *origargstr,char *sender,char *previpaddr,char *coin,char **coins,double *rates,char ***coinaddrs,int32_t numcoins);
char *ramaddrlist(char *origargstr,char *sender,char *previpaddr,char *coin);

struct ramchain_info *get_ramchain_info(char *coinstr);

#endif
#else
#ifndef crypto777_ramchainapi_c
#define crypto777_ramchainapi_c

#ifndef crypto777_ramchainapi_h
#define DEFINES_ONLY
#include "api.c"
#undef DEFINES_ONLY
#endif

uint64_t ram_unspent_json(cJSON **arrayp,char *destcoin,double rate,char *coin,char *addr)
{
    struct ramchain_info *ram = get_ramchain_info(coin);
    uint64_t unspent = 0;
    cJSON *item;
    if ( ram != 0 )
    {
        if ( (unspent= ram_calc_unspent(0,0,0,ram,addr,0)) != 0 && arrayp != 0 )
        {
            item = cJSON_CreateObject();
            cJSON_AddItemToObject(item,addr,cJSON_CreateNumber(dstr(unspent)));
            if ( rate != 0. )
            {
                unspent *= rate;
                cJSON_AddItemToObject(item,destcoin,cJSON_CreateNumber(dstr(unspent)));
            }
            cJSON_AddItemToArray(*arrayp,item);
        }
        else if ( rate != 0. )
            unspent *= rate;
    }
    return(unspent);
}

static int _decreasing_double_cmp(const void *a,const void *b)
{
#define double_a (*(double *)a)
#define double_b (*(double *)b)
	if ( double_b > double_a )
		return(1);
	else if ( double_b < double_a )
		return(-1);
	return(0);
#undef double_a
#undef double_b
}

/*static int _decreasing_uint64_cmp(const void *a,const void *b)
 {
 #define uint64_a (*(uint64_t *)a)
 #define uint64_b (*(uint64_t *)b)
 if ( uint64_b > uint64_a )
 return(1);
 else if ( uint64_b < uint64_a )
 return(-1);
 return(0);
 #undef uint64_a
 #undef uint64_b
 }*/

struct ramchain_hashptr **ram_getallstrptrs(int32_t *numstrsp,struct ramchain_info *ram,char type)
{
    struct ramchain_hashptr **strs = 0;
    struct ramchain_hashtable *hash;
    hash = ram_gethash(ram,type);
    *numstrsp = hash->ind;
    strs = calloc(*numstrsp+1,sizeof(*strs));
    memcpy(strs,hash->ptrs+1,(*numstrsp) * sizeof(*strs));
    return(strs);
}

char *ramaddrlist(char *origargstr,char *sender,char *previpaddr,char *coin)
{
    cJSON *json,*array,*item;
    char retbuf[1024],coinaddr[MAX_JSON_FIELD],account[MAX_JSON_FIELD],*retstr = 0;
    uint64_t value;
    uint32_t rawind;
    struct ramchain_hashtable *addrhash;
    struct ramchain_hashptr *addrptr;
    struct rampayload *payloads;
    int32_t i,j,k,z,n,m,num,numpayloads,errs,count = 0; // ,ismine,ismultisig
    struct ramchain_info *ram = get_ramchain_info(coin);
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    errs = 0;
    addrhash = ram_gethash(ram,'a');
    if ( (json= _get_localaddresses(ram->name,ram->serverport,ram->userpass)) != 0 )
    {
        if ( is_cJSON_Array(json) != 0 && (n= cJSON_GetArraySize(json)) > 0 )
        {
            for (i=0; i<n; i++)
            {
                if ( (array= cJSON_GetArrayItem(json,i)) != 0 && is_cJSON_Array(array) != 0 && (m= cJSON_GetArraySize(array)) > 0 )
                {
                    for (j=0; j<m; j++)
                    {
                        item = cJSON_GetArrayItem(array,j);
                        if ( (item= cJSON_GetArrayItem(array,j)) != 0 && is_cJSON_Array(item) != 0 && (num= cJSON_GetArraySize(item)) > 0 )
                        {
                            value = coinaddr[0] = account[0] = 0;
                            for (k=0; k<num; k++)
                            {
                                if ( k == 0 )
                                    copy_cJSON(coinaddr,cJSON_GetArrayItem(item,0));
                                else if ( k == 1 )
                                    value = (SATOSHIDEN * get_API_float(cJSON_GetArrayItem(item,1)));
                                else if ( k == 2 )
                                    copy_cJSON(account,cJSON_GetArrayItem(item,2));
                                else printf("ramaddrlist unexpected item array size: %d\n",num);
                            }
                            rawind = 0;
                            if ( coinaddr[0] != 0 && (rawind= ram_addrind(ram,coinaddr)) != 0 )
                            {
                                if ( (payloads= ram_addrpayloads(&addrptr,&numpayloads,ram,coinaddr)) != 0 && addrptr != 0 && numpayloads > 0 )
                                {
                                    addrptr->mine = 1;
                                    printf("%d: (%s).%-6d %.8f %.8f (%s) %s\n",count,coinaddr,rawind,dstr(addrptr->unspent),dstr(value),account,(addrptr->unspent != value) ? "STAKING": "");
                                    errs += (addrptr->unspent != value);
                                    count++;
                                } else printf("ramaddrlist error finding rawind.%d\n",rawind);
                            } else printf("ramaddrlist no coinaddr for item or null rawind.%d\n",rawind);
                        } else printf("ramaddrlist unexpected item not array\n");
                    }
                } else printf("ramaddrlist unexpected array not array\n");
            }
        } else printf("ramaddrlist unexpected json not array\n");
        free_json(json);
        n = m = 0;
        for (z=1; z<=addrhash->ind; z++)
        {
            if ( (addrptr= addrhash->ptrs[z]) != 0 && (addrptr->multisig != 0 || addrptr->mine != 0) && ram_decode_hashdata(coinaddr,'a',addrptr->hh.key) != 0 )
            {
                /*if ( 0 && addrptr->mine == 0 && addrptr->verified == 0 )
                {
                    addrptr->verified = _verify_coinaddress(account,&ismultisig,&ismine,ram,coinaddr);
                    if ( ismultisig != 0 )
                        addrptr->multisig = 1;
                    if ( ismine != 0 )
                        addrptr->mine = 1;
                }*/
                if ( addrptr->mine != 0 )
                    m++;
                if ( addrptr->multisig != 0 || addrptr->mine != 0 )
                    printf("n.%d check.(%s) account.(%s) multisig.%d nonstandard.%d mine.%d verified.%d\n",n,coinaddr,account,addrptr->multisig,addrptr->nonstandard,addrptr->mine,addrptr->verified), n++;
            }
        }
        sprintf(retbuf,"{\"result\":\"addrlist\",\"multisig\":%d,\"mine\":%d,\"total\":%d}",n,m,count);
        retstr = clonestr(retbuf);
    } else retstr = clonestr("{\"error\":\"ramaddrlist no data\"}");
    return(retstr);
}

cJSON *ram_address_entry_json(struct address_entry *bp)
{
    cJSON *array = cJSON_CreateArray();
    cJSON_AddItemToArray(array,cJSON_CreateNumber(bp->blocknum));
    cJSON_AddItemToArray(array,cJSON_CreateNumber(bp->txind));
    cJSON_AddItemToArray(array,cJSON_CreateNumber(bp->v));
    return(array);
}

void ram_payload_json(cJSON *json,struct rampayload *payload,int32_t spentflag)
{
    cJSON_AddItemToObject(json,"n",cJSON_CreateNumber(payload->B.v));
    cJSON_AddItemToObject(json,"value",cJSON_CreateNumber(dstr(payload->value)));
    if ( payload->B.isinternal != 0 )
        cJSON_AddItemToObject(json,"MGWinternal",cJSON_CreateNumber(1));
    if ( spentflag != 0 && payload->B.spent != 0 )
        cJSON_AddItemToObject(json,"spent",ram_address_entry_json(&payload->spentB));
}

cJSON *ram_addrpayload_json(struct ramchain_info *ram,struct rampayload *payload)
{
    char txidstr[8192];
    ram_txid(txidstr,ram,payload->otherind);
    cJSON *json = cJSON_CreateObject();
    if ( payload->pendingdeposit != 0 )
        cJSON_AddItemToObject(json,"pendingdeposit",cJSON_CreateNumber(1));
    cJSON_AddItemToObject(json,"txid",cJSON_CreateString(txidstr));
    cJSON_AddItemToObject(json,"txid_rawind",cJSON_CreateNumber(payload->otherind));
    cJSON_AddItemToObject(json,"txout",ram_address_entry_json(&payload->B));
    cJSON_AddItemToObject(json,"scriptind",cJSON_CreateNumber(payload->extra));
    ram_payload_json(json,payload,1);
    return(json);
}

#define ram_rawtx(raw,txind) (((txind) < (raw)->numtx) ? &(raw)->txspace[txind] : 0)

struct rawvout *ram_rawvout(struct rawblock *raw,int32_t txind,int32_t v)
{
    struct rawtx *tx;
    if ( txind < raw->numtx )
    {
        if ( (tx= ram_rawtx(raw,txind)) != 0 )
            return(&raw->voutspace[tx->firstvout + v]);
    }
    return(0);
}

struct rawvin *ram_rawvin(struct rawblock *raw,int32_t txind,int32_t v)
{
    struct rawtx *tx;
    if ( txind < raw->numtx )
    {
        if ( (tx= ram_rawtx(raw,txind)) != 0 )
            return(&raw->vinspace[tx->firstvin + v]);
    }
    return(0);
}

cJSON *ram_txpayload_json(struct ramchain_info *ram,struct rampayload *txpayload,char *spent_txidstr,int32_t spent_vout)
{
    cJSON *item;
    HUFF *hp;
    int32_t datalen;
    char coinaddr[8192],scriptstr[8192];
    struct rawvin *vi;
    struct rawtx *tx;
    struct ramchain_hashptr *addrptr;
    struct rampayload *addrpayload;
    ram_addr(coinaddr,ram,txpayload->otherind);
    cJSON *json = cJSON_CreateObject();
    cJSON_AddItemToObject(json,"address",cJSON_CreateString(coinaddr));
    cJSON_AddItemToObject(json,"addr_rawind",cJSON_CreateNumber(txpayload->otherind));
    cJSON_AddItemToObject(json,"addr_txlisti",cJSON_CreateNumber(txpayload->extra));
    ram_payload_json(json,txpayload,0);
    if ( txpayload->spentB.spent != 0 )
    {
        item = cJSON_CreateObject();
        cJSON_AddItemToObject(item,"height",cJSON_CreateNumber(txpayload->spentB.blocknum));
        cJSON_AddItemToObject(item,"txind",cJSON_CreateNumber(txpayload->spentB.txind));
        cJSON_AddItemToObject(item,"vin",cJSON_CreateNumber(txpayload->spentB.v));
        if ( (hp= ram->blocks.hps[txpayload->spentB.blocknum]) != 0 && (datalen= ram_expand_bitstream(0,ram->R,ram,hp)) > 0 )
        {
            if ( (vi= ram_rawvin(ram->R,txpayload->spentB.txind,txpayload->spentB.v)) != 0 )
            {
                if ( strcmp(vi->txidstr,spent_txidstr) != 0 )
                    cJSON_AddItemToObject(item,"vin_txid_error",cJSON_CreateString(vi->txidstr));
                if ( vi->vout != spent_vout )
                    cJSON_AddItemToObject(item,"vin_error",cJSON_CreateNumber(spent_vout));
            }
            if ( (tx= ram_rawtx(ram->R,txpayload->spentB.txind)) != 0 )
                cJSON_AddItemToObject(item,"txid",cJSON_CreateString(tx->txidstr));
        }
        cJSON_AddItemToObject(json,"spent",item);
    }
    else
    {
        if ( (addrpayload= ram_getpayloadi(&addrptr,ram,'a',txpayload->otherind,txpayload->extra)) != 0 )
        {
            ram_script(scriptstr,ram,addrpayload->extra);
            cJSON_AddItemToObject(json,"script",cJSON_CreateString(scriptstr));
            cJSON_AddItemToObject(json,"script_rawind",cJSON_CreateNumber(addrpayload->extra));
        }
    }
    return(json);
}

cJSON *ram_coinaddr_json(struct ramchain_info *ram,char *coinaddr,int32_t unspentflag,int32_t truncateflag,int32_t searchperms)
{
    char *permstr;
    int64_t total = 0;
    cJSON *json = 0,*array = 0;
    int32_t i,n,numpayloads;
    struct ramchain_hashptr *addrptr;
    struct rampayload *payloads;
    json = cJSON_CreateObject();
    if ( (payloads= ram_addrpayloads(&addrptr,&numpayloads,ram,coinaddr)) != 0 && addrptr != 0 && numpayloads > 0 )
    {
        if ( truncateflag == 0 )
        {
            for (i=n=0; i<numpayloads; i++)
            {
                if ( unspentflag == 0 || payloads[i].B.spent == 0 )
                {
                    if ( payloads[i].B.spent == 0 && payloads[i].B.isinternal == 0 )
                    {
                        n++;
                        total += payloads[i].value;
                    }
                    if ( array == 0 )
                        array = cJSON_CreateArray();
                    cJSON_AddItemToArray(array,ram_addrpayload_json(ram,&payloads[i]));
                }
            }
            if ( array != 0 )
                cJSON_AddItemToObject(json,coinaddr,array);
            cJSON_AddItemToObject(json,"calc_numunspent",cJSON_CreateNumber(n));
            cJSON_AddItemToObject(json,"calc_unspent",cJSON_CreateNumber(dstr(total)));
        }
        cJSON_AddItemToObject(json,"numunspent",cJSON_CreateNumber(addrptr->numunspent));
        cJSON_AddItemToObject(json,"unspent",cJSON_CreateNumber(dstr(addrptr->unspent)));
    }
    cJSON_AddItemToObject(json,"numtx",cJSON_CreateNumber(numpayloads));
    cJSON_AddItemToObject(json,"rawind",cJSON_CreateNumber(addrptr->rawind));
    cJSON_AddItemToObject(json,"permind",cJSON_CreateNumber(addrptr->permind));
    if ( searchperms != 0 )
    {
        if ( (permstr= ram_searchpermind(ram_gethash(ram,'a'),addrptr->rawind)) != 0 )
            cJSON_AddItemToObject(json,"permstr",cJSON_CreateString(permstr));
    }
    cJSON_AddItemToObject(json,ram->name,cJSON_CreateString(coinaddr));
    cJSON_AddItemToObject(json,"NXT",cJSON_CreateString(ram->srvNXTADDR));
    return(json);
}

char *ram_coinaddr_str(struct ramchain_info *ram,char *coinaddr,int32_t truncateflag,int32_t searchperms)
{
    cJSON *json;
    char retbuf[1024],*retstr;
    if ( coinaddr != 0 && coinaddr[0] != 0 && (json= ram_coinaddr_json(ram,coinaddr,1,truncateflag,searchperms)) != 0 )
    {
        retstr = cJSON_Print(json);
        free_json(json);
        return(retstr);
    }
    sprintf(retbuf,"{\"error\":\"no addr info\",\"coin\":\"%s\",\"addr\":\"%s\"}",ram->name,coinaddr);
    return(clonestr(retbuf));
}

char *ram_addr_json(struct ramchain_info *ram,uint32_t rawind,int32_t truncateflag)
{
    char hashstr[8193];
    ram_addr(hashstr,ram,rawind);
    printf("ram_addr_json(%d) -> (%s)\n",rawind,hashstr);
    return(ram_coinaddr_str(ram,hashstr,truncateflag,1));
}

char *ram_addrind_json(struct ramchain_info *ram,char *coinaddr,int32_t truncateflag)
{
    return(ram_coinaddr_str(ram,coinaddr,truncateflag,0));
}

cJSON *ram_txidstr_json(struct ramchain_info *ram,char *txidstr,int32_t truncateflag,int32_t searchperms)
{
    char *permstr;
    int64_t unspent = 0,total = 0;
    cJSON *json = 0,*array = 0;
    int32_t i,n,numpayloads;
    struct ramchain_hashptr *txptr;
    struct rampayload *txpayloads;
    json = cJSON_CreateObject();
    if ( (txpayloads= ram_txpayloads(&txptr,&numpayloads,ram,txidstr)) != 0 && txptr != 0 && numpayloads > 0 )
    {
        cJSON_AddItemToObject(json,"height",cJSON_CreateNumber(txpayloads->B.blocknum));
        cJSON_AddItemToObject(json,"txind",cJSON_CreateNumber(txpayloads->B.txind));
        cJSON_AddItemToObject(json,"numvouts",cJSON_CreateNumber(numpayloads));
        if ( truncateflag == 0 )
        {
            array = cJSON_CreateArray();
            for (i=n=0; i<numpayloads; i++)
            {
                total += txpayloads[i].value;
                if ( txpayloads[i].spentB.spent == 0 )
                    unspent += txpayloads[i].value;
                cJSON_AddItemToArray(array,ram_txpayload_json(ram,&txpayloads[i],txidstr,i));
            }
            cJSON_AddItemToObject(json,"vouts",array);
            cJSON_AddItemToObject(json,"total",cJSON_CreateNumber(dstr(total)));
            cJSON_AddItemToObject(json,"unspent",cJSON_CreateNumber(dstr(unspent)));
        }
    }
    cJSON_AddItemToObject(json,"rawind",cJSON_CreateNumber(txptr->rawind));
    cJSON_AddItemToObject(json,"permind",cJSON_CreateNumber(txptr->permind));
    cJSON_AddItemToObject(json,"txid",cJSON_CreateString(txidstr));
    if ( searchperms != 0 )
    {
        if ( (permstr= ram_searchpermind(ram_gethash(ram,'t'),txptr->rawind)) != 0 )
            cJSON_AddItemToObject(json,"permstr",cJSON_CreateString(permstr));
    }
    cJSON_AddItemToObject(json,"NXT",cJSON_CreateString(ram->srvNXTADDR));
    return(json);
}

char *ram_txidstr(struct ramchain_info *ram,char *txidstr,int32_t truncateflag,int32_t searchperms)
{
    cJSON *json;
    char *retstr;
    if ( txidstr != 0 && txidstr[0] != 0 && (json= ram_txidstr_json(ram,txidstr,truncateflag,searchperms)) != 0 )
    {
        retstr = cJSON_Print(json);
        free_json(json);
        return(retstr);
    }
    return(clonestr("{\"error\":\"no txid info\"}"));
}

char *ram_txid_json(struct ramchain_info *ram,uint32_t rawind,int32_t truncateflag)
{
    char hashstr[8193];
    return(ram_txidstr(ram,ram_txid(hashstr,ram,rawind),truncateflag,1));
}

char *ram_txidind_json(struct ramchain_info *ram,char *txidstr,int32_t truncateflag)
{
    return(ram_txidstr(ram,txidstr,truncateflag,0));
}

char *ram_script_json(struct ramchain_info *ram,uint32_t rawind,int32_t truncateflag)
{
    char hashstr[8193],retbuf[1024],*permstr;
    if ( ram_script(hashstr,ram,rawind) != 0 )
    {
      if ( (permstr= ram_searchpermind(ram_gethash(ram,'s'),rawind)) == 0 )
          permstr = "0";
        sprintf(retbuf,"{\"NXT\":\"%s\",\"result\":\"%u\",\"script\":\"%s\",\"rawind\":\"%u\",\"permstr\":\"%s\"}",ram->srvNXTADDR,rawind,hashstr,rawind,permstr);
        return(clonestr(retbuf));
    }
    return(clonestr("{\"error\":\"no script info\"}"));
}

char *ram_scriptind_json(struct ramchain_info *ram,char *str,int32_t truncateflag)
{
    char retbuf[1024];
    uint32_t rawind,permind;
    if ( (rawind= ram_scriptind_RO(&permind,ram,str)) != 0 )
    {
        sprintf(retbuf,"{\"NXT\":\"%s\",\"result\":\"%s\",\"rawind\":\"%u\",\"permind\":\"%u\"}",ram->srvNXTADDR,str,rawind,permind);
        return(clonestr(retbuf));
    }
    return(clonestr("{\"error\":\"no script info\"}"));
}

void ram_parse_snapshot(struct ramsnapshot *snap,cJSON *json)
{
    memset(snap,0,sizeof(*snap));
    snap->permoffset = (long)get_API_int(cJSON_GetObjectItem(json,"permoffset"),0);
    snap->addrind = (uint32_t)get_API_int(cJSON_GetObjectItem(json,"addrind"),0);
    snap->addroffset = (long)get_API_int(cJSON_GetObjectItem(json,"addroffset"),0);
    snap->scriptind = (uint32_t)get_API_int(cJSON_GetObjectItem(json,"scriptind"),0);
    snap->scriptoffset = (long)get_API_int(cJSON_GetObjectItem(json,"scriptoffset"),0);
    snap->txidind = (uint32_t)get_API_int(cJSON_GetObjectItem(json,"txidind"),0);
    snap->txidoffset = (long)get_API_int(cJSON_GetObjectItem(json,"txidoffset"),0);
}

cJSON *ram_snapshot_json(struct ramsnapshot *snap)
{
    char numstr[64];
    cJSON *json = cJSON_CreateObject();
    sprintf(numstr,"%ld",snap->permoffset), cJSON_AddItemToObject(json,"permoffset",cJSON_CreateString(numstr));
    sprintf(numstr,"%u",snap->addrind), cJSON_AddItemToObject(json,"addrind",cJSON_CreateString(numstr));
    sprintf(numstr,"%ld",snap->addroffset), cJSON_AddItemToObject(json,"addroffset",cJSON_CreateString(numstr));
    sprintf(numstr,"%u",snap->scriptind), cJSON_AddItemToObject(json,"scriptind",cJSON_CreateString(numstr));
    sprintf(numstr,"%ld",snap->scriptoffset), cJSON_AddItemToObject(json,"scriptoffset",cJSON_CreateString(numstr));
    sprintf(numstr,"%u",snap->txidind), cJSON_AddItemToObject(json,"txidind",cJSON_CreateString(numstr));
    sprintf(numstr,"%ld",snap->txidoffset), cJSON_AddItemToObject(json,"txidoffset",cJSON_CreateString(numstr));
    return(json);
}

// >>>>>>>>>>>>>>  start external and API interface functions
char *ramstatus(char *origargstr,char *sender,char *previpaddr,char *coin)
{
    struct ramchain_info *ram = get_ramchain_info(coin);
    char retbuf[1024],*str;
    if ( ram == 0 || ram->MGWpingstr[0] == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    ram_setdispstr(retbuf,ram,ram->startmilli);
    str = stringifyM(retbuf);
    sprintf(retbuf,"{\"result\":\"MGWstatus\",%s\"ramchain\":%s}",ram->MGWpingstr,str);
    free(str);
    return(clonestr(retbuf));
}

int32_t ram_perm_sha256(bits256 *hashp,struct ramchain_info *ram,uint32_t blocknum,int32_t n)
{
    bits256 tmp;
    int32_t i;
    HUFF *hp,*permhp;
    memset(hashp->bytes,0,sizeof(*hashp));
    for (i=0; i<n; i++)
    {
        if ( (hp= ram->blocks.hps[blocknum+i]) == 0 )
            break;
        if ( (permhp = ram_conv_permind(ram->tmphp3,ram,hp,blocknum+i)) == 0 )
            break;
        calc_sha256cat(tmp.bytes,hashp->bytes,sizeof(*hashp),permhp->buf,hconv_bitlen(permhp->endpos)), *hashp = tmp;
    }
    return(i);
}

char *rampyramid(char *myNXTaddr,char *origargstr,char *sender,char *previpaddr,char *coin,uint32_t blocknum,char *typestr)
{
    struct ramchain_info *ram = get_ramchain_info(coin);
    char shastr[65],*hexstr,*retstr = 0;
    bits256 hash;
    HUFF *permhp,*hp,*newhp,**hpptr;
    cJSON *json;
    int32_t size,n;
    printf("rampyramid.%s (%s).%u permblocks.%d\n",coin,typestr,blocknum,ram->S.permblocks);
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    else if ( blocknum >= ram->maxblock )
        return(clonestr("{\"error\":\"blocknum too big\"}"));
    else if ( blocknum >= ram->S.permblocks )
        return(clonestr("{\"error\":\"blocknum past permblocks\"}"));
    if ( strcmp(typestr,"B64") == 0 )
    {
        n = 64;
        if ( (blocknum % n) != 0 )
            return(clonestr("{\"error\":\"B64 blocknum misaligned\"}"));
        hash = ram->snapshots[blocknum / n].hash;
    }
    else if ( strcmp(typestr,"B4096") == 0 )
    {
        n = 4096;
        if ( (blocknum % n) != 0 )
            return(clonestr("{\"error\":\"B4096 blocknum misaligned\"}"));
        //printf("rampyramid B4096 for blocknum.%d\n",blocknum);
        hash = ram->permhash4096[blocknum / n];
    }
    else
    {
        if ( (hp= ram->blocks.hps[blocknum]) == 0 )
        {
            if ( (hpptr= ram_get_hpptr(&ram->Vblocks,blocknum)) != 0 && (hp= *hpptr) != 0 )
            {
                if ( ram_expand_bitstream(0,ram->R3,ram,hp) > 0 )
                {
                    newhp = ram_makehp(ram->tmphp,'B',ram,ram->R3,blocknum);
                    if ( (hpptr= ram_get_hpptr(&ram->Bblocks,blocknum)) != 0 )
                        hp = ram->blocks.hps[blocknum] = *hpptr = newhp;
                } else hp = 0;
            }
        }
        if ( hp != 0 )
        {
            if ( (permhp= ram_conv_permind(ram->tmphp,ram,hp,blocknum)) != 0 )
            {
                size = hconv_bitlen(permhp->endpos);
                hexstr = calloc(1,size*2+1);
                init_hexbytes_noT(hexstr,permhp->buf,size);
                retstr = calloc(1,size*2+1+512);
                sprintf(retstr,"{\"NXT\":\"%s\",\"blocknum\":\"%d\",\"size\":\"%d\",\"data\":\"%s\"}",myNXTaddr,blocknum,size,hexstr);
                free(hexstr);
                return(retstr);
            } else return(clonestr("{\"error\":\"error doing ram_conv_permind\"}"));
        } else return(clonestr("{\"error\":\"no ramchain info for blocknum\"}"));
    }
    json = ram_snapshot_json(&ram->snapshots[blocknum/64]);
    init_hexbytes_noT(shastr,hash.bytes,sizeof(hash));
    cJSON_AddItemToObject(json,"NXT",cJSON_CreateString(myNXTaddr));
    cJSON_AddItemToObject(json,"blocknum",cJSON_CreateNumber(blocknum));
    cJSON_AddItemToObject(json,"B",cJSON_CreateNumber(n));
    cJSON_AddItemToObject(json,"sha256",cJSON_CreateString(shastr));
    retstr = cJSON_Print(json);
    free_json(json);
    return(retstr);
}

void ram_setsnapshot(struct ramchain_info *ram,struct syncstate *sync,uint32_t blocknum,struct ramsnapshot *snap,uint64_t senderbits)
{
    int32_t i,num = (int32_t)(sizeof(sync->requested)/sizeof(*sync->requested));
    bits256 majority,zerokey;
    //fprintf(stderr,"ram_setsnapshot.%d\n",blocknum);
    for (i=0; i<num&&sync->requested[i]!=0; i++)
    {
        if ( senderbits == sync->requested[i] )
        {
            if ( (blocknum % 4096) != 0 )
                sync->snaps[i] = *snap;
            break;
        }
    }
    if ( sync->requested[i] == 0 )
    {
        sync->requested[i] = senderbits;
        if ( i == 0 )
        {
            if ( (blocknum % 4096) == 0 )
                ram->permhash4096[blocknum >> 12] = snap->hash;
            sync->majority = snap->hash;
        }
    }
    majority = sync->majority;
    memset(&zerokey,0,sizeof(zerokey));
    memset(&sync->minority,0,sizeof(sync->minority));
    sync->majoritybits = sync->minoritybits = 0;
    for (i=0; i<num&&sync->requested[i]!=0; i++)
    {
        //printf("check i.%d of %d: %d %d\n",i,num,sync->majoritybits,sync->minoritybits);
        if ( memcmp(sync->snaps[i].hash.bytes,majority.bytes,sizeof(majority)) == 0 )
            sync->majoritybits |= (1 << i);
        else
        {
            sync->minoritybits |= (1 << i);
            if ( memcmp(sync->snaps[i].hash.bytes,zerokey.bytes,sizeof(zerokey)) == 0 )
                sync->minority = sync->snaps[i].hash;
            else if ( memcmp(sync->snaps[i].hash.bytes,sync->minority.bytes,sizeof(sync->minority)) != 0 )
                printf("WARNING: third different hash for blocknum.%d\n",blocknum);
        }
    }
    //fprintf(stderr,"done ram_setsnapshot.%d\n",blocknum);
}

char *ramresponse(char *origargstr,char *sender,char *senderip,char *datastr)
{
    char origcmd[MAX_JSON_FIELD],coin[MAX_JSON_FIELD],permstr[MAX_JSON_FIELD],shastr[MAX_JSON_FIELD],*snapstr,*retstr = 0;
    cJSON *array,*json,*snapjson;
    uint8_t *data;
    bits256 hash;
    struct ramchain_info *ram;
    struct ramsnapshot snap;
    uint32_t blocknum,size,permind,i;
    int32_t format = 0,type = 0;
    permstr[0] = 0;
    //fprintf(stderr,"ramresponse\n");
    if ( (array= cJSON_Parse(origargstr)) != 0 )
    {
        if ( is_cJSON_Array(array) != 0 && cJSON_GetArraySize(array) == 2 )
        {
            retstr = cJSON_Print(array);
            json = cJSON_GetArrayItem(array,0);
            if ( datastr == 0 )
                datastr = cJSON_str(cJSON_GetObjectItem(json,"data"));
            copy_cJSON(origcmd,cJSON_GetObjectItem(json,"origcmd"));
            copy_cJSON(coin,cJSON_GetObjectItem(json,"coin"));
            ram = get_ramchain_info(coin);
            //printf("orig.(%s) ram.%p %s\n",origcmd,ram,coin);
            if ( strcmp(origcmd,"rampyramid") == 0 )
            {
                blocknum = (uint32_t)get_API_int(cJSON_GetObjectItem(json,"blocknum"),0);
                if ( (format= (int32_t)get_API_int(cJSON_GetObjectItem(json,"B"),0)) == 0 )
                {
                    size = (uint32_t)get_API_int(cJSON_GetObjectItem(json,"size"),0);
                    if ( size > 0 )
                    {
                        if ( datastr != 0 && strlen(datastr) == size*2 )
                        {
                            printf("PYRAMID.(%u %s).%d from NXT.(%s) ip.(%s)\n",blocknum,datastr,size,sender,senderip);
                            data = calloc(1,size);
                            decode_hex(data,size,datastr);
                            // update pyramid
                            free(data);
                        } else if ( datastr != 0 ) printf("strlen(%s) is %ld not %d*2\n",datastr,strlen(datastr),size);
                    }
                }
                else
                {
                    ram_parse_snapshot(&snap,json);
                    snapjson = ram_snapshot_json(&snap);
                    snapstr = cJSON_Print(snapjson), free_json(snapjson);
                    copy_cJSON(shastr,cJSON_GetObjectItem(json,"sha256"));
                    decode_hex(hash.bytes,sizeof(hash),shastr);
                    _stripwhite(snapstr,' ');
                    // update pyramid
                    if ( ram != 0 )
                    {
                        i = (blocknum >> 6);
                        ram_setsnapshot(ram,&ram->verified[i],blocknum,&snap,calc_nxt64bits(sender));
                    }
                    printf("PYRAMID.B%d blocknum.%u [%d] sha.(%s) (%s) from NXT.(%s) ip.(%s)\n",format,blocknum,i,shastr,snapstr,sender,senderip);
                    free(snapstr);
                }
            }
            else if ( strcmp(origcmd,"ramblock") == 0 )
            {
                if ( datastr != 0 )
                    printf("PYRAMID.B%d blocknum.%u (%s).permsize %ld from NXT.(%s) ip.(%s)\n",format,blocknum,datastr,strlen(datastr)/2,sender,senderip);
                else printf("PYRAMID.B%d blocknum.%u from NXT.(%s) ip.(%s)\n",format,blocknum,sender,senderip);
            }
            else
            {
                if ( strcmp(origcmd,"addr") == 0 )
                    type = 'a';
                else if ( strcmp(origcmd,"script") == 0 )
                    type = 's';
                else if ( strcmp(origcmd,"txid") == 0 )
                    type = 't';
                if ( type != 0 )
                {
                    copy_cJSON(permstr,cJSON_GetObjectItem(json,"permstr"));
                    permind = (uint32_t)get_API_int(cJSON_GetObjectItem(json,"rawind"),0);
                    printf("PYRAMID.%s (permind.%d %s).%c from NXT.(%s) ip.(%s)\n",origcmd,permind,permstr,type,sender,senderip);
                    // update pyramid
                }
                else if ( format == 0 )
                    printf("RAMRESPONSE unhandled: (%s) (%s) (%s) (%s) from NXT.(%s) ip.(%s)\n",coin,origcmd,permstr,origargstr,sender,senderip);
            }
        }
        free_json(array);
    }
    // fprintf(stderr,"done ramresponse\n");
    return(retstr);
}

int32_t is_remote_access(char *previpaddr);
char *ramstring(char *origargstr,char *sender,char *previpaddr,char *coin,char *typestr,uint32_t rawind)
{
    struct ramchain_info *ram = get_ramchain_info(coin);
    int32_t truncateflag = is_remote_access(previpaddr);
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    if ( strcmp(typestr,"script") == 0 )
        return(ram_script_json(ram,rawind,truncateflag));
    else if ( strcmp(typestr,"addr") == 0 )
        return(ram_addr_json(ram,rawind,truncateflag));
    else if ( strcmp(typestr,"txid") == 0 )
        return(ram_txid_json(ram,rawind,truncateflag));
    else return(clonestr("{\"error\":\"no ramstring invalid type\"}"));
}

char *ramrawind(char *origargstr,char *sender,char *previpaddr,char *coin,char *typestr,char *str)
{
    struct ramchain_info *ram = get_ramchain_info(coin);
    int32_t truncateflag = is_remote_access(previpaddr);
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    if ( strcmp(typestr,"script") == 0 )
        return(ram_scriptind_json(ram,str,truncateflag));
    else if ( strcmp(typestr,"addr") == 0 )
        return(ram_addrind_json(ram,str,truncateflag));
    else if ( strcmp(typestr,"txid") == 0 )
        return(ram_txidind_json(ram,str,truncateflag));
    else return(clonestr("{\"error\":\"no ramrawind invalid type\"}"));
}

char *ramscript(char *origargstr,char *sender,char *previpaddr,char *coin,char *txidstr,int32_t tx_vout,struct address_entry *bp)
{
    struct ramchain_info *ram = get_ramchain_info(coin);
    char retbuf[1024],scriptstr[8192];
    struct rawvout *vo;
    HUFF *hp;
    struct ramchain_hashptr *txptr,*addrptr;
    struct rampayload *txpayloads,*txpayload,*addrpayload;
    int32_t datalen,numpayloads;
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    if ( bp == 0 )
    {
        if ( (txpayloads= ram_txpayloads(&txptr,&numpayloads,ram,txidstr)) != 0 )
        {
            if ( tx_vout < txptr->numpayloads )
            {
                txpayload = &txpayloads[tx_vout];
                if ( (addrpayload= ram_getpayloadi(&addrptr,ram,'a',txpayload->otherind,txpayload->extra)) != 0 )
                {
                    ram_script(scriptstr,ram,addrpayload->extra);
                    sprintf(retbuf,"{\"result\":\"script\",\"txid\":\"%s\",\"vout\":%u,\"script\":\"%s\"}",txidstr,tx_vout,scriptstr);
                    return(clonestr(retbuf));
                } else return(clonestr("{\"error\":\"ram_getpayloadi error\"}"));
            } else return(clonestr("{\"error\":\"tx_vout error\"}"));
        }
        return(clonestr("{\"error\":\"no ram_txpayloads info\"}"));
    }
    else if ( (hp= ram->blocks.hps[bp->blocknum]) != 0 )
    {
        if ( (datalen= ram_expand_bitstream(0,ram->R,ram,hp)) > 0 )
        {
            if ( (vo= ram_rawvout(ram->R,bp->txind,bp->v)) != 0 )
            {
                sprintf(retbuf,"{\"result\":\"script\",\"txid\":\"%s\",\"vout\":%u,\"script\":\"%s\"}",txidstr,bp->v,vo->script);
                return(clonestr(retbuf));
            } else return(clonestr("{\"error\":\"ram_rawvout error\"}"));
        } else return(clonestr("{\"error\":\"ram_expand_bitstream error\"}"));
    }
    else return(clonestr("{\"error\":\"no blocks.hps[] info\"}"));
}

char *ramtxlist(char *origargstr,char *sender,char *previpaddr,char *coin,char *coinaddr,int32_t unspentflag)
{
    cJSON *json;
    char *retstr = 0;
    struct ramchain_info *ram = get_ramchain_info(coin);
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    json = ram_coinaddr_json(ram,coinaddr,unspentflag,0,0);
    if ( json != 0 )
    {
        retstr = cJSON_Print(json);
        free_json(json);
    } else retstr = clonestr("{\"error\":\"ramtxlist no data\"}");
    return(retstr);
}

char *ramrichlist(char *origargstr,char *sender,char *previpaddr,char *coin,int32_t numwhales,int32_t recalcflag)
{
    int32_t i,ind,good,bad,numunspent,numaddrs,n = 0;
    cJSON *item,*array = 0;
    char coinaddr[1024];
    struct ramchain_hashptr **addrs,*addrptr;
    char *retstr;
    double *sortbuf,startmilli = milliseconds();
    uint64_t unspent;
    struct ramchain_info *ram = get_ramchain_info(coin);
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    if ( (addrs= ram_getallstrptrs(&numaddrs,ram,'a')) != 0 && numaddrs > 0 )
    {
        sortbuf = calloc(2*numaddrs,sizeof(*sortbuf));
        for (i=good=bad=0; i<numaddrs; i++)
        {
            ram_decode_hashdata(coinaddr,'a',addrs[i]->hh.key);
            if ( recalcflag != 0 )
                unspent = ram_calc_unspent(0,&numunspent,&addrptr,ram,coinaddr,0);
            else unspent = addrs[i]->unspent, addrptr = addrs[i], numunspent = addrptr->numunspent;
            if ( unspent != 0 )
            {
                if ( addrs[i]->unspent == unspent && addrptr->numunspent == numunspent )
                    good++;
                else bad++;
                sortbuf[n << 1] = dstr(unspent);
                memcpy(&sortbuf[(n << 1) + 1],&i,sizeof(i));
                n++;
            }
        }
        if ( n > 1 )
            qsort(sortbuf,n,sizeof(double) * 2,_decreasing_double_cmp);
        if ( n > 0 )
        {
            array = cJSON_CreateArray();
            for (i=0; i<numwhales&&i<n; i++)
            {
                item = cJSON_CreateObject();
                memcpy(&ind,&sortbuf[(i << 1) + 1],sizeof(i));
                ram_decode_hashdata(coinaddr,'a',addrs[ind]->hh.key);
                cJSON_AddItemToObject(item,coinaddr,cJSON_CreateNumber(sortbuf[i<<1]));
                cJSON_AddItemToObject(item,"unspent",cJSON_CreateNumber(dstr(addrs[ind]->unspent)));
                cJSON_AddItemToArray(array,item);
            }
            item = cJSON_CreateObject();
            if ( recalcflag != 0 )
            {
                cJSON_AddItemToObject(item,"cumulative errors",cJSON_CreateNumber(bad));
                cJSON_AddItemToObject(item,"cumulative correct",cJSON_CreateNumber(good));
            }
            cJSON_AddItemToObject(item,"milliseconds",cJSON_CreateNumber(milliseconds()-startmilli));
            cJSON_AddItemToArray(array,item);
        }
        free(sortbuf);
        free(addrs);
    }
    if ( array != 0 )
    {
        retstr = cJSON_Print(array);
        free_json(array);
    } else retstr = clonestr("{\"error\":\"ramrichlist no data\"}");
    return(retstr);
}

char *rambalances(char *origargstr,char *sender,char *previpaddr,char *coin,char **coins,double *rates,char ***coinaddrs,int32_t numcoins)
{
    uint64_t total = 0;
    char *retstr = 0;
    int32_t i,j;
    cJSON *retjson,*array;
    struct ramchain_info *ram = get_ramchain_info(coin);
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    if ( numcoins > 0 && coins != 0 && coinaddrs != 0 )
    {
        retjson = cJSON_CreateObject();
        array = cJSON_CreateArray();
        if ( numcoins == 1 && strcmp(coins[0],coin) == 0 )
        {
            for (j=0; coinaddrs[0][j]!=0; j++)
                total += ram_unspent_json(&array,coin,0.,coin,coinaddrs[0][j]);
            cJSON_AddItemToObject(retjson,"total",array);
        }
        else if ( rates != 0 )
        {
            for (i=0; i<numcoins; i++)
            {
                for (j=0; coinaddrs[i][j]!=0; j++)
                    total += ram_unspent_json(&array,coin,rates[i],coins[i],coinaddrs[i][j]);
            }
            cJSON_AddItemToObject(retjson,"subtotals",array);
            cJSON_AddItemToObject(retjson,"estimated total",cJSON_CreateString(coin));
            cJSON_AddItemToObject(retjson,coin,cJSON_CreateNumber(dstr(total)));
        } else return(clonestr("{\"error\":\"rambalances: need rates for multicoin request\"}"));
        retstr = cJSON_Print(retjson);
        free_json(retjson);
    }
    return(clonestr("{\"error\":\"rambalances: numcoins zero or bad ptr\"}"));
}

char *ramblock(char *myNXTaddr,char *origargstr,char *sender,char *previpaddr,char *coin,uint32_t blocknum)
{
    struct ramchain_info *ram = get_ramchain_info(coin);
    char hexstr[8192];
    cJSON *json = 0;
    HUFF *hp,*permhp;
    int32_t datalen;
    char *retstr = 0;
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    if ( (hp= ram->blocks.hps[blocknum]) == 0 )
    {
        _get_blockinfo(ram->R,ram,blocknum);
        json = ram_rawblock_json(ram->R,0);
    }
    else
    {
        ram_expand_bitstream(&json,ram->R,ram,hp);
        permhp = ram_conv_permind(ram->tmphp,ram,hp,blocknum);
        datalen = hconv_bitlen(permhp->endpos);
        if ( json != 0 && permhp != 0 && datalen < (sizeof(hexstr)/2-1) )
        {
            init_hexbytes_noT(hexstr,permhp->buf,datalen);
            if ( is_remote_access(previpaddr) != 0 )
            {
                free_json(json);
                json = cJSON_CreateObject();
                cJSON_AddItemToObject(json,"NXT",cJSON_CreateString(myNXTaddr));
                cJSON_AddItemToObject(json,"blocknum",cJSON_CreateNumber(blocknum));
            }
            cJSON_AddItemToObject(json,"data",cJSON_CreateString(hexstr));
        } else printf("error getting json.%p or permhp.%p allocsize.%d\n",json,permhp,permhp != 0 ? datalen : 0);
    }
    if ( json != 0 )
    {
        retstr = cJSON_Print(json);
        free_json(json);
    }
    return(retstr);
}

char *ramcompress(char *origargstr,char *sender,char *previpaddr,char *coin,char *blockhex)
{
    struct ramchain_info *ram = get_ramchain_info(coin);
    uint8_t *data;
    cJSON *json;
    int32_t datalen,complen;
    char *retstr,*hexstr;
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    datalen = (int32_t)strlen(blockhex);
    datalen >>= 1;
    data = calloc(1,datalen);
    decode_hex(data,datalen,blockhex);
    if ( (complen= ram_compress(ram->tmphp,ram,data,datalen)) > 0 )
    {
        hexstr = calloc(1,complen*2+1);
        init_hexbytes_noT(hexstr,ram->tmphp->buf,complen);
        json = cJSON_CreateObject();
        cJSON_AddItemToObject(json,"result",cJSON_CreateString(coin));
        cJSON_AddItemToObject(json,"bitstream",cJSON_CreateString(hexstr));
        cJSON_AddItemToObject(json,"datalen",cJSON_CreateNumber(datalen));
        cJSON_AddItemToObject(json,"compressed",cJSON_CreateNumber(complen));
        retstr = cJSON_Print(json);
        free_json(json);
        free(hexstr);
    } else retstr = clonestr("{\"error\":\"no block info\"}");
    free(data);
    return(retstr);
}

char *ramexpand(char *origargstr,char *sender,char *previpaddr,char *coin,char *bitstream)
{
    struct ramchain_info *ram = get_ramchain_info(coin);
    uint8_t *data;
    HUFF *hp;
    int32_t datalen,expandlen;
    char *retstr;
    if ( ram == 0 )
        return(clonestr("{\"error\":\"no ramchain info\"}"));
    datalen = (int32_t)strlen(bitstream);
    datalen >>= 1;
    data = calloc(1,datalen);
    decode_hex(data,datalen,bitstream);
    hp = hopen(ram->name,&ram->Perm,data,datalen,0);
    if ( (expandlen= ram_expand_bitstream(0,ram->R,ram,hp)) > 0 )
    {
        free(retstr);
        retstr = ram_blockstr(ram->R2,ram,ram->R);
    } else clonestr("{\"error\":\"no ram_expand_bitstream info\"}");
    hclose(hp);
    free(data);
    return(retstr);
}

#define RAMAPI_ERRORSTR "{\"error\":\"invalid ramchain parameters\"}"
#define RAMAPI_ILLEGALREMOTE "{\"error\":\"invalid ramchain remote access\"}"
char *preprocess_ram_apiargs(char *coin,char *previpaddr,cJSON **objs,int32_t valid,char *origargstr,char *NXTaddr,char *NXTACCTSECRET)
{
 /*   static bits256 zerokey;
    char hopNXTaddr[64],destNXTaddr[64],destip[MAX_JSON_FIELD],*str,*jsonstr,*retstr = 0;
    uint16_t port;
    cJSON *array,*json;
    int32_t createdflag;
    struct pserver_info *pserver;
    struct NXT_acct *destnp;
    copy_cJSON(destip,objs[0]);
    port = (uint16_t)get_API_int(objs[1],0);
    copy_cJSON(coin,objs[2]);
    if ( strcmp(Global_mp->ipaddr,destip) == 0 )
        return(0);
    //printf("myipaddr.(%s) process args (%s) (%s) port.%d\n",Global_mp->ipaddr,destip,coin,port);
    if ( coin[0] != 0 && destip[0] != 0 && valid > 0 )
    {
        if ( is_remote_access(previpaddr) == 0 )
        {
            pserver = get_pserver(0,destip,0,0);
            if ( pserver->nxt64bits != 0 )
            {
                expand_nxt64bits(destNXTaddr,pserver->nxt64bits);
                destnp = get_NXTacct(&createdflag,destNXTaddr);
                if ( (memcmp(destnp->stats.pubkey,&zerokey,sizeof(zerokey)) == 0 || port != 0) && destip[0] != 0 )
                {
                    //printf("send to ipaddr.(%s/%d)\n",destip,port);
                    send_to_ipaddr(port,0,destip,origargstr,NXTACCTSECRET);
                }
                else if ( (array= cJSON_Parse(origargstr)) != 0 )
                {
                    if ( is_cJSON_Array(array) != 0 && cJSON_GetArraySize(array) == 2 )
                    {
                        json = cJSON_GetArrayItem(array,0);
                        jsonstr = cJSON_Print(json);
                        stripwhite_ns(jsonstr,strlen(jsonstr));
                        //printf("send cmd.(%s)\n",jsonstr);
                        if ( (str = send_tokenized_cmd(!prevent_queueing("ramchain"),hopNXTaddr,0,NXTaddr,NXTACCTSECRET,jsonstr,destNXTaddr)) != 0 )
                            free(str);
                        free(jsonstr);
                    }
                    free_json(array);
                } else printf("preprocess_ram_apiargs: error parsing (%s)\n",origargstr);
                return(clonestr("{\"result\":\"sent request to destip\"}"));
            } // only path to continue sequence
        } else retstr = clonestr(RAMAPI_ERRORSTR);
    }
    if ( destip[0] != 0 )
    {
        retstr = clonestr("{\"error\":\"unvalidated path with destip\"}");
        destip[0] = 0;
    }
    return(retstr);*/
    return(0);
}

void ram_request(uint64_t nxt64bits,char *destip,struct ramchain_info *ram,char *jsonstr)
{
   /* static bits256 zerokey;
    char hopNXTaddr[64],destNXTaddr[64],ipaddr[64],*str;
    struct pserver_info *pserver;
    int32_t createdflag;
    struct NXT_acct *destnp;
    if ( nxt64bits == 0 )
    {
        pserver = get_pserver(0,destip,0,0);
        nxt64bits =  pserver->nxt64bits;
    }
    if ( nxt64bits != 0 && nxt64bits != Global_mp->nxt64bits )
    {
        expand_nxt64bits(destNXTaddr,nxt64bits);
        destnp = get_NXTacct(&createdflag,destNXTaddr);
        expand_ipbits(ipaddr,destnp->stats.ipbits);
        if ( 1 || memcmp(destnp->stats.pubkey,&zerokey,sizeof(zerokey)) == 0 )
        {
            //printf("send to ipaddr.(%s)\n",destip);
            send_to_ipaddr(0,1,ipaddr,jsonstr,ram->srvNXTACCTSECRET);
        }
        else if ( (str = send_tokenized_cmd(!prevent_queueing("ramchain"),hopNXTaddr,0,ram->srvNXTADDR,ram->srvNXTACCTSECRET,jsonstr,destNXTaddr)) != 0 )
            free(str);
    }*/
}

void ram_syncblocks(struct ramchain_info *ram,uint32_t blocknum,int32_t numblocks,uint64_t *sources,int32_t n,int32_t addshaflag)
{
    int32_t ram_perm_sha256(bits256 *hashp,struct ramchain_info *ram,uint32_t blocknum,int32_t n);
    char destip[64],jsonstr[MAX_JSON_FIELD],shastr[128],hashstr[65];
    int32_t i;
    //cJSON *array;
    bits256 hash;
    if ( addshaflag != 0 && ram_perm_sha256(&hash,ram,blocknum,numblocks) == numblocks )
    {
        init_hexbytes_noT(hashstr,hash.bytes,sizeof(hash));
        sprintf(shastr,",\"mysha256\":\"%s\"",hashstr);
    }
    else shastr[0] = 0;
    sprintf(jsonstr,"{\"requestType\":\"rampyramid\",\"coin\":\"%s\",\"NXT\":\"%s\",\"blocknum\":%u,\"type\":\"B%d\"%s}",ram->name,ram->srvNXTADDR,blocknum,numblocks,shastr);
    if ( sources != 0 && n > 0 )
    {
        for (i=0; i<n; i++)
            if ( sources[i] != 0 )
                ram_request(sources[i],0,ram,jsonstr);
    }
    else
    {
        //array = cJSON_GetObjectItem(MGWconf,"whitelist");
        //if ( array != 0 && is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
        {
            //printf("RAMSYNC.(%s)\n",jsonstr);
            for (i=0; i<SUPERNET.numgateways; i++)
            {
                //copy_cJSON(destip,cJSON_GetArrayItem(array,i));
                expand_ipbits(destip,SUPERNET.srv64bits[i]);
                ram_request(0,destip,ram,jsonstr);
            }
        }
    }
}

void ram_sendresponse(char *origcmd,char *coinstr,char *retstr,char *NXTaddr,char *NXTACCTSECRET,char *destNXTaddr,char *previpaddr)
{
    printf("code sendresponse\n");
    /*
    int32_t len,timeout = 300;
    cJSON *json;
    char fname[MAX_JSON_FIELD],hopNXTaddr[64],*jsonstr,*str = 0;
    if ( is_remote_access(previpaddr) != 0 )
    {
        if ( (json= cJSON_Parse(retstr)) != 0 )
        {
            ensure_jsonitem(json,"coin",coinstr);
            ensure_jsonitem(json,"origcmd",origcmd);
            ensure_jsonitem(json,"requestType","ramresponse");
            jsonstr = cJSON_Print(json);
            _stripwhite(jsonstr,' ');
            if ( (len= (int32_t)strlen(jsonstr)) < 1024 )
            {
                hopNXTaddr[0] = 0;
                str = send_tokenized_cmd(!prevent_queueing("ramchain"),hopNXTaddr,0,NXTaddr,NXTACCTSECRET,jsonstr,destNXTaddr);
            }
            else
            {
                sprintf(fname,"ramresponse.%s.%d",NXTaddr,rand());
                str = start_transfer(previpaddr,destNXTaddr,NXTaddr,NXTACCTSECRET,previpaddr,fname,(uint8_t *)jsonstr,len,timeout,"ramchain",0);
            }
            if ( str != 0 )
                free(str);
            free_json(json);
            free(jsonstr);
        }
    }*/
}

char *ramresponse_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    if ( is_remote_access(previpaddr) == 0 )
        return(0);
    if ( Debuglevel > 2 )
        fprintf(stderr,"ramresponse_func(%s)\n",origargstr);
    if ( sender[0] != 0 && valid > 0 )
        return(ramresponse(origargstr,sender,previpaddr,cJSON_str(objs[2])));
    else return(clonestr(RAMAPI_ERRORSTR));
}

char *ramstring_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],typestr[MAX_JSON_FIELD],*retstr = 0;
    uint32_t rawind = 0;
    if ( (retstr= preprocess_ram_apiargs(coin,previpaddr,objs,valid,origargstr,NXTaddr,NXTACCTSECRET)) != 0 )
        return(retstr);
    copy_cJSON(typestr,objs[3]);
    rawind = (uint32_t)get_API_int(objs[4],0);
    if ( get_ramchain_info(coin) != 0 && typestr[0] != 0 && sender[0] != 0 && valid > 0 )
    {
        retstr = ramstring(origargstr,sender,previpaddr,coin,typestr,rawind);
        ram_sendresponse(typestr,coin,retstr,NXTaddr,NXTACCTSECRET,sender,previpaddr);
    }
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

char *ramrawind_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],typestr[MAX_JSON_FIELD],str[MAX_JSON_FIELD],*retstr = 0;
    if ( (retstr= preprocess_ram_apiargs(coin,previpaddr,objs,valid,origargstr,NXTaddr,NXTACCTSECRET)) != 0 )
        return(retstr);
    copy_cJSON(typestr,objs[3]);
    copy_cJSON(str,objs[4]);
    if ( get_ramchain_info(coin) != 0 && typestr[0] != 0 && str[0] != 0 && sender[0] != 0 && valid > 0 )
    {
        retstr = ramrawind(origargstr,sender,previpaddr,coin,typestr,str);
        ram_sendresponse(typestr,coin,retstr,NXTaddr,NXTACCTSECRET,sender,previpaddr);
    }
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

char *ramstatus_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],*retstr = 0;
    if ( (retstr= preprocess_ram_apiargs(coin,previpaddr,objs,valid,origargstr,NXTaddr,NXTACCTSECRET)) != 0 )
        return(retstr);
    printf("after process args\n");
    if ( get_ramchain_info(coin) != 0 && sender[0] != 0 && valid > 0 )
    {
        printf("calling ramstatus\n");
        retstr = ramstatus(origargstr,sender,previpaddr,coin);
        ram_sendresponse("ramstatus",coin,retstr,NXTaddr,NXTACCTSECRET,sender,previpaddr);
    }
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

char *rampyramid_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],typestr[MAX_JSON_FIELD],*retstr = 0;
    uint32_t blocknum;
    if ( (retstr= preprocess_ram_apiargs(coin,previpaddr,objs,valid,origargstr,NXTaddr,NXTACCTSECRET)) != 0 )
        return(retstr);
    blocknum = (uint32_t)get_API_int(objs[3],-1);
    copy_cJSON(typestr,objs[4]);
    if ( Debuglevel > 2 )
        printf("got pyramid: (%s)\n",origargstr);
    if ( get_ramchain_info(coin) != 0 && sender[0] != 0 && valid > 0 )
    {
        retstr = rampyramid(NXTaddr,origargstr,sender,previpaddr,coin,blocknum,typestr);
        ram_sendresponse("rampyramid",coin,retstr,NXTaddr,NXTACCTSECRET,sender,previpaddr);
    }
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

char *ramscript_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],*txidstr,*retstr = 0;
    int32_t vout,tx_vout,blocknum,txind,validB = 0;
    struct address_entry B;
    memset(&B,0,sizeof(B));
    if ( (retstr= preprocess_ram_apiargs(coin,previpaddr,objs,valid,origargstr,NXTaddr,NXTACCTSECRET)) != 0 )
        return(retstr);
    txidstr = cJSON_str(objs[3]);
    tx_vout = (uint32_t)get_API_int(objs[4],-1);
    B.blocknum = blocknum = (uint32_t)get_API_int(objs[5],-1);
    B.txind = txind = (uint32_t)get_API_int(objs[6],-1);
    B.v = vout = (uint32_t)get_API_int(objs[7],-1);
    if ( blocknum >= 0 && txind >= 0 && vout >= 0 && B.blocknum == blocknum && B.txind == txind && B.v == vout )
        validB = 1;
    if ( get_ramchain_info(coin) != 0 && ((txidstr != 0 && tx_vout >= 0) || validB != 0) && sender[0] != 0 && valid > 0 )
    {
        retstr = ramscript(origargstr,sender,previpaddr,coin,txidstr,tx_vout,(validB != 0) ? &B : 0);
        ram_sendresponse("ramscript",coin,retstr,NXTaddr,NXTACCTSECRET,sender,previpaddr);
    }
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

char *ramblock_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],*retstr = 0;
    uint32_t blocknum;
    if ( (retstr= preprocess_ram_apiargs(coin,previpaddr,objs,valid,origargstr,NXTaddr,NXTACCTSECRET)) != 0 )
        return(retstr);
    blocknum = (uint32_t)get_API_int(objs[3],0);
    if ( get_ramchain_info(coin) != 0 && sender[0] != 0 && valid > 0 )
    {
        retstr = ramblock(NXTaddr,origargstr,sender,previpaddr,coin,blocknum);
        ram_sendresponse("ramblock",coin,retstr,NXTaddr,NXTACCTSECRET,sender,previpaddr);
    }
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

// local ramchain funcs
char *ramcompress_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],*ramhex,*retstr = 0;
    if ( is_remote_access(previpaddr) != 0 )
        return(clonestr(RAMAPI_ILLEGALREMOTE));
    copy_cJSON(coin,objs[0]);
    ramhex = cJSON_str(objs[1]);
    if ( coin[0] != 0 && ramhex != 0 && sender[0] != 0 && valid > 0 )
        retstr = ramcompress(origargstr,sender,previpaddr,coin,ramhex);
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

char *ramexpand_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],*bitstream,*retstr = 0;
    if ( is_remote_access(previpaddr) != 0 )
        return(clonestr(RAMAPI_ILLEGALREMOTE));
    copy_cJSON(coin,objs[0]);
    bitstream = cJSON_str(objs[1]);
    if ( coin[0] != 0 && bitstream != 0 && sender[0] != 0 && valid > 0 )
        retstr = ramexpand(origargstr,sender,previpaddr,coin,bitstream);
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

char *ramaddrlist_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],*retstr = 0;
    if ( is_remote_access(previpaddr) != 0 )
        return(clonestr(RAMAPI_ILLEGALREMOTE));
    copy_cJSON(coin,objs[0]);
    if ( coin[0] != 0 && sender[0] != 0 && valid > 0 )
        retstr = ramaddrlist(origargstr,sender,previpaddr,coin);
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

char *ramtxlist_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],coinaddr[MAX_JSON_FIELD],*retstr = 0;
    int32_t unspentflag;
    if ( is_remote_access(previpaddr) != 0 )
        return(clonestr(RAMAPI_ILLEGALREMOTE));
    copy_cJSON(coin,objs[0]);
    copy_cJSON(coinaddr,objs[1]);
    unspentflag = (int32_t)get_API_int(objs[2],0);
    if ( coin[0] != 0 && coinaddr[0] != 0 && sender[0] != 0 && valid > 0 )
        retstr = ramtxlist(origargstr,sender,previpaddr,coin,coinaddr,unspentflag);
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

char *ramrichlist_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],*retstr = 0;
    uint32_t num;
    int32_t recalcflag;
    if ( is_remote_access(previpaddr) != 0 )
        return(clonestr(RAMAPI_ILLEGALREMOTE));
    copy_cJSON(coin,objs[0]);
    num = (uint32_t)get_API_int(objs[1],0);
    recalcflag = (uint32_t)get_API_int(objs[2],1);
    if ( coin[0] != 0 && num != 0 && sender[0] != 0 && valid > 0 )
        retstr = ramrichlist(origargstr,sender,previpaddr,coin,num,recalcflag);
    else retstr = clonestr(RAMAPI_ERRORSTR);
    return(retstr);
}

double extract_rate(cJSON *array,char *base,char *rel)
{
    int32_t i,n;
    cJSON *item;
    double rate = 0.;
    char basestr[MAX_JSON_FIELD],relstr[MAX_JSON_FIELD];
    if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
    {
        for (i=0; i<n; i++)
        {
            item = cJSON_GetArrayItem(array,i);
            copy_cJSON(basestr,cJSON_GetObjectItem(item,"base"));
            copy_cJSON(relstr,cJSON_GetObjectItem(item,"rel"));
            rate = get_API_float(cJSON_GetObjectItem(item,"rate"));
            if ( strcmp(base,basestr) == 0 && strcmp(rel,relstr) == 0 )
                return(rate);
            if ( strcmp(rel,basestr) == 0 && strcmp(base,relstr) == 0 && rate != 0. )
                return(1. / rate);
        }
    }
    return(0.);
}

char *rambalances_func(char *NXTaddr,char *NXTACCTSECRET,char *previpaddr,char *sender,int32_t valid,cJSON **objs,int32_t numobjs,char *origargstr)
{
    char coin[MAX_JSON_FIELD],srccoin[MAX_JSON_FIELD],**coins = 0,**list,***coinaddrs = 0,*retstr = 0;
    double *rates = 0;
    cJSON *item,*subarray;
    uint32_t numcoins = 0,numaddrs,i,j;
    if ( is_remote_access(previpaddr) != 0 )
        return(clonestr(RAMAPI_ILLEGALREMOTE));
    copy_cJSON(coin,objs[0]);
    if ( is_cJSON_Array(objs[1]) != 0 && (numcoins= cJSON_GetArraySize(objs[1])) > 0 )
    {
        coins = calloc(numcoins,sizeof(*coins));
        rates = calloc(numcoins,sizeof(*rates));
        coinaddrs = calloc(numcoins,sizeof(*coinaddrs));
        for (i=0; i<numcoins; i++)
        {
            item = cJSON_GetArrayItem(objs[1],i);
            coins[i] = cJSON_str(cJSON_GetObjectItem(item,"coin"));
            subarray = cJSON_GetObjectItem(item,"addrs");
            if ( srccoin[0] != 0 && subarray != 0 && is_cJSON_Array(subarray) != 0 && (numaddrs= cJSON_GetArraySize(subarray)) > 0 )
            {
                list = calloc(numaddrs+1,sizeof(*list));
                for (j=0; j<numaddrs; j++)
                    list[j] = cJSON_str(cJSON_GetArrayItem(subarray,j));
                coinaddrs[i] = list;
                rates[i] = extract_rate(objs[2],srccoin,coin);
            }
        }
    }
    if ( coin[0] != 0 && numcoins != 0 && coins != 0 && coinaddrs != 0 && rates != 0 && sender[0] != 0 && valid > 0 )
        retstr = rambalances(origargstr,sender,previpaddr,coin,coins,rates,coinaddrs,numcoins);
    else retstr = clonestr(RAMAPI_ERRORSTR);
    if ( coins != 0 )
        free(coins);
    if ( coinaddrs != 0 )
    {
        for (i=0; i<numcoins; i++)
            if ( coinaddrs[i] != 0 )
                free(coinaddrs[i]);
        free(coinaddrs);
    }
    if ( rates != 0 )
        free(rates);
    return(retstr);
}

#endif
#endif

redpajama_set_name: RedPajamaGithub


Since its creation, routes have now been the primary way of long-distance transportation. These are typically safe and convenient to obtain from 1 nation to a different, along with one continent to a different. Thinking about the interest in flights of a few nature, they've been classified into numerous categories which make planning ones travel much more much easier.
To start with you have got direct routes. They're the ones that just take you against one destination to another without stopping over at any point. Another kind of trip you have may be the stopover trip or perhaps the connecting flight. In a stopover flight, you stick with similar flight, but your flight stops at one destination before it really moves on towards location you will be headed for. In a connecting flight, you can elect to change your flight at stopover if it works aside cheaper for your needs.
Flights will also be categorized on the basis of nationwide and worldwide routes. Some nations eg India, Australia together with American tend to be huge in terms of geographic area. In such cases, you have got many regional routes that help men and women cover distances inside the nation quicker. Irony of the matter is the fact that there are several international routes that are shorter than nationwide people in the country.
Routes aim at supplying its consumers many different amenities in line with the form of travelling class you decide on. The most famous among the list of masses needless to say may be the economic climate class, in which chairs are closer together and perhaps the leg room limited. Food is offered to you on pre-plated trays. But except that this you have got all amenities of in-flight films and enjoyment, liquor where applicable and stuff like that.
Others important class in routes is of this very first or company course. Here chairs tend to be spaced apart, occasionally only two chairs to either side of the airplane. The seating unfold is completely horizontal beds. Food is offered because could be in a superb dining restaurant and several times it's served on need and not to all at once. In addition enjoy facilities particularly your own toiletry bags, movies on need and the like. This course definitely is the privilege of internet marketers as well as famous people. But needless to say, treating yourself to routes similar to this can be a once in a life time event.
Welcome to flylink internet site, committed to proclaiming to offer you the cheap atmosphere flights to your top locations and discount vacations at time of scheduling. Book a cheap routes to kiev, inexpensive routes to lisbon trip because of the most readily useful prices using the internet for flight tickets, last minute discounts, automobiles, hotels and travel insurance.


Confusion regarding a girl I like. Not sure what to do? Please help?
We've known each other for 4 years and share a common friend circle. But we started talking more in the last 1 yr. She has a guy best friend in the same circle and he's my friend too. Everyone else thinks they are dating, I used think the same thing. But in the past six months weird things have been happening. We hit off really nice. And she used joke around about us kissing and dating. When we sit together, she points at random people and says "They must think we are dating".
One day I was texting on my phone for a while and she was continuously trying to catch a peek as to what i was doing. She behaved pretty weird later on like making weird noises, shouting weird stuff, talking loudly etc. She even used to compliment me everytime. Slowly I started liking her too but with everyone saying she and her best friend are dating i always get confused because they are indeed pretty close. Now she says that her father wants her to get married (arranged) and our friends keep saying that it must be her and her best friend.
One I mentioned that to one of our friends about how i think that i met a cool girl and that i i got her number, she was there listening to us and she got really pissed and things have been weird between us since that time. She doesn't even respond to my texts properly now. But she git concerned when I got sick recently, she replied to all my texts immediately and gave numbers of doctors.
Just recently few of us met, she was there and all of us were cracking silly adult jokes and girls pretended that we were being vulgar. So I joked that "where are the girls", pointing at her and another girl. She shot back "that's why you're single". I kinda felt offended.
She's a flirty girl but now talks to everyone properly except me nowadays.
All this confusion regarding her best friend and now the added marriage confusion is making me mad. Can someone please help? I don't usually ask online but i just don't know what to do because i like her too.
Would you date someone you know is not an affectionate person? Why are people self destructive? Would you date a person with a family history of cancer? Did it happen too fast? Singles, do you all feel confident you'll find the right person?
Home > Dating > Confusion regarding a girl I like. Not sure what to do? Please help?


Enter Wayne Shorter – The Second Great Quintet.
The Finale – Filles de Kilimanjaro.
The final LP of Davis's Second Great Quintet, Filles de Kilimanjaro, started with the classic lineup in a session from June 1968 and finished with Chick Corea on keyboards and Dave Holland on bass in a session that fall. This was a very different sounding record in 1968, foreshadowing the role these musicians would play in creating a jazz-rock fusion music in the next several years.
Filles de Kilimanjaro would be the swansong for the Davis – Shorter – Hancock – Carter – Williams quintet. Each of the players would make major contributions to jazz in the years to come. Jazz-rock fusion would be defined around Davis's subsequent work and also that of Shorter in Weather Report, Hancock in The Headhunters and Tony Williams' Lifetime.
During the five-year tenure of Miles Davis's Second Great Quintet (1963 – 1968), Wayne Shorter, Herbie Hancock and Tony Williams were very active on their own projects, many of which included Ron Carter. Several of the resulting releases are classics of the period and laid the foundation for their significant careers after the Quintet broke up in 1968. The highly productive moonlighting of Wayne Shorter, Herbie Hancock and Tony Williams in the next hour of Jazz at 100.
Carr, Ian. 1998. Miles Davis: The Definitive Biography. New York, NY. Thunder Mouth Press.
Chapter 13. Play What's Not There!
Giddins, Gary. 1998. Visions of Jazz: The First Century. New York. Oxford University Press.


text:
4 dead in Memorial Day weekend shootings in Chicago
Jessica Durando
At least four people were left dead and dozens wounded following gun violence over Memorial Day weekend in Chicago.
Thirteen people were hurt as of early Monday. One person was killed and 24 wounded by Sunday morning and three people were killed and 12 injured Friday through Saturday. The majority of the holiday weekend violence took place on the West Side, the Chicago Tribune reported.
Among the youngest victims, a 15-year-old girl was shot and killed while riding in a car with a gang member on Lake Shore Drive, NBC News reported.
First Deputy Superintendent John Escalante said the police department planned to increase patrols in certain areas on Monday.
Chicago mayor wants new oversight agency for troubled police department
"As we've said before, it's about 1,500 people that are driving the violence," Escalente said, according to NBC. "Those are the people we're trying to concentrate on."
The Harrison District of the West Side is one of the city's most violent and has more police officers assigned to it than almost any other district in the city.
Last year, 12 people were killed and 44 injured over Memorial Day weekend, according to the Tribune.
Chicago's murder rate soars 72% in 2016; shootings up more than 88%
Murders in the nation's third-largest city are up about 72%, while shootings have surged more than 88% in the first three months of 2016 compared with the same period last year, according to data released in April by the Chicago Police Department.
Police said the disturbing rise in violence is driven by gangs and mostly contained to a handful of pockets on the city's South and West Sides.
The Chicago Police Department reported 468 murders in 2015, a 12.5% increase from the year before. There were 2,900 shootings in 2015, 13% more than the year before, according to department records.
Contributing: Aamer Madhani

redpajama_set_name: RedPajamaCommonCrawl


text:
Wednesday, June 21, 2017 3:34pm
n The Summertime in Soldotna – Music in the Park Concert Series will feature the Robb Justice Band and 907 from 6-9 p.m. Wednesday.
n The Kobuk Kaladi Brothers features Alaskan photography displayed on metal prints by Laurie Johnson for the month of June.
n Opening First Thursday July 6, 5 – 7 p.m. will be an exhibition by Sonya Kelliher-Combs, at Kenai Fine Art Center, 816 Cook Avenue, Old Town Kenai. All galleries are open from noon to 5:00 pm Wednesday through Saturday, staffed by volunteer artist participation. Call 907-283-7040 for further information.
n Donations are requested for original works of art to be auctioned off at Kenai Fine Art Center's annual Harvest Auction September 30, at the gallery located at 816 Cook Avenue in Old Town Kenai. Donations may be submitted from noon to 5:00 p.m. Wednesday through Saturday until August 26. The donated works will become the September show, hanging September 1 – 29. For more information, call 907-283-7040 or stop by during open hours.
n Kenai Performers is hosting a July 4th Cosplay Costume Contest as part of Kenai's July 4th festivities held on the green strip park by the softball fields. Cash prizes. Costume parade and judging at 1:30 p.m. This is a family friendly event open to all ages. Costume rules and entry forms available at Curtain Call Consignment Boutique in Kenai and online at www.kenaiperformers.org. Call Terri at 262-5486 or 252-6808, if more information is needed.
n Art Quilts Extraordinaire, a judged exhibit, is on display at the Kenai Fine Art Center, 816 Cook Avenue, Old Town Kenai. All galleries are open from noon-5:00 p.m. Wednesday through Saturday, manned by volunteer artist participation. Call 907-283-7040 for further information.
n The Kenai Peninsula Woodturners 2017 Summer Exhibit is on display at the Kenai Visitors and Cultural Center, 11471 Kenai Spur Highway in Kenai. Call 283-1991.
n ARTspace Drawer is on display at the Soldotna Library, the first annual collection of locally created 2D art. The first of its kind in Alaska, this display is made possible by a partnership between Soldotna Rotary, ARTspace Inc., and the Soldotna Public Library.
n The 17th annual Seldovia Summer Solstice Music Festival is June 22-25 at the Susan B. English School in Seldovia. Headliners performing Friday and Saturday include Alex DePue and Miguel DeHoyes, world renowned violinist and guitarist; and the Denali Cooks band. Other performers include: The Hannah Yoter Band, Elena Lukina on violin, the Umpqua Singers from Oregon, Patrice Webb, a country singer from Nashville, Ryan Hiller from Kenai on guitar, Wes Westlake and Judi Works on guitar, and Betsy Scott on banjo and ukulele from Seldovia. Events include an Open Mic night Thursday, busking performances around Seldovia Friday, yoga, song circle and workshops on Saturday with evening performances starting at 6:15 p.m. Friday and Saturday. "En Plein Air" art event for visiting artists will also happen throughout the weekend. Tickets: entire festival including workshops: Adults: $49, Teens $16, under 12-free. More info: 907-399-7379, Facebook at Seldovia Summer Solstice Music Festival, or at seldoviamusicfestival.info.
n The Alaska Ocean Observing System is now accepting submissions for their 2017 short film contest! Films should center around Alaska's coast and oceans, and must be under 10 minutes in length. The deadline to submit is September 15. For more information and to submit a film, go to aoos.org. Questions can be directed to Holly Kent at kent@aoos.org.
n The Vagabond Inn on Kalifornsky Beach Road has live music with the Zack Daniels Band 8 p.m.-midnight Friday only. This is a non-smoking show.
n Veronica's in Old Town Kenai has Open Mic from 6-8 p.m. Friday, and live music on Saturday with Just We Two at 6:30 p.m. Reservations encouraged. Call Veronica's at 283-2725.
n Goody2Shoes Dancehall and Cafe, Mile 132.6, 13364 Sterling Highway in Ninilchick, has a DJ and karaoke on Friday from 5-8 p.m. $5 cover. Saturday features the Dogwood Blossom Trioplaying traditional country from 5-8 p.m., $5 cover. On Sunday, Mario Carboni, "The Honky Tonk Rebel" from Portland, Oregon, plays from 3-7 p.m., $14 admission. Goody2Shoes is a non-alcoholic, non-smoking establishment. For more info call 907-252-6326 or www.goody2shoes.us
n A bluegrass jam takes place on the first Sunday of the month at from 1-4 p.m. at the Mount Redoubt Baptist Church on South Lovers Loop in Nikiski.
n The Flats Bistro on Kalifornsky Beach Road has live music with Daniel Tuttle Mondays from 6-8 p.m.; Pat Wendt on Wednesdays from 6-8 p.m.; Garrett Mayer on Thursdays from 6:30-8:30 p.m.; and Robb Justice on Fridays from 8-10 p.m.
n An all acoustic jam takes place every Thursday. The jam is at Christ Lutheran Church in Soldotna on the first Thursday of the month, and at the Kenai Senior Center during the rest of the month. Jam starts at 6:30 p.m.
n AmVets Post 4 has reopened in its brand new building on Kalifornsky Beach across from Jumpin' Junction. Eligible veterans and their families are invited to stop by to find out more about AmVets and their involvement in the Veteran community. For members and invited guests, Friday night dance to "Running with Scissors," and Saturday Burn your own steak and karaoke with Cowboy Don.
n Odie's Deli in Soldotna has live music Friday from 6-8 p.m. and Pub Quiz night every Wednesday from 6-8 p.m.
n The Bow bar in Kenai has karaoke at 9 p.m. Thursdays and live music Fridays, Saturdays at 10 p.m.
n The Duck Inn on Kalifornsky Beach Road has karaoke at 9 p.m. Thursdays and Fridays, and DJ Arisen on Saturdays.
n Call Orca Theaters at 262-7003 or visit http://www.orcatheater.com for listings and times.
n Visit Kenai Cinema at www.catheatres.com for listings and times.
Fairs, Markets and Bazaars
n The Saturday Market at the Kenai Visitors Center is open from 10 a.m.-5 p.m. Saturday through Sept. 2.
n The Farmers Fresh Market is open from 3-6 p.m. on Tuesdays into September at the Kenai Peninsula Food Bank on Kalifornsky Beach Road.
n The Soldotna Wednesday Market is open from 11 a.m.-6 p.m. on Wednesdays at Soldotna Creek Park.
n The Central Kenai Peninsula Farmers' Market is open from 10 a.m.-2 p.m. Saturdays at the corner of East Corral and the Kenai Spur Highway in Soldotna.
Down the Road
n The Pratt Museum in Homer is from 10 a.m.-6 p.m. daily. For more information and a schedule of events, visit www.prattmuseum.org.
Submissions may be emailed to news@peninsulaclarion. com. The deadline is 5 p.m. Mondays.
Local Boundary Commission extends comment period for Nikiski incorporation petition
Work continues on East Fork fire break


text:
Raising Doubts About Drugs
Washington Post ran this article about the MindFreedom hunger strike "Fast for Freedom in Mental Health."
Author: Kimberly Edds
article also published here with photo:
http://www.commondreams.org/headlines03/0830-07.htm
Calif. Hunger Strike Challenges Use of Antidepressants
PASADENA, Calif., Aug. 29 — After two weeks, four mental health advocates are still on a hunger strike, protesting the widespread use of prescription drugs to treat mental illnesses and challenging psychiatrists to document their rationale for prescribing them.
Over the last few decades, doctors have embraced the view that depression, schizophrenia and other mental illnesses result from imbalances in brain chemistry, and they have treated such illnesses with drugs intended to rebalance that chemistry. In recent years, the use of antidepressant drugs has grown dramatically in the United States, with the number of prescriptions nearly doubling since 1998, according to the pharmaceutical consulting company IMS Health.
As more people turn to antidepressants, mental health experts and patient advocates are beginning to raise questions about side effects and the potential for addiction.
The strikers are calling on some of the strongest voices in the psychiatric profession, including the American Psychiatric Association and the National Alliance for the Mentally Ill, to provide concrete evidence that mental illnesses are the result of brain chemistry imbalances. They also want to call attention to alternative treatments.
"Millions of people are signing up for these prescriptions because they are convinced they have a chemical imbalance. But there is not one piece of evidence that can back that up," said David Oaks, executive director of MindFreedom Support Coalition International, or SCI, an organization of current and former psychiatric patients that organized the strike.
A spokesman for the American Psychiatric Association referred a reporter to a letter the association's medical director, James H. Scully, wrote to Oaks on Aug. 12. "In recent years, there has been substantial progress in understanding the neuroscientific basis of many mental illnesses," it said. "Research offers hope and must continue."
The National Alliance for the Mentally Ill (NAMI) did not respond to several requests to comment, but Oaks made available an e-mail he received today from Rick Birkel, NAMI's national executive director.
"NAMI has never stated to my knowledge that 'mental disorders are caused exclusively by biological factors,' " it said. "Instead, we are saying that biological or genetic vulnerability appears to be pre-requisite to serious mental disorder."
Birkel added that "mental disorders result from complex interactions of many factors, including environmental forces, stress, personality, social support, illness and injury."
Birkel's e-mail reflects a growing consensus in the psychiatric establishment. Most psychiatrists say that complex mental disorders are like arthritis and other chronic physical ailments — no less real because they cannot be spotted with laboratory tests.
The hunger strikers, who include three former mental patients, said that the responses were not satisfactory and that they wanted a study and a diagnostic lab test that proves the connection. Until then, they plan to continue their protest.
They began with six hunger strikers, but two, including Oaks, left because of health difficulties. The remaining four have been downing daily a dark red brew of juices from garlic, beets, kale and carrots, and spending their time answering supporters' e-mails and making phone calls to media outlets.
Hunger striker David Gonzalez said he spent two years confined in an inpatient facility after being diagnosed with major depression and, later, manic depression, and that he was forcibly drugged during that time. He said the drugs impaired his eyesight and memory.
"When someone has cancer, they don't lock the door behind them, and they show them the tests," Gonzalez said. "But when someone has a mental illness, they lock the door behind them and show them no tests. When they lock that door behind me, I want to know why."
Oaks said he, too, had been confined in institutions and forcibly drugged for what was diagnosed as schizophrenia. He recovered, he said, through the love and support of his family, rather than drugs.
"People do not know what it's like to be on these drugs," Oaks said. "If you want to take it and it obliterates your pain, that's one thing, but when you are pushed to be on it, it's like a wrecking ball to your thoughts and feelings."
Studies have shown that daily exercise, psychotherapy and even changes in diet and nutrition are as effective as, if not more effective than, prescription drugs, said Stuart Shipko, a Pasadena psychiatrist and panic disorder specialist who serves on an SCI scientific panel. But there is not widespread support for such treatments.
"We're overdiagnosing. How many of these supposed mental illnesses are really just problems in your family life? They're anxious, and they're being put in a chemical straitjacket," Shipko said.
© 2003 The Washington Post Company
photo accompanying original article:
David Gonzalez, left, and Mickey Weinberg are participating in a hungerstrike to question the treatment of mental illnesses through drugs. (WPPhoto/Kimberly Edds)


Free umbrella with every order at Grofers from 15th June to 18th June as part of mid-month sale.
Validity – For every order between 15th June to 18th June.
T&C – Awaited (most likely it will be Rs 500 or Rs 1000 as min order criteria but there will be lot of mid month sale offers to combine with like paytm cb, SBC members offer, some bank offers also (possibly HDFC).
Is it very bad in quality?
Even at order of rs 10?
It work on order of 30?
Hmm, seems more like ur maid problem than the umbrella.
Sorry sorry. Kahaani har ghar ki. Kahaani Ghar Ghar ki.
Trans – Same story every house. Dnt say anything to/abt maid.
if i order today for delivery on 15-18 is better or order during offer period.
Better to order during offer period if getting umbrella is one of ur needs.
you have the option to cancel the order if it is not packed and re order the same list of products again today.
Yes, offer is now not visible on their app. Strange… Looks like Grofers didn't get the desired no of umbrellas looking at their order book starting today.
Yes not appearing, should display sometime in the day.
BTW below is the terms of the offer which I received from Grofers chat executive.


Looking to host an outdoor wedding and need wedding rentals? Learn more about our tent rentals, tables and chairs and more.
Need to rent tables and chairs for your corporate event? Read about table and chair rentals for your corporate event.
Want to rent pipe and drape or tables and chairs for a trade show? Learn more about our professional trade show rentals.
You've been planning your wedding, family reunion or corporate event for months. You know that compromise isn't an option. We do too.
Ontario Tent and Event Rentals are committed to meeting all of your event needs. Our extensive inventory of tents can handle any function at any size. And our dedicated team of consultants are there every step of the way, to help bring your vision to life.
Want to know more? Request a Free Estimate on the tent of your choosing.
Large weddings. Small corporate events. Civic festivals. Size doesn't matter.
no matter where you're holding your event – we'll deliver the tent you want.
Wedding Rentals From ceremony to reception, dinner and dancing, our tents can handle all aspects of your special day.
Trade Show Rentals No venue is too big or too small for us to help your trade show or festival with tables, piping, draperies and booth spaces in a variety of colours and sizes.
Corporate Event & Rentals Show your employees how much you appreciate them with tents, tables and games to create an elegantly memorable corporate event.
Casino & Game Rentals Treat your guests to fun with casino equipment, games, and other challenging activities.
Inflatable Rentals Bouncy castles, obstacle courses, slides and water fun are sure to bring excitement to your event.
Concession Rentals When your guests hungry, let us take care of it by supplying your event with carnival snacks or ice cream truck rentals.
Tent rental for your wedding or event.
Frame Tents Our most flexible tent, frame tents are designed for strength, work in all weather and allows for 100% usable space.
Marquee Tents Marquee tents have a high-peaked centre which creates a bold look. They can be joined together to create larger spaces such as entryways or reception areas.
Canopy Tents Canopy tents are designed for quick installation and can accommodate a large group of people with the option to have the sidewalls openved or closed as needed.
Tent Accessories Enhance your tent with elegant accessories such as lighting, heating and cooling needs, flooring and staging requirements or piping and drapery highlights.
Our tents are kept in pristine condition. No rips. No stains. No missing pieces or replaced parts.
Advance set-up: We'll set-up your tent days ahead of your event. No rush installations – unless required by the venue on the day of the event.
Help when you need it: More people coming than expected? Need a larger or different type of tent? Contact us to speak with a member of our helpful staff.
We cater to you: We'll do everything we can to answer your questions and address your concerns.
Request a Free Estimate on a tent rental for your wedding or event.


text:
Home » Browse » Academic journals » Economics Journals » Economic Inquiry » Article details, "Why Do Firms Contrive Shortages? the Economics..."
Academic journal article Economic Inquiry
Why Do Firms Contrive Shortages? the Economics of Intentional Mispricing
By Haddock, David D.; McChesney, Fred S.
Economists typically inveigh against government-imposed price controls, finding them and the shortages they create to be Kaldor-Hicks inefficient.(1) But not all observed shortages result from government price controls. When firms experience sudden changes in costs or demand, they sometimes voluntarily but temporarily refuse to clear the market rather than alter prices.(2) Depending on whether the temporary price is above or below market-clearing levels, a firm's intentional refusal to alter price forces potential buyers or sellers to queue, so that rationing is required and both the firm and its clients incur additional costs [Barzel 1974]. When the abnormal events pass, mispricing and rationing disappear as well. But price alteration was always open to firms in those situations, and no widely accepted price-theoretic explanation exists for their insistence on mispricing.(3) That is the phenomenon investigated in this article.
Economists' inability to derive a convincing model of episodic mispricing, and in particular to test various models using conventional empirical methods, has begun to spawn new theories at variance with received economic doctrine (e.g., Basu [1987]; Kahneman, Knetsch and Thaler [1986]). One recent study by Blinder [1991] has addressed the problem through interviews, in the belief that price stickiness can be explained by asking business executives themselves for the reasons. Though preliminary, that study has already attracted substantial attention.(4)
Those few, more orthodox price-theoretic inquiries into voluntary mispricing fall into two distinct categories. In the first category, researchers model inventories and order backlogs in which all participants are ignorant of present or impending market supply and demand, due largely to stochastic features of markets.(5) Inventories or backlogs are expectable, because it is not economic (or possible) for market participants to predict market supply and demand with precision. Indeed, in some of those situations the apparent queues are not even real. For example, De Vany and Frey [1982] show that where production processes are especially time consuming, apparent queues are actually a listing of forward orders by buyers who would not even want delivery at present.
By contrast, in the second category, no participant need be ignorant of impending market conditions.(6) Rather, queues arise either because buyers prefer to consume some products (restaurant meals, rock concerts, athletic events) as part of a crowd [e.g., Becker 1991]; because under-pricing of some goods is preferable when the alternative is other buyers just taking the goods [Cheung 1977]; because the cost of waiting in a queue is low relative to the cost of continuously adjusting price (e.g., ski lifts [Barro and Romer 1987] or peak-time telephone service(7)); or even because--jumping outside price theory--ill-defined ethical considerations interdict market-clearing price adjustments (e.g., following catastrophes [Kahneman et al. 1986]).
A third logical category exists--one in which participants on one side of a market are substantially better informed about market conditions than are participants on the other. That third category is the one studied here. In retail markets, sellers are able to ascertain the nature and likely duration of market alterations more often than are buyers. In upstream markets, some buyers survey a larger part of the market than do sellers, and so are in a better position to interpret market conditions.
Logically, the analysis here would apply to both situations, but the examples that we consider are of the former sort. Thus, this article considers situations in which perfectly informed sellers tolerate shortages that cost them money in the short run in order to protect long-term, profitable relationships with consumers who are not as well informed.(8) The analysis is based upon a conventional price-theoretic model and specifies empirical tests showing why and how profit maximizers nevertheless run shortages intentionally. …
Publication: Economic Inquiry
Haddock, David D.
McChesney, Fred S.
Pricing--Analysis
Inventory Shortages--Analysis
Asset Pricing under Asymmetric Information: Bubbles, Crashes, Technical Analysis, and Herding By Markus K. Brunnermeier Oxford University Press, 2001
The Basing-Point System: An Economic Analysis of a Controversial Pricing Practice By Fritz Machlup Blakiston Co., 1949
Critical Concerns in Transfer Pricing and Practice By Wagdy M. Abdallah Praeger, 2004
The Role of Cluster Analysis in Assessing Comparability under the U.S. Transfer Pricing Regulations By Johnson, Robert E. Business Economics, Vol. 36, No. 2, April 2001
Bond Ratings and New Issue Municipal Bond Pricing: Path Analysis Results By Stover, Roger D. Quarterly Journal of Business and Economics, Vol. 30, No. 1, Winter 1991
The Exchange Traded Funds' Pricing Deviation: Analysis and Forecasts By DeFusco, Richard A. Ivanov, Stoyu I. Karels, Gordon V. Journal of Economics and Finance, Vol. 35, No. 2, April 2011
Commercial Loan Pricing and Profitability Analysis By Ferrari, Richard H. Journal of Commercial Lending, Vol. 74, No. 7, March 1992
Commercial Loan Pricing and Profitability Analysis By Ferrari, Richard H. Journal of Commercial Lending, Vol. 74, No. 6, February 1992
Better Leveraging of Inventory Can Resolve Cashflow Problems By Van Ryzin, Gary Business Credit, Vol. 100, No. 4, April 1998
I Was Driven to Campaign against Road Pricing; ANALYSIS Peter Roberts Has Found Himself an Unlikely Hero for Motorists across the UK, after Attracting Nearly Two Million Signatures to His Anti-Road Charging Petition. Here He Explains His Motivation By Roberts, Peter The Birmingham Post (England), May 24, 2007
ANALYSIS: Road Pricing Alone Will Not Ease Road Congestion; Last Month the Birmingham Post and NEC's Big Debate Deliberated Congestion Charging. Today Alan Wenban-Smith Argues Jammed Roads Are Too Complex an Issue to Be Solved by Pricing Alone By Wenban-Smith, Alan The Birmingham Post (England), June 4, 2007
Analysis: Healthcare Pricing By Manila Bulletin, October 15, 2013


text:
You are at:Home»Fitness»Marine Corps Marathon Notebook: Half Marathon Success
Marine Corps Marathon Notebook: Half Marathon Success
By Bethany Crudele on	 September 21, 2012 Fitness, Marines, Sports, Wounded warriors
Retired Staff Sgt. Jeremy Boutwell traveled to Washington, D.C. last weekend for the Inaugural Navy-Air Force half marathon in preparation for next month's Marine Corps Marathon.
In preparation for next month's Marine Corps Marathon, retired Staff Sgt. Jeremy Boutwell and I decided to run the Navy-Air Force half marathon last weekend in Washington, D.C. Jeremy flew in from Texas on Sept. 14 and after a well-balanced meal of spaghetti, Oreos and Gatorade Saturday night, we felt ready to run 13.1 miles.
Before crossing the start line, we had a chance to mingle with other Run and Remember teammates who were racing. Several runners, in addition to Jeremy, flew in from out of town.
"It was a beautiful morning," Jeremy said, "Just perfect weather, nice and cool. We really couldn't have asked for a better day to run that race."
Thanks to an extraordinarily scenic and flat course, we ran an 8:38 pace per mile and finished in 1:52:55. We both agreed the pacing on our first three miles was slower than we anticipated. A slightly crowded start and an unfamiliarity with racing side by side probably had something to do with how fast (or slow!) we weaved in between other runners.
"I don't know what happened to our pacing, but we evened it out in the end. By mile six we were just rolling right through it and by the half way point we were feeling pretty good," Jeremy said.
Runners from our Tragedy Assistance Program for Survivors Run & Remember Teams. We gathered at the base of the Washington Monument before crossing the start line. (Photo credit: Tragedy Assistance Program for Survivors/Marie Campbell)
Jeremy told me after the race he started to have back pain around mile four and that the worst of the pain came at mile eight. He admitted he was gritting his teeth for most of the course. Jeremy battles regular pain brought on by injuries from a 2004 IED attack.
"I was just thinking about finishing the race. I didn't want to let anyone down. I always say the same poem, 'Invictus' by Robert Henley, over and over to myself in my head when I get real bad pain. I just try to zone out and run," Jeremy said.
The last verse, "I am the master of my fate and the captain of my soul," is a phrase from which Jeremy routinely draws comfort and motivation.
We still have a lot of training to do, including an 18-mile training run this weekend. It will be the longest either of us have run during our preparation for the marathon and, of course, we won't be able to pump each other up with words of encouragement as the trail gets tough. So, this weekend will be a challenge. While Jeremy repeats "Invictus" to himself, I'll be reminding myself to put one foot in front of the other. Lather, rinse, repeat.
No race would be complete without a photo at the finish line. We ran an 8:38 pace per mile and finished the course in 1:52:55.
Jeremy and I couldn't be more confident that we'll both be ready for Marine Corps Marathon after last weekend's race. We were able to validate a pace and pin down how long we'll spend at each water stop. And while Jeremy is nervous for how his body will respond to running 26.2 miles, we'll both be ready to take it one mile at a time.
"I'm not running [the marathon]for me. I'm running it for Marines that are no longer with us. I'm going to do anything I absolutely have to do, up to and including, crawling my way across that finish line," Jeremy said.
Deputy News Editor Bethany Crudele plans to run in October's Marine Corps Marathon with retired Staff Sgt. Jeremy Boutwell. She is blogging weekly about his preparations for the race — and hers — on Battle Rattle.
Bethany Crudele


Is your life lacking a mini-submarine / for your goldfish tank? Or do you really need some musical cats / to brighten your day? Never fear, / Japan has just the thing.
The Tokyo Toy Show offers a smorgasboard / of high-tech frippery / to bemuse, delight and entertain / in equal measure.
Masayoshi Goto, / a spokesman for Takara Tomy A.R.T.S, / proudly showed off / his company's set of musical felines.
"When you press the back of these cats, / they meow in a scale, / so you can play music with them," / he proudly explained.