text:
#include "HeightfieldSC.h"

#include <iostream>
#include "MathCalcs.h"
#include "SystemErrors.h"

#include "ThreadSplitter.h"
#include <cmath>
#include <memory>

#include "DebugTimer.h"

#include "VectorCalcs.h"

HeightfieldScalable::HeightfieldScalable() : _loadingTiles( false ) {

}
HeightfieldScalable::~HeightfieldScalable() {

}

bool HeightfieldScalable::initializeHeightmap( std::string hmapFileFormat, std::string hmapFileExtension,
    std::string ptexFileFormat, std::string ptexFileExtension,
    int numTilesX, int numTilesY, int tileSize, float loadFar, float mapHeight, float patchSize, int regionSize ) {

    _hFileName = hmapFileFormat;
    _hFileExtension = hmapFileExtension;

    _hNumTilesX = numTilesX;
    _hNumTilesY = numTilesY;

    _hTileSize = tileSize;

    _regionSize = regionSize;

    _pFileName = ptexFileFormat;
    _pFileExtension = ptexFileExtension;

    _lastLevel = (int)log2( getHeightmapWidth() );
    _maxMipmapLevel = (int)log2( _hTileSize );

    _mapHeight = mapHeight;
    _patchSize = patchSize;

    // Initialize Sparse textures
    GLuint sparseHfCompact, sparsePhotoTex, sparseMaxMip, sparseNormalMap;
    glGenTextures( 1, &sparseHfCompact );
    glGenTextures( 1, &sparsePhotoTex );
    glGenTextures( 1, &sparseMaxMip );
    glGenTextures( 1, &sparseNormalMap );

    if ( getOpenGLError( "Error generating texture ids." ) ) {
        return false;
    }

    // Initialize heightfield sparse texture
    glBindTexture( GL_TEXTURE_2D, sparseHfCompact );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA );
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SPARSE_ARB, GL_TRUE );
    //glTexParameteri( GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, 0 );
    glTexStorage2D( GL_TEXTURE_2D, _maxMipmapLevel + 1, GL_RGBA8, _hTileSize * 3, _hTileSize * 3 );
    glBindTexture( GL_TEXTURE_2D, 0 );
    if ( getOpenGLError( "Error happened after initializing Sparse Heightmap." ) ) {
        return false;
    }

    // Initialize maximum mipmap sparse texture
    glBindTexture( GL_TEXTURE_2D, sparseMaxMip );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA );
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SPARSE_ARB, GL_TRUE );
    //glTexParameteri( GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, 0 );
    glTexStorage2D( GL_TEXTURE_2D, _maxMipmapLevel+1, GL_RGBA8, _hTileSize * 3, _hTileSize * 3 );
    glBindTexture( GL_TEXTURE_2D, 0 );
    if ( getOpenGLError( "Error happened after initializing Sparse Maximum Mipmap Tex." ) ) {
        return false;
    }

    // Initialize photo sparse texture
    glBindTexture( GL_TEXTURE_2D, sparsePhotoTex );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SPARSE_ARB, GL_TRUE );
    //glTexParameteri( GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, 0 );
    glTexStorage2D( GL_TEXTURE_2D, 1, GL_RGBA8, _hTileSize * 3, _hTileSize * 3 );
    glBindTexture( GL_TEXTURE_2D, 0 );
    if ( getOpenGLError( "Error happened after initializing Sparse Photo Tex." ) ) {
        return false;
    }

    // Initialize normal map
    _normalW = _normalH = _hTileSize; // _hTileSize+1;
    glBindTexture( GL_TEXTURE_2D, sparseNormalMap );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE );
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SPARSE_ARB, GL_TRUE );
    //glTexParameteri( GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, 0 );
    glTexStorage2D( GL_TEXTURE_2D, 1, GL_RGB8, _normalW * 3, _normalH * 3 );
    glBindTexture( GL_TEXTURE_2D, 0 );
    if ( getOpenGLError( "Error happened after initializing Sparse Normal Map." ) ) {
        return false;
    }

    // Assign handles to textures (only for automatic management)
    _hfCompact.assignTextureHandle( sparseHfCompact );
    _photoTexture.assignTextureHandle( sparsePhotoTex );
    _maximumMipmaps.assignTextureHandle( sparseMaxMip );
    _normalMap.assignTextureHandle( sparseNormalMap );
    // Maximum mipmap structure will be accessed per index. Interpolation is not needed.
    _maximumMipmaps.setMinMagFilter( GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST );
    _maximumMipmaps.setWrapMode( GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE );
    if ( getOpenGLError( "Error happened after assigning texture handles." ) ) {
        return false;
    }

    // Default center of loaded region to Tile 1,1
    _llTileX = 0;
    _llTileY = 0;
    _tileStates.resize( numTilesX, std::vector< int >( numTilesY, -1 ) );
    _tileOrder = { -1,-1,-1, -1,-1,-1, -1,-1,-1 };
    _availableTiles = { 8, 7, 6, 5, 4, 3, 2, 1, 0 };
    _nextTile = 0;
    _farz = loadFar;

    _tileDimensions.setVector( _hTileSize, _hTileSize );

    for ( int i = 0; i < 9; ++i ) {
        int x = i % 3;
        int y = i / 3;

        if ( !loadTile( x+_llTileX, y+_llTileY, _nextTile ) ) {
            std::cout << "Failed to initialize tile" << std::endl;
            return false;
        }
        _nextTile = ( i + 1 ) % 9;
    }

    userPosition.setVector( 0, 0, 0 );
    boundsLL.setVector( 0.0f, 0.0f ); // tileSizeX * ( tileCenterX-1), tileSizeY * (tileCenterY-1)
    boundsDIM.setVector( _hTileSize * 3, _hTileSize * 3 );

    spawnWorkerThread();

    return true;
}

bool HeightfieldScalable::loadCompactFormat( const std::string& file ) {

    DebugTimer tmr;

    Texture hfTex;

    tmr.start();
    std::cout << "Loading heightmap image: ";
    // Load texture - assuming dimensions equal to POWER-OF-TWO+1 (ex: 257, 1025, etc..)
    if ( !hfTex.loadTexture( file ) ) {
        std::cout << "Failed." << std::endl;
        return false;
    }
    tmr.stop();
    std::cout << " Complete. " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;
    hfTex.downloadPixels();

    int width = hfTex.getWidth(); // POT+1
    int height = hfTex.getHeight(); // POT+1

    int newWidth = width - 1; // POT
    int newHeight = height - 1; // POT

                                /*std::cout << "W:  " << width << " " << " H:  " << height << std::endl;
                                std::cout << "NW: " << newWidth << " " << " NH: " << newHeight << std::endl;*/

    auto pixels = hfTex.getPixels<Color4C>();
    PixelArray<Color4C> compact;
    compact.createPixelArrayEmpty( newWidth, newHeight ); // Ex: 1024x1024

    // Convert heightfield to compact format
    /*
    red  -x = p00
    green-y = p10
    blue -z = p01
    alpha-w = p11
    */
    // For each pixel xy, copy the height values from the surrounding patch in the original image
    // into a single pixel in the compact buffer
    tmr.start();
    ThreadSplitter::threadizeDual(
        [&]( int xa, int xb, int ya, int yb ) {
        for ( int y = ya; y < yb; ++y ) {
            for ( int x = xa; x < xb; ++x ) {
                compact.getPixel( x, y ).red = pixels[ y* width + x ].red;
                compact.getPixel( x, y ).green = pixels[ y* width + x + 1 ].red;
                compact.getPixel( x, y ).blue = pixels[ ( y + 1 )* width + x ].red;
                compact.getPixel( x, y ).alpha = pixels[ ( y + 1 )* width + x + 1 ].red;
            }
        }
    },
        newWidth, newHeight, 8 );
    tmr.stop();
    std::cout << "Reformat heightfield: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;
    // No need to keep the heightmap texture open
    hfTex.closeTexture();

    // Create a texture from the compact buffer (ex: 1024x1024)
    /*if ( !_hfCompact.createSpecialTexture( newWidth, newHeight, GL_COMPRESSED_RGBA, GL_RGBA, compact.getPixels() ) ) {
    return false;
    }*/

    tmr.start();
    if ( !_hfCompact.loadTexture( compact.getPixels(), newWidth, newHeight ) ) {
        std::cout << "Error loading image to GPU." << std::endl;
        getchar();
        return false;
    }
    tmr.stop();
    std::cout << "Upload heightfield: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    // Create finest mipmap level
    // Where each pixel contains the maximum height value from the corresponding patch in the compact format
    PixelArray<Color4C> topMipmap;
    topMipmap.createPixelArrayEmpty( newWidth, newHeight );

    tmr.start();
    ThreadSplitter::threadizeDual(
        [&]( int xa, int xb, int ya, int yb ) {
        for ( int x = xa; x < xb; ++x ) {
            for ( int y = ya; y < yb; ++y ) {
                Color4C sample = compact.getPixel( x, y );
                topMipmap.getPixel( x, y ).red =
                    (GLubyte)mathCalcs::max( mathCalcs::max( (int)sample.green, (int)sample.red ),
                        mathCalcs::max( (int)sample.blue, (int)sample.alpha ) );
            }
        }
    },
        newWidth, newHeight, 8 );
    tmr.stop();
    std::cout << "Create mipmap toplevel: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    // Create finest mipmap level with POT dimensions (ex: 1024x1024)
    /*if ( !_maximumMipmaps.createSpecialTexture( newWidth, newHeight, GL_R8, GL_RED, topMipmap.getPixels() ) ) {
    return false;
    }*/
    if ( !_maximumMipmaps.loadTexture( topMipmap.getPixels(), newWidth, newHeight ) ) {
        std::cout << "Failed to create maximum mipmap texture." << std::endl;
        return false;
    }

    // Create remaining mipmap levels starting at level 1
    // Each consecutive level has half the size of the previous level (ex: L1=512x512,L2=256x256, etc)
    int level = 1;
    _maximumMipmaps.bindTexture();

    int maxLevel = (int)log2( newWidth );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, maxLevel );
    std::cout << "Max LOD: " << maxLevel << std::endl;

    tmr.start();
    while ( newHeight != 1 && newWidth != 1 ) {
        newWidth /= 2;
        newHeight /= 2;

        std::cout << "MipLevel(" << level << ") W:  " << newWidth << " " << " H:  " << newHeight << std::endl;

        // Create half sized buffer to hold data for the next level
        PixelArray<Color4C> mipmapData;
        mipmapData.createPixelArrayEmpty( newWidth, newHeight );

        // Multithreading can be applied to the following nested for loop
        // However, the last few levels have very small workloads and do not require multithreading
        for ( int x = 0; x < newWidth; ++x ) {
            for ( int y = 0; y < newHeight; ++y ) {
                int tx = x * 2;
                int ty = y * 2;

                mipmapData.getPixel( x, y ).red =
                    mathCalcs::max( mathCalcs::max( (int)topMipmap.getPixel( tx, ty ).red, (int)topMipmap.getPixel( tx + 1, ty ).red ),
                        mathCalcs::max( (int)topMipmap.getPixel( tx, ty + 1 ).red, (int)topMipmap.getPixel( tx + 1, ty + 1 ).red ) );
            }
        }

        // Create next level mipmap
        //glTexImage2D( GL_TEXTURE_2D, level, GL_R8, newWidth, newHeight, 0, GL_RED, GL_UNSIGNED_BYTE, mipmapData.getPixels() );
        glTexImage2D( GL_TEXTURE_2D, level, GL_RGBA, newWidth, newHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, mipmapData.getPixels() );

        topMipmap = mipmapData;
        level++;
    }
    tmr.stop();
    std::cout << "Mipmap generation: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;
    _maximumMipmaps.unbindTexture();

    // Maximum mipmap structure will be accessed per index. Interpolation is not needed.
    _maximumMipmaps.setMinMagFilter( GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST );
    _maximumMipmaps.setWrapMode( GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE );

    // #level is incremented one last time by the end of the previous loop
    _lastLevel = level - 1;

    // Maximum value could aid in determining a better/smaller value for the heightmap Z dimensions, as a small optimization
    /*int max = topMipmap.getPixel(0,0);*/

    return true;
}

bool HeightfieldScalable::loadCompactFormatA2( int tileX, int tileY, int orderTile ) {
    // Determine which tile in the sparse texture is to be used
    int texTile = findAvailableTile();
    int sparseX = texTile % 3;
    int sparseY = texTile / 3;

    std::string heightFile = getHeighTileFilename( tileX, tileY );
    std::string photoFile = getPhotoTileFilename( tileX, tileY );

    _tileCacheMap[ std::pair<int, int>( tileX, tileY ) ] = std::shared_ptr<TileCache>( new TileCache() );
    TileCache* tCache = getTileCache( tileX, tileY );
    tCache->tileX = tileX;
    tCache->tileY = tileY;
    tCache->assignedIndex = -1;
    tCache->error = false;
    tCache->loaded = true;
    tCache->heightTile.push_back( PixelArray<Color4C>() );

    DebugTimer tmr;

    // Read heightfield tile
    tmr.start();
    PixelArray< Color4C > compactPixels;
    if ( !Texture::loadPixelsFromImage( heightFile, compactPixels ) ) {
        std::cout << "Tile loading error: Unable to read data from \"" << heightFile << "\"." << std::endl;
        getchar();
        return false;
    }
    tmr.stop();
    std::cout << "Read heightfield tile: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    int width = compactPixels.getWidth();
    int height = compactPixels.getHeight();

    if ( width != _hTileSize || height != _hTileSize ) {
        std::cout << "Tile loading error: Tile \"" << heightFile << " " << " size mismatch (" << width << " , " << height << ")" << std::endl;
        return false;
    }

    tCache->heightTile[ 0 ].createPixelArrayEmpty( width, height );
    tCache->heightTile[ 0 ].overwritePixelArray( compactPixels, 0, 0 );

    if ( getOpenGLError( "Random error" ) ) {
        std::cout << "Random error" << std::endl;
        return false;
    }

    // Upload heightfield tile to sparse texture
    tmr.start();
    _hfCompact.bindTexture();
    /*glTexPageCommitmentARB( GL_TEXTURE_2D, 0,
        _hTileSize * sparseX, _hTileSize * sparseY, 0,
        _hTileSize, _hTileSize, 1,
        GL_TRUE );*/
    glTexSubImage2D( GL_TEXTURE_2D, 0, _hTileSize * sparseX, _hTileSize * sparseY, _hTileSize, _hTileSize, GL_RGBA, GL_UNSIGNED_BYTE, compactPixels.getPixels() );
    _hfCompact.unbindTexture();
    tmr.stop();
    std::cout << "Stored HF tile: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;
    if ( getOpenGLError( "Error committing heightfield compact" ) ) {
        std::cout << "Error comitting heightfield compact." << std::endl;
        return false;
    }

    // Read in the photo texture
    tmr.start();
    PixelArray< Color4C > photoPixels;
    if ( !Texture::loadPixelsFromImage( photoFile, photoPixels ) ) {
        std::cout << "PhotoTexture could not be read: " << photoFile << std::endl;
        return false;
    }
    _photoTexture.bindTexture();
    /*glTexPageCommitmentARB( GL_TEXTURE_2D, 0,
    _hTileSize * sparseX, _hTileSize * sparseY, 0,
    _hTileSize, _hTileSize, 1,
    GL_TRUE );
    if ( getOpenGLError( "Error committing photo texture pages" ) ) {
    std::cout << "Error committing photo texture pages: " << std::endl;
    std::cout << "Offsets: " << _hTileSize * sparseX << " , " << _hTileSize * sparseY << std::endl;
    std::cout << "Sizes: " << _hTileSize << " , " << _hTileSize << std::endl;
    return false;
    }*/
    glTexSubImage2D( GL_TEXTURE_2D, 0, _hTileSize * sparseX, _hTileSize * sparseY, _hTileSize, _hTileSize, GL_RGBA, GL_UNSIGNED_BYTE, photoPixels.getPixels() );
    if ( getOpenGLError( "Error uploading photo texture data" ) ) {
        std::cout << "Error uploading photo texture data." << std::endl;
        return false;
    }
    _photoTexture.unbindTexture();
    photoPixels.deletePixelArray();
    tmr.stop();
    std::cout << "Photo texture: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    // Generate the mipmap levels
    // Create finest mipmap level
    // Where each pixel contains the maximum height value from the corresponding patch in the compact format
    PixelArray<Color4C> topMipmap;
    topMipmap.createPixelArrayEmpty( width, height );

    tmr.start();
    ThreadSplitter::threadizeDual(
        [&]( int xa, int xb, int ya, int yb ) {
        for ( int x = xa; x < xb; ++x ) {
            for ( int y = ya; y < yb; ++y ) {
                Color4C sample = compactPixels[ y * width + x ];
                topMipmap.getPixel( x, y ).red =
                    (GLubyte)mathCalcs::max( mathCalcs::max( (int)sample.green, (int)sample.red ),
                        mathCalcs::max( (int)sample.blue, (int)sample.alpha ) );
            }
        }
    },
        width, height, 8 );
    tmr.stop();
    std::cout << "Create mipmap toplevel: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;
    //compactPixels.deletePixelArray();

    // Create remaining mipmap levels starting at level 1
    // Each consecutive level has half the size of the previous level (ex: L1=512x512,L2=256x256, etc)
    _maximumMipmaps.bindTexture();
    /*glTexPageCommitmentARB( GL_TEXTURE_2D, 0,
        _hTileSize * sparseX, _hTileSize * sparseY, 0,
        _hTileSize, _hTileSize, 1,
        GL_TRUE );
    if ( getOpenGLError( "Error committing mipmap top" ) ) {
        std::cout << "Error committing mipmap top" << std::endl;
        return false;
    }*/
    glTexSubImage2D( GL_TEXTURE_2D, 0, width * sparseX, height * sparseY, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, topMipmap.getPixels() );
    if ( getOpenGLError( "Error storing mipmap top" ) ) {
        std::cout << "Error storing mipmap top" << std::endl;
        return false;
    }

    int level = 1;
    int lodWidth = width;
    int lodHeight = height;
    tmr.start();
    while ( level <= _maxMipmapLevel ) {
        lodWidth /= 2;
        lodHeight /= 2;

        //std::cout << "MipLevel(" << level << ") W:  " << width << " " << " H:  " << height << std::endl;

        // Create half sized buffer to hold data for the next level
        PixelArray<Color4C> mipmapData;
        mipmapData.createPixelArrayEmpty( lodWidth, lodHeight );

        // Multithreading can be applied to the following nested for loop
        // However, the last few levels have very small workloads and do not require multithreading
        for ( int x = 0; x < lodWidth; ++x ) {
            for ( int y = 0; y < lodHeight; ++y ) {
                int tx = x * 2;
                int ty = y * 2;

                mipmapData.getPixel( x, y ).red =
                    mathCalcs::max( mathCalcs::max( (int)topMipmap.getPixel( tx, ty ).red, (int)topMipmap.getPixel( tx + 1, ty ).red ),
                        mathCalcs::max( (int)topMipmap.getPixel( tx, ty + 1 ).red, (int)topMipmap.getPixel( tx + 1, ty + 1 ).red ) );
            }
        }

        // Create next level mipmap
        //glTexImage2D( GL_TEXTURE_2D, level, GL_R8, newWidth, newHeight, 0, GL_RED, GL_UNSIGNED_BYTE, mipmapData.getPixels() );
        //glTexImage2D( GL_TEXTURE_2D, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, mipmapData.getPixels() );

        /*glTexPageCommitmentARB( GL_TEXTURE_2D, level,
            _hTileSize * sparseX, _hTileSize * sparseY, 0,
            _hTileSize, _hTileSize, 1,
            GL_TRUE );*/
        //std::cout << level << " : Off: " << width * sparseX << " , " << height * sparseY << " D: " << width << " , " << height << std::endl;
        glTexSubImage2D( GL_TEXTURE_2D, level, lodWidth * sparseX, lodHeight * sparseY, lodWidth, lodHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, mipmapData.getPixels() );
        if ( getOpenGLError( "Error committing mipmap level: " + std::to_string( level )  ) ) {
            std::cout << "Error committing mipmap level: " << level << std::endl;
            return false;
        }

        topMipmap = mipmapData;
        level++;
    }
    tmr.stop();
    std::cout << "Mipmap generation: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;
    _maximumMipmaps.unbindTexture();

    std::cout << "Generating normal map: ";
    tmr.start();
    int normW = _hTileSize + 0;
    int normH = _hTileSize + 0;
    PixelArray< Color3C > normals;
    normals.createPixelArray( normW, normH );

    ThreadSplitter::threadizeDual(
        [&]( int xa, int xb, int ya, int yb ) {
        for ( int x = xa; x < xb; ++x ) {
            for ( int y = ya; y < yb; ++y ) {
                Vector3D nUp = genNormal( &compactPixels, x, y, x, y + 1 );
                Vector3D nDown = genNormal( &compactPixels, x, y, x, y - 1 );
                Vector3D nLeft = genNormal( &compactPixels, x, y, x - 1, y );
                Vector3D nRight = genNormal( &compactPixels, x, y, x + 1, y );

                Vector3D norm = nUp + nDown + nLeft + nRight; norm.normalize();
                normals.getPixel( x, y ) = convertNormalToPixel( norm );
            }
        }
    },
        normH, normH, 8 );
    _normalMap.bindTexture();
    glTexSubImage2D( GL_TEXTURE_2D, 0, normW * sparseX, normH * sparseY, normW, normH, GL_RGB, GL_UNSIGNED_BYTE, normals.getPixels() );
    if ( getOpenGLError( "Error uploading normal texture data" ) ) {
        std::cout << "Error uploading normal texture data." << std::endl;
        return false;
    }
    _normalMap.unbindTexture();
    std::cout << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    // Generate heightfield mipmaps
    tmr.start();
    _hfCompact.bindTexture();
    level = 1;
    lodWidth = width;
    lodHeight = height;
    while ( lodHeight != 1 && lodWidth != 1 ) {
        lodWidth /= 2;
        lodHeight /= 2;

        //std::cout << "HF MipLevel(" << level << ") W:  " << lodWidth << " " << " H:  " << lodHeight << std::endl;

        // Create half sized buffer to hold data for the next level
        PixelArray<Color4C> compactData;
        compactData.createPixelArrayEmpty( lodWidth, lodHeight );

        // Multithreading can be applied to the following nested for loop
        // However, the last few levels have very small workloads and do not require multithreading
        for ( int x = 0; x < lodWidth; ++x ) {
            for ( int y = 0; y < lodHeight; ++y ) {
                int tx = x * 2;
                int ty = y * 2;

                /*compactData.getPixel( x, y ).setColor(
                    compactPixels.getPixel( tx, ty ).red,
                    compactPixels.getPixel( tx + 1, ty ).green,
                    compactPixels.getPixel( tx, ty + 1 ).blue,
                    compactPixels.getPixel( tx + 1, ty + 1 ).alpha );*/
                // GL_RGBA,GL_UNSIGNED_SHORT has the byte order reversed
                compactData.getPixel( x, y ).setColor(
                    compactPixels.getPixel( tx + 1, ty + 1 ).red,
                    compactPixels.getPixel( tx, ty + 1 ).green,
                    compactPixels.getPixel( tx + 1, ty ).blue,
                    compactPixels.getPixel( tx, ty ).alpha );
            }
        }

        // Create next level mipmap
        glTexSubImage2D( GL_TEXTURE_2D, level, lodWidth * sparseX, lodHeight * sparseY, lodWidth, lodHeight,
            GL_RGBA, GL_UNSIGNED_BYTE, compactData.getPixels() );

        compactPixels = compactData;
        level++;
    }
    _hfCompact.unbindTexture();
    tmr.stop();
    std::cout << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    /*ArrayWrapper< GLubyte > photoPixels;
    if ( !Texture::loadCompressedPixelsFromImage( photoFile, photoPixels ) ) {
        std::cout << "Photo pixels are BAD" << std::endl;
        return false;
    }

    _photoTexture.bindTexture();
    glTexPageCommitmentARB( GL_TEXTURE_2D, 0,
        _hTileSize * sparseX, _hTileSize * sparseY, 0,
        _hTileSize, _hTileSize, 1,
        GL_TRUE );
    if ( getOpenGLError( "Error committing photo texture pages" ) ) {
        std::cout << "Error committing photo texture pages: " << photoPixels.getSize() << std::endl;
        std::cout << "Offsets: " << _hTileSize * sparseX << " , " << _hTileSize * sparseY << std::endl;
        std::cout << "Sizes: " << _hTileSize << " , " << _hTileSize << std::endl;
        return false;
    }
    glCompressedTexSubImage2D( GL_TEXTURE_2D, 0, width * sparseX, height * sparseY, width, height,
        GL_COMPRESSED_RGB_S3TC_DXT1_EXT, photoPixels.getSize(), photoPixels.getPointer() );
    //glTexSubImage2D( GL_TEXTURE_2D, level, width * sparseX, height * sparseY, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, photoPixels.getPointer() );
    _photoTexture.unbindTexture();
    if ( getOpenGLError( "Error uploading photo texture data" ) ) {
        std::cout << "Error uploading photo texture data. Buffer size: " << photoPixels.getSize() << std::endl;
        return false;
    }*/

    // Update round-robin index
    _tileOrder[ orderTile ] = texTile;
    _tileStates[ tileX ][ tileY ] = orderTile;

    // Maximum value could aid in determining a better/smaller value for the heightmap Z dimensions, as a small optimization
    /*int max = topMipmap.getPixel(0,0);*/

    return true;
}

bool HeightfieldScalable::uploadTile( int tileX, int tileY ) {
    TileCache* tCache = getTileCache( tileX, tileY );
    if ( tCache == nullptr ) {
        return false;
    }

    // Determine which tile in the sparse texture is to be used
    int orderTile = ( tileX - _llTileX ) + ( tileY - _llTileY ) * 3;
    if ( orderTile < 0 || orderTile > 8 ) { std::cout << "Attempting to upload tile outside the active region" << std::endl; return false; }
    int texTile = findAvailableTile();
    int sparseX = texTile % 3;
    int sparseY = texTile / 3;

    std::string heightFile = getHeighTileFilename( tileX, tileY );
    std::string photoFile = getPhotoTileFilename( tileX, tileY );

    DebugTimer tmr;

    // Upload heightfield tile
    tmr.start();
    _hfCompact.bindTexture();
    for ( int i = 0; i < tCache->heightTile.size(); ++i ) {
        glTexSubImage2D( GL_TEXTURE_2D, i, tCache->heightTile[ i ].getWidth() * sparseX, tCache->heightTile[ i ].getHeight() * sparseY,
            tCache->heightTile[ i ].getWidth(), tCache->heightTile[ i ].getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, tCache->heightTile[ i ].getPixels() );
    }
    _hfCompact.unbindTexture();
    tmr.stop();
    std::cout << "Stored HF tile: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;
    if ( getOpenGLError( "Error committing heightfield compact" ) ) {
        std::cout << "Error comitting heightfield compact." << std::endl;
        return false;
    }

    // Read in the photo texture
    tmr.start();
    _photoTexture.bindTexture();
    glTexSubImage2D( GL_TEXTURE_2D, 0, _hTileSize * sparseX, _hTileSize * sparseY, _hTileSize, _hTileSize, GL_RGBA, GL_UNSIGNED_BYTE, tCache->photoTile.getPixels() );
    if ( getOpenGLError( "Error uploading photo texture data" ) ) {
        std::cout << "Error uploading photo texture data." << std::endl;
        return false;
    }
    _photoTexture.unbindTexture();
    tmr.stop();
    std::cout << "Photo texture: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    // Read in mipmaps
    for ( int i = 0; i < tCache->mipmaps.size(); ++i ) {
        _maximumMipmaps.bindTexture();
        glTexSubImage2D( GL_TEXTURE_2D, i, tCache->mipmaps[i].getWidth() * sparseX, tCache->mipmaps[ i ].getHeight() * sparseY,
            tCache->mipmaps[ i ].getWidth(), tCache->mipmaps[ i ].getHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, tCache->mipmaps[i].getPixels() );
    }

    // Generate the mipmap levels
    // Create finest mipmap level
    // Where each pixel contains the maximum height value from the corresponding patch in the compact format
    /*PixelArray<Color4C> topMipmap;
    topMipmap.createPixelArrayEmpty( _hTileSize, _hTileSize );

    tmr.start();
    ThreadSplitter::threadizeDual(
        [&]( int xa, int xb, int ya, int yb ) {
        for ( int x = xa; x < xb; ++x ) {
            for ( int y = ya; y < yb; ++y ) {
                Color4C sample = tCache->heightTile[ y * _hTileSize + x ];
                topMipmap.getPixel( x, y ).red =
                    (GLubyte)mathCalcs::max( mathCalcs::max( (int)sample.green, (int)sample.red ),
                        mathCalcs::max( (int)sample.blue, (int)sample.alpha ) );
            }
        }
    },
        _hTileSize, _hTileSize, 8 );
    tmr.stop();
    std::cout << "Create mipmap toplevel: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    // Create remaining mipmap levels starting at level 1
    // Each consecutive level has half the size of the previous level (ex: L1=512x512,L2=256x256, etc)
    _maximumMipmaps.bindTexture();
    glTexSubImage2D( GL_TEXTURE_2D, 0, _hTileSize * sparseX, _hTileSize * sparseY, _hTileSize, _hTileSize, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, topMipmap.getPixels() );
    if ( getOpenGLError( "Error storing mipmap top" ) ) {
        std::cout << "Error storing mipmap top" << std::endl;
        return false;
    }

    int width = _hTileSize, height = _hTileSize;
    int level = 1;
    tmr.start();
    while ( level <= _maxMipmapLevel ) {
        width /= 2;
        height /= 2;

        //std::cout << "MipLevel(" << level << ") W:  " << width << " " << " H:  " << height << std::endl;

        // Create half sized buffer to hold data for the next level
        PixelArray<Color4C> mipmapData;
        mipmapData.createPixelArrayEmpty( width, height );

        // Multithreading can be applied to the following nested for loop
        // However, the last few levels have very small workloads and do not require multithreading
        for ( int x = 0; x < width; ++x ) {
            for ( int y = 0; y < height; ++y ) {
                int tx = x * 2;
                int ty = y * 2;

                mipmapData.getPixel( x, y ).red =
                    mathCalcs::max( mathCalcs::max( (int)topMipmap.getPixel( tx, ty ).red, (int)topMipmap.getPixel( tx + 1, ty ).red ),
                        mathCalcs::max( (int)topMipmap.getPixel( tx, ty + 1 ).red, (int)topMipmap.getPixel( tx + 1, ty + 1 ).red ) );
            }
        }

        // Create next level mipmap
        //std::cout << level << " : Off: " << width * sparseX << " , " << height * sparseY << " D: " << width << " , " << height << std::endl;
        glTexSubImage2D( GL_TEXTURE_2D, level, width * sparseX, height * sparseY, width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, mipmapData.getPixels() );
        if ( getOpenGLError( "Error committing mipmap level: " + std::to_string( level ) ) ) {
            std::cout << "Error committing mipmap level: " << level << std::endl;
            return false;
        }

        topMipmap = mipmapData;
        level++;
    }
    tmr.stop();*/
    std::cout << "Mipmap generation: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;
    _maximumMipmaps.unbindTexture();

    // Read in the normal map
    _normalMap.bindTexture();
    glTexSubImage2D( GL_TEXTURE_2D, 0, tCache->normalTile.getWidth() * sparseX, tCache->normalTile.getHeight() * sparseY,
        tCache->normalTile.getWidth(), tCache->normalTile.getHeight(), GL_RGB, GL_UNSIGNED_BYTE, tCache->normalTile.getPixels() );
    if ( getOpenGLError( "Error uploading normal map data" ) ) {
        std::cout << "Error uploading normal map data." << std::endl;
        return false;
    }
    _normalMap.unbindTexture();

    // Update round-robin index
    _tileOrder[ orderTile ] = texTile;
    _tileStates[ tileX ][ tileY ] = orderTile;

    return true;
}

bool HeightfieldScalable::loadPhotoTexture( const std::string &file ) {
    return _photoTexture.loadTexture( file, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE );
}

TileCache* HeightfieldScalable::getTileCache( int tileX, int tileY ) {
    auto it = _tileCacheMap.find( std::make_pair( tileX, tileY ) );
    if ( it != _tileCacheMap.end() ) {
        return it->second.get();
    }
    return nullptr;
}
void HeightfieldScalable::prepareToLoadTile( int tileX, int tileY ) {
    _tilesToLoad.push_back( std::pair< int, int>( tileX, tileY ) );
}
bool HeightfieldScalable::preLoadTile( int tileX, int tileY ) {
    // Determine which tile in the sparse texture is to be used
    if ( isTilePreLoaded( tileX, tileY ) ) {
        return true;
    }

    std::cout << "Loading: " << tileX << " " << tileY << std::endl;

    _tileCacheMap[ std::pair<int, int>( tileX, tileY ) ] = std::shared_ptr<TileCache>( new TileCache() );
    TileCache* tCache = getTileCache( tileX, tileY );
    tCache->tileX = tileX;
    tCache->tileY = tileY;
    tCache->assignedIndex = -1;
    tCache->error = false;
    tCache->loaded = false;

    std::string heightFile = getHeighTileFilename( tileX, tileY );
    std::string photoFile = getPhotoTileFilename( tileX, tileY );

    DebugTimer tmr;

    // Read heightfield tile
    tmr.start();
    tCache->heightTile.push_back( PixelArray<Color4C>() );
    if ( !Texture::loadPixelsFromImage( heightFile, tCache->heightTile[0] ) ) {
        //std::cout << "Tile loading error: Unable to read data from \"" << heightFile << "\"." << std::endl;
        tCache->error = true;
        return false;
    }
    tmr.stop();
    //std::cout << "Read heightfield tile: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    int width = tCache->heightTile[0].getWidth();
    int height = tCache->heightTile[ 0 ].getHeight();

    if ( width != _hTileSize || height != _hTileSize ) {
        //std::cout << "Tile loading error: Tile \"" << heightFile << " " << " size mismatch (" << width << " , " << height << ")" << std::endl;
        tCache->error = true;
        return false;
    }
    // Generate remaining heightmap levels
    for ( int i = 1; i <= _maxMipmapLevel; ++i ) {
        tCache->heightTile.push_back( PixelArray<Color4C>() );
        PixelArray<Color4C>& prevLevel = tCache->heightTile[ i - 1 ];
        PixelArray<Color4C>& nextLevel = tCache->heightTile[ i ];
        int newW = prevLevel.getWidth() / 2;
        int newH = prevLevel.getHeight() / 2;
        nextLevel.createPixelArrayEmpty( newW, newH );

        for ( int x = 0; x < newW; ++x ) {
            for ( int y = 0; y < newH; ++y ) {
                int tx = x * 2;
                int ty = y * 2;

                nextLevel.getPixel( x, y ).setColor(
                    prevLevel.getPixel( tx + 1, ty + 1 ).red,
                    prevLevel.getPixel( tx, ty + 1 ).green,
                    prevLevel.getPixel( tx + 1, ty ).blue,
                    prevLevel.getPixel( tx, ty ).alpha );
            }
        }

    }

    // Read in the photo texture
    tmr.start();
    if ( !Texture::loadPixelsFromImage( photoFile, tCache->photoTile ) ) {
        //std::cout << "PhotoTexture could not be read: " << photoFile << std::endl;
        tCache->error = true;
        return false;
    }
    tmr.stop();
    //std::cout << "Read photo texture: " << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    // Preload maximum mipmaps
    // Generate top level mipmap
    tCache->mipmaps.push_back( PixelArray<Color4C>() );
    PixelArray<Color4C>& topMip = tCache->mipmaps[ 0 ];
    topMip.createPixelArrayEmpty( _hTileSize, _hTileSize );
    tmr.start();
    ThreadSplitter::threadizeDual(
        [&]( int xa, int xb, int ya, int yb ) {
        for ( int x = xa; x < xb; ++x ) {
            for ( int y = ya; y < yb; ++y ) {
                Color4C sample = tCache->heightTile[0][ y * _hTileSize + x ];
                topMip.getPixel( x, y ).red =
                    (GLubyte)mathCalcs::max( mathCalcs::max( (int)sample.green, (int)sample.red ),
                        mathCalcs::max( (int)sample.blue, (int)sample.alpha ) );
            }
        }
    },
        _hTileSize, _hTileSize, 8 );
    // Generate remaining mipmap levels
    for ( int i = 1; i <= _maxMipmapLevel; ++i ) {
        tCache->mipmaps.push_back( PixelArray<Color4C>() );
        PixelArray<Color4C>& prevLevel = tCache->mipmaps[ i-1 ];
        PixelArray<Color4C>& nextLevel = tCache->mipmaps[ i ];
        int newW = prevLevel.getWidth() / 2;
        int newH = prevLevel.getHeight() / 2;
        nextLevel.createPixelArrayEmpty( newW, newH );

        for ( int x = 0; x < newW; ++x ) {
            for ( int y = 0; y < newH; ++y ) {
                int tx = x * 2;
                int ty = y * 2;

                nextLevel.getPixel( x, y ).red =
                    mathCalcs::max( mathCalcs::max( (int)prevLevel.getPixel( tx, ty ).red, (int)prevLevel.getPixel( tx + 1, ty ).red ),
                        mathCalcs::max( (int)prevLevel.getPixel( tx, ty + 1 ).red, (int)prevLevel.getPixel( tx + 1, ty + 1 ).red ) );
            }
        }
    }

    // Generate normals
     tCache->normalTile.createPixelArrayEmpty( _normalW, _normalH );

    ThreadSplitter::threadizeDual(
        [&]( int xa, int xb, int ya, int yb ) {
        for ( int x = xa; x < xb; ++x ) {
            for ( int y = ya; y < yb; ++y ) {
                Vector3D nUp = genNormal( &tCache->heightTile[0], x, y, x, y + 1 );
                Vector3D nDown = genNormal( &tCache->heightTile[ 0 ], x, y, x, y - 1 );
                Vector3D nLeft = genNormal( &tCache->heightTile[ 0 ], x, y, x - 1, y );
                Vector3D nRight = genNormal( &tCache->heightTile[ 0 ], x, y, x + 1, y );

                Vector3D norm = nUp + nDown + nLeft + nRight; norm.normalize();
                tCache->normalTile.getPixel( x, y ) = convertNormalToPixel( norm );
            }
        }
    },
        _normalW, _normalH, 8 );
    std::cout << tmr.getTimeElapsed() / 1000.0 << "s" << std::endl;

    tCache->loaded = true;

    return true;
}
bool HeightfieldScalable::isTilePreLoaded( int tileX, int tileY ) {
    TileCache* tCache = getTileCache( tileX, tileY );
    return ( tCache != nullptr ) && ( tCache->loaded );
}
/*bool HeightfieldScalable::loadDefaultPhotoTexture() {
    PixelArray< Color4C > defaultPtex;
    defaultPtex.createPixelArrayEmpty( 16, 16 );
    defaultPtex.fill( Color4C( 255, 255, 255, 255 ) );
    return _photoTexture.loadTexture( defaultPtex.getPixels(), 16, 16 );
}*/

/*Texture *HeightfieldScalable::getHeightmapTexture() {
    return &_hftex;
}*/

bool HeightfieldScalable::unloadTile( int x, int y ) {
    int tileIndex = _tileStates[ x ][ y ];
    if ( tileIndex == -1 ) { return true; }

    // If the actual tile is still being loaded, an invalid old tile may be rendered until the new tile is ready!
    // Actually erase the data instead of just marking it unused

    _tileStates[ x ][ y ] = -1;
    _availableTiles.push_back( _tileOrder[ tileIndex ] );
    _tileOrder[ tileIndex ] = -1;

    return true;
}
void HeightfieldScalable::deleteTile( int tileX, int tileY ) {
    auto it = _tileCacheMap.find( std::pair<int, int>( tileX, tileY ) );
    if ( it != _tileCacheMap.end() ) {
        _tileCacheMap.erase( it );
    }
}
bool HeightfieldScalable::loadTile( int x, int y, int texTile ) {
    // Check if next tile is suitable
    if ( !loadCompactFormatA2( x, y, texTile ) ) {
        std::cout << "Failed to load tile: " << x << " , " << y << std::endl;
        return false;
    }
    return true;
}
void HeightfieldScalable::reloadRegion( int x, int y ) {
    for ( int x = 0; x < 3; ++x ) {
        for ( int y = 0; y < 3; ++y ) {
            unloadTile( _llTileX + x, _llTileY + y );
        }
    }
    _llTileX = x; _llTileY = y;
    for ( int x = 0; x < 3; ++x ) {
        for ( int y = 0; y < 3; ++y ) {
            loadTile( _llTileX + x, _llTileY + y, (x+1) + (y+1)*3 );
        }
    }
}
void HeightfieldScalable::recenterRegion( int nx, int ny ) {
    // Region data
    for ( int x = 0; x < 3; ++x ) {
        for ( int y = 0; y < 3; ++y ) {
            if ( abs( ( _llTileX + x ) - (nx+1) ) > 1 || abs( ( _llTileY + y ) - (ny+1) ) > 1 ) {
                std::cout << "Unload: " << _llTileX + x << "  ,  " << _llTileY + y << std::endl;
                unloadTile( _llTileX + x, _llTileY + y );
                deleteTile( _llTileX + x, _llTileY + y );
            }
        }
    }

    /*int px = _centerTileX;
    int py = _centerTileY;

    int minpx = mathCalcs::max( px - 1, 0 );
    int maxpx = mathCalcs::min( px + 1, 3 );
    int minx = mathCalcs::max( nx - 1, 0 );
    int maxx = mathCalcs::min( nx + 1, 3 );

    int minpy = mathCalcs::max( py - 1, 0 );
    int maxpy = mathCalcs::min( py + 1, 3 );
    int miny = mathCalcs::max( ny - 1, 0 );
    int maxy = mathCalcs::min( ny + 1, 3 );

    // Unload only tiles that are outside of the new region
    for ( int x = minpx; x <= maxpx; ++x ) {
        for ( int y = minpy; y <= maxpy; ++y ) {
            if ( !( ( minx <= x && x <= maxx ) && ( miny <= y && y <= maxy ) ) ) {
                if ( _tileStates[ x ][ y ] > 0 ) {
                    unloadTile( x, y );
                    std::cout << "Unloading: " << x << " " << y << std::endl;
                }
            }
        }
    }*/

    // Remove active region
    for ( int x = 0; x < 3; ++x ) {
        for ( int y = 0; y < 3; ++y ) {
            _tileStates[ _llTileX + x ][ _llTileY + y ] = -1;
        }
    }
    // Set new active region
    for ( int x = 0; x < 3; ++x ) {
        for ( int y = 0; y < 3; ++y ) {
            _tileStates[ nx + x ][ ny + y ] = x + y*3;
        }
    }

    // Shift previous active region into new active region
    int dx = nx - _llTileX, dy = ny - _llTileY;
    int startx, starty, endx, endy, stepx, stepy;
    if ( dx < 0 ) { startx = 2; endx = -1; stepx = -1; }
    else { startx = 0; endx = 3; stepx = 1; }
    if ( dy < 0 ) { starty = 2; endy = -1; stepy = -1; }
    else { starty = 0; endy = 3; stepy = 1; }

    for ( int x = startx; x != endx; x += stepx ) {
        for ( int y = starty; y != endy; y += stepy ) {
            int shiftx = x + dx, shifty = y + dy;
            // If still in active area
            if ( ( 0 <= shiftx && shiftx <= 2 ) && ( 0 <= shifty && shifty <= 2 ) ) {
                _tileOrder[ x + y * 3 ] = _tileOrder[ shiftx + shifty * 3 ];
            }
            else {
                _tileOrder[ x + y * 3 ] = -1;
            }
        }
    }

    _llTileX = nx;
    _llTileY = ny;

    // Determine which tiles need loading
    for ( int x = 0; x < 3; ++x ) {
        for ( int y = 0; y < 3; ++y ) {
            if ( _tileOrder[ _tileStates[ nx + x ][ ny + y ] ] == -1 ) {
                std::cout << "Load tile: " << nx + x << " , " << ny + y << std::endl;
                //loadTile( nx + x, ny + y, _tileStates[ nx + x ][ ny + y ] );
                prepareToLoadTile( nx + x, ny + y );
                _loadingTiles = true;
            }
        }
    }

    _loadSignal.notify_all();
    /*int px = _centerTileX;
    int py = _centerTileY;

    int minpx = mathCalcs::max( px - 1, 0 );
    int maxpx = mathCalcs::min( px + 1, 3 );
    int minx = mathCalcs::max( nx - 1, 0 );
    int maxx = mathCalcs::min( nx + 1, 3 );

    int minpy = mathCalcs::max( py - 1, 0 );
    int maxpy = mathCalcs::min( py + 1, 3 );
    int miny = mathCalcs::max( ny - 1, 0 );
    int maxy = mathCalcs::min( ny + 1, 3 );

    /*for ( int x = 0; x < 3; ++x ) {
        for ( int y = 0; y < 3; ++y ) {

        }
    }*/

    // Unload only tiles that are outside of the new region
    //std::cout << "pX: " << minpx << " " << maxpx << "      pY: " << minpy << " " << maxpy << std::endl;
    /*for ( int x = minpx; x <= maxpx; ++x ) {
        for ( int y = minpy; y <= maxpy; ++y ) {
            if ( !( ( minx <= x && x <= maxx ) && ( miny <= y && y <= maxy ) ) ) {
                if ( _tileStates[ x ][ y ] > 0 ) {
                    unloadTile( x, y );
                    _tileStates[ x ][ y ] = -1;
                }
            }
        }
    }*/

    // Load only tiles that are outside of the old region
    //std::cout << "X: " << minx << " " << maxx << "      Y: " << miny << " " << maxy << std::endl;
    /*for ( int x = minx; x <= maxx; ++x ) {
        for ( int y = miny; y <= maxy; ++y ) {
            if ( !( ( minpx <= x && x <= maxpx ) && ( minpy <= y && y <= maxpy ) ) ) {
                if ( _tileStates[ x ][ y ] == -1 ) {
                    loadTile( x, y );
                    _tileStates[ x ][ y ] = true;
                }
            }
        }
    }*/
}

void HeightfieldScalable::update( float dtime ) {
    Vector2D realTileDimensions = getFinalTileDimensions();
    // if LOADING TILES
    if ( _loadingTiles ) {
        // Upload ready tiles to GPU
        bool allLoaded = true;
        for ( int i = 0; i < 9; ++i ) {
            if ( _tileOrder[ i ] == -1 ) {
                int x =  _llTileX + i % 3;
                int y =  _llTileY + i / 3;
                //std::cout << "Try load: " << x << " " << y << std::endl;
                if ( isTilePreLoaded( x, y ) ) {
                    if ( !uploadTile( x, y ) ) {
                        std::cout << "Failed to load" << std::endl;
                    }
                    break;
                }
                allLoaded = false;
            }
        }
        // if tile loading is done
        if ( allLoaded ) {
            _loadingTiles = false;
            std::cout << "Loaded all tiles" << std::endl;
        }
    }
    // if NOT LOADING TILES
    else {
        // Too close to the left border
        bool change = false;
        int newX = _llTileX, newY = _llTileY;
        if ( ( userPosition.x - _llTileX * realTileDimensions.x ) < _farz ) {// Move to the left
                    if ( _llTileX > 0 ) {
                        //shiftRegionX( false );
                        change = true;
                        newX = _llTileX - 1;
                    }
        }
        else if ( ( ( _llTileX + _regionSize ) * realTileDimensions.x - userPosition.x ) < _farz ) { // Move to the right
                    if ( _llTileX < _hNumTilesX-_regionSize ) {
                        //shiftRegionX( true );
                        change = true;
                        newX = _llTileX + 1;
                    }
        }
        if ( ( userPosition.y - _llTileY * realTileDimensions.y ) < _farz ) {// Move to the lower part
                    if ( _llTileY > 0 ) {
                        change = true;
                        newY = _llTileY - 1;
                    }
        }
        else if ( ( ( _llTileY + _regionSize ) * realTileDimensions.y - userPosition.y ) < _farz ) { // Move to the upper part
                    if ( _llTileY < _hNumTilesY - _regionSize ) {
                        change = true;
                        newY = _llTileY + 1;
                    }
        }
        if ( change ) {
            std::cout << "Updating active region. ";
            recenterRegion( newX, newY );
            boundsLL.setVector( _llTileX * _tileDimensions.x, _llTileY *_tileDimensions.y );
            std::cout << "[Complete]" << std::endl;;
        }
        //boundsDIM = boundsDIM; // Bounds do not change
    }

    // Check collision

    // If user is inside any tile we can do collision checking
    if ( ( 0 <= userPosition.x && userPosition.x < getPatchSize()*getHeightmapWidth() ) && ( 0 <= userPosition.y || userPosition.y < getPatchSize()*getHeightmapHeight() ) ) {
        int uTileX = userPosition.x / realTileDimensions.x;
        int uTileY = userPosition.y / realTileDimensions.y;

        if ( isTilePreLoaded( uTileX, uTileY ) ) {
            auto currentTile = getTileCache( uTileX, uTileY );

            //std::cout << uTileX << " " << uTileY << std::endl;

            float uX = ( userPosition.x - ( uTileX * realTileDimensions.x ) ) / getPatchSize();
            float uY = ( userPosition.y - ( uTileY * realTileDimensions.y ) ) / getPatchSize();
            Color4C patch = currentTile->heightTile[ 0 ].getPixel( (int)uX, (int)uY );

            float interX = uX - (int)( uX );
            float interY = uY - (int)( uY );

            /*std::cout << uX << " " << uY << std::endl;
            std::cout << interX << " " << interY << std::endl;*/

            float height = (float)mathCalcs::blerp( patch.alpha, patch.green, patch.blue, patch.red, interX, interY ) / 255.0f;

            if ( ( userPosition.z - 2.0f ) < height * _mapHeight ) {
                userPosition.z = height *_mapHeight + 2.01f;
            }
        }
    }
}

Vector3D HeightfieldScalable::genNormal( PixelArray<Color4C>* hmap, int ix, int iy, int tx, int ty ) {
    int hWidth = hmap->getWidth();
    int hHeight = hmap->getHeight();

    GLubyte iHeight = 0;
    if ( validInterval( ix, 0, hmap->getWidth() - 1 ) && validInterval( iy, 0, hmap->getHeight() - 1 ) ) {
        iHeight = hmap->getPixel( ix, iy ).red;
    }
    else if ( validInterval( ix - 1, 0, hmap->getWidth() - 1 ) && validInterval( iy - 1, 0, hmap->getHeight() - 1 ) ) {
        iHeight = hmap->getPixel( ix - 1, iy - 1 ).alpha;
    }

    // 0 = up, 1 = down, 2 = right, 3 = left
    int dir = ( ty != iy ? ( ty > iy ? 0 : 1 ) : ( tx > ix ? 2 : 3 ) );

    Vector3D normal{ 0.0f, 0.0f, 1.0f };
    // Up
    if ( dir == 0 ) {
        if ( validInterval( tx, 0, hmap->getWidth() - 1 ) && validInterval( ty, 0, hmap->getHeight() - 1 ) ) {
            GLubyte tHeight = hmap->getPixel( tx, ty ).blue;
            normal.setVector( 0, 1 * _patchSize, ( tHeight - iHeight ) / 255.0f * _mapHeight );
            normal = rotate90_Xccw( normal );
        }
        else if ( validInterval( tx - 1, 0, hmap->getWidth() - 1 ) && validInterval( ty, 0, hmap->getHeight() - 1 ) ) {
            GLubyte tHeight = hmap->getPixel( tx - 1, ty ).alpha;
            normal.setVector( 0, 1 * _patchSize, ( tHeight - iHeight ) / 255.0f * _mapHeight );
            normal = rotate90_Xccw( normal );
        }
    }
    // Down
    else if ( dir == 1 ) {
        if ( validInterval( tx, 0, hmap->getWidth() - 1 ) && validInterval( ty - 1, 0, hmap->getHeight() - 1 ) ) {
            GLubyte tHeight = hmap->getPixel( tx, ty - 1 ).red;
            normal.setVector( 0, -1 * _patchSize, ( tHeight - iHeight ) / 255.0f * _mapHeight );
            normal = rotate90_Xcw( normal );
        }
        else if ( validInterval( tx - 1, 0, hmap->getWidth() - 1 ) && validInterval( ty - 1, 0, hmap->getHeight() - 1 ) ) {
            GLubyte tHeight = hmap->getPixel( tx - 1, ty - 1 ).green;
            normal.setVector( 0, -1 * _patchSize, ( tHeight - iHeight ) / 255.0f * _mapHeight );
            normal = rotate90_Xcw( normal );
        }
    }
    // Right
    else if ( dir == 2 ) {
        if ( validInterval( tx, 0, hmap->getWidth() - 1 ) && validInterval( ty, 0, hmap->getHeight() - 1 ) ) {
            GLubyte tHeight = hmap->getPixel( tx, ty ).green;
            normal.setVector( 1 * _patchSize, 0, ( tHeight - iHeight ) / 255.0f * _mapHeight );
            normal = rotate90_Yccw( normal );
        }
        else if ( validInterval( tx, 0, hmap->getWidth() - 1 ) && validInterval( ty - 1, 0, hmap->getHeight() - 1 ) ) {
            GLubyte tHeight = hmap->getPixel( tx, ty - 1 ).alpha;
            normal.setVector( 1 * _patchSize, 0, ( tHeight - iHeight ) / 255.0f * _mapHeight );
            normal = rotate90_Yccw( normal );
        }
    }
    // Left
    else if ( dir == 3 ) {
        if ( validInterval( tx - 1, 0, hmap->getWidth() - 1 ) && validInterval( ty, 0, hmap->getHeight() - 1 ) ) {
            GLubyte tHeight = hmap->getPixel( tx - 1, ty ).red;
            normal.setVector( -1 * _patchSize, 0, ( tHeight - iHeight ) / 255.0f * _mapHeight );
            normal = rotate90_Ycw( normal );
        }
        else if ( validInterval( tx - 1, 0, hmap->getWidth() - 1 ) && validInterval( ty - 1, 0, hmap->getHeight() - 1 ) ) {
            GLubyte tHeight = hmap->getPixel( tx - 1, ty - 1 ).blue;
            normal.setVector( -1 * _patchSize, 0, ( tHeight - iHeight ) / 255.0f * _mapHeight );
            normal = rotate90_Ycw( normal );
        }
    }
    normal.normalize();

    return normal;
}

int HeightfieldScalable::findAvailableTile() {
    if ( _availableTiles.empty() ) {
        return -1;
    }
    int tile = _availableTiles.back();
    _availableTiles.pop_back();
    return tile;
}

void HeightfieldScalable::printActiveRegion() {
    for ( int y = 0; y < 4; ++y ) {
        for ( int x = 0; x < 4; ++x ) {
            std::cout << _tileStates[ x ][ 3 - y ] << "\t";
        }
        std::cout << std::endl;
    }
    for ( int i = 0; i < 9; ++i ) {
        std::cout << _tileOrder[ i ] << " ";
    }
    std::cout << std::endl;
    std::cout << "LL: " << boundsLL.x << " " << boundsLL.y << std::endl;
    std::cout << "BD: " << boundsDIM.x << " " << boundsDIM.y << std::endl;
    std::cout << "LT: " << getLowerLeftX() << " " << getLowerLeftY() << std::endl;
}

void HeightfieldScalable::spawnWorkerThread() {
    // if bpc == 8
    std::thread wkThread{
        [&] {
            std::mutex mtx;
            std::unique_lock < std::mutex > loadSig( mtx );

            while ( !_endThread ) {
                if ( _tilesToLoad.empty() ) {
                    _loadSignal.wait( loadSig );
                }
                std::pair<int, int> tIndices( -1, -1 );
                _loadMutex.lock();
                if ( !_tilesToLoad.empty() ) {
                    tIndices = _tilesToLoad.back();
                    _tilesToLoad.pop_back();
                }
                _loadMutex.unlock();
                if ( tIndices.first != -1 && tIndices.second != -1 ) {
                    preLoadTile( tIndices.first, tIndices.second );
                }
            }
            std::cout << "Thread over." << std::endl;
        }
    };
    // else if bpc == 16
    wkThread.detach();
}
void HeightfieldScalable::closeHeightfield() {
    std::cout << "Closing loading threads.." << std::endl;
    _tilesToLoad.clear();
    _endThread = true;
    _loadSignal.notify_all();
    using namespace std::chrono_literals;
    std::this_thread::sleep_for( 3s );

}


text:
<!DOCTYPE html>

<link type=text/css rel=stylesheet href="//www.gstatic.com/authtoolkit/css/gitkit.css" />

    WELCOME_MESSAGE

redpajama_set_name: RedPajamaGithub


text:
class CreateNewsletters < ActiveRecord::Migration[5.0]
  def change
    create_table :newsletters do |t|

      t.timestamps
    end
  end
end


text:
import { IVector, V } from "./Vector"

export interface IRectangleInterace {
  min: IVector | V,
  max: IVector | V
}

export class Rectangle implements IRectangleInterace {
  min: V
  max: V

  constructor(min: V | IRectangleInterace, max?: V) {
    if (min instanceof V) {
      this.min = min
      this.max = max
    } else {
      let rect = min
      this.min = new V(rect.min)
      this.max = new V(rect.max)
    }
  }

  checkCollision(rect: Rectangle): boolean {
    let rectMin = rect.min
    let thisMin = this.min

    if (
      thisMin.x < rectMin.x + rect.max.x &&
      this.max.x + thisMin.x > rectMin.x &&
      thisMin.y < rect.max.y + rectMin.y &&
      this.max.y + thisMin.y > rectMin.y
    ) {
      return true
    }

    return false
  }

  drawRectangle(origin: V, ctx: CanvasRenderingContext2D) {
    ctx.fillStyle = "rgba(0, 0, 0, 0.4)"
    ctx.fillRect(origin.x + this.min.x, origin.y + this.min.y, this.max.x, this.max.y)
    ctx.fill()
  }
}


text:
package io.cdap.wrangler.utils;

import org.apache.avro.Schema;
import org.apache.commons.collections4.SetValuedMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

import java.io.IOException;

public class AvroSchemaGlossaryTest {
  private static final String AVRO_STR = "{\n"
      + "    \"type\": \"record\",\n"
      + "    \"name\": \"TEST_6_0_0\",\n"
      + "    \"namespace\": \"google.com.datamodels.test\",\n"
      + "    \"_revision\": \"1\",\n"
      + "    \"fields\": []\n"
      + "}";
  private static final String REVISION_TWO_AVRO_STR = "{\n"
      + "    \"type\": \"record\",\n"
      + "    \"name\": \"TEST_6_0_0\",\n"
      + "    \"namespace\": \"google.com.datamodels.test\",\n"
      + "    \"_revision\": \"2\",\n"
      + "    \"fields\": []\n"
      + "}";
  private static final String DUMMY_SCHEMA = "{\n"
      + "    \"type\": \"record\",\n"
      + "    \"name\": \"TEST_6_0_1\",\n"
      + "    \"namespace\": \"google.com.datamodels.test\",\n"
      + "    \"_revision\": \"1\",\n"
      + "    \"fields\": []\n"
      + "}";
  private static final String SCHEMA_NAME = "google.com.datamodels.test.TEST_6_0_0";
  private static final String DUMMY_NAME = "google.com.datamodels.test.TEST_6_0_1";

  private class StubSchemaLoader implements AvroSchemaLoader {

    StubSchemaLoader(){}

    @Override
    public SetValuedMap<String, Schema> load() throws IOException {
      return new HashSetValuedHashMap<>();
    }
  }

  @Test
  public void testConfigure_schema_successulLoad() throws IOException {
    StubSchemaLoader loader = Mockito.mock(StubSchemaLoader.class);
    Mockito.when(loader.load()).thenReturn(new HashSetValuedHashMap<>());
    AvroSchemaGlossary glossary = new AvroSchemaGlossary(loader);
    Assert.assertTrue(glossary.configure());
  }

  @Test
  public void testConfigure_schema_failureLoading() throws IOException {
    StubSchemaLoader loader = Mockito.mock(StubSchemaLoader.class);
    Mockito.doThrow(new IOException()).when(loader).load();

    AvroSchemaGlossary glossary = new AvroSchemaGlossary(loader);
    Assert.assertFalse(glossary.configure());
  }

  @Test
  public void testGet_schema_successful() throws IOException {
    Schema.Parser parser = new Schema.Parser().setValidate(false);
    SetValuedMap<String, Schema> expected = new HashSetValuedHashMap<>();
    expected.put(SCHEMA_NAME, parser.parse(AVRO_STR));

    StubSchemaLoader loader = Mockito.mock(StubSchemaLoader.class);
    Mockito.when(loader.load()).thenReturn(expected);

    AvroSchemaGlossary glossary = new AvroSchemaGlossary(loader);
    Assert.assertTrue(glossary.configure());
    Assert.assertEquals(SCHEMA_NAME, glossary.get(SCHEMA_NAME, 1L).getFullName());
  }

  @Test
  public void testGet_schema_notFoundInGlossary() throws IOException {
    SetValuedMap<String, Schema> expected = new HashSetValuedHashMap<>();
    StubSchemaLoader loader = Mockito.mock(StubSchemaLoader.class);
    Mockito.when(loader.load()).thenReturn(expected);

    AvroSchemaGlossary glossary = new AvroSchemaGlossary(loader);
    Assert.assertTrue(glossary.configure());
    Assert.assertNull(glossary.get(SCHEMA_NAME, 0L));
  }

  @Test
  public void testGet_schema_unknownVersion() throws IOException {
    Schema.Parser parser = new Schema.Parser().setValidate(false);
    SetValuedMap<String, Schema> expected = new HashSetValuedHashMap<>();
    expected.put(SCHEMA_NAME, parser.parse(AVRO_STR));

    StubSchemaLoader loader = Mockito.mock(StubSchemaLoader.class);
    Mockito.when(loader.load()).thenReturn(expected);

    AvroSchemaGlossary glossary = new AvroSchemaGlossary(loader);
    Assert.assertTrue(glossary.configure());
    Assert.assertNull(glossary.get(SCHEMA_NAME, 99L));
  }

  @Test
  public void testGetAll_schema_populatedCollection() throws IOException {
    Schema.Parser parser = new Schema.Parser().setValidate(false);
    SetValuedMap<String, Schema> expected = new HashSetValuedHashMap<>();
    expected.put(SCHEMA_NAME, parser.parse(AVRO_STR));
    expected.put(SCHEMA_NAME, new Schema.Parser().setValidate(false).parse(REVISION_TWO_AVRO_STR));
    expected.put(DUMMY_NAME, parser.parse(DUMMY_SCHEMA));

    StubSchemaLoader loader = Mockito.mock(StubSchemaLoader.class);
    Mockito.when(loader.load()).thenReturn(expected);

    AvroSchemaGlossary glossary = new AvroSchemaGlossary(loader);
    Assert.assertTrue(glossary.configure());
    Assert.assertEquals(3, glossary.getAll().size());
  }

  @Test
  public void testGetAll_multipleRevisions_populatedCollection() throws IOException {
    SetValuedMap<String, Schema> expected = new HashSetValuedHashMap<>();
    expected.put(SCHEMA_NAME, new Schema.Parser().setValidate(false).parse(AVRO_STR));
    expected.put(SCHEMA_NAME, new Schema.Parser().setValidate(false).parse(REVISION_TWO_AVRO_STR));

    StubSchemaLoader loader = Mockito.mock(StubSchemaLoader.class);
    Mockito.when(loader.load()).thenReturn(expected);

    AvroSchemaGlossary glossary = new AvroSchemaGlossary(loader);
    Assert.assertTrue(glossary.configure());
    Assert.assertEquals(2, glossary.getAll().size());
  }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <string-array name="otr_options">
        <item>Force / vereisen</item>
        <item>Automatisch proberen</item>
        <item>Zoals gevraagd</item>
        <item>Gehandicapten / nooit</item>
    </string-array>
</resources>


text:
/*
* Chris Samuel
* ksamuel.chris@gmail.com
*
* fileName : main.js
*
* The main.js is the entry point for our React application. We use it in gulpfile.js where Browserify will traverse the entire
* tree of dependencies and generate the final bundle.js file. You will rarely have to touch this file after its initial setup.
*
* */

import React from 'react';
import Router from 'react-router';
import routes from './routes';

Router.run(routes, Router.HistoryLocation, function(Handler) {
    React.render(<Handler />, document.getElementById('app'));
});

//File Breakdown

/*
*HistoryLocation
*   to enable HTML5 History API in order to make URLs look pretty. For example, it navigates to http://localhost:3000/add instead of http://localhost:3000/#add. Since we are building an Isomorphic React application (rendered on the server and the client) we do not have to do any hacky
*   wildcard redirects
 *
 *
 *
 *  on the server to enable this support. It just works out of the box.
*
*
* */


text:
package com.arpnetworking.commons.akka;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.ActorRefFactory;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

/**
 * Tests for the ActorProvider class.
 *
 * @author Brandon Arp (brandon dot arp at inscopemetrics dot io)
 */
public final class ActorProviderTest {

    @Test
    public void testBuildsInRefFactory() {
        final String path = "testChild";
        final ActorRefFactory refFactory = Mockito.mock(ActorRefFactory.class);
        final ActorProvider provider = new ActorProvider(path, TestActor.class, refFactory);
        provider.get();
        Mockito.verify(refFactory).actorOf(Mockito.any(), Mockito.eq(path));
    }

    @Test
    public void testInjectorIsInjectedWithBinding() {
        final String path = "testChild";
        final ActorRefFactory refFactory = Mockito.mock(ActorRefFactory.class);
        final ActorProvider actorProvider = new ActorProvider(path, TestActor.class, refFactory);
        final AbstractModule mod = new TestActorBuilderModule(actorProvider);
        final Injector injector = Guice.createInjector(mod);
        injector.getInstance(ActorRef.class);
        Assert.assertSame(injector, actorProvider.getInjector());
    }

    private static class TestActor extends AbstractActor {

        @Override
        public Receive createReceive() {
            return receiveBuilder().build();
        }
    }

    private static class TestActorBuilderModule extends AbstractModule {

        TestActorBuilderModule(final ActorProvider actorProvider) {
            _actorProvider = actorProvider;
        }

        @Override
        protected void configure() {
            bind(ActorRef.class).toProvider(_actorProvider);
        }

        private final ActorProvider _actorProvider;
    }
}


text:
@interface MCProperties : NSObject

+(NSString *) getValueOfProperty: (NSString *) property;

+(NSNumber *) getNumberValueOfProperty: (NSString *) property;

+(NSArray *) getArrayOfProperty: (NSString *) property;

+(NSDictionary *) getDictionaryOfProperty: (NSString *) property;

+(BOOL) getBoolOfProperty: (NSString *) property;

@end


text:
Template.layoutModern.events({
  'click #content, click aside': function(e) {
    Aside.hide();
    hideBalloons();
  }
});


text:
#ifndef THIRD_PARTY_TENSORFLOW_CORE_KERNELS_TILE_OPS_CPU_IMPL_H_
#define THIRD_PARTY_TENSORFLOW_CORE_KERNELS_TILE_OPS_CPU_IMPL_H_

#define EIGEN_USE_THREADS

#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/kernels/tile_ops_impl.h"

namespace tensorflow {
namespace functor {

typedef Eigen::ThreadPoolDevice CPUDevice;

// Register functors used for TileOp.
#define DEFINE_DIM(T, NDIM) template struct Tile<CPUDevice, T, NDIM>;
#define DEFINE_TYPE(T) DEFINE_DIM(T, CPU_PROVIDED_IXDIM)

TF_CALL_bool(DEFINE_TYPE);
TF_CALL_float(DEFINE_TYPE);
TF_CALL_double(DEFINE_TYPE);
TF_CALL_uint8(DEFINE_TYPE);
TF_CALL_int32(DEFINE_TYPE);
TF_CALL_int16(DEFINE_TYPE);
TF_CALL_int64(DEFINE_TYPE);
TF_CALL_half(DEFINE_TYPE);
TF_CALL_complex64(DEFINE_TYPE);
TF_CALL_complex128(DEFINE_TYPE);
TF_CALL_string(DEFINE_TYPE);

#undef DEFINE_DIM
#undef DEFINE_TYPE

// Register functors used for TileGradientOp.
#define DEFINE_DIM(T, NDIM)                     \
  template struct TileGrad<CPUDevice, T, NDIM>; \
  template struct ReduceAndReshape<CPUDevice, T, NDIM, 1>;
#define DEFINE_TYPE(T) DEFINE_DIM(T, CPU_PROVIDED_IXDIM)

TF_CALL_float(DEFINE_TYPE);
TF_CALL_double(DEFINE_TYPE);
TF_CALL_int16(DEFINE_TYPE);
TF_CALL_int32(DEFINE_TYPE);
TF_CALL_int64(DEFINE_TYPE);
TF_CALL_half(DEFINE_TYPE);
TF_CALL_complex64(DEFINE_TYPE);
TF_CALL_complex128(DEFINE_TYPE);

#undef DEFINE_DIM
#undef DEFINE_TYPE

#ifdef TENSORFLOW_USE_SYCL
typedef Eigen::SyclDevice SYCLDevice;

// Register functors used for TileOp.
#define DEFINE_DIM(T, NDIM) template struct Tile<SYCLDevice, T, NDIM>;
#define DEFINE_TYPE(T) DEFINE_DIM(T, CPU_PROVIDED_IXDIM)

TF_CALL_float(DEFINE_TYPE);

#undef DEFINE_DIM
#undef DEFINE_TYPE

// Register functors used for TileGradientOp.
#define DEFINE_DIM(T, NDIM)                      \
  template struct TileGrad<SYCLDevice, T, NDIM>; \
  template struct ReduceAndReshape<SYCLDevice, T, NDIM, 1>;
#define DEFINE_TYPE(T) DEFINE_DIM(T, CPU_PROVIDED_IXDIM)

TF_CALL_float(DEFINE_TYPE);

#undef DEFINE_DIM
#undef DEFINE_TYPE
#endif // TENSORFLOW_USE_SYCL

}  // end namespace functor
}  // end namespace tensorflow

#endif  // THIRD_PARTY_TENSORFLOW_CORE_KERNELS_TILE_OPS_CPU_IMPL_H_


text:
function smoothblockcline2gmt(h, outname, cpt)
% SMOOTHBLOCKCLINE2GMT  Converts all blocks plotted using SMOOTHBLOCKCLINE to GMT format.
%   CLINE2GMT(H, OUTNAME), where H is the handle produced by MYCLINE,
%   converts the segment data into a format useable in GMT and writes
%   them to OUTNAME.xy.  The output produced can be plotted using a
%   straight up PSXY command, as the pen attributes are fully
%   specified.
%
%   CLINE2GMT(H, OUTNAME, CPT) also writes a GMT colormap file, with
%   limits as specified in the Matlab figure, based on the colormap
%   given by CPT.  CPT can be any valid GMT colormap file.  Note that
%   adding a ' -I' after the .cpt name allows an inverse colormap to
%   be produced.  In this case, only the color table lookup is given
%   in each segment's header line, requiring the use of the "-C" option
%   with PSXY.
%

% Get color info
C = get(h, 'cdata'); % Segment colors
ax = get(h, 'parent'); % Axis handle
cols = floor(255*colormap(ax)); % Colormap, converted to 0-256
m = size(cols, 1); % length of current colormap
clims = get(ax, 'clim'); % Current color limits
index = fix((C-clims(1))/diff(clims)*(m-1))+1; % Get indices of each segment value
index(index < 1) = 1; index(index > m) = m;

% Get coordinate info
x = get(h, 'xdata');
y = get(h, 'ydata');

% Make specific coordinate array
nc = size(x, 1);
coords = zeros(2*nc, size(x, 2));
coords(1:2:end, :) = x;
coords(2:2:end, :) = y;

fid = fopen([outname '.xy'], 'w');
% Write out
if ~exist('cpt', 'var') % option 1: full pen specification
   out = [cols(index, 1)'; cols(index, 2)'; cols(index, 3)'; coords];
   fprintf(fid, ['> -G%d/%d/%d\n' repmat('%d %d\n', 1, nc)], out);
else
   out = [C'; coords];
   fprintf(fid, ['> -Z%d\n' repmat('%d %d\n', 1, nc)], out);
   cptfile = [outname '.cpt'];
   cptcom = sprintf('makecpt -C%s -T%d/%d/1 > %s', cpt, clims(1), clims(2), cptfile);
   system(cptcom);
end
fclose(fid);


text:
package com.flyingosred.app.perpetualcalendar.database.xml;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

public class XmlHelper {

    private static int INDENT_SIZE = 4;

    public static Document createDocument() {
        return DocumentHelper.createDocument();
    }

    public static void addComment(Document document) {
        document.addComment("Copyright (C) 2016 Osred Brockhoist <osred.brockhoist@hotmail.com>. All Rights Reserved.");
        document.addComment("This file is auto-generated");
        document.addComment("DO NOT MODIFY");
    }

    public static Element createRootElement(Document document, String rootName) {
        Element root = document.addElement(rootName);
        return root;
    }

    public static Element createElement(Element parent, String name, String value) {
        return parent.addElement(name).addText(value);
    }

    public static Element createElement(Element parent, String name) {
        return parent.addElement(name);
    }

    public static void outputFile(String path, Document document) {
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setIndentSize(INDENT_SIZE);
        XMLWriter writer;
        try {
            writer = new XMLWriter(new FileOutputStream(path), format);
            writer.write(document);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void createXmlFile(String path, String rootName, String element, String elementName, String item,
            List<String> itemNameList) {
        Document document = DocumentHelper.createDocument();
        document.addComment("Copyright (C) 2016 Osred Brockhoist <osred.brockhoist@hotmail.com>. All Rights Reserved.");
        document.addComment("This file is auto-generated");
        document.addComment("DO NOT MODIFY");
        Element root = document.addElement(rootName);
        Element rootElement = root.addElement(element).addAttribute("name", elementName);
        for (String itemName : itemNameList) {
            rootElement.addElement(item).addText(itemName);
        }
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setIndentSize(INDENT_SIZE);
        XMLWriter writer;
        try {
            writer = new XMLWriter(new FileOutputStream(path), format);
            writer.write(document);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void createXmlFile(String path, String rootName, String element, Map<String, String> elementValues) {
        Document document = DocumentHelper.createDocument();
        document.addComment("Copyright (C) 2016 Osred Brockhoist <osred.brockhoist@hotmail.com>. All Rights Reserved.");
        document.addComment("This file is auto-generated");
        document.addComment("DO NOT MODIFY");
        Element root = document.addElement(rootName);
        for (Map.Entry<String, String> entry : elementValues.entrySet()) {
            root.addElement(element).addAttribute("name", entry.getKey()).addText(entry.getValue());
        }
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setIndentSize(INDENT_SIZE);
        XMLWriter writer;
        try {
            writer = new XMLWriter(new FileOutputStream(path), format);
            writer.write(document);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}


text:
/* TEMPLATE GENERATED TESTCASE FILE
Filename: CWE127_Buffer_Underread__new_char_memmove_63b.cpp
Label Definition File: CWE127_Buffer_Underread__new.label.xml
Template File: sources-sink-63b.tmpl.cpp
*/
/*
 * @description
 * CWE: 127 Buffer Under-read
 * BadSource:  Set data pointer to before the allocated memory buffer
 * GoodSource: Set data pointer to the allocated memory buffer
 * Sinks: memmove
 *    BadSink : Copy data to string using memmove
 * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files
 *
 * */

#include "std_testcase.h"

#include <wchar.h>

namespace CWE127_Buffer_Underread__new_char_memmove_63
{

#ifndef OMITBAD

void badSink(char * * dataPtr)
{
    char * data = *dataPtr;
    {
        char dest[100];
        memset(dest, 'C', 100-1); /* fill with 'C's */
        dest[100-1] = '\0'; /* null terminate */
        /* POTENTIAL FLAW: Possibly copy from a memory location located before the source buffer */
        memmove(dest, data, 100*sizeof(char));
        /* Ensure null termination */
        dest[100-1] = '\0';
        printLine(dest);
        /* INCIDENTAL CWE-401: Memory Leak - data may not point to location
         * returned by new [] so can't safely call delete [] on it */
    }
}

#endif /* OMITBAD */

#ifndef OMITGOOD

/* goodG2B uses the GoodSource with the BadSink */
void goodG2BSink(char * * dataPtr)
{
    char * data = *dataPtr;
    {
        char dest[100];
        memset(dest, 'C', 100-1); /* fill with 'C's */
        dest[100-1] = '\0'; /* null terminate */
        /* POTENTIAL FLAW: Possibly copy from a memory location located before the source buffer */
        memmove(dest, data, 100*sizeof(char));
        /* Ensure null termination */
        dest[100-1] = '\0';
        printLine(dest);
        /* INCIDENTAL CWE-401: Memory Leak - data may not point to location
         * returned by new [] so can't safely call delete [] on it */
    }
}

#endif /* OMITGOOD */

} /* close namespace */


text:
package project;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.xml.sax.Attributes;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

class Piece {
	String name;
	String color;
	String position;

	public Piece(String name, String color, String position) {
		super();
		this.name = name;
		this.color = color;
		this.position = position;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Piece))
			return false;

		Piece objPiece = (Piece) obj;

		return (objPiece.name.equals(name) && objPiece.color.equals(color));
	}

	@Override
	public String toString() {
		if(position == null)
			return String.format("%s %s", color, name.toLowerCase());
		return String.format("%s %s: %s", color, name.toLowerCase(), position);
	}

}

class Task1Handler extends DefaultHandler {
	List<Piece> pieces = new ArrayList<>();

	public void startElement(String uri, String localName, String qName,
			Attributes atts) {
		if ("piece".equals(localName)) {
			pieces.add(new Piece(atts.getValue("name"), atts.getValue("color"),
					atts.getValue("position")));
		}
	}
}

public class Task1 {

	public static void main(String[] args) {

		// create list of all pieces
		String[] pices_names = new String[] { "Pawn", "Knight", "Bishop",
				"Rook", "Queen", "King" };
		String[] colors_names = new String[] { "Black", "White" };
		List<Piece> pieces = new ArrayList<>();

		for(String name : pices_names) {
			for(String color : colors_names) {
				pieces.add(new Piece(name, color, null));
			}
		}

		Task1Handler handler = new Task1Handler();
		try {
			XMLReader reader = XMLReaderFactory.createXMLReader();
			reader.setContentHandler(handler);
			reader.parse("task1.xml");
		} catch (Exception e) {
			System.err.println(e);
		}

		System.out.println("Pieces:");
		for (Piece item : handler.pieces) {
			System.out.println(item);
		}
		System.out.println("\nMissing:");
		for (Piece item : pieces) {
			if(!handler.pieces.contains(item)) {
				System.out.println(item);
			}
		}
	}
}


text:
.charsheet button[type="roll"] {border:none; background:transparent; margin:0; padding:0; text-shadow:none !important; box-shadow:none !important;}
.ui-dialog .charsheet {padding: 0;}
.ui-dialog .charsheet button[type=roll]:before {content: "";}
.ui-dialog .charsheet button[type=roll], .ui-dialog .charsheet button[type=compendium] {padding: 0;}
.charsheet * {font-family: ;}
input, textarea, select, .uneditable-input {margin:0; padding:0; width: 100%; background-color: transparent; border-bottom: 0.5px solid var(--Liberl); padding-top: 2px; border-radius: 5px; color: rgba(255, 255, 255, 0.5); border-top: none;}
input[type="text"] {}
input[type="checkbox"] {height: ;}
input[type="number"] {padding-top: 3px !important; width: 100% !important;}
input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {-webkit-appearance: none; margin: 0;}
textarea {margin: 0 !important; width: 100%; resize: none;}
.nav {margin-bottom: 0px;}
.nav-tabs {border-bottom: none;}
.nav-tabs>li:not(.active)>a, .nav-tabs>li:not(.active)>a:hover, .nav-tabs>li:not(.active)>a:focus {color: var(--Liberl);}
.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {color: #555; background-color: var(--Liberl); border: none;}
.characterviewer label {font-weight: normal; margin-bottom: 0px; }
.largedialog label {width: auto;}
input::-webkit-calendar-picker-indicator {display: none !important;}
select, option {text-align: center; height: 100%; width: auto;}
.repcontrol_add, .repcontrol_edit, .repcontrol_move, .repcontrol_del, .itemcontrol {z-index: 100;}
.sheetform {background-color: transparent; color: var(--Liberl);}
.charsheet span {padding: 3px 5px;}
.ui-dialog {background-color: #1f1f1f; --Liberl:#1fcbff; --liberl:rgba(31, 203, 255, 0.5);}
.sheet-kiseki {--Liberl:#ff1fa4; --liberl:rgba(255, 31, 164, 0.5);}

/* ===== BOX LAYOUT ===== */
input {text-align: center;}
textarea {padding-left: 3px; width: calc(100% - 5px) !important;}
.sheet-type button[type="roll"] {background-color: var(--Liberl);}
.sheet-type {display: none; margin-bottom: 25px; color: var(--Liberl);}
.shtte-type>div:first-child>div * {height: 100%;}
input[name="attr_type"]:checked+div {display: block;}
.sheet-flexbox {display: flex; flex-wrap: wrap;}
.sheet-flexbox>.sheet-flexbox {align-items: center;}
.sheet-flexbox>div {flex: 1; text-align: center;}
.sheet-inputbox {display: grid; grid-template-columns: auto 1fr; align-items: center;}
[class$="box"] span, [class$="box"] button {word-break: keep-all;}
.ui-dialog .charsheet .sheet-often button[type=roll] {margin: 0px 1px 0px 1px;}

.sheet-profile {display: flex; flex-direction: column;}
.sheet-memo {flex: 1;}
div .sheet-kizuna {text-align: center; flex: 0.33;}
.sheet-kizuna>div, .sheet-kizuna summary {display: grid; grid-template-columns: auto 1fr auto 30px; gap: 5px; place-items: center;}
.sheet-kizuna summary>span:first-child {cursor: pointer;}
.sheet-kizuna>div {place-items: center;}
.sheet-kizuna span, .sheet-bullet span, .sheet-kizuato span {padding: 0;}
/*.sheet-skill input, .sheet-kizuato input, .sheet-enemy input {border: none;}*/
.sheet-color {position: relative;}
.sheet-color input[type="checkbox"] {opacity: 0; z-index: 10; position: absolute; width: 100%;}
.sheet-color input[type="checkbox"]:checked+span {color: rgba(255, 255, 255, 1.0);}
.sheet-color input[type="checkbox"]:not(:checked)+span {color: rgba(255, 255, 255, 0.1);}

button.sheet-make {font-size: 1em; margin: 0; background-color: transparent; color: inherit;}
input.sheet-battletype:not(:checked)+.sheet-skill {display: none;}
.sheet-bullet button {font-size: 1.0em !important; padding: 0px !important; margin: 1px 0px !important;}
.sheet-bullet summary {color: white;}
.sheet-bullet details+details>summary {text-align: right;}
.sheet-skill, .sheet-bullet .repcontainer {display: flex; flex-wrap: wrap; text-align: center; color: rgba(255, 255, 255, 0.5);}

.sheet-bullet .repcontainer>div {flex: 1;}
.sheet-skill>div:not(.repcontainer) {max-width: 400px; min-width: 50%;}
.sheet-skill>div:not(.repcontainer), .sheet-es {display: grid; grid-template-columns: repeat(4, 1fr); align-items: center;}
.sheet-skill .sheet-title {color: var(--Liberl);}
.sheet-skill select {border: none; font-weight: normal; color: var(--Liberl);}
.sheet-skill .sheet-autoex, .sheet-es .sheet-autoex {grid-column: span 4;}

.sheet-bullet .repcontainer>div {flex: 1;}
.sheet-kiseki input[name*="esname"] {background-color: var(--Liberl); color: #1f1f1f; border: none;}
.sheet-button {display: grid; grid-template-columns: 19px 1fr;}
.sheet-bullet {position: relative;}
.sheet-invisible {width: 100% !important; height: 1.2em; opacity: 0; z-index: 10; position: absolute;}
input.sheet-battletype+label {color: white; text-align: center; z-index: 1;}
input.sheet-battletype:not(:checked)+label:before, input.sheet-battletype:checked+label:hover {content: "서포트";}
input.sheet-battletype:checked+label:before, input.sheet-battletype:not(:checked)+label:hover {content: "어택";}

.sheet-kizuato {margin-top: 5px; display: grid; grid-template-columns: 1fr 0.5fr 0.5fr 1fr 1fr 0.5fr 0.5fr 1fr; text-align: center;}
.sheet-kizuato>button {grid-row: span 2; font-size: 1.5em;}
.sheet-kizuato>button+input {grid-column: span 4; grid-row: span 2; font-size: 2.0em; color: var(--Liberl); border: none;}
.sheet-kizuato>.sheet-double {grid-column: span 2;}
.sheet-kizuato>.sheet-autoex {grid-column: span 4;}

.sheet-enemy {display: grid; grid-template-columns: 1fr 0.5fr 0.5fr 1fr;}
.sheet-enemy>input:first-child {grid-column: span 2; grid-row: span 2; font-size: 2.0em; color: var(--Liberl); border: none;}
.sheet-enemy>button {grid-row: span 2;}
.sheet-enemy>.sheet-double {grid-column: span 2;}
.sheet-enemy>.sheet-autoex {grid-column: span 4;}

input[name="attr_ruby"] {font-size: 0.8em;}
.sheet-hidden {display: none;}
div>textarea {height: 100% !important;}
div>.sheet-quarter {flex: 0.25;}
div>.sheet-half {flex: 0.5;}
.ui-dialog .charsheet .sheet-type .sheet-make[type="roll"] {font-size: 1em; margin: 0; background-color: transparent; color: inherit; text-align: center;}
.ui-dialog .charsheet .sheet-type .sheet-make[type="roll"]:hover, .ui-dialog .charsheet .sheet-type .sheet-make[type="roll"]:focus {color: white;}
/* ===== AUTO EXPAND TEXTAREA ===== */
.sheet-autoex {
    position: relative;
    cursor: text;
    font-family: "영어폰트","일본어폰트","한글폰트";
    /*font-size: 1.0em;*/
    /*line-height: 1.5em;*/
    min-height: 2.0em;
    text-align: left;
    margin-bottom: 5px;
    width: 100%;
}
.sheet-autoex span {
    visibility: hidden;
    display: block;
    font-family: inherit;
    /*font-size: inherit;*/
    line-height: inherit;
    white-space: pre-wrap;
    text-align: inherit;
    min-height: inherit;
    min-height: inherit;
    /*background-color: transparent;*/
}
.sheet-autoex textarea {
    display: block;
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    overflow: hidden;
    font-family: inherit;
    /*font-size: inherit;*/
    line-height: inherit;
    white-space: pre-wrap;
    /*text-align: inherit;*/
    min-height: inherit;
    margin: 10px;
    border-radius: 5px;
    box-sizing: content-box;
    /*border: none;*/
}

input:focus, input:hover, textarea:focus, textarea:hover, select:hover, select:focus {background-color: var(--liberl); outline: none; color: white;}
button[type="roll"]:focus, button[type="roll"]:hover {background-color: white; color: var(--Liberl);}
label:focus, label:hover {text-shadow: 0px 0px 3px var(--Liberl), 0px 0px 3px var(--Liberl),, 0px 0px 3px var(--Liberl),, 0px 0px 3px var(--Liberl), 0px 0px 3px var(--Liberl); color:black;}

/* ===== ROLL TEMPLATE ===== */

.sheet-rolltemplate-kb .inlinerollresult, .sheet-rolltemplate-kb .inlinerollresult.fullcrit, .sheet-rolltemplate-kb .inlinerollresult.fullfail, .sheet-rolltemplate-kb .inlinerollresult.importantroll {background-color: transparent; border: none;}

.sheet-rolltemplate-kb>div {width: 100%px;
  background-color:#00acee;
  border-radius: 10px;
  padding: 5px 0px 5px 5px;}
.sheet-rolltemplate-kb .sheet-name {display: grid;
  grid-template-columns: 25px 1fr;
  padding-bottom: 10px;
}
.sheet-rolltemplate-kb .sheet-name>div:nth-child(1) {grid-row: span 2;
    padding: 0px 5px;
  writing-mode: tb-rl;
  text-align: center;
  font-size: 1.5em;
  color: white;
}
.sheet-rolltemplate-kb .sheet-name>div:nth-child(2) {text-align: right;
  padding-right: 10px;
  font-size: 0.5em;
  padding-bottom: 5px;}
.sheet-rolltemplate-kb .sheet-name>div:nth-child(3) {
  padding-left: 10px;
  font-size: 2.0em;
  line-height: 1.5em;
  color: white;
  background-color: black;
  border-radius: 25px 0 0 25px;
}

.sheet-rolltemplate-kb .sheet-prop {
  display: flex;
  flex-wrap: wrap;
}
.sheet-rolltemplate-kb .sheet-prop>div {
  margin: 5px 0px;
}
.sheet-rolltemplate-kb .sheet-prop>div>span:nth-child(odd) {
  background-color: white;
  color: #00acee;
  border-radius: 15px;
  padding: 3px 5px 2px 5px;
}
.sheet-rolltemplate-kb .sheet-prop>div>span:nth-child(even) {
  border-radius: 10px;
  padding: 0px 5px;
}
.sheet-rolltemplate-kb .sheet-detail {
  margin: 5px;
  color: white;
}
.sheet-rolltemplate-kb .sheet-result {
    color: black;
}


text:
class Metric(object):
    '''
    Interface class for the various metrics.
    '''

    def calculate(self, node):
        '''
        Calculate the metric for the given node. A metric may be a number,
        a string or any other measurable value about the code.
        '''

        raise NotImplementedError('{}.calculate'.format(type(self).__name__))

    def get_metric_name(self):
        '''
        Return a string containing the full name of the metric.
        '''

        raise NotImplementedError('{}.get_metric_name'.format(type(self).__name__))


text:
package io.dockstore.webservice.resources;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.ws.rs.NameBinding;

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface UsernameRenameRequired {

}


text:
const path = require('path');
const assert = require('assert');
const nock = require('nock');
const common = require('../../../common.js');
const {runTests} = common.require('index.js');

xdescribe('Cucumber  Browserstack integration', function() {

  before(function(done) {
    try {
      nock.activate();
    // eslint-disable-next-line no-empty
    } catch (err) {
    }

    nock('https://hub-cloud.browserstack.com')
      .post('/wd/hub/session')
      .reply(201, {
        status: 0,
        sessionId: '1352110219202',
        value: {
          browserName: 'chrome'
        }
      });

    nock('https://api.browserstack.com')
      .get('/automate/builds.json')
      .reply(200, []);

    nock('https://hub-cloud.browserstack.com')
      .post('/wd/hub/session/1352110219202/url')
      .reply(200, {
        value: null
      });

    nock('https://hub-cloud.browserstack.com')
      .post('/wd/hub/session/1352110219202/elements')
      .reply(200, {
        status: 0,
        sessionId: '1352110219202',
        value: [{
          'ELEMENT': '0'
        }]
      });

    nock('https://hub-cloud.browserstack.com')
      .delete('/wd/hub/session/1352110219202')
      .reply(200, {
        value: []
      });

    done();
  });

  after(function(done) {
    nock.restore();
    done();
  });

  it('testCucumberSampleTests - [Passed]', function() {

    nock('https://api.browserstack.com')
      .put('/automate/sessions/1352110219202.json', body => body.status === 'passed')
      .reply(200);

    const source = [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')];

    return runTests({
      source,
      tags: ['@pass'],
      verbose: false,
      config: path.join(__dirname, '../../../extra/cucumber-config.js'),
      env: 'browserstack'
    }, {}).then(failures => {
      assert.strictEqual(failures, false, 'Cucumber has test failures. Run with verbose to investigate.');
    });
  });

  it('testCucumberSampleTests with failures', function() {

    nock('https://api.browserstack.com')
      .put('/automate/sessions/1352110219202.json', body => body.status === 'failed')
      .reply(200);

    const source = [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testWithFailures.js')];

    return runTests({
      source,
      env: 'browserstack',
      tags: ['@fail'],
      verbose: false,
      config: path.join(__dirname, '../../../extra/cucumber-config.js')
    }, {}).then(failures => {
      assert.strictEqual(failures, true, 'Cucumber tests should have failed. Run with verbose to investigate.');
    });
  });
});


text:
int main(void)
{
	// ports and io
	ConfigureDisplay();
	ConfigurePushButtons();
	ConfigureUART();
	ConfigureI2C();
	ConfigureExternalEEPROM();
	InitAnim();

	sei();

	for(;;)
    {
		if(GetPendingSerialDataSize())
		{
			DispatchSerialCommand();
			ResetIdleTime();
		}
		else if(g_CommandReg.AnimPlaying)
		{
			DispatchAnimCommand();
			ResetIdleTime();
		}

		PumpAck();
	}
}


text:
require_dependency "qe/application_helper"

module Qe
	module ReferenceSheetsHelper
	end
end