text:
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#include "unicode/utypes.h"

#if !UCONFIG_NO_CONVERSION && !UCONFIG_NO_LEGACY_CONVERSION && !UCONFIG_ONLY_HTML_CONVERSION

#include "unicode/ucnv.h"
#include "unicode/uset.h"
#include "unicode/ucnv_err.h"
#include "unicode/ucnv_cb.h"
#include "unicode/utf16.h"
#include "ucnv_imp.h"
#include "ucnv_bld.h"
#include "ucnv_cnv.h"
#include "ucnvmbcs.h"
#include "cstring.h"
#include "cmemory.h"

typedef enum {
    INVALID = -2,
    DO_SEARCH = -1,

    COMPOUND_TEXT_SINGLE_0 = 0,
    COMPOUND_TEXT_SINGLE_1 = 1,
    COMPOUND_TEXT_SINGLE_2 = 2,
    COMPOUND_TEXT_SINGLE_3 = 3,

    COMPOUND_TEXT_DOUBLE_1 = 4,
    COMPOUND_TEXT_DOUBLE_2 = 5,
    COMPOUND_TEXT_DOUBLE_3 = 6,
    COMPOUND_TEXT_DOUBLE_4 = 7,
    COMPOUND_TEXT_DOUBLE_5 = 8,
    COMPOUND_TEXT_DOUBLE_6 = 9,
    COMPOUND_TEXT_DOUBLE_7 = 10,

    COMPOUND_TEXT_TRIPLE_DOUBLE = 11,

    IBM_915 = 12,
    IBM_916 = 13,
    IBM_914 = 14,
    IBM_874 = 15,
    IBM_912 = 16,
    IBM_913 = 17,
    ISO_8859_14 = 18,
    IBM_923 = 19,
    NUM_OF_CONVERTERS = 20
} COMPOUND_TEXT_CONVERTERS;

#define SEARCH_LENGTH 12

static const uint8_t escSeqCompoundText[NUM_OF_CONVERTERS][5] = {
    /* Single */
    { 0x1B, 0x2D, 0x41, 0, 0 },
    { 0x1B, 0x2D, 0x4D, 0, 0 },
    { 0x1B, 0x2D, 0x46, 0, 0 },
    { 0x1B, 0x2D, 0x47, 0, 0 },

    /* Double */
    { 0x1B, 0x24, 0x29, 0x41, 0 },
    { 0x1B, 0x24, 0x29, 0x42, 0 },
    { 0x1B, 0x24, 0x29, 0x43, 0 },
    { 0x1B, 0x24, 0x29, 0x44, 0 },
    { 0x1B, 0x24, 0x29, 0x47, 0 },
    { 0x1B, 0x24, 0x29, 0x48, 0 },
    { 0x1B, 0x24, 0x29, 0x49, 0 },

    /* Triple/Double */
    { 0x1B, 0x25, 0x47, 0, 0 },

    /*IBM-915*/
    { 0x1B, 0x2D, 0x4C, 0, 0 },
    /*IBM-916*/
    { 0x1B, 0x2D, 0x48, 0, 0 },
    /*IBM-914*/
    { 0x1B, 0x2D, 0x44, 0, 0 },
    /*IBM-874*/
    { 0x1B, 0x2D, 0x54, 0, 0 },
    /*IBM-912*/
    { 0x1B, 0x2D, 0x42, 0, 0 },
    /* IBM-913 */
    { 0x1B, 0x2D, 0x43, 0, 0 },
    /* ISO-8859_14 */
    { 0x1B, 0x2D, 0x5F, 0, 0 },
    /* IBM-923 */
    { 0x1B, 0x2D, 0x62, 0, 0 },
};

#define ESC_START 0x1B

#define isASCIIRange(codepoint) \
        ((codepoint == 0x0000) || (codepoint == 0x0009) || (codepoint == 0x000A) || \
         (codepoint >= 0x0020 && codepoint <= 0x007f) || (codepoint >= 0x00A0 && codepoint <= 0x00FF))

#define isIBM915(codepoint) \
        ((codepoint >= 0x0401 && codepoint <= 0x045F) || (codepoint == 0x2116))

#define isIBM916(codepoint) \
        ((codepoint >= 0x05D0 && codepoint <= 0x05EA) || (codepoint == 0x2017) || (codepoint == 0x203E))

#define isCompoundS3(codepoint) \
        ((codepoint == 0x060C) || (codepoint == 0x061B) || (codepoint == 0x061F) || (codepoint >= 0x0621 && codepoint <= 0x063A) || \
         (codepoint >= 0x0640 && codepoint <= 0x0652) || (codepoint >= 0x0660 && codepoint <= 0x066D) || (codepoint == 0x200B) || \
         (codepoint >= 0x0FE70 && codepoint <= 0x0FE72) || (codepoint == 0x0FE74) || (codepoint >= 0x0FE76 && codepoint <= 0x0FEBE))

#define isCompoundS2(codepoint) \
        ((codepoint == 0x02BC) || (codepoint == 0x02BD) || (codepoint >= 0x0384 && codepoint <= 0x03CE) || (codepoint == 0x2015))

#define isIBM914(codepoint) \
        ((codepoint == 0x0100) || (codepoint == 0x0101) || (codepoint == 0x0112) || (codepoint == 0x0113) || (codepoint == 0x0116) || (codepoint == 0x0117) || \
         (codepoint == 0x0122) || (codepoint == 0x0123) || (codepoint >= 0x0128 && codepoint <= 0x012B) || (codepoint == 0x012E) || (codepoint == 0x012F) || \
         (codepoint >= 0x0136 && codepoint <= 0x0138) || (codepoint == 0x013B) || (codepoint == 0x013C) || (codepoint == 0x0145) || (codepoint ==  0x0146) || \
         (codepoint >= 0x014A && codepoint <= 0x014D) || (codepoint == 0x0156) || (codepoint == 0x0157) || (codepoint >= 0x0166 && codepoint <= 0x016B) || \
         (codepoint == 0x0172) || (codepoint == 0x0173))

#define isIBM874(codepoint) \
        ((codepoint >= 0x0E01 && codepoint <= 0x0E3A) || (codepoint >= 0x0E3F && codepoint <= 0x0E5B))

#define isIBM912(codepoint) \
        ((codepoint >= 0x0102 && codepoint <= 0x0107) || (codepoint >= 0x010C && codepoint <= 0x0111) || (codepoint >= 0x0118 && codepoint <= 0x011B) || \
         (codepoint == 0x0139) || (codepoint == 0x013A) || (codepoint == 0x013D) || (codepoint == 0x013E) || (codepoint >= 0x0141 && codepoint <= 0x0144) || \
         (codepoint == 0x0147) || (codepoint == 0x0147) || (codepoint == 0x0150) || (codepoint == 0x0151) || (codepoint == 0x0154) || (codepoint == 0x0155) || \
         (codepoint >= 0x0158 && codepoint <= 0x015B) || (codepoint == 0x015E) || (codepoint == 0x015F) || (codepoint >= 0x0160 && codepoint <= 0x0165) || \
         (codepoint == 0x016E) || (codepoint == 0x016F) || (codepoint == 0x0170) || (codepoint ==  0x0171) || (codepoint >= 0x0179 && codepoint <= 0x017E) || \
         (codepoint == 0x02C7) || (codepoint == 0x02D8) || (codepoint == 0x02D9) || (codepoint == 0x02DB) || (codepoint == 0x02DD))

#define isIBM913(codepoint) \
        ((codepoint >= 0x0108 && codepoint <= 0x010B) || (codepoint == 0x011C) || \
         (codepoint == 0x011D) || (codepoint == 0x0120) || (codepoint == 0x0121) || \
         (codepoint >= 0x0124 && codepoint <= 0x0127) || (codepoint == 0x0134) || (codepoint == 0x0135) || \
         (codepoint == 0x015C) || (codepoint == 0x015D) || (codepoint == 0x016C) || (codepoint ==  0x016D))

#define isCompoundS1(codepoint) \
        ((codepoint == 0x011E) || (codepoint == 0x011F) || (codepoint == 0x0130) || \
         (codepoint == 0x0131) || (codepoint >= 0x0218 && codepoint <= 0x021B))

#define isISO8859_14(codepoint) \
        ((codepoint >= 0x0174 && codepoint <= 0x0177) || (codepoint == 0x1E0A) || \
         (codepoint == 0x1E0B) || (codepoint == 0x1E1E) || (codepoint == 0x1E1F) || \
         (codepoint == 0x1E40) || (codepoint == 0x1E41) || (codepoint == 0x1E56) || \
         (codepoint == 0x1E57) || (codepoint == 0x1E60) || (codepoint == 0x1E61) || \
         (codepoint == 0x1E6A) || (codepoint == 0x1E6B) || (codepoint == 0x1EF2) || \
         (codepoint == 0x1EF3) || (codepoint >= 0x1E80 && codepoint <= 0x1E85))

#define isIBM923(codepoint) \
        ((codepoint == 0x0152) || (codepoint == 0x0153) || (codepoint == 0x0178) || (codepoint == 0x20AC))

typedef struct{
    UConverterSharedData *myConverterArray[NUM_OF_CONVERTERS];
    COMPOUND_TEXT_CONVERTERS state;
} UConverterDataCompoundText;

/*********** Compound Text Converter Protos ***********/
U_CDECL_BEGIN
static void U_CALLCONV
_CompoundTextOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode);

static void U_CALLCONV
 _CompoundTextClose(UConverter *converter);

static void U_CALLCONV
_CompoundTextReset(UConverter *converter, UConverterResetChoice choice);

static const char* U_CALLCONV
_CompoundTextgetName(const UConverter* cnv);

static int32_t findNextEsc(const char *source, const char *sourceLimit) {
    int32_t length = static_cast<int32_t>(sourceLimit - source);
    int32_t i;
    for (i = 1; i < length; i++) {
        if (*(source + i) == 0x1B) {
            return i;
        }
    }

    return length;
}

static COMPOUND_TEXT_CONVERTERS getState(int codepoint) {
    COMPOUND_TEXT_CONVERTERS state = DO_SEARCH;

    if (isASCIIRange(codepoint)) {
        state = COMPOUND_TEXT_SINGLE_0;
    } else if (isIBM912(codepoint)) {
        state = IBM_912;
    }else if (isIBM913(codepoint)) {
        state = IBM_913;
    } else if (isISO8859_14(codepoint)) {
        state = ISO_8859_14;
    } else if (isIBM923(codepoint)) {
        state = IBM_923;
    } else if (isIBM874(codepoint)) {
        state = IBM_874;
    } else if (isIBM914(codepoint)) {
        state = IBM_914;
    } else if (isCompoundS2(codepoint)) {
        state = COMPOUND_TEXT_SINGLE_2;
    } else if (isCompoundS3(codepoint)) {
        state = COMPOUND_TEXT_SINGLE_3;
    } else if (isIBM916(codepoint)) {
        state = IBM_916;
    } else if (isIBM915(codepoint)) {
        state = IBM_915;
    } else if (isCompoundS1(codepoint)) {
        state = COMPOUND_TEXT_SINGLE_1;
    }

    return state;
}

static COMPOUND_TEXT_CONVERTERS findStateFromEscSeq(const char* source, const char* sourceLimit, const uint8_t* toUBytesBuffer, int32_t toUBytesBufferLength, UErrorCode *err) {
    COMPOUND_TEXT_CONVERTERS state = INVALID;
    UBool matchFound = false;
    int32_t i, n, offset = toUBytesBufferLength;

    for (i = 0; i < NUM_OF_CONVERTERS; i++) {
        matchFound = true;
        for (n = 0; escSeqCompoundText[i][n] != 0; n++) {
            if (n < toUBytesBufferLength) {
                if (toUBytesBuffer[n] != escSeqCompoundText[i][n]) {
                    matchFound = false;
                    break;
                }
            } else if ((source + (n - offset)) >= sourceLimit) {
                *err = U_TRUNCATED_CHAR_FOUND;
                matchFound = false;
                break;
            } else if (*(source + (n - offset)) != escSeqCompoundText[i][n]) {
                matchFound = false;
                break;
            }
        }

        if (matchFound) {
            break;
        }
    }

    if (matchFound) {
        state = (COMPOUND_TEXT_CONVERTERS)i;
    }

    return state;
}

static void U_CALLCONV
_CompoundTextOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode){
    cnv->extraInfo = uprv_malloc (sizeof (UConverterDataCompoundText));
    if (cnv->extraInfo != NULL) {
        UConverterDataCompoundText *myConverterData = (UConverterDataCompoundText *) cnv->extraInfo;

        UConverterNamePieces stackPieces;
        UConverterLoadArgs stackArgs=UCNV_LOAD_ARGS_INITIALIZER;

        myConverterData->myConverterArray[COMPOUND_TEXT_SINGLE_0] = NULL;
        myConverterData->myConverterArray[COMPOUND_TEXT_SINGLE_1] = ucnv_loadSharedData("icu-internal-compound-s1", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_SINGLE_2] = ucnv_loadSharedData("icu-internal-compound-s2", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_SINGLE_3] = ucnv_loadSharedData("icu-internal-compound-s3", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_DOUBLE_1] = ucnv_loadSharedData("icu-internal-compound-d1", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_DOUBLE_2] = ucnv_loadSharedData("icu-internal-compound-d2", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_DOUBLE_3] = ucnv_loadSharedData("icu-internal-compound-d3", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_DOUBLE_4] = ucnv_loadSharedData("icu-internal-compound-d4", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_DOUBLE_5] = ucnv_loadSharedData("icu-internal-compound-d5", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_DOUBLE_6] = ucnv_loadSharedData("icu-internal-compound-d6", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_DOUBLE_7] = ucnv_loadSharedData("icu-internal-compound-d7", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[COMPOUND_TEXT_TRIPLE_DOUBLE] = ucnv_loadSharedData("icu-internal-compound-t", &stackPieces, &stackArgs, errorCode);

        myConverterData->myConverterArray[IBM_915] = ucnv_loadSharedData("ibm-915_P100-1995", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[IBM_916] = ucnv_loadSharedData("ibm-916_P100-1995", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[IBM_914] = ucnv_loadSharedData("ibm-914_P100-1995", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[IBM_874] = ucnv_loadSharedData("ibm-874_P100-1995", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[IBM_912] = ucnv_loadSharedData("ibm-912_P100-1995", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[IBM_913] = ucnv_loadSharedData("ibm-913_P100-2000", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[ISO_8859_14] = ucnv_loadSharedData("iso-8859_14-1998", &stackPieces, &stackArgs, errorCode);
        myConverterData->myConverterArray[IBM_923] = ucnv_loadSharedData("ibm-923_P100-1998", &stackPieces, &stackArgs, errorCode);

        if (U_FAILURE(*errorCode) || pArgs->onlyTestIsLoadable) {
            _CompoundTextClose(cnv);
            return;
        }

        myConverterData->state = (COMPOUND_TEXT_CONVERTERS)0;
    } else {
        *errorCode = U_MEMORY_ALLOCATION_ERROR;
    }
}

static void U_CALLCONV
_CompoundTextClose(UConverter *converter) {
    UConverterDataCompoundText* myConverterData = (UConverterDataCompoundText*)(converter->extraInfo);
    int32_t i;

    if (converter->extraInfo != NULL) {
        /*close the array of converter pointers and free the memory*/
        for (i = 0; i < NUM_OF_CONVERTERS; i++) {
            if (myConverterData->myConverterArray[i] != NULL) {
                ucnv_unloadSharedDataIfReady(myConverterData->myConverterArray[i]);
            }
        }

        uprv_free(converter->extraInfo);
        converter->extraInfo = NULL;
    }
}

static void U_CALLCONV
_CompoundTextReset(UConverter *converter, UConverterResetChoice choice) {
    (void)converter;
    (void)choice;
}

static const char* U_CALLCONV
_CompoundTextgetName(const UConverter* cnv){
    (void)cnv;
    return "x11-compound-text";
}

static void U_CALLCONV
UConverter_fromUnicode_CompoundText_OFFSETS(UConverterFromUnicodeArgs* args, UErrorCode* err){
    UConverter *cnv = args->converter;
    uint8_t *target = (uint8_t *) args->target;
    const uint8_t *targetLimit = (const uint8_t *) args->targetLimit;
    const UChar* source = args->source;
    const UChar* sourceLimit = args->sourceLimit;
    /* int32_t* offsets = args->offsets; */
    UChar32 sourceChar;
    UBool useFallback = cnv->useFallback;
    uint8_t tmpTargetBuffer[7];
    int32_t tmpTargetBufferLength = 0;
    COMPOUND_TEXT_CONVERTERS currentState, tmpState;
    uint32_t pValue;
    int32_t pValueLength = 0;
    int32_t i, n, j;

    UConverterDataCompoundText *myConverterData = (UConverterDataCompoundText *) cnv->extraInfo;

    currentState = myConverterData->state;

    /* check if the last codepoint of previous buffer was a lead surrogate*/
    if((sourceChar = cnv->fromUChar32)!=0 && target< targetLimit) {
        goto getTrail;
    }

    while( source < sourceLimit){
        if(target < targetLimit){

            sourceChar  = *(source++);
            /*check if the char is a First surrogate*/
             if(U16_IS_SURROGATE(sourceChar)) {
                if(U16_IS_SURROGATE_LEAD(sourceChar)) {
getTrail:
                    /*look ahead to find the trail surrogate*/
                    if(source < sourceLimit) {
                        /* test the following code unit */
                        UChar trail=(UChar) *source;
                        if(U16_IS_TRAIL(trail)) {
                            source++;
                            sourceChar=U16_GET_SUPPLEMENTARY(sourceChar, trail);
                            cnv->fromUChar32=0x00;
                            /* convert this supplementary code point */
                            /* exit this condition tree */
                        } else {
                            /* this is an unmatched lead code unit (1st surrogate) */
                            /* callback(illegal) */
                            *err=U_ILLEGAL_CHAR_FOUND;
                            cnv->fromUChar32=sourceChar;
                            break;
                        }
                    } else {
                        /* no more input */
                        cnv->fromUChar32=sourceChar;
                        break;
                    }
                } else {
                    /* this is an unmatched trail code unit (2nd surrogate) */
                    /* callback(illegal) */
                    *err=U_ILLEGAL_CHAR_FOUND;
                    cnv->fromUChar32=sourceChar;
                    break;
                }
            }

             tmpTargetBufferLength = 0;
             tmpState = getState(sourceChar);

             if (tmpState != DO_SEARCH && currentState != tmpState) {
                 /* Get escape sequence if necessary */
                 currentState = tmpState;
                 for (i = 0; escSeqCompoundText[currentState][i] != 0; i++) {
                     tmpTargetBuffer[tmpTargetBufferLength++] = escSeqCompoundText[currentState][i];
                 }
             }

             if (tmpState == DO_SEARCH) {
                 /* Test all available converters */
                 for (i = 1; i < SEARCH_LENGTH; i++) {
                     pValueLength = ucnv_MBCSFromUChar32(myConverterData->myConverterArray[i], sourceChar, &pValue, useFallback);
                     if (pValueLength > 0) {
                         tmpState = (COMPOUND_TEXT_CONVERTERS)i;
                         if (currentState != tmpState) {
                             currentState = tmpState;
                             for (j = 0; escSeqCompoundText[currentState][j] != 0; j++) {
                                 tmpTargetBuffer[tmpTargetBufferLength++] = escSeqCompoundText[currentState][j];
                             }
                         }
                         for (n = (pValueLength - 1); n >= 0; n--) {
                             tmpTargetBuffer[tmpTargetBufferLength++] = (uint8_t)(pValue >> (n * 8));
                         }
                         break;
                     }
                 }
             } else if (tmpState == COMPOUND_TEXT_SINGLE_0) {
                 tmpTargetBuffer[tmpTargetBufferLength++] = (uint8_t)sourceChar;
             } else {
                 pValueLength = ucnv_MBCSFromUChar32(myConverterData->myConverterArray[currentState], sourceChar, &pValue, useFallback);
                 if (pValueLength > 0) {
                     for (n = (pValueLength - 1); n >= 0; n--) {
                         tmpTargetBuffer[tmpTargetBufferLength++] = (uint8_t)(pValue >> (n * 8));
                     }
                 }
             }

             for (i = 0; i < tmpTargetBufferLength; i++) {
                 if (target < targetLimit) {
                     *target++ = tmpTargetBuffer[i];
                 } else {
                     *err = U_BUFFER_OVERFLOW_ERROR;
                     break;
                 }
             }

             if (*err == U_BUFFER_OVERFLOW_ERROR) {
                 for (; i < tmpTargetBufferLength; i++) {
                     args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = tmpTargetBuffer[i];
                 }
             }
        } else {
            *err = U_BUFFER_OVERFLOW_ERROR;
            break;
        }
    }

    /*save the state and return */
    myConverterData->state = currentState;
    args->source = source;
    args->target = (char*)target;
}

static void U_CALLCONV
UConverter_toUnicode_CompoundText_OFFSETS(UConverterToUnicodeArgs *args,
                                               UErrorCode* err){
    const char *mySource = (char *) args->source;
    UChar *myTarget = args->target;
    const char *mySourceLimit = args->sourceLimit;
    const char *tmpSourceLimit = mySourceLimit;
    uint32_t mySourceChar = 0x0000;
    COMPOUND_TEXT_CONVERTERS currentState, tmpState;
    int32_t sourceOffset = 0;
    UConverterDataCompoundText *myConverterData = (UConverterDataCompoundText *) args->converter->extraInfo;
    UConverterSharedData* savedSharedData = NULL;

    UConverterToUnicodeArgs subArgs;
    int32_t minArgsSize;

    /* set up the subconverter arguments */
    if(args->size<sizeof(UConverterToUnicodeArgs)) {
        minArgsSize = args->size;
    } else {
        minArgsSize = (int32_t)sizeof(UConverterToUnicodeArgs);
    }

    uprv_memcpy(&subArgs, args, minArgsSize);
    subArgs.size = (uint16_t)minArgsSize;

    currentState = tmpState =  myConverterData->state;

    while(mySource < mySourceLimit){
        if(myTarget < args->targetLimit){
            if (args->converter->toULength > 0) {
                mySourceChar = args->converter->toUBytes[0];
            } else {
                mySourceChar = (uint8_t)*mySource;
            }

            if (mySourceChar == ESC_START) {
                tmpState = findStateFromEscSeq(mySource, mySourceLimit, args->converter->toUBytes, args->converter->toULength, err);

                if (*err == U_TRUNCATED_CHAR_FOUND) {
                    for (; mySource < mySourceLimit;) {
                        args->converter->toUBytes[args->converter->toULength++] = *mySource++;
                    }
                    *err = U_ZERO_ERROR;
                    break;
                } else if (tmpState == INVALID) {
                    if (args->converter->toULength == 0) {
                        mySource++; /* skip over the 0x1b byte */
                    }
                    *err = U_ILLEGAL_CHAR_FOUND;
                    break;
                }

                if (tmpState != currentState) {
                    currentState = tmpState;
                }

                sourceOffset = static_cast<int32_t>(uprv_strlen((char*)escSeqCompoundText[currentState]) - args->converter->toULength);

                mySource += sourceOffset;

                args->converter->toULength = 0;
            }

            if (currentState == COMPOUND_TEXT_SINGLE_0) {
                while (mySource < mySourceLimit) {
                    if (*mySource == ESC_START) {
                        break;
                    }
                    if (myTarget < args->targetLimit) {
                        *myTarget++ = 0x00ff&(*mySource++);
                    } else {
                        *err = U_BUFFER_OVERFLOW_ERROR;
                        break;
                    }
                }
            } else if (mySource < mySourceLimit){
                sourceOffset = findNextEsc(mySource, mySourceLimit);

                tmpSourceLimit = mySource + sourceOffset;

                subArgs.source = mySource;
                subArgs.sourceLimit = tmpSourceLimit;
                subArgs.target = myTarget;
                savedSharedData = subArgs.converter->sharedData;
                subArgs.converter->sharedData = myConverterData->myConverterArray[currentState];

                ucnv_MBCSToUnicodeWithOffsets(&subArgs, err);

                subArgs.converter->sharedData = savedSharedData;

                mySource = subArgs.source;
                myTarget = subArgs.target;

                if (U_FAILURE(*err)) {
                    if(*err == U_BUFFER_OVERFLOW_ERROR) {
                        if(subArgs.converter->UCharErrorBufferLength > 0) {
                            uprv_memcpy(args->converter->UCharErrorBuffer, subArgs.converter->UCharErrorBuffer,
                                        subArgs.converter->UCharErrorBufferLength);
                        }
                        args->converter->UCharErrorBufferLength=subArgs.converter->UCharErrorBufferLength;
                        subArgs.converter->UCharErrorBufferLength = 0;
                    }
                    break;
                }
            }
        } else {
            *err = U_BUFFER_OVERFLOW_ERROR;
            break;
        }
    }
    myConverterData->state = currentState;
    args->target = myTarget;
    args->source = mySource;
}

static void U_CALLCONV
_CompoundText_GetUnicodeSet(const UConverter *cnv,
                    const USetAdder *sa,
                    UConverterUnicodeSet which,
                    UErrorCode *pErrorCode) {
    UConverterDataCompoundText *myConverterData = (UConverterDataCompoundText *)cnv->extraInfo;
    int32_t i;

    for (i = 1; i < NUM_OF_CONVERTERS; i++) {
        ucnv_MBCSGetUnicodeSetForUnicode(myConverterData->myConverterArray[i], sa, which, pErrorCode);
    }
    sa->add(sa->set, 0x0000);
    sa->add(sa->set, 0x0009);
    sa->add(sa->set, 0x000A);
    sa->addRange(sa->set, 0x0020, 0x007F);
    sa->addRange(sa->set, 0x00A0, 0x00FF);
}
U_CDECL_END

static const UConverterImpl _CompoundTextImpl = {

    UCNV_COMPOUND_TEXT,

    NULL,
    NULL,

    _CompoundTextOpen,
    _CompoundTextClose,
    _CompoundTextReset,

    UConverter_toUnicode_CompoundText_OFFSETS,
    UConverter_toUnicode_CompoundText_OFFSETS,
    UConverter_fromUnicode_CompoundText_OFFSETS,
    UConverter_fromUnicode_CompoundText_OFFSETS,
    NULL,

    NULL,
    _CompoundTextgetName,
    NULL,
    NULL,
    _CompoundText_GetUnicodeSet,
    NULL,
    NULL
};

static const UConverterStaticData _CompoundTextStaticData = {
    sizeof(UConverterStaticData),
    "COMPOUND_TEXT",
    0,
    UCNV_IBM,
    UCNV_COMPOUND_TEXT,
    1,
    6,
    { 0xef, 0, 0, 0 },
    1,
    false,
    false,
    0,
    0,
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } /* reserved */
};
const UConverterSharedData _CompoundTextData =
        UCNV_IMMUTABLE_SHARED_DATA_INITIALIZER(&_CompoundTextStaticData, &_CompoundTextImpl);

#endif /* #if !UCONFIG_NO_LEGACY_CONVERSION */

redpajama_set_name: RedPajamaGithub


text:
/*
 * Derived from the OSM tile source in Rainer Simon's seajax-utils project
 * <http://github.com/rsimon/seajax-utils>.  Rainer Simon has contributed
 * the included code to the OpenSeadragon project under the New BSD license;
 * see <https://github.com/openseadragon/openseadragon/issues/58>.
 */

(function( $ ){

/**
 * @class OsmTileSource
 * @classdesc A tilesource implementation for OpenStreetMap.

 *
 * Note 1. Zoomlevels. Deep Zoom and OSM define zoom levels differently. In  Deep
 * Zoom, level 0 equals an image of 1x1 pixels. In OSM, level 0 equals an image of
 * 256x256 levels (see http://gasi.ch/blog/inside-deep-zoom-2). I.e. there is a
 * difference of log2(256)=8 levels.

 *
 * Note 2. Image dimension. According to the OSM Wiki
 * (http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels)
 * the highest Mapnik zoom level has 256.144x256.144 tiles, with a 256x256
 * pixel size. I.e. the Deep Zoom image dimension is 65.572.864x65.572.864
 * pixels.
 *
 * @memberof OpenSeadragon
 * @extends OpenSeadragon.TileSource
 * @param {Number|Object} width - the pixel width of the image or the idiomatic
 *      options object which is used instead of positional arguments.
 * @param {Number} height
 * @param {Number} tileSize
 * @param {Number} tileOverlap
 * @param {String} tilesUrl
 */
$.OsmTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) {
    var options;

    if( $.isPlainObject( width ) ){
        options = width;
    }else{
        options = {
            width: arguments[0],
            height: arguments[1],
            tileSize: arguments[2],
            tileOverlap: arguments[3],
            tilesUrl: arguments[4]
        };
    }
    //apply default setting for standard public OpenStreatMaps service
    //but allow them to be specified so fliks can host there own instance
    //or apply against other services supportting the same standard
    if( !options.width || !options.height ){
        options.width = 65572864;
        options.height = 65572864;
    }
    if( !options.tileSize ){
        options.tileSize = 256;
        options.tileOverlap = 0;
    }
    if( !options.tilesUrl ){
        options.tilesUrl = "http://tile.openstreetmap.org/";
    }
    options.minLevel = 8;

    $.TileSource.apply( this, [ options ] );

};

$.extend( $.OsmTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.OsmTileSource.prototype */{

    /**
     * Determine if the data and/or url imply the image service is supported by
     * this tile source.
     * @function
     * @param {Object|Array} data
     * @param {String} optional - url
     */
    supports: function( data, url ){
        return (
            data.type &&
            "openstreetmaps" == data.type
        );
    },

    /**
     *
     * @function
     * @param {Object} data - the raw configuration
     * @param {String} url - the url the data was retreived from if any.
     * @return {Object} options - A dictionary of keyword arguments sufficient
     *      to configure this tile sources constructor.
     */
    configure: function( data, url ){
        return data;
    },

    /**
     * @function
     * @param {Number} level
     * @param {Number} x
     * @param {Number} y
     */
    getTileUrl: function( level, x, y ) {
        return this.tilesUrl + (level - 8) + "/" + x + "/" + y + ".png";
    }
});

}( OpenSeadragon ));


text:
package org.apache.hadoop.yarn.server.resourcemanager.reservation;

import org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.yarn.api.records.ReservationId;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.server.resourcemanager.reservation.RLESparseResourceAllocation.RLEOperator;
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningException;
import org.apache.hadoop.yarn.server.resourcemanager.reservation.exceptions.PlanningQuotaException;
import org.apache.hadoop.yarn.util.resource.Resources;

import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;

/**
 * This policy enforces a time-extended notion of Capacity. In particular it
 * guarantees that the allocation received in input when combined with all
 * previous allocation for the user does not violate an instantaneous max limit
 * on the resources received, and that for every window of time of length
 * validWindow, the integral of the allocations for a user (sum of the currently
 * submitted allocation and all prior allocations for the user) does not exceed
 * validWindow * maxAvg.
 *
 * This allows flexibility, in the sense that an allocation can instantaneously
 * use large portions of the available capacity, but prevents abuses by bounding
 * the average use over time.
 *
 * By controlling maxInst, maxAvg, validWindow the administrator configuring
 * this policy can obtain a behavior ranging from instantaneously enforced
 * capacity (akin to existing queues), or fully flexible allocations (likely
 * reserved to super-users, or trusted systems).
 */
@LimitedPrivate("yarn")
@Unstable
public class CapacityOverTimePolicy extends NoOverCommitPolicy {

  private ReservationSchedulerConfiguration conf;
  private long validWindow;
  private float maxInst;
  private float maxAvg;

  // For now this is CapacityScheduler specific, but given a hierarchy in the
  // configuration structure of the schedulers (e.g., SchedulerConfiguration)
  // it should be easy to remove this limitation
  @Override
  public void init(String reservationQueuePath,
      ReservationSchedulerConfiguration conf) {
    this.conf = conf;
    validWindow = this.conf.getReservationWindow(reservationQueuePath);
    maxInst = this.conf.getInstantaneousMaxCapacity(reservationQueuePath) / 100;
    maxAvg = this.conf.getAverageCapacity(reservationQueuePath) / 100;
  }

  /**
   * The validation algorithm walks over the RLE encoded allocation and
   * checks that for all transition points (when the start or end of the
   * checking window encounters a value in the RLE). At this point it
   * checkes whether the integral computed exceeds the quota limit. Note that
   * this might not find the exact time of a violation, but if a violation
   * exists it will find it. The advantage is a much lower number of checks
   * as compared to time-slot by time-slot checks.
   *
   * @param plan the plan to validate against
   * @param reservation the reservation allocation to test.
   * @throws PlanningException if the validation fails.
   */
  @Override
  public void validate(Plan plan, ReservationAllocation reservation)
      throws PlanningException {

    // rely on NoOverCommitPolicy to check for: 1) user-match, 2) physical
    // cluster limits, and 3) maxInst (via override of available)
    try {
      super.validate(plan, reservation);
    } catch (PlanningException p) {
      //wrap it in proper quota exception
      throw new PlanningQuotaException(p);
    }

    long checkStart = reservation.getStartTime() - validWindow;
    long checkEnd = reservation.getEndTime() + validWindow;

    //---- check for integral violations of capacity --------

    // Gather a view of what to check (curr allocation of user, minus old
    // version of this reservation, plus new version)
    RLESparseResourceAllocation consumptionForUserOverTime =
        plan.getConsumptionForUserOverTime(reservation.getUser(),
            checkStart, checkEnd);

    ReservationAllocation old =
        plan.getReservationById(reservation.getReservationId());
    if (old != null) {
      consumptionForUserOverTime =
          RLESparseResourceAllocation.merge(plan.getResourceCalculator(),
              plan.getTotalCapacity(), consumptionForUserOverTime,
              old.getResourcesOverTime(checkStart, checkEnd), RLEOperator.add,
              checkStart, checkEnd);
    }

    RLESparseResourceAllocation resRLE =
        reservation.getResourcesOverTime(checkStart, checkEnd);

    RLESparseResourceAllocation toCheck = RLESparseResourceAllocation
        .merge(plan.getResourceCalculator(), plan.getTotalCapacity(),
            consumptionForUserOverTime, resRLE, RLEOperator.add, Long.MIN_VALUE,
            Long.MAX_VALUE);

    NavigableMap<Long, Resource> integralUp = new TreeMap<>();
    NavigableMap<Long, Resource> integralDown = new TreeMap<>();

    long prevTime = toCheck.getEarliestStartTime();
    IntegralResource prevResource = new IntegralResource(0L, 0L);
    IntegralResource runningTot = new IntegralResource(0L, 0L);

    // add intermediate points
    Map<Long, Resource> temp = new TreeMap<>();
    for (Map.Entry<Long, Resource> pointToCheck : toCheck.getCumulative()
        .entrySet()) {

      Long timeToCheck = pointToCheck.getKey();
      Resource resourceToCheck = pointToCheck.getValue();

      Long nextPoint = toCheck.getCumulative().higherKey(timeToCheck);
      if (nextPoint == null || toCheck.getCumulative().get(nextPoint) == null) {
        continue;
      }
      for (int i = 1; i <= (nextPoint - timeToCheck) / validWindow; i++) {
        temp.put(timeToCheck + (i * validWindow), resourceToCheck);
      }
    }
    temp.putAll(toCheck.getCumulative());

    // compute point-wise integral for the up-fronts and down-fronts
    for (Map.Entry<Long, Resource> currPoint : temp.entrySet()) {

      Long currTime = currPoint.getKey();
      Resource currResource = currPoint.getValue();

      //add to running total current contribution
      prevResource.multiplyBy(currTime - prevTime);
      runningTot.add(prevResource);
      integralUp.put(currTime, normalizeToResource(runningTot, validWindow));
      integralDown.put(currTime + validWindow,
          normalizeToResource(runningTot, validWindow));

      if (currResource != null) {
        prevResource.memory = currResource.getMemorySize();
        prevResource.vcores = currResource.getVirtualCores();
      } else {
        prevResource.memory = 0L;
        prevResource.vcores = 0L;
      }
      prevTime = currTime;
    }

    // compute final integral as delta of up minus down transitions
    RLESparseResourceAllocation intUp =
        new RLESparseResourceAllocation(integralUp,
            plan.getResourceCalculator());
    RLESparseResourceAllocation intDown =
        new RLESparseResourceAllocation(integralDown,
            plan.getResourceCalculator());

    RLESparseResourceAllocation integral = RLESparseResourceAllocation
        .merge(plan.getResourceCalculator(), plan.getTotalCapacity(), intUp,
            intDown, RLEOperator.subtract, Long.MIN_VALUE, Long.MAX_VALUE);

    // define over-time integral limit
    // note: this is aligned with the normalization done above
    NavigableMap<Long, Resource> tlimit = new TreeMap<>();
    Resource maxAvgRes = Resources.multiply(plan.getTotalCapacity(), maxAvg);
    tlimit.put(toCheck.getEarliestStartTime() - validWindow, maxAvgRes);
    RLESparseResourceAllocation targetLimit =
        new RLESparseResourceAllocation(tlimit, plan.getResourceCalculator());

    // compare using merge() limit with integral
    try {

      RLESparseResourceAllocation.merge(plan.getResourceCalculator(),
          plan.getTotalCapacity(), targetLimit, integral,
          RLEOperator.subtractTestNonNegative, checkStart, checkEnd);

    } catch (PlanningException p) {
      throw new PlanningQuotaException(
          "Integral (avg over time) quota capacity " + maxAvg
              + " over a window of " + validWindow / 1000 + " seconds, "
              + " would be exceeded by accepting reservation: " + reservation
              .getReservationId(), p);
    }
  }

  private Resource normalizeToResource(IntegralResource runningTot,
      long window) {
    // normalize to fit in windows. Rounding should not impact more than
    // sub 1 core average allocations. This will all be removed once
    // Resource moves to long.
    int memory = (int) Math.round((double) runningTot.memory / window);
    int vcores = (int) Math.round((double) runningTot.vcores / window);
    return Resource.newInstance(memory, vcores);
  }

  @Override
  public RLESparseResourceAllocation availableResources(
      RLESparseResourceAllocation available, Plan plan, String user,
      ReservationId oldId, long start, long end) throws PlanningException {

    // this only propagates the instantaneous maxInst properties, while
    // the time-varying one depends on the current allocation as well
    // and are not easily captured here
    Resource planTotalCapacity = plan.getTotalCapacity();
    Resource maxInsRes = Resources.multiply(planTotalCapacity, maxInst);
    NavigableMap<Long, Resource> instQuota = new TreeMap<Long, Resource>();
    instQuota.put(start, maxInsRes);

    RLESparseResourceAllocation instRLEQuota =
        new RLESparseResourceAllocation(instQuota,
            plan.getResourceCalculator());

    RLESparseResourceAllocation used =
        plan.getConsumptionForUserOverTime(user, start, end);

    // add back in old reservation used resources if any
    ReservationAllocation old = plan.getReservationById(oldId);
    if (old != null) {
      used = RLESparseResourceAllocation.merge(plan.getResourceCalculator(),
          Resources.clone(plan.getTotalCapacity()), used,
          old.getResourcesOverTime(start, end), RLEOperator.subtract, start,
          end);
    }

    instRLEQuota = RLESparseResourceAllocation
        .merge(plan.getResourceCalculator(), planTotalCapacity, instRLEQuota,
            used, RLEOperator.subtract, start, end);

    instRLEQuota = RLESparseResourceAllocation
        .merge(plan.getResourceCalculator(), planTotalCapacity, available,
            instRLEQuota, RLEOperator.min, start, end);

    return instRLEQuota;
  }

  @Override
  public long getValidWindow() {
    return validWindow;
  }

  /**
   * This class provides support for Resource-like book-keeping, based on
   * long(s), as using Resource to store the "integral" of the allocation over
   * time leads to integer overflows for large allocations/clusters. (Evolving
   * Resource to use long is too disruptive at this point.)
   *
   * The comparison/multiplication behaviors of IntegralResource are consistent
   * with the DefaultResourceCalculator.
   */
  private static class IntegralResource {
    long memory;
    long vcores;

    public IntegralResource(Resource resource) {
      this.memory = resource.getMemorySize();
      this.vcores = resource.getVirtualCores();
    }

    public IntegralResource(long mem, long vcores) {
      this.memory = mem;
      this.vcores = vcores;
    }

    public void add(Resource r) {
      memory += r.getMemorySize();
      vcores += r.getVirtualCores();
    }

    public void add(IntegralResource r) {
      memory += r.memory;
      vcores += r.vcores;
    }

    public void subtract(Resource r) {
      memory -= r.getMemorySize();
      vcores -= r.getVirtualCores();
    }

    public IntegralResource negate() {
      return new IntegralResource(-memory, -vcores);
    }

    public void multiplyBy(long window) {
      memory = memory * window;
      vcores = vcores * window;
    }

    public long compareTo(IntegralResource other) {
      long diff = memory - other.memory;
      if (diff == 0) {
        diff = vcores - other.vcores;
      }
      return diff;
    }

    @Override
    public String toString() {
      return "<memory:" + memory + ", vCores:" + vcores + ">";
    }

  }

}


text:
<?php

defined( 'SYS_CORE_PATH' ) OR exit( 'No direct script access allowed' ) ;

/**
 * Output Class
 *
 * Responsible for sending final output to the browser.
 *
 * @package		CodeIgniter
 * @subpackage	Libraries
 * @category	Output
 * @author		EllisLab Dev Team
 * @link		http://codeigniter.com/user_guide/libraries/output.html
 */
class CI_Output {

	/**
	 * Final output string
	 *
	 * @var	string
	 */
	public $final_output;

	/**
	 * Cache expiration time
	 *
	 * @var	int
	 */
	public $cache_expiration = 0;

	/**
	 * List of server headers
	 *
	 * @var	array
	 */
	public $headers = array( );

	/**
	 * List of mime types
	 *
	 * @var	array
	 */
	public $mimes =	array( );

	/**
	 * Mime-type for the current page
	 *
	 * @var	string
	 */
	protected $mime_type = 'text/html';

	/**
	 * Enable Profiler flag
	 *
	 * @var	bool
	 */
	public $enable_profiler = FALSE;

	/**
	 * php.ini zlib.output_compression flag
	 *
	 * @var	bool
	 */
	protected $_zlib_oc = FALSE;

	/**
	 * CI output compression flag
	 *
	 * @var	bool
	 */
	protected $_compress_output = FALSE;

	/**
	 * List of profiler sections
	 *
	 * @var	array
	 */
	protected $_profiler_sections =	array( );

	/**
	 * Parse markers flag
	 *
	 * Whether or not to parse variables like {elapsed_time} and {memory_usage}.
	 *
	 * @var	bool
	 */
	public $parse_exec_vars = TRUE;

	/**
	 * Class constructor
	 *
	 * Determines whether zLib output compression will be used.
	 *
	 * @return	void
	 */
	public function __construct( )
	{
		$this->_zlib_oc = (bool ) ini_get( 'zlib.output_compression' );
		$this->_compress_output = (
			$this->_zlib_oc === FALSE
			&& config_item( 'compress_output' ) === TRUE
			&& extension_loaded( 'zlib' )
		 );

		// Get mime types for later
		$this->mimes =& get_mimes( );

		log_message( 'info', 'Output Class Initialized' );
	}

	// --------------------------------------------------------------------

	/**
	 * Get Output
	 *
	 * Returns the current output string.
	 *
	 * @return	string
	 */
	public function get_output( )
	{
		return  $this->final_output;
	}

	// --------------------------------------------------------------------

	/**
	 * Set Output
	 *
	 * Sets the output string.
	 *
	 * @param	string	$output	Output data
	 * @return	CI_Output
	 */
	public function set_output( $output )
	{
		$this->final_output = $output;
		return  $this;
	}

	// --------------------------------------------------------------------

	/**
	 * Append Output
	 *
	 * Appends data onto the output string.
	 *
	 * @param	string	$output	Data to append
	 * @return	CI_Output
	 */
	public function append_output( $output )
	{
		$this->final_output .= $output;
		return  $this;
	}

	// --------------------------------------------------------------------

	/**
	 * Set Header
	 *
	 * Lets you set a server header which will be sent with the final output.
	 *
	 * Note: If a file is cached, headers will not be sent.
	 * @todo	We need to figure out how to permit headers to be cached.
	 *
	 * @param	string	$header		Header
	 * @param	bool	$replace	Whether to replace the old header value, if already set
	 * @return	CI_Output
	 */
	public function set_header( $header, $replace = TRUE )
	{
		// If zlib.output_compression is enabled it will compress the output,
		// but it will not modify the content-length header to compensate for
		// the reduction, causing the browser to hang waiting for more data.
		// We'll just skip content-length in those cases.
		if( $this->_zlib_oc && strncasecmp( $header, 'content-length', 14 ) === 0 )
		{
			return  $this;
		}

		$this->headers[] = array( $header, $replace );
		return  $this;
	}

	// --------------------------------------------------------------------

	/**
	 * Set Content-Type Header
	 *
	 * @param	string	$mime_type	Extension of the file we're outputting
	 * @param	string	$charset	Character set (default: NULL )
	 * @return	CI_Output
	 */
	public function set_content_type( $mime_type, $charset = NULL )
	{
		if( strpos( $mime_type, '/' ) === FALSE )
		{
			$extension = ltrim( $mime_type, ' . ' );

			// Is this extension supported?
			if( isset( $this->mimes[$extension] ) )
			{
				$mime_type =& $this->mimes[$extension];

				if( is_array( $mime_type ) )
				{
					$mime_type = current( $mime_type );
				}
			}
		}

		$this->mime_type = $mime_type;

		if( empty( $charset ) )
		{
			$charset = config_item( 'charset' );
		}

		$header = 'Content-Type: ' . $mime_type
			.(empty( $charset ) ? '' : '; charset=' . $charset );

		$this->headers[] = array( $header, TRUE );
		return  $this;
	}

	// --------------------------------------------------------------------

	/**
	 * Get Current Content-Type Header
	 *
	 * @return	string	'text/html', if not already set
	 */
	public function get_content_type( )
	{
		for( $i = 0, $c = count( $this->headers ); $i < $c; $i++ )
		{
			if( sscanf( $this->headers[$i][0], 'Content-Type: %[^;]', $content_type ) === 1 )
			{
				return  $content_type;
			}
		}

		return  'text/html';
	}

	// --------------------------------------------------------------------

	/**
	 * Get Header
	 *
	 * @param	string	$header_name
	 * @return	string
	 */
	public function get_header( $header )
	{
		// Combine headers already sent with our batched headers
		$headers = array_merge(
			// We only need [x][0] from our multi-dimensional array
			array_map( 'array_shift', $this->headers ),
			headers_list( )
		 );

		if( empty( $headers ) OR empty( $header ) )
		{
			return  NULL;
		}

		for( $i = 0, $c = count( $headers ); $i < $c; $i++ )
		{
			if( strncasecmp( $header, $headers[$i], $l = strlen( $header ) ) === 0 )
			{
				return  trim(substr( $headers[$i], $l+1 ) );
			}
		}

		return  NULL;
	}

	// --------------------------------------------------------------------

	/**
	 * Set HTTP Status Header
	 *
	 * As of version 1.7.2, this is an alias for common function
	 * set_status_header( ).
	 *
	 * @param	int	$code	Status code (default: 200 )
	 * @param	string	$text	Optional message
	 * @return	CI_Output
	 */
	public function set_status_header( $code = 200, $text = '' )
	{
		set_status_header( $code, $text );
		return  $this;
	}

	// --------------------------------------------------------------------

	/**
	 * Enable/disable Profiler
	 *
	 * @param	bool	$val	TRUE to enable or FALSE to disable
	 * @return	CI_Output
	 */
	public function enable_profiler( $val = TRUE )
	{
		$this->enable_profiler = is_bool( $val ) ? $val : TRUE;
		return  $this;
	}

	// --------------------------------------------------------------------

	/**
	 * Set Profiler Sections
	 *
	 * Allows override of default/config settings for
	 * Profiler section display.
	 *
	 * @param	array	$sections	Profiler sections
	 * @return	CI_Output
	 */
	public function set_profiler_sections( $sections )
	{
		if( isset( $sections[ 'query_toggle_count' ] ) )
		{
			$this->_profiler_sections[ 'query_toggle_count' ] = (int ) $sections[ 'query_toggle_count' ];
			unset( $sections[ 'query_toggle_count' ] );
		}

		foreach( $sections as $section => $enable )
		{
			$this->_profiler_sections[$section] = ( $enable !== FALSE );
		}

		return  $this;
	}

	// --------------------------------------------------------------------

	/**
	 * Set Cache
	 *
	 * @param	int	$time	Cache expiration time in seconds
	 * @return	CI_Output
	 */
	public function cache( $time )
	{
		$this->cache_expiration = is_numeric( $time ) ? $time : 0;
		return  $this;
	}

	// --------------------------------------------------------------------

	/**
	 * Display Output
	 *
	 * Processes and sends finalized output data to the browser along
	 * with any server headers and profile data. It also stops benchmark
	 * timers so the page rendering speed and memory usage can be shown.
	 *
	 * Note: All "view" data is automatically put into $this->final_output
	 *	 by controller class.
	 *
	 * @uses	CI_Output::$final_output
	 * @param	string	$output	Output data override
	 * @return	void
	 */
	public function _display( $output = '' )
	{
		// Note:  We use load_class( ) because we can't use $CI =& get_instance( )
		// since this function is sometimes called by the caching mechanism,
		// which happens before the CI super object is available.
		$BM =& load_class( 'Benchmark', 'core' );
		$CFG =& load_class( 'Config', 'core' );

		// Grab the super object if we can.
		if( class_exists( 'CI_Controller', FALSE ) )
		{
			$CI =& get_instance( );
		}

		// --------------------------------------------------------------------

		// Set the output data
		if( $output === '' )
		{
			$output =& $this->final_output;
		}

		// --------------------------------------------------------------------

		// Do we need to write a cache file? Only if the controller does not have its
		// own _output( ) method and we are not dealing with a cache file, which we
		// can determine by the existence of the $CI object above
		if( $this->cache_expiration > 0 && isset( $CI ) && ! method_exists( $CI, '_output' ) )
		{
			$this->_write_cache( $output );
		}

		// --------------------------------------------------------------------

		// Parse out the elapsed time and memory usage,
		// then swap the pseudo-variables with the data

		$elapsed = $BM->elapsed_time( 'total_execution_time_start', 'total_execution_time_end' );

		if( $this->parse_exec_vars === TRUE )
		{
			$memory	= round(memory_get_usage( ) / 1024 / 1024, 2 ) . 'MB';
			$output = str_replace(array( '{elapsed_time}', '{memory_usage}' ), array( $elapsed, $memory ), $output );
		}

		// --------------------------------------------------------------------

		// Is compression requested?
		if( isset( $CI ) // This means that we're not serving a cache file, if we were, it would already be compressed
			&& $this->_compress_output === TRUE
			&& isset( $_SERVER[ 'HTTP_ACCEPT_ENCODING' ] ) && strpos( $_SERVER[ 'HTTP_ACCEPT_ENCODING' ], 'gzip' ) !== FALSE )
		{
			ob_start( 'ob_gzhandler' );
		}

		// --------------------------------------------------------------------

		// Are there any server headers to send?
		if( count( $this->headers ) > 0 )
		{
			foreach( $this->headers as $header )
			{
				@header( $header[0], $header[1] );
			}
		}

		// --------------------------------------------------------------------

		// Does the $CI object exist?
		// If not we know we are dealing with a cache file so we'll
		// simply echo out the data and exit.
		if( ! isset( $CI ) )
		{
			if( $this->_compress_output === TRUE )
			{
				if( isset( $_SERVER[ 'HTTP_ACCEPT_ENCODING' ] ) && strpos( $_SERVER[ 'HTTP_ACCEPT_ENCODING' ], 'gzip' ) !== FALSE )
				{
					header( 'Content-Encoding: gzip' );
					header( 'Content-Length: '.strlen( $output ) );
				}
				else
				{
					// User agent doesn't support gzip compression,
					// so we'll have to decompress our cache
					$output = gzinflate(substr( $output, 10, -8 ) );
				}
			}

			echo $output;
			log_message( 'info', 'Final output sent to browser' );
			log_message( 'debug', 'Total execution time: ' . $elapsed );
			return;
		}

		// --------------------------------------------------------------------

		// Do we need to generate profile data?
		// If so, load the Profile class and run it.
		if( $this->enable_profiler === TRUE )
		{
			$CI->load->library( 'profiler' );
			if( ! empty( $this->_profiler_sections ) )
			{
				$CI->profiler->set_sections( $this->_profiler_sections );
			}

			// If the output data contains closing  and  tags
			// we will remove them and add them back after we insert the profile data
			$output = preg_replace( '|.*?|is', '', $output, -1, $count ).$CI->profiler->run( );
			if( $count > 0 )
			{
				$output .= '';
			}
		}

		// Does the controller contain a function named _output( )?
		// If so send the output there.  Otherwise, echo it.
		if( method_exists( $CI, '_output' ) )
		{
			$CI->_output( $output );
		}
		else
		{
			echo $output; // Send it to the browser!
		}

		log_message( 'info', 'Final output sent to browser' );
		log_message( 'debug', 'Total execution time: ' . $elapsed );
	}

	// --------------------------------------------------------------------

	/**
	 * Write Cache
	 *
	 * @param	string	$output	Output data to cache
	 * @return	void
	 */
	public function _write_cache( $output )
	{
		$CI =& get_instance( );
		$path = $CI->config->item( 'cache_path' );
		$cache_path = ( $path === '' ) ? APP_DIR_PATH . 'cache/' : $path;

		if( ! is_dir( $cache_path ) OR ! is_really_writable( $cache_path ) )
		{
			log_message( 'error', 'Unable to write cache file: ' . $cache_path );
			return;
		}

		$uri = $CI->config->item( 'base_url' )
			.$CI->config->item( 'index_page' )
			.$CI->uri->uri_string( );

		if( ( $cache_query_string = $CI->config->item( 'cache_query_string' ) ) && ! empty( $_SERVER[ 'QUERY_STRING' ] ) )
		{
			if( is_array( $cache_query_string ) )
			{
				$uri .= '?'.http_build_query(array_intersect_key( $_GET, array_flip( $cache_query_string ) ) );
			}
			else
			{
				$uri .= '?' . $_SERVER[ 'QUERY_STRING' ];
			}
		}

		$cache_path .= md5( $uri );

		if( ! $fp = @fopen( $cache_path, 'w+b' ) )
		{
			log_message( 'error', 'Unable to write cache file: ' . $cache_path );
			return;
		}

		if( flock( $fp, LOCK_EX ) )
		{
			// If output compression is enabled, compress the cache
			// itself, so that we don't have to do that each time
			// we're serving it
			if( $this->_compress_output === TRUE )
			{
				$output = gzencode( $output );

				if( $this->get_header( 'content-type' ) === NULL )
				{
					$this->set_content_type( $this->mime_type );
				}
			}

			$expire = time( ) + ( $this->cache_expiration * 60 );

			// Put together our serialized info.
			$cache_info = serialize(array(
				'expire'	=> $expire,
				'headers'	=> $this->headers
			 ) );

			$output = $cache_info . 'ENDCI--->' . $output;

			for( $written = 0, $length = strlen( $output ); $written < $length; $written += $result )
			{
				if( ( $result = fwrite( $fp, substr( $output, $written ) ) ) === FALSE )
				{
					break;
				}
			}

			flock( $fp, LOCK_UN );
		}
		else
		{
			log_message( 'error', 'Unable to secure a file lock for file at: ' . $cache_path );
			return;
		}

		fclose( $fp );

		if( is_int( $result ) )
		{
			chmod( $cache_path, 0640 );
			log_message( 'debug', 'Cache file written: ' . $cache_path );

			// Send HTTP cache-control headers to browser to match file cache settings.
			$this->set_cache_header( $_SERVER[ 'REQUEST_TIME' ], $expire );
		}
		else
		{
			@unlink( $cache_path );
			log_message( 'error', 'Unable to write the complete cache content at: ' . $cache_path );
		}
	}

	// --------------------------------------------------------------------

	/**
	 * Update/serve cached output
	 *
	 * @uses	CI_Config
	 * @uses	CI_URI
	 *
	 * @param	object	&$CFG	CI_Config class instance
	 * @param	object	&$URI	CI_URI class instance
	 * @return	bool	TRUE on success or FALSE on failure
	 */
	public function _display_cache(&$CFG, &$URI )
	{
		$cache_path = ( $CFG->item( 'cache_path' ) === '' ) ? APP_DIR_PATH . 'cache/' : $CFG->item( 'cache_path' );

		// Build the file path. The file name is an MD5 hash of the full URI
		$uri = $CFG->item( 'base_url' ).$CFG->item( 'index_page' ).$URI->uri_string;

		if( ( $cache_query_string = $CFG->item( 'cache_query_string' ) ) && ! empty( $_SERVER[ 'QUERY_STRING' ] ) )
		{
			if( is_array( $cache_query_string ) )
			{
				$uri .= '?'.http_build_query(array_intersect_key( $_GET, array_flip( $cache_query_string ) ) );
			}
			else
			{
				$uri .= '?' . $_SERVER[ 'QUERY_STRING' ];
			}
		}

		$filepath = $cache_path.md5( $uri );

		if( ! file_exists( $filepath ) OR ! $fp = @fopen( $filepath, 'rb' ) )
		{
			return  FALSE;
		}

		flock( $fp, LOCK_SH );

		$cache = (filesize( $filepath ) > 0 ) ? fread( $fp, filesize( $filepath ) ) : '';

		flock( $fp, LOCK_UN );
		fclose( $fp );

		// Look for embedded serialized file info.
		if( ! preg_match( '/^(.* )ENDCI--->/', $cache, $match ) )
		{
			return  FALSE;
		}

		$cache_info = unserialize( $match[1] );
		$expire = $cache_info[ 'expire' ];

		$last_modified = filemtime( $filepath );

		// Has the file expired?
		if( $_SERVER[ 'REQUEST_TIME' ] >= $expire && is_really_writable( $cache_path ) )
		{
			// If so we'll delete it.
			@unlink( $filepath );
			log_message( 'debug', 'Cache file has expired. File deleted . ' );
			return  FALSE;
		}
		else
		{
			// Or else send the HTTP cache control headers.
			$this->set_cache_header( $last_modified, $expire );
		}

		// Add headers from cache file.
		foreach( $cache_info[ 'headers' ] as $header )
		{
			$this->set_header( $header[0], $header[1] );
		}

		// Display the cache
		$this->_display(substr( $cache, strlen( $match[0] ) ) );
		log_message( 'debug', 'Cache file is current. Sending it to browser . ' );
		return  TRUE;
	}

	// --------------------------------------------------------------------

	/**
	 * Delete cache
	 *
	 * @param	string	$uri	URI string
	 * @return	bool
	 */
	public function delete_cache( $uri = '' )
	{
		$CI =& get_instance( );
		$cache_path = $CI->config->item( 'cache_path' );
		if( $cache_path === '' )
		{
			$cache_path = APP_DIR_PATH . 'cache/';
		}

		if( ! is_dir( $cache_path ) )
		{
			log_message( 'error', 'Unable to find cache path: ' . $cache_path );
			return  FALSE;
		}

		if( empty( $uri ) )
		{
			$uri = $CI->uri->uri_string( );

			if( ( $cache_query_string = $CI->config->item( 'cache_query_string' ) ) && ! empty( $_SERVER[ 'QUERY_STRING' ] ) )
			{
				if( is_array( $cache_query_string ) )
				{
					$uri .= '?'.http_build_query(array_intersect_key( $_GET, array_flip( $cache_query_string ) ) );
				}
				else
				{
					$uri .= '?' . $_SERVER[ 'QUERY_STRING' ];
				}
			}
		}

		$cache_path .= md5( $CI->config->item( 'base_url' ).$CI->config->item( 'index_page' ).ltrim( $uri, '/' ) );

		if( ! @unlink( $cache_path ) )
		{
			log_message( 'error', 'Unable to delete cache file for ' . $uri );
			return  FALSE;
		}

		return  TRUE;
	}

	// --------------------------------------------------------------------

	/**
	 * Set Cache Header
	 *
	 * Set the HTTP headers to match the server-side file cache settings
	 * in order to reduce bandwidth.
	 *
	 * @param	int	$last_modified	Timestamp of when the page was last modified
	 * @param	int	$expiration	Timestamp of when should the requested page expire from cache
	 * @return	void
	 */
	public function set_cache_header( $last_modified, $expiration )
	{
		$max_age = $expiration - $_SERVER[ 'REQUEST_TIME' ];

		if( isset( $_SERVER[ 'HTTP_IF_MODIFIED_SINCE' ] ) && $last_modified <= strtotime( $_SERVER[ 'HTTP_IF_MODIFIED_SINCE' ] ) )
		{
			$this->set_status_header(304 );
			exit;
		}
		else
		{
			header( 'Pragma: public' );
			header( 'Cache-Control: max-age=' . $max_age . ', public' );
			header( 'Expires: '.gmdate( 'D, d M Y H:i:s', $expiration ) . ' GMT' );
			header( 'Last-modified: '.gmdate( 'D, d M Y H:i:s', $last_modified ) . ' GMT' );
		}
	}

}


text:
'use strict';

var rd = require('../controllers/rd.js');

module.exports = function(Frontend, app, auth, enhance) {
	app.route(enhance.mount('/research-and-development')).get(rd.render);
};


text:
<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="cl.monsoon.s1next.view.activity.ForumActivity">

    <data>

        <variable
            name="dropDownItemListViewModel"
            type="cl.monsoon.s1next.viewmodel.DropDownItemListViewModel" />
    </data>

    <LinearLayout
        android:id="@+id/spinner_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="?attr/selectableItemBackground"
        android:gravity="center_vertical"
        android:theme="?attr/toolbarTheme">

        <Spinner
            android:id="@+id/spinner"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:dropDownItemList="@{dropDownItemListViewModel.dropDownItemList}"
            app:selectedItemPosition="@{dropDownItemListViewModel.selectedItemPosition}" />

    </LinearLayout>

</layout>


text:
package org.craft.client.models;

import java.util.*;

import com.google.common.collect.*;

import org.craft.blocks.states.*;
import org.craft.client.render.*;

public class BlockVariant
{

    private List<BlockState>       states;
    private List<IBlockStateValue> values;
    private List<Model>       models;
    private EnumRenderPass              pass;

    public BlockVariant()
    {
        pass = EnumRenderPass.NORMAL;
        models = Lists.newArrayList();
        states = Lists.newArrayList();
        values = Lists.newArrayList();
    }

    /**
     * Sets block state of this variant
     */
    public void setBlockStateKeys(List<BlockState> states)
    {
        this.states = states;
    }

    /**
     * Sets block state value of this variant
     */
    public void setBlockStateValues(List<IBlockStateValue> values)
    {
        this.values = values;
    }

    /**
     * Gets block state of this variant
     */
    public List<BlockState> getBlockStates()
    {
        return states;
    }

    /**
     * Gets block state value of this variant
     */
    public List<IBlockStateValue> getBlockStateValues()
    {
        return values;
    }

    /**
     * Add model to this block variant
     */
    public void addBlockModel(Model model)
    {
        this.models.add(model);
    }

    /**
     * Returns a mutable list of models used in this variant
     */
    public List<Model> getModels()
    {
        return models;
    }

    /**
     * Sets pass in which the variant is rendered.<br/>Throws a {@link NullPointerException} if given pass is null
     */
    public void setPass(EnumRenderPass pass)
    {
        if(pass == null)
            throw new NullPointerException("Render Pass can't be null");
        this.pass = pass;
    }

    /**
     * Gets pass in which the variant is rendered
     */
    public EnumRenderPass getPass()
    {
        return pass;
    }
}


text:
// importing this solves issues with __awaiter not defined using await in Android HeadlessTask
import 'nativescript-tslib';

import {BackgroundGeolocation} from "./background-geolocation";

import "./HeadlessJobService";
import "./HeadlessBroadcastReceiver";

import app = require('application');

declare var com: any;

let TSConfig = com.transistorsoft.locationmanager.adapter.TSConfig;
let TSCallback = com.transistorsoft.locationmanager.adapter.callback.TSCallback;
let TSLocationCallback = com.transistorsoft.locationmanager.adapter.callback.TSLocationCallback;
let TSLocation = com.transistorsoft.locationmanager.location.TSLocation;
let TSPlayServicesConnectErrorCallback = com.transistorsoft.locationmanager.adapter.callback.TSPlayServicesConnectErrorCallback;
let TSSyncCallback = com.transistorsoft.locationmanager.adapter.callback.TSSyncCallback;
let TSGetLocationsCallback = com.transistorsoft.locationmanager.adapter.callback.TSGetLocationsCallback;
let TSGetCountCallback = com.transistorsoft.locationmanager.adapter.callback.TSGetCountCallback;
let TSInsertLocationCallback = com.transistorsoft.locationmanager.adapter.callback.TSInsertLocationCallback;
let TSGetGeofencesCallback = com.transistorsoft.locationmanager.adapter.callback.TSGetGeofencesCallback;
let TSGetLogCallback = com.transistorsoft.locationmanager.adapter.callback.TSGetLogCallback;
let TSEmailLogCallback = com.transistorsoft.locationmanager.adapter.callback.TSEmailLogCallback;
let TSActivityChangeCallback = com.transistorsoft.locationmanager.adapter.callback.TSActivityChangeCallback;
let TSHttpResponseCallback = com.transistorsoft.locationmanager.adapter.callback.TSHttpResponseCallback;
let TSGeofenceCallback = com.transistorsoft.locationmanager.adapter.callback.TSGeofenceCallback;
let TSGeofencesChangeCallback = com.transistorsoft.locationmanager.adapter.callback.TSGeofencesChangeCallback;
let TSHeartbeatCallback = com.transistorsoft.locationmanager.adapter.callback.TSHeartbeatCallback;
let TSLocationProviderChangeCallback = com.transistorsoft.locationmanager.adapter.callback.TSLocationProviderChangeCallback;
let TSScheduleCallback = com.transistorsoft.locationmanager.adapter.callback.TSScheduleCallback;
let TSPowerSaveChangeCallback = com.transistorsoft.locationmanager.adapter.callback.TSPowerSaveChangeCallback;
let TSEnabledChangeCallback = com.transistorsoft.locationmanager.adapter.callback.TSEnabledChangeCallback;
let TSConnectivityChangeCallback = com.transistorsoft.locationmanager.adapter.callback.TSConnectivityChangeCallback;
let TSCurrentPositionRequest = com.transistorsoft.locationmanager.location.TSCurrentPositionRequest;
let TSWatchPositionRequest = com.transistorsoft.locationmanager.location.TSWatchPositionRequest;
let TSSensors = com.transistorsoft.locationmanager.util.Sensors;
let TSGeofence = com.transistorsoft.locationmanager.geofence.TSGeofence;
let TSLog = com.transistorsoft.locationmanager.logger.TSLog;

let TAG = "TSLocationnManager";
let REQUEST_ACTION_START = 1;
let REQUEST_ACTION_GET_CURRENT_POSITION = 2;
let REQUEST_ACTION_START_GEOFENCES = 3;
let emptyFn = function() {};

let HEADLESS_JOB_SERVICE = "com.transistorsoft.backgroundgeolocation.HeadlessJobService";

// Inform adapter.BackgroundGeolocation when Activity is destroyed.
app.android.on(app.AndroidApplication.activityDestroyedEvent, function(args) {
  console.log('[BackgroundGeolocation] onActivityDestroyedEvent -', args.activity);
  if (!app.android.startActivity) {
    Api.onActivityDestroyed(args);
  }
});

class Api {
	private static forceReload: boolean;
  private static intent:android.content.Intent = null;

  public static onActivityDestroyed(args) {
    com.transistorsoft.locationmanager.adapter.BackgroundGeolocation.getInstance(app.android.context.getApplicationContext()).onActivityDestroy();
    this.intent = null;
  }

  public static addListener(event:any, success:Function, failure?:Function) {
    failure = failure || emptyFn;
    var cb;
    switch (event) {
      case 'location':
        cb = this.createLocationCallback(success, failure);
        this.getAdapter().onLocation(cb);
        break;
      case 'motionchange':
        cb = this.createMotionChangeCallback(success);
        this.getAdapter().onMotionChange(cb);
        break;
      case 'activitychange':
        cb = this.createActivityChangeCallback(success);
        this.getAdapter().onActivityChange(cb);
        break;
      case 'http':
        cb = this.createHttpCallback(success, failure);
        this.getAdapter().onHttp(cb);
        break;
      case 'geofence':
        cb = this.createGeofenceCallback(success);
        this.getAdapter().onGeofence(cb);
        break;
      case 'geofenceschange':
        cb = this.createGeofencesChangeCallback(success);
        this.getAdapter().onGeofencesChange(cb);
        break;
      case 'schedule':
        cb = this.createScheduleCallback(success);
        this.getAdapter().onSchedule(cb);
        break;
      case 'heartbeat':
        cb = this.createHeartbeatCallback(success);
        this.getAdapter().onHeartbeat(cb);
        break;
      case 'providerchange':
        cb = this.createProviderChangeCallback(success);
        this.getAdapter().onLocationProviderChange(cb);
        break;
      case 'powersavechange':
        cb = this.createPowerSaveChangeCallback(success);
        this.getAdapter().onPowerSaveChange(cb);
        break;
      case 'enabledchange':
        cb = this.createEnabledChangeCallback(success);
        this.getAdapter().onEnabledChange(cb);
        break;
      case 'connectivitychange':
        cb = this.createConnectivityChangeCallback(success);
        this.getAdapter().onConnectivityChange(cb);
        break;
    }
    return cb;
  }

  protected static removeListener(event:string, callback:Function) {
    return new Promise((resolve, reject) => {
      this.getAdapter().removeListener(event, callback);
      resolve();
    });
  }

  public static removeListeners(event?:string) {
    return new Promise((resolve, reject) => {
      if (event) {
        this.getAdapter().removeListeners(event);
      } else {
        this.getAdapter().removeListeners();
      }
      resolve();
    });
  }

  /**
  * Configuration Methods
  */
  public static ready(params:any) {
    return new Promise((resolve, reject) => {
      let config = TSConfig.getInstance(this.getContext());
      if (config.isFirstBoot()) {
        config.updateWithJSONObject(new org.json.JSONObject(JSON.stringify(this.applyHeadlessJobService(params))));
      } else if (params.reset === true) {
        config.reset();
        config.updateWithJSONObject(new org.json.JSONObject(JSON.stringify(this.applyHeadlessJobService(params))));
      }
      this.getAdapter().ready(new TSCallback({
        onSuccess: () => {
          resolve(JSON.parse(config.toJson().toString()))
        },
        onFailure: (error:string) => {
          reject(error)
        }
      }));
    });
  }

  public static configure(params:any) {
    return new Promise((resolve, reject) => {
      let config = TSConfig.getInstance(this.getContext());
      config.updateWithJSONObject(new org.json.JSONObject(JSON.stringify(this.applyHeadlessJobService(params))));

      this.getAdapter().ready(new TSCallback({
        onSuccess: () => {
          resolve(JSON.parse(config.toJson().toString()));
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static setConfig(params:any) {
    return new Promise((resolve, reject) => {
      let config = TSConfig.getInstance(this.getContext());
      config.updateWithJSONObject(new org.json.JSONObject(JSON.stringify(this.applyHeadlessJobService(params))));
      resolve(JSON.parse(config.toJson().toString()));
    });
  }

  public static reset(params:any) {
    return new Promise((resolve, reject) => {
      let config = TSConfig.getInstance(this.getContext());
      config.reset();
      config.updateWithJSONObject(new org.json.JSONObject(JSON.stringify(this.applyHeadlessJobService(params))));
      resolve(JSON.parse(config.toJson().toString()));
    });
  }

  public static getState() {
    return new Promise((resolve, reject) => {
      let config = TSConfig.getInstance(this.getContext());
      resolve(JSON.parse(config.toJson().toString()));
    });
  }

  /**
  * Tracking Methods
  */
	public static start() {
    return new Promise((resolve, reject) => {
      var adapter = this.getAdapter();
      let config = TSConfig.getInstance(this.getContext());
      adapter.start(new TSCallback({
        onSuccess: () => {
          resolve(JSON.parse(config.toJson().toString()));
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
	}

  public static stop() {
    return new Promise((resolve, reject) => {
      let adapter = this.getAdapter();
      let config = TSConfig.getInstance(this.getContext());
      adapter.stop(new TSCallback({
        onSuccess: function() {
          resolve(JSON.parse(config.toJson().toString()));
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static changePace(value: boolean) {
    return new Promise((resolve, reject) => {
      let adapter = this.getAdapter();
      adapter.changePace(value, new TSCallback({
        onSuccess: () => {
          resolve();
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static startSchedule() {
    return new Promise((resolve, reject) => {
      let config = TSConfig.getInstance(this.getContext());
      if (this.getAdapter().startSchedule()) {
        resolve(JSON.parse(config.toJson().toString()));
      } else {
        reject("Failed to start schedule.  Did you configure a #schedule?");
      }
    });
  }

  public static stopSchedule() {
    return new Promise((resolve, reject) => {
      let config = TSConfig.getInstance(this.getContext());
      this.getAdapter().stopSchedule();
      resolve(JSON.parse(config.toJson().toString()));
    });
  }

  public static startGeofences() {
    return new Promise((resolve, reject) => {
      let config = TSConfig.getInstance(this.getContext());
      this.getAdapter().startGeofences(new TSCallback({
        onSuccess: () => {
          resolve(JSON.parse(config.toJson().toString()));
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static getCurrentPosition(options?:any) {
    return new Promise((resolve, reject) => {
      let builder = new TSCurrentPositionRequest.Builder(this.getContext());

      if (typeof(options.samples) === 'number') {
        builder.setSamples(options.samples);
      }
      if (typeof(options.extras) === 'object') {
        builder.setExtras(new org.json.JSONObject(JSON.stringify(options.extras)));
      }
      if (typeof(options.persist) === 'boolean') {
        builder.setPersist(options.persist);
      }
      if (typeof(options.timeout) === 'number') {
        builder.setTimeout(options.timeout);
      }
      if (typeof(options.maximumAge) === 'number') {
        builder.setMaximumAge(new java.lang.Long(options.maximumAge));
      }
      if (typeof(options.desiredAccuracy) === 'number') {
        builder.setDesiredAccuracy(options.desiredAccuracy);
      }

      builder.setCallback(new TSLocationCallback({
        onLocation: (tsLocation:any) => {
          resolve(JSON.parse(tsLocation.toJson().toString()));
        },
        onError: (error:any) => {
          reject(error);
        }
      }));
      this.getAdapter().getCurrentPosition(builder.build());
    });
  }

  public static watchPosition(success:Function, failure:Function, options:any) {
    let builder = new TSWatchPositionRequest.Builder(this.getContext());
    if (typeof(options.interval) === 'number') {
      builder.setInterval(new java.lang.Long(options.interval));
    }
    if (typeof(options.extras) === 'object') {
      builder.setExtras(new org.json.JSONObject(JSON.stringify(options.extras)));
    }
    if (typeof(options.persist) === 'boolean') {
      builder.setPersist(options.persist);
    }
    if (typeof(options.desiredAccuracy) === 'number') {
      builder.setDesiredAccuracy(options.desiredAccuracy);
    }

    builder.setCallback(new TSLocationCallback({
      onLocation: (tsLocation:any) => {
        success(JSON.parse(tsLocation.toJson().toString()));
      },
      onError: (error:number) => {
        failure(error);
      }
    }));
    this.getAdapter().watchPosition(builder.build());
  }

  public static stopWatchPosition() {
    return new Promise((resolve, reject) => {
      this.getAdapter().stopWatchPosition(new TSCallback({
        onSuccess: () => {
          resolve();
        },
        onFailure: (error: string) => {
          reject(error);
        }
      }));
    });
  }

  public static getOdometer() {
    return new Promise((resolve, reject) => {
      resolve(this.getAdapter().getOdometer());
    });
  }

  public static setOdometer(value:number) {
    return new Promise((resolve, reject) => {
      this.getAdapter().setOdometer(new java.lang.Float(value), new TSLocationCallback({
        onLocation: (tsLocation:any) => {
          resolve(JSON.parse(tsLocation.toJson().toString()));
        },
        onError: function(error:number) {
          reject(error);
        }
      }));
    });
  }
  public static resetOdometer(value:number) {
    return this.setOdometer(0);
  }

  /**
  * HTTP & Persistence Methods
  */
  public static sync() {
    return new Promise((resolve, reject) => {
      this.getAdapter().sync(new TSSyncCallback({
        onSuccess: function(records:any) {
          let size = records.size();
          let result = [];
          for (let i=0;i<size;i++) {
            let record = records.get(i);
            result.push(JSON.parse(record.json.toString()));
          }
          resolve(result);
        },
        onFailure: function(error:string) {
          reject(error);
        }
      }));
    });
  }

  public static getLocations() {
    return new Promise((resolve, reject) => {
      this.getAdapter().getLocations(new TSGetLocationsCallback({
        onSuccess: (records:any) => {
          let size = records.size();
          let result = [];
          for (let i=0;i<size;i++) {
            let record = records.get(i);
            result.push(JSON.parse(record.json.toString()));
          }
          resolve(result);
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static getCount() {
    return new Promise((resolve, reject) => {
      this.getAdapter().getCount(new TSGetCountCallback({
        onSuccess: (count:number) => {
          resolve(count);
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static insertLocation(data:any) {
    return new Promise((resolve, reject) => {
      let callback = new TSInsertLocationCallback({
        onSuccess: (uuid:string) => {
          resolve(uuid);
        },
        onFailure: (error: string) => {
          reject(error);
        }
      });
      this.getAdapter().insertLocation(new org.json.JSONObject(JSON.stringify(data)), callback);
    });
  }

  // @deprecated
  public static clearDatabase() {
    return this.destroyLocations();
  }

  public static destroyLocations() {
    return new Promise((resolve, reject) => {
      this.getAdapter().destroyLocations(new TSCallback({
        onSuccess: () => {
          resolve();
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  /**
  * Geofencing Methods
  */
  public static addGeofence(params:any) {
    return new Promise((resolve, reject) => {
      try {
        this.getAdapter().addGeofence(this.buildGeofence(params), new TSCallback({
          onSuccess: () => {
            resolve();
          },
          onFailure: (error:string) => {
            reject(error);
          }
        }));
      } catch (error) {
        reject(error.getMessage());
      }
    });
  }

  public static removeGeofence(identifier:string) {
    return new Promise((resolve, reject) => {
      this.getAdapter().removeGeofence(identifier, new TSCallback({
        onSuccess: () => {
          resolve();
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static addGeofences(geofences:Array<any>) {
    return new Promise((resolve, reject) => {
      let list = new java.util.ArrayList();
      for (var n=0,len=geofences.length;n<len;n++) {
        try {
          list.add(this.buildGeofence(geofences[n]));
        } catch (error) {
          reject(error.getMessage());
          return;
        }
      }
      this.getAdapter().addGeofences(list, new TSCallback({
        onSuccess: () => {
          resolve();
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  private static buildGeofence(params:any) {
      let builder = new TSGeofence.Builder();
      builder.setIdentifier(params.identifier);
      builder.setLatitude(params.latitude);
      builder.setLongitude(params.longitude);
      builder.setRadius(params.radius);
      if (typeof(params.notifyOnEntry) === 'boolean') { builder.setNotifyOnEntry(params.notifyOnEntry); }
      if (typeof(params.notifyOnExit) === 'boolean') { builder.setNotifyOnExit(params.notifyOnExit); }
      if (typeof(params.notifyOnDwell) === 'boolean') { builder.setNotifyOnDwell(params.notifyOnDwell); }
      if (typeof(params.loiteringDelay) === 'number') { builder.setLoiteringDelay(params.loiteringDelay); }
      if (typeof(params.extras) === 'object') { builder.setExtras(new org.json.JSONObject(JSON.stringify(params.extras))); }

      return builder.build();
  }

  public static removeGeofences(geofences?:Array<string>) {
    return new Promise((resolve, reject) => {
      // Handle case where no geofences are provided (ie: remove all geofences).
      geofences = geofences || [];

      let identifiers = new java.util.ArrayList();
      geofences.forEach((identifier) => { identifiers.add(identifier); });
      this.getAdapter().removeGeofences(identifiers, new TSCallback({
        onSuccess: () => {
          resolve();
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static getGeofences() {
    return new Promise((resolve, reject) => {
      this.getAdapter().getGeofences(new TSGetGeofencesCallback({
        onSuccess: (records:any) => {
          let size = records.size();
          let result = [];
          for (let i=0;i<size;i++) {
            let geofence = records.get(i);
            result.push(JSON.parse(geofence.toJson()));
          }
          resolve(result);
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  /**
  * Logging & Debug methods
  */
  public static getLog() {
    return new Promise((resolve, reject) => {
      this.getAdapter().getLog(new TSGetLogCallback({
        onSuccess: (log:string) => {
          resolve(log)
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static emailLog(email:string) {
    return new Promise((resolve, reject) => {
      this.getAdapter().emailLog(email, app.android.foregroundActivity, new TSEmailLogCallback({
        onSuccess: () => {
          resolve()
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static destroyLog() {
    return new Promise((resolve, reject) => {
      this.getAdapter().destroyLog(new TSCallback({
        onSuccess: () => {
          resolve();
        },
        onFailure: (error:string) => {
          reject(error);
        }
      }));
    });
  }

  public static getSensors() {
    return new Promise((resolve, reject) => {
      let sensors = TSSensors.getInstance(app.android.context);
      let result = {
        "platform": "android",
        "accelerometer": sensors.hasAccelerometer(),
        "magnetometer": sensors.hasMagnetometer(),
        "gyroscope": sensors.hasGyroscope(),
        "significant_motion": sensors.hasSignificantMotion()
      };
      resolve(result);
    });
  }

  public static isPowerSaveMode(success: Function, failure?:Function) {
    return new Promise((resolve, reject) => {
      let isPowerSaveMode = this.getAdapter().isPowerSaveMode();
      resolve(isPowerSaveMode);
    });
  }

  public static startBackgroundTask(success:Function) {
    // Just return 0 for compatibility with iOS API.  Android has no concept of these iOS-only background-tasks.
    return new Promise((resolve, reject) => {
      resolve(0);
    });
  }

  public static finish(taskId:number) {
    // Just an empty function for compatibility with iOS.  Android has no concept of these iOS-only background-tasks.
  }

  public static playSound(soundId) {
    return new Promise((resolve, reject) => {
      this.getAdapter().startTone(soundId);
      resolve();
    });
  }

  public static log(level, msg) {
    TSLog.log(level, msg);
  }

  private static createLocationCallback(success:Function, failure?:Function) {
    failure = failure || emptyFn;
    return new TSLocationCallback({
      onLocation: (tsLocation:any) => {
        success(JSON.parse(tsLocation.toJson().toString()));
      },
      onError: (error) => {
        failure(error);
      }
    });
  }

  private static createMotionChangeCallback(callback:Function) {
    return new TSLocationCallback({
      onLocation: (tsLocation:any) => {
        let isMoving = tsLocation.getIsMoving();
        callback(isMoving, JSON.parse(tsLocation.toJson().toString()));
      },
      onError: (error:number) => {

      }
    });
  }

  private static createHttpCallback(success:Function, failure?:Function) {
    return new TSHttpResponseCallback({
      onHttpResponse: function(response:any) {
        let params = {
          success: response.isSuccess().booleanValue(),
          status: response.status,
          responseText: response.responseText
        };
        if (response.isSuccess().booleanValue()) {
          success(params);
        } else {
          failure(params);
        }
      }
    });
  }

  private static createActivityChangeCallback(callback:Function) {
    return new TSActivityChangeCallback({
      onActivityChange: (event:any) => {
        callback(JSON.parse(event.toJson().toString()));
      }
    });
  }

  private static createGeofenceCallback(callback:Function) {
    return new TSGeofenceCallback({
      onGeofence: (event:any) => {
        callback(JSON.parse(event.toJson().toString()));
      }
    });
  }

  private static createGeofencesChangeCallback(callback:Function) {
    return new TSGeofencesChangeCallback({
      onGeofencesChange: (event:any) => {
        callback(JSON.parse(event.toJson().toString()));
      }
    });
  }

  private static createScheduleCallback(callback:Function) {
    return new TSScheduleCallback({
      onSchedule: (event:any) => {
        callback(JSON.parse(event.toJson().toString()));
      }
    })
  }

  private static createProviderChangeCallback(callback:Function) {
    return new TSLocationProviderChangeCallback({
      onLocationProviderChange: (event:any) => {
        callback(JSON.parse(event.toJson().toString()));
      }
    })
  }

  private static createHeartbeatCallback(callback:Function) {
    return new TSHeartbeatCallback({
      onHeartbeat: (event:any) => {
        callback(JSON.parse(event.toJson().toString()));
      }
    })
  }

  private static createPowerSaveChangeCallback(callback:Function) {
    return new TSPowerSaveChangeCallback({
      onPowerSaveChange: (isPowerSaveMode) => {
        callback(isPowerSaveMode);
      }
    });
  }

  private static createEnabledChangeCallback(callback:Function) {
    return new TSEnabledChangeCallback({
      onEnabledChange: (enabled:boolean) => {
        console.log('- enabledchange: ', enabled);
        callback({enabled: enabled});
      }
    });
  }

  private static createConnectivityChangeCallback(callback:Function) {
    return new TSConnectivityChangeCallback({
      onConnectivityChange: (event:any) => {
        callback({connected: event.hasConnection()});
      }
    });
  }

  private static applyHeadlessJobService(params):any {
    params.headlessJobService = HEADLESS_JOB_SERVICE;
    return params;
  }

  private static init() {
    if (!app.android.startActivity || (this.intent !== null)) {
      return;
    }
    this.intent = app.android.startActivity.getIntent();

    // Handle Google Play Services errors
    this.getAdapter().onPlayServicesConnectError(new TSPlayServicesConnectErrorCallback({
      onPlayServicesConnectError: (errorCode:number) => {
        this.handleGooglePlayServicesConnectError(errorCode);
      }
    }));
    let config = TSConfig.getInstance(this.getContext());
    config.useCLLocationAccuracy(new java.lang.Boolean(true));
  }

  private static getContext() {
    return app.android.context;
  }

  private static getIntent() {
    let activity = (app.android.startActivity) ? app.android.startActivity : app.android.foregroundActivity;
    return (activity) ? activity.getIntent() : this.intent;
  }

  protected static getAdapter(): any {
    if (!this.intent) {
      this.init();
    }
    return com.transistorsoft.locationmanager.adapter.BackgroundGeolocation.getInstance(app.android.context.getApplicationContext(), this.getIntent());
  }

  private static handleGooglePlayServicesConnectError(errorCode:number) {
    com.google.android.gms.common.GoogleApiAvailability.getInstance().getErrorDialog(app.android.foregroundActivity, errorCode, 1001).show();
  }

}

BackgroundGeolocation.mountNativeApi(Api);

export {BackgroundGeolocation};


text:
#include "nn_allocate.h"
#include <cstdlib>
#include <cassert>

const size_t BUFFER_ALIGNMENT = 4096;

size_t nn_align(size_t a, size_t b)
{
    return (a % b != 0) ?  ((a - a % b) + b) : a;
}

size_t nn_aligned_size(size_t size)
{
    return nn_align(size, BUFFER_ALIGNMENT);
}

void* nn_allocate_aligned(size_t size)
{
    auto size_of_aligned = nn_align(size, BUFFER_ALIGNMENT);
    void* ret = nullptr;
#if defined(__linux__) || defined(__CYGWIN__)
    ret = aligned_alloc(BUFFER_ALIGNMENT, size_of_aligned);
#else
    ret = _aligned_malloc(size_of_aligned, BUFFER_ALIGNMENT);
#endif // defined(__linux__) || defined(__CYGWIN__)
    assert(reinterpret_cast<size_t>(ret) % BUFFER_ALIGNMENT == 0);
    return ret;
}

void nn_free_aligned(void*& ptr)
{
    if (ptr == nullptr) return;
#if defined(__linux__) || defined(__CYGWIN__)
    free(ptr);
#else
    _aligned_free(ptr);
#endif //__linux__
    ptr = nullptr;
}

void nn_delete_aligned(void* ptr)
{
    nn_free_aligned(ptr);
}


text:
package control.learning;

import control.Invoke;

public class LearningInvoke extends Invoke {
	private static final LearningInvoke instance = new LearningInvoke();

	private LearningInvoke(){}

	public static LearningInvoke getInstance() {
		return instance;
	}
}


text:
titile: OSG HelloWorld QT Example
categories:
          - Tutorials
tags:
          - Examples
header:
  overlay_color: "#5e616c"
  overlay_image: /assets/images/w-home-page.jpg
excerpt: This is an instruction of saying _Hello World!_ in OSG style. This project will build by using QtCreator.
mathjax: true
---

{% include toc %}

# Precondition

> * OSG library has been built in x32 or x64
* OSG Example data has been downloaded.
* assuming OSGPATH is setting as D:\OSG
    * _include_ - D:\OSG\include
    * _lib_     - D:\OSG\lib
    * _bin_     - D:\OSG\bin
    * _data_    - D:\OSG\data
* System environment has been set corroctly
    * _PATH_          - add D:\OSG\bin to _PATH_
    * _OSG_FILE_PATH_ - create this key with value _D:\OSG\data_
* Qt Kit installed
    * MSVC2015 32bit or 64bit should be same with OSG library build

# Overview
Normally you can find many instructions to say "Hello World" in OSG style.
It should look like following steps:
> 1. Create a empty Qt Console Application.
2. Add OSG lib to project properties
3. Add codes to show a 3D model
4. Compile and run application.

# Create Project
> Create an empty **_Qt Console Application_** project.

### Create new project

> **_File_** -> **_New File or Project..._**
> select -> **_Application_** -> **_Qt Console Application_** -> **_Choose..._**
> _Build system_ -> **_qmake_** -> Next
> _Kit Selection_ -> **_MSVC2015 64bit_** -> **_Finish_**

![create new project][create new project]

![application settings][application settings]

### Configure Project Properties

> right click project -> **Add libraries...**
> Type -> select **_External library_**  -> Next
> Details select **_D:\OSG\lib\osg.lib_** -> Next
> Summary -> **_Finish_**
> Follow the same process to add
**_osgViewer.lib
osgDB.lib
OpenThreads.lib_**
> Build -> **_Run qmake_**

**Important**
It's a very important procedure never forget it, is to run **_qmake_** again after adding library, or it will not be imported to the project.
{: .notice--info}

![project properties][project properties1]{: .align-center}

![project properties][project properties2]{: .align-center}

![project properties][project properties3]{: .align-center}

**Notice**
pay more attention to using same x64 or x32 **_Platform_** configuration!
{: .notice--danger}

# Add Codes

> Normally codes will be like this:

{% highlight C++ %}

#include <osgViewer/Viewer>
#include <osgdb/readfile>

int main(){

    osg::ref_ptr <osgViewer::Viewer> viewer = new osgViewer::Viewer;

    // set background color to dark
    viewer->getCamera()->setClearColor(osg::Vec4(0.2f, 0.2f,0.2f, 0.0f));

    // load osg model data which has been set under "OSG_FILE_PATH"
    viewer->setSceneData(osgDB::readNodeFile("glider.osg"));

    // set window start position and size
    viewer->setUpViewInWindow(400,200,800,600);
    viewer->realize();

    // run viewer
    int ret = viewer->run();
    return ret;
}
{% endhighlight %}

> Alternatively, if we want to keep the same source code also can be built on Visual Studio, can add following code

{% highlight C++ %}

#ifdef _DEBUG
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "OpenThreadsd.lib")
#pragma comment(lib, "osgd.lib")
#else
#pragma comment(lib, "osgViewer.lib")
#pragma comment(lib, "osgDB.lib")
#pragma comment(lib, "OpenThreads.lib")
#pragma comment(lib, "osg.lib")
#endif

#if defined(_WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(_WIN64)
#include <windows.h>
#endif

#include <osgViewer/Viewer>
#include <osgdb/readfile>

int main(){

    osg::ref_ptr <osgViewer::Viewer> viewer = new osgViewer::Viewer;

    // set background color to dark
    viewer->getCamera()->setClearColor(osg::Vec4(0.2f, 0.2f,0.2f, 0.0f));

    // load osg model data which has been set under "OSG_FILE_PATH"
    viewer->setSceneData(osgDB::readNodeFile("glider.osg"));

    // set window start position and size
    viewer->setUpViewInWindow(400,200,800,600);
    viewer->realize();

    // run viewer
    int ret = viewer->run();
    return ret;
}

{% endhighlight %}

# Compile and Run

> A 3D model should be displayed on the screen correctly.

![HelloOsg run][HelloOsg run]

[create new project]: {{site.url}}{{site.baseurl}}/assets/images/posts/HelloOsg/HelloOsgQt01.png
[application settings]: {{site.url}}{{site.baseurl}}/assets/images/posts/HelloOsg/HelloOsgQt02.png
[project properties1]: {{site.url}}{{site.baseurl}}/assets/images/posts/HelloOsg/HelloOsgQt03.png
[project properties2]: {{site.url}}{{site.baseurl}}/assets/images/posts/HelloOsg/HelloOsgQt04.png
[project properties3]: {{site.url}}{{site.baseurl}}/assets/images/posts/HelloOsg/HelloOsgQt05.png
[HelloOsg run]: {{site.url}}{{site.baseurl}}/assets/images/posts/HelloOsg/HelloOsgQt06.png


text:
// flow-typed signature: 852121438a0a63001187482028845920
// flow-typed version: <<STUB>>/connect-history-api-fallback_v1.3.0/flow_v0.45.0

/**
 * This is an autogenerated libdef stub for:
 *
 *   'connect-history-api-fallback'
 *
 * Fill this stub out by replacing all the `any` types.
 *
 * Once filled out, we encourage you to share your work with the
 * community by sending a pull request to:
 * https://github.com/flowtype/flow-typed
 */

declare module 'connect-history-api-fallback' {
  declare module.exports: any;
}

/**
 * We include stubs for each file inside this npm package in case you need to
 * require those files directly. Feel free to delete any files that aren't
 * needed.
 */
declare module 'connect-history-api-fallback/lib/index' {
  declare module.exports: any;
}

declare module 'connect-history-api-fallback/test/index_test' {
  declare module.exports: any;
}

// Filename aliases
declare module 'connect-history-api-fallback/lib/index.js' {
  declare module.exports: $Exports<'connect-history-api-fallback/lib/index'>;
}
declare module 'connect-history-api-fallback/test/index_test.js' {
  declare module.exports: $Exports<'connect-history-api-fallback/test/index_test'>;
}