text:
const char *WINDOWTITLE = { "OpenCL/OpenGL Particle System -- Joe Parallel" };
const char *GLUITITLE   = { "User Interface Window" };

// random parameters:

const float XMIN =  { -100.0 };
const float XMAX =  {  100.0 };
const float YMIN =  { -100.0 };
const float YMAX =  {  100.0 };
const float ZMIN =  { -100.0 };
const float ZMAX =  {  100.0 };

const float VMIN =  {   -100. };
const float VMAX =  {    100. };

const int NUM_PARTICLES = 1024*1024;
const int LOCAL_SIZE    = 32;
const char *CL_FILE_NAME   = { "particles.cl" };
const char *CL_BINARY_NAME = { "particles.nv" };

const int GLUITRUE  = { true  };
const int GLUIFALSE = { false };

#define ESCAPE    0x1b

const int INIT_WINDOW_SIZE = { 700 };   // window size in pixels

const float ANGFACT = { 1. };
const float SCLFACT = { 0.005f };
const float MINSCALE = { 0.001f };

const int LEFT   = { 4 };
const int MIDDLE = { 2 };
const int RIGHT  = { 1 };

enum Projections
{
  ORTHO,
  PERSP
};

enum ButtonVals
{
  GO,
  PAUSE,
  RESET,
  QUIT
};

const float BACKCOLOR[ ] = { 0., 0., 0., 0. };

const GLfloat AXES_COLOR[ ] = { 1., .5, 0. };
const GLfloat AXES_WIDTH   = { 3. };

//
// structs we will need later:

struct xyzw
{
  float x, y, z, w;
};

struct rgba
{
  float r, g, b, a;
};

// non-constant global variables:

int ActiveButton;   // current button that is down
GLuint  AxesList;   // list to hold the axes
int AxesOn;     // ON or OFF
GLUI *  Glui;     // instance of glui window
int GluiWindow;   // the glut id for the glui window
int MainWindow;   // window id for main graphics window
int Paused;
GLfloat RotMatrix[4][4];  // set by glui rotation widget
float Scale, Scale2;    // scaling factors
GLuint  SphereList;
int WhichProjection;  // ORTHO or PERSP
int Xmouse, Ymouse;   // mouse values
float Xrot, Yrot;   // rotation angles in degrees
float TransXYZ[3];    // set by glui translation widgets

double  ElapsedTime;
int   ShowPerformance;

size_t GlobalWorkSize[3] = { NUM_PARTICLES, 1, 1 };
size_t LocalWorkSize[3]  = { LOCAL_SIZE,    1, 1 };

GLuint      hPobj;
GLuint      hCobj;
cl_mem      dPobj;
cl_mem      dCobj;
struct xyzw * hVel;
cl_mem      dVel;
cl_command_queue  CmdQueue;
cl_device_id    Device;
cl_kernel   Kernel;
cl_platform_id    Platform;
cl_program    Program;
cl_platform_id    PlatformID;

//
// function prototypes:
//

inline
float
SQR( float x )
{
  return x * x;
}

void  Animate( );
void  Axes( float );
void  Buttons( int );
void  Display( );
void  DoRasterString( float, float, float, char * );
void  DoStrokeString( float, float, float, float, char * );
void  InitCL( );
void  InitGlui( );
void  InitGraphics( );
void  InitLists( );
bool  IsCLExtensionSupported( const char * );
void  Keyboard( unsigned char, int, int );
void  MouseButton( int, int, int, int );
void  MouseMotion( int, int );
void  PrintCLError( cl_int, char * = "", FILE * = stderr );
void  Quit( );
float Ranf( float, float );
void  Reset( );
void  ResetParticles( );
void  Resize( int, int );
void  Traces( int );
void  Visibility( int );

//
// main Program:
//

int
main( int argc, char *argv[ ] )
{
  glutInit( &argc, argv );
  InitGraphics( );
  InitLists( );
  InitCL( );
  Reset( );
  InitGlui( );
  glutMainLoop( );
  return 0;
}

void
Animate( )
{
  cl_int  status;
  double time0, time1;

  // acquire the vertex buffers from opengl:

  glutSetWindow( MainWindow );
  glFinish( );

  status = clEnqueueAcquireGLObjects( CmdQueue, 1, &dPobj, 0, NULL, NULL );
  PrintCLError( status, "clEnqueueAcquireGLObjects (1): " );
  status = clEnqueueAcquireGLObjects( CmdQueue, 1, &dCobj, 0, NULL, NULL );
  PrintCLError( status, "clEnqueueAcquireGLObjects (2): " );

  if( ShowPerformance )
    time0 = omp_get_wtime( );

  // 11. enqueue the Kernel object for execution:

  cl_event wait;
  status = clEnqueueNDRangeKernel( CmdQueue, Kernel, 1, NULL, GlobalWorkSize, LocalWorkSize, 0, NULL, &wait );
  PrintCLError( status, "clEnqueueNDRangeKernel: " );

  if( ShowPerformance )
  {
    status = clWaitForEvents( 1, &wait );
    PrintCLError( status, "clWaitForEvents: " );
    time1 = omp_get_wtime( );
    ElapsedTime = time1 - time0;
  }

  clFinish( CmdQueue );
  status = clEnqueueReleaseGLObjects( CmdQueue, 1, &dCobj, 0, NULL, NULL );
  PrintCLError( status, "clEnqueueReleaseGLObjects (2): " );
  status = clEnqueueReleaseGLObjects( CmdQueue, 1, &dPobj, 0, NULL, NULL );
  PrintCLError( status, "clEnqueueReleaseGLObjects (2): " );

  glutSetWindow( MainWindow );
  glutPostRedisplay( );
}

//
// glui buttons callback:
//

void
Buttons( int id )
{
  cl_int status;
  switch( id )
  {
    case GO:
      GLUI_Master.set_glutIdleFunc( Animate );
      break;

    case PAUSE:
      Paused = ! Paused;
      if( Paused )
        GLUI_Master.set_glutIdleFunc( NULL );
      else
        GLUI_Master.set_glutIdleFunc( Animate );
      break;

    case RESET:
      Reset( );
      ResetParticles( );
      status = clEnqueueWriteBuffer( CmdQueue, dVel, CL_FALSE, 0, 4*sizeof(float)*NUM_PARTICLES, hVel, 0, NULL, NULL );
      PrintCLError( status, "clEneueueWriteBuffer: " );
      GLUI_Master.set_glutIdleFunc( NULL );
      Glui->sync_live( );
      glutSetWindow( MainWindow );
      glutPostRedisplay( );
      break;

    case QUIT:
      Quit( );
      break;

    default:
      fprintf( stderr, "Don't know what to do with Button ID %d\n", id );
  }

}

//
// draw the complete scene:
//

void
Display( )
{
  glutSetWindow( MainWindow );
  glDrawBuffer( GL_BACK );
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  glEnable( GL_DEPTH_TEST );
  glShadeModel( GL_FLAT );
  GLsizei vx = glutGet( GLUT_WINDOW_WIDTH );
  GLsizei vy = glutGet( GLUT_WINDOW_HEIGHT );
  GLsizei v = vx < vy ? vx : vy;      // minimum dimension
  GLint xl = ( vx - v ) / 2;
  GLint yb = ( vy - v ) / 2;
  glViewport( xl, yb,  v, v );

  glMatrixMode( GL_PROJECTION );
  glLoadIdentity( );
  if( WhichProjection == ORTHO )
    glOrtho( -300., 300.,  -300., 300., 0.1, 2000. );
  else
    gluPerspective( 50., 1.,  0.1, 2000. );

  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity( );
  gluLookAt( 0., -100., 800.,     0., -100., 0.,     0., 1., 0. );
  glTranslatef( (GLfloat)TransXYZ[0], (GLfloat)TransXYZ[1], -(GLfloat)TransXYZ[2] );
  glRotatef( (GLfloat)Yrot, 0., 1., 0. );
  glRotatef( (GLfloat)Xrot, 1., 0., 0. );
  glMultMatrixf( (const GLfloat *) RotMatrix );
  glScalef( (GLfloat)Scale, (GLfloat)Scale, (GLfloat)Scale );
  float scale2 = 1. + Scale2;   // because glui translation starts at 0.
  if( scale2 < MINSCALE )
    scale2 = MINSCALE;
  glScalef( (GLfloat)scale2, (GLfloat)scale2, (GLfloat)scale2 );

  glDisable( GL_FOG );

  if( AxesOn != GLUIFALSE )
    glCallList( AxesList );

  // ****************************************
  // Here is where you draw the current state of the particles:
  // ****************************************

  glBindBuffer( GL_ARRAY_BUFFER, hPobj );
  glVertexPointer( 4, GL_FLOAT, 0, (void *)0 );
  glEnableClientState( GL_VERTEX_ARRAY );

  glBindBuffer( GL_ARRAY_BUFFER, hCobj );
  glColorPointer( 4, GL_FLOAT, 0, (void *)0 );
  glEnableClientState( GL_COLOR_ARRAY );

  glPointSize( 3. );
  glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
  glPointSize( 1. );

  glDisableClientState( GL_VERTEX_ARRAY );
  glDisableClientState( GL_COLOR_ARRAY );
  glBindBuffer( GL_ARRAY_BUFFER, 0 );

  glCallList( SphereList );

  if( ShowPerformance )
  {
    char str[128];
    sprintf( str, "%6.1f GigaParticles/Sec", (float)NUM_PARTICLES/ElapsedTime/1000000000. );
    glDisable( GL_DEPTH_TEST );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluOrtho2D( 0., 100.,     0., 100. );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glColor3f( 1., 1., 1. );
    DoRasterString( 5., 95., 0., str );
  }

  glutSwapBuffers( );
  glFlush( );
}

//
// use glut to display a string of characters using a raster font:
//

void
DoRasterString( float x, float y, float z, char *s )
{
  char c;     // one character to print

  glRasterPos3f( (GLfloat)x, (GLfloat)y, (GLfloat)z );
  for( ; ( c = *s ) != '\0'; s++ )
  {
    glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24, c );
  }
}

//
// use glut to display a string of characters using a stroke font:
//

void
DoStrokeString( float x, float y, float z, float ht, char *s )
{
  char c;     // one character to print

  glPushMatrix( );
    glTranslatef( (GLfloat)x, (GLfloat)y, (GLfloat)z );
    float sf = ht / ( 119.05 + 33.33 );
    glScalef( (GLfloat)sf, (GLfloat)sf, (GLfloat)sf );
    for( ; ( c = *s ) != '\0'; s++ )
    {
      glutStrokeCharacter( GLUT_STROKE_ROMAN, c );
    }
  glPopMatrix( );
}

//
// initialize the opencl stuff:
//

void
InitCL( )
{
  // see if we can even open the opencl Kernel Program
  // (no point going on if we can't):

  FILE *fp = fopen( CL_FILE_NAME, "r" );
  if( fp == NULL )
  {
    fprintf( stderr, "Cannot open OpenCL source file '%s'\n", CL_FILE_NAME );
    return;
  }

  // 2. allocate the host memory buffers:

  cl_int status;    // returned status from opencl calls
        // test against CL_SUCCESS

  // get the platform id:

  status = clGetPlatformIDs( 1, &Platform, NULL );
  PrintCLError( status, "clGetPlatformIDs: " );

  // get the device id:

  status = clGetDeviceIDs( Platform, CL_DEVICE_TYPE_GPU, 1, &Device, NULL );
  PrintCLError( status, "clGetDeviceIDs: " );

  // since this is an opengl interoperability program,
  // check if the opengl sharing extension is supported,
  // (no point going on if it isn't):
  // (we need the Device in order to ask, so can't do it any sooner than here)

  if(  IsCLExtensionSupported( "cl_khr_gl_sharing" )  )
  {
    fprintf( stderr, "cl_khr_gl_sharing is supported.\n" );
  }
  else
  {
    fprintf( stderr, "cl_khr_gl_sharing is not supported -- sorry.\n" );
    return;
  }

  // 3. create an opencl context based on the opengl context:

  cl_context_properties props[ ] =
  {
    CL_GL_CONTEXT_KHR,    (cl_context_properties) wglGetCurrentContext( ),
    CL_WGL_HDC_KHR,     (cl_context_properties) wglGetCurrentDC( ),
    CL_CONTEXT_PLATFORM,    (cl_context_properties) Platform,
    0
  };

  cl_context Context = clCreateContext( props, 1, &Device, NULL, NULL, &status );
  PrintCLError( status, "clCreateContext: " );

  // 4. create an opencl command queue:

  CmdQueue = clCreateCommandQueue( Context, Device, 0, &status );
  if( status != CL_SUCCESS )
    fprintf( stderr, "clCreateCommandQueue failed\n" );

  // create the velocity array and the opengl vertex array buffer and color array buffer:

  delete [ ] hVel;
  hVel = new struct xyzw [ NUM_PARTICLES ];

  glGenBuffers( 1, &hPobj );
  glBindBuffer( GL_ARRAY_BUFFER, hPobj );
  glBufferData( GL_ARRAY_BUFFER, 4 * NUM_PARTICLES * sizeof(float), NULL, GL_STATIC_DRAW );

  glGenBuffers( 1, &hCobj );
  glBindBuffer( GL_ARRAY_BUFFER, hCobj );
  glBufferData( GL_ARRAY_BUFFER, 4 * NUM_PARTICLES * sizeof(float), NULL, GL_STATIC_DRAW );

  glBindBuffer( GL_ARRAY_BUFFER, 0 ); // unbind the buffer

  // fill those arrays and buffers:

  ResetParticles( );

  // 5. create the opencl version of the opengl buffers:

  dPobj = clCreateFromGLBuffer( Context, 0, hPobj, &status );
  PrintCLError( status, "clCreateFromGLBuffer (1)" );

  dCobj = clCreateFromGLBuffer( Context, 0, hCobj, &status );
  PrintCLError( status, "clCreateFromGLBuffer (2)" );

  // 5. create the opencl version of the velocity array:

  dVel = clCreateBuffer( Context, CL_MEM_READ_WRITE, 4*sizeof(float)*NUM_PARTICLES, NULL, &status );
  PrintCLError( status, "clCreateBuffer: " );

  // 6. enqueue the command to write the data from the host buffers to the Device buffers:

  status = clEnqueueWriteBuffer( CmdQueue, dVel, CL_FALSE, 0, 4*sizeof(float)*NUM_PARTICLES, hVel, 0, NULL, NULL );
  PrintCLError( status, "clEneueueWriteBuffer: " );

  // 7. read the Kernel code from a file:

  fseek( fp, 0, SEEK_END );
  size_t fileSize = ftell( fp );
  fseek( fp, 0, SEEK_SET );
  char *clProgramText = new char[ fileSize+1 ];   // leave room for '\0'
  size_t n = fread( clProgramText, 1, fileSize, fp );
  clProgramText[fileSize] = '\0';
  fclose( fp );

  // create the text for the Kernel Program:

  char *strings[1];
  strings[0] = clProgramText;
  Program = clCreateProgramWithSource( Context, 1, (const char **)strings, NULL, &status );
  if( status != CL_SUCCESS )
    fprintf( stderr, "clCreateProgramWithSource failed\n" );
  delete [ ] clProgramText;

  // 8. compile and link the Kernel code:

  char *options = { "" };
  status = clBuildProgram( Program, 1, &Device, options, NULL, NULL );
  if( status != CL_SUCCESS )
  {
    size_t size;
    clGetProgramBuildInfo( Program, Device, CL_PROGRAM_BUILD_LOG, 0, NULL, &size );
    cl_char *log = new cl_char[ size ];
    clGetProgramBuildInfo( Program, Device, CL_PROGRAM_BUILD_LOG, size, log, NULL );
    fprintf( stderr, "clBuildProgram failed:\n%s\n", log );
    delete [ ] log;
  }

#ifdef  EXPORT_BINARY
  size_t binary_sizes;
  status = clGetProgramInfo( Program, CL_PROGRAM_BINARY_SIZES, 0, NULL, &binary_sizes );
  PrintCLError( status, "clGetProgramInfo (1):" );
  //fprintf( stderr, "binary_sizes = %d\n", binary_sizes );
  size_t size;
  status = clGetProgramInfo( Program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &size, NULL );
  PrintCLError( status, "clGetProgramInfo (2):" );
  //fprintf( stderr, "size = %d\n", size );
  unsigned char *binary = new unsigned char [ size ];
  status = clGetProgramInfo( Program, CL_PROGRAM_BINARIES, size, &binary, NULL );
  PrintCLError( status, "clGetProgramInfo (3):" );
  FILE *fpbin = fopen( CL_BINARY_NAME, "wb" );
  if( fpbin == NULL )
  {
    fprintf( stderr, "Cannot create '%s'\n", CL_BINARY_NAME );
  }
  else
  {
    fwrite( binary, 1, size, fpbin );
    fclose( fpbin );
    fprintf( stderr, "Binary written to '%s'\n", CL_BINARY_NAME );
  }
  delete [ ] binary;
#endif

  // 9. create the Kernel object:

  Kernel = clCreateKernel( Program, "Particle", &status );
  PrintCLError( status, "clCreateKernel failed: " );

  // 10. setup the arguments to the Kernel object:

  status = clSetKernelArg( Kernel, 0, sizeof(cl_mem), &dPobj );
  PrintCLError( status, "clSetKernelArg (1): " );

  status = clSetKernelArg( Kernel, 1, sizeof(cl_mem), &dVel );
  PrintCLError( status, "clSetKernelArg (2): " );

  status = clSetKernelArg( Kernel, 2, sizeof(cl_mem), &dCobj );
  PrintCLError( status, "clSetKernelArg (3): " );
}

//
// initialize the glui window:
//

void
InitGlui( )
{
  glutInitWindowPosition( INIT_WINDOW_SIZE + 50, 0 );
  Glui = GLUI_Master.create_glui( (char *) GLUITITLE );
  Glui->add_statictext( (char *) GLUITITLE );
  Glui->add_separator( );
  Glui->add_checkbox( "Axes",             &AxesOn );
  Glui->add_checkbox( "Perspective",      &WhichProjection );
  Glui->add_checkbox( "Show Performance", &ShowPerformance );

  GLUI_Panel *panel = Glui->add_panel( "Object Transformation" );

    GLUI_Rotation *rot = Glui->add_rotation_to_panel( panel, "Rotation", (float *) RotMatrix );
    rot->set_spin( 1.0 );

    Glui->add_column_to_panel( panel, GLUIFALSE );
    GLUI_Translation *scale = Glui->add_translation_to_panel( panel, "Scale",  GLUI_TRANSLATION_Y , &Scale2 );
    scale->set_speed( 0.01f );

    Glui->add_column_to_panel( panel, FALSE );
    GLUI_Translation *trans = Glui->add_translation_to_panel( panel, "Trans XY", GLUI_TRANSLATION_XY, &TransXYZ[0] );
    trans->set_speed( 1.1f );

    Glui->add_column_to_panel( panel, FALSE );
    trans = Glui->add_translation_to_panel( panel, "Trans Z",  GLUI_TRANSLATION_Z , &TransXYZ[2] );
    trans->set_speed( 1.1f );

  panel = Glui->add_panel( "", FALSE );
    Glui->add_button_to_panel( panel, "Go !", GO, (GLUI_Update_CB) Buttons );
    Glui->add_column_to_panel( panel, FALSE );
    Glui->add_button_to_panel( panel, "Pause", PAUSE, (GLUI_Update_CB) Buttons );
    Glui->add_column_to_panel( panel, FALSE );
    Glui->add_button_to_panel( panel, "Reset", RESET, (GLUI_Update_CB) Buttons );
    Glui->add_column_to_panel( panel, FALSE );
    Glui->add_button_to_panel( panel, "Quit", QUIT, (GLUI_Update_CB) Buttons );

  Glui->set_main_gfx_window( MainWindow );
  GLUI_Master.set_glutIdleFunc( NULL );
}

//
// initialize the glut and OpenGL libraries:
//  also setup display lists and callback functions
//

void
InitGraphics( )
{
  glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
  glutInitWindowPosition( 0, 0 );
  glutInitWindowSize( INIT_WINDOW_SIZE, INIT_WINDOW_SIZE );

  MainWindow = glutCreateWindow( WINDOWTITLE );
  glutSetWindowTitle( WINDOWTITLE );
  glClearColor( BACKCOLOR[0], BACKCOLOR[1], BACKCOLOR[2], BACKCOLOR[3] );

  // setup the callback routines:

  glutSetWindow( MainWindow );
  glutDisplayFunc( Display );
  glutReshapeFunc( Resize );
  glutKeyboardFunc( Keyboard );
  glutMouseFunc( MouseButton );
  glutMotionFunc( MouseMotion );
  glutVisibilityFunc( Visibility );

#ifdef WIN32
  GLenum err = glewInit();
  if( err != GLEW_OK )
  {
    fprintf( stderr, "glewInit Error\n" );
  }
#endif
}

//
// initialize the display lists that will not change:
//

void
InitLists( )
{
  SphereList = glGenLists( 1 );
  glNewList( SphereList, GL_COMPILE );
    glColor3f( .9f, .9f, 0. );
    glPushMatrix( );
      glTranslatef( -100., -800., 0. );
      glutWireSphere( 600., 100., 100. );
    glPopMatrix( );
  glEndList( );

  AxesList = glGenLists( 1 );
  glNewList( AxesList, GL_COMPILE );
    glColor3fv( AXES_COLOR );
    glLineWidth( AXES_WIDTH );
      Axes( 150. );
    glLineWidth( 1. );
  glEndList( );
}

//
// the keyboard callback:
//

void
Keyboard( unsigned char c, int x, int y )
{
  switch( c )
  {
    case 'o':
    case 'O':
      WhichProjection = ORTHO;
      break;

    case 'p':
    case 'P':
      WhichProjection = PERSP;
      break;

    case 'q':
    case 'Q':
    case ESCAPE:
      Buttons( QUIT );  // will not return here
      break;      // happy compiler

    default:
      fprintf( stderr, "Don't know what to do with keyboard hit: '%c' (0x%0x)\n", c, c );
  }
  Glui->sync_live( );
  glutSetWindow( MainWindow );
  glutPostRedisplay( );
}

//
// called when the mouse button transitions down or up:
//

void
MouseButton( int button, int state, int x, int y )
{
  int b;      // LEFT, MIDDLE, or RIGHT

  switch( button )
  {
    case GLUT_LEFT_BUTTON:
      b = LEFT;   break;

    case GLUT_MIDDLE_BUTTON:
      b = MIDDLE;   break;

    case GLUT_RIGHT_BUTTON:
      b = RIGHT;    break;

    default:
      b = 0;
      fprintf( stderr, "Unknown mouse button: %d\n", button );
  }

  // button down sets the bit, up clears the bit:

  if( state == GLUT_DOWN )
  {
    Xmouse = x;
    Ymouse = y;
    ActiveButton |= b;    // set the proper bit
  }
  else
  {
    ActiveButton &= ~b;   // clear the proper bit
  }
}

//
// called when the mouse moves while a button is down:
//

void
MouseMotion( int x, int y )
{
  int dx = x - Xmouse;    // change in mouse coords
  int dy = y - Ymouse;

  if( ActiveButton & LEFT )
  {
      Xrot += ( ANGFACT*dy );
      Yrot += ( ANGFACT*dx );
  }

  if( ActiveButton & MIDDLE )
  {
    Scale += SCLFACT * (float) ( dx - dy );

    // keep object from turning inside-out or disappearing:

    if( Scale < MINSCALE )
      Scale = MINSCALE;
  }

  Xmouse = x;     // new current position
  Ymouse = y;

  glutSetWindow( MainWindow );
  glutPostRedisplay( );
}

//
// reset the transformations and the colors:
//
// this only sets the global variables --
// the glut main loop is responsible for redrawing the scene
//

void
Reset( )
{
  ActiveButton = 0;
  AxesOn = GLUIFALSE;
  Paused = GLUIFALSE;
  Scale  = 1.0;
  Scale2 = 0.0;   // because add 1. to it in Display( )
  ShowPerformance = GLUIFALSE;
  WhichProjection = PERSP;
  Xrot = Yrot = 0.;
  TransXYZ[0] = TransXYZ[1] = TransXYZ[2] = 0.;

                    RotMatrix[0][1] = RotMatrix[0][2] = RotMatrix[0][3] = 0.;
  RotMatrix[1][0]                   = RotMatrix[1][2] = RotMatrix[1][3] = 0.;
  RotMatrix[2][0] = RotMatrix[2][1]                   = RotMatrix[2][3] = 0.;
  RotMatrix[3][0] = RotMatrix[3][1] = RotMatrix[3][3]                   = 0.;
  RotMatrix[0][0] = RotMatrix[1][1] = RotMatrix[2][2] = RotMatrix[3][3] = 1.;
}

void
ResetParticles( )
{
  glBindBuffer( GL_ARRAY_BUFFER, hPobj );
  struct xyzw *points = (struct xyzw *) glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
  for( int i = 0; i < NUM_PARTICLES; i++ )
  {
    points[i].x = Ranf( XMIN, XMAX );
    points[i].y = Ranf( YMIN, YMAX );
    points[i].z = Ranf( ZMIN, ZMAX );
    points[i].w = 1.;
  }
  glUnmapBuffer( GL_ARRAY_BUFFER );

  glBindBuffer( GL_ARRAY_BUFFER, hCobj );
  struct rgba *colors = (struct rgba *) glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
  for( int i = 0; i < NUM_PARTICLES; i++ )
  {
    colors[i].r = Ranf( .3f, 1. );
    colors[i].g = Ranf( .3f, 1. );
    colors[i].b = Ranf( .3f, 1. );
    colors[i].a = 1.;
  }
  glUnmapBuffer( GL_ARRAY_BUFFER );

  for( int i = 0; i < NUM_PARTICLES; i++ )
  {
    hVel[i].x = Ranf( VMIN, VMAX );
    hVel[i].y = Ranf(   0., VMAX );
    hVel[i].z = Ranf( VMIN, VMAX );
  }
}

void
Resize( int width, int height )
{
  glutSetWindow( MainWindow );
  glutPostRedisplay( );
}

void
Visibility ( int state )
{
  if( state == GLUT_VISIBLE )
  {
    glutSetWindow( MainWindow );
    glutPostRedisplay( );
  }
  else
  {
    // could optimize by keeping track of the fact
    // that the window is not visible and avoid
    // animating or redrawing it ...
  }
}

// the stroke characters 'X' 'Y' 'Z' :

static float xx[ ] = {
    0., 1., 0., 1.
        };

static float xy[ ] = {
    -.5, .5, .5, -.5
        };

static int xorder[ ] = {
    1, 2, -3, 4
    };

static float yx[ ] = {
    0., 0., -.5, .5
        };

static float yy[ ] = {
    0., .6f, 1., 1.
        };

static int yorder[ ] = {
    1, 2, 3, -2, 4
    };

static float zx[ ] = {
    1., 0., 1., 0., .25, .75
        };

static float zy[ ] = {
    .5, .5, -.5, -.5, 0., 0.
        };

static int zorder[ ] = {
    1, 2, 3, 4, -5, 6
    };

// fraction of the length to use as height of the characters:

#define LENFRAC   0.10

// fraction of length to use as start location of the characters:

#define BASEFRAC  1.10

//
//  Draw a set of 3D axes:
//  (length is the axis length in world coordinates)
//

void
Axes( float length )
{
  glBegin( GL_LINE_STRIP );
    glVertex3f( length, 0., 0. );
    glVertex3f( 0., 0., 0. );
    glVertex3f( 0., length, 0. );
  glEnd( );
  glBegin( GL_LINE_STRIP );
    glVertex3f( 0., 0., 0. );
    glVertex3f( 0., 0., length );
  glEnd( );

  float fact = LENFRAC * length;
  float base = BASEFRAC * length;

  glBegin( GL_LINE_STRIP );
    for( int i = 0; i < 4; i++ )
    {
      int j = xorder[i];
      if( j < 0 )
      {

        glEnd( );
        glBegin( GL_LINE_STRIP );
        j = -j;
      }
      j--;
      glVertex3f( base + fact*xx[j], fact*xy[j], 0.0 );
    }
  glEnd( );

  glBegin( GL_LINE_STRIP );
    for( int i = 0; i < 5; i++ )
    {
      int j = yorder[i];
      if( j < 0 )
      {

        glEnd( );
        glBegin( GL_LINE_STRIP );
        j = -j;
      }
      j--;
      glVertex3f( fact*yx[j], base + fact*yy[j], 0.0 );
    }
  glEnd( );

  glBegin( GL_LINE_STRIP );
    for( int i = 0; i < 6; i++ )
    {
      int j = zorder[i];
      if( j < 0 )
      {

        glEnd( );
        glBegin( GL_LINE_STRIP );
        j = -j;
      }
      j--;
      glVertex3f( 0.0, fact*zy[j], base + fact*zx[j] );
    }
  glEnd( );

}

//
// exit gracefully:
//

void
Quit( )
{
  Glui->close( );
  glutSetWindow( MainWindow );
  glFinish( );
  glutDestroyWindow( MainWindow );

  // 13. clean everything up:

  clReleaseKernel(        Kernel   );
  clReleaseProgram(       Program  );
  clReleaseCommandQueue(  CmdQueue );
  clReleaseMemObject(     dPobj  );
  clReleaseMemObject(     dCobj  );

  exit( 0 );
}

#define TOP 2147483647.   // 2^31 - 1

float
Ranf( float low, float high )
{
  long random( );   // returns integer 0 - TOP

  float r = (float)rand( );
  return(   low  +  r * ( high - low ) / (float)RAND_MAX   );
}

bool
IsCLExtensionSupported( const char *extension )
{
  // see if the extension is bogus:

  if( extension == NULL  ||  extension[0] == '\0' )
    return false;

  char * where = (char *) strchr( extension, ' ' );
  if( where != NULL )
    return false;

  // get the full list of extensions:

  size_t extensionSize;
  clGetDeviceInfo( Device, CL_DEVICE_EXTENSIONS, 0, NULL, &extensionSize );
  char *extensions = new char [extensionSize];
  clGetDeviceInfo( Device, CL_DEVICE_EXTENSIONS, extensionSize, extensions, NULL );

  for( char * start = extensions; ; )
  {
    where = (char *) strstr( (const char *) start, extension );
    if( where == 0 )
    {
      delete [ ] extensions;
      return false;
    }

    char * terminator = where + strlen(extension);  // points to what should be the separator

    if( *terminator == ' '  ||  *terminator == '\0'  ||  *terminator == '\r'  ||  *terminator == '\n' )
    {
      delete [ ] extensions;
      return true;
    }
    start = terminator;
  }

  delete [ ] extensions;
  return false;
}


text:
#include <linux/mutex.h>
#include <linux/buffer_head.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/lzo.h>

#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
#include "squashfs.h"
#include "decompressor.h"
#include "page_actor.h"

struct squashfs_lzo {
	void	*input;
	void	*output;
};

static void *lzo_init(struct squashfs_sb_info *msblk, void *buff)
{
	int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);

	struct squashfs_lzo *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
	if (stream == NULL)
		goto failed;
	stream->input = vmalloc(block_size);
	if (stream->input == NULL)
		goto failed;
	stream->output = vmalloc(block_size);
	if (stream->output == NULL)
		goto failed2;

	return stream;

failed2:
	vfree(stream->input);
failed:
	ERROR("Failed to allocate lzo workspace\n");
	kfree(stream);
	return ERR_PTR(-ENOMEM);
}

static void lzo_free(void *strm)
{
	struct squashfs_lzo *stream = strm;

	if (stream) {
		vfree(stream->input);
		vfree(stream->output);
	}
	kfree(stream);
}

static int lzo_uncompress(struct squashfs_sb_info *msblk, void *strm,
	struct buffer_head **bh, int b, int offset, int length,
	struct squashfs_page_actor *output)
{
	struct squashfs_lzo *stream = strm;
	void *buff = stream->input, *data;
	int avail, i, bytes = length, res;
	size_t out_len = output->length;

	for (i = 0; i < b; i++) {
		avail = min(bytes, msblk->devblksize - offset);
		memcpy(buff, bh[i]->b_data + offset, avail);
		buff += avail;
		bytes -= avail;
		offset = 0;
		put_bh(bh[i]);
	}

	res = lzo1x_decompress_safe(stream->input, (size_t)length,
					stream->output, &out_len);
	if (res != LZO_E_OK)
		goto failed;

	res = bytes = (int)out_len;
	data = squashfs_first_page(output);
	buff = stream->output;
	while (data) {
		if (bytes <= PAGE_SIZE) {
			memcpy(data, buff, bytes);
			break;
		} else {
			memcpy(data, buff, PAGE_SIZE);
			buff += PAGE_SIZE;
			bytes -= PAGE_SIZE;
			data = squashfs_next_page(output);
		}
	}
	squashfs_finish_page(output);

	return res;

failed:
	return -EIO;
}

const struct squashfs_decompressor squashfs_lzo_comp_ops = {
	.init = lzo_init,
	.free = lzo_free,
	.decompress = lzo_uncompress,
	.id = LZO_COMPRESSION,
	.name = "lzo",
	.supported = 1
};

redpajama_set_name: RedPajamaGithub


text:
/**
 * file created at 2013-6-9
 */
package bingo.lang.serialize;

import bingo.lang.Strings;
import bingo.lang.json.JSON;

public class JsonSerializer implements Serializer {

	public String serialize(Object value) {
	    return JSON.encode(value);
    }

	public Object deserialize(String string) {
	    return JSON.decode(string).value();
    }

	public Object tryDeserialize(String string) {
		if(Strings.isEmpty(string)){
			return null;
		}

		string = string.trim();

		if("null".equals(string)){
			return null;
		}

		if((string.startsWith("[") && string.endsWith("]")) || (string.startsWith("{") && string.endsWith("}"))){
			return JSON.decode(string).value();
		}

	    return string;
    }
}


text:
package com.squareup.wire.protos.single_level;

import com.squareup.wire.FieldEncoding;
import com.squareup.wire.Message;
import com.squareup.wire.ProtoAdapter;
import com.squareup.wire.ProtoReader;
import com.squareup.wire.ProtoWriter;
import com.squareup.wire.ReverseProtoWriter;
import com.squareup.wire.Syntax;
import com.squareup.wire.WireField;
import com.squareup.wire.internal.Internal;
import java.io.IOException;
import java.lang.Integer;
import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.lang.StringBuilder;
import okio.ByteString;

public final class Foo extends Message<Foo, Foo.Builder> {
  public static final ProtoAdapter<Foo> ADAPTER = new ProtoAdapter_Foo();

  private static final long serialVersionUID = 0L;

  public static final Integer DEFAULT_BAR = 0;

  @WireField(
      tag = 1,
      adapter = "com.squareup.wire.ProtoAdapter#INT32"
  )
  public final Integer bar;

  public Foo(Integer bar) {
    this(bar, ByteString.EMPTY);
  }

  public Foo(Integer bar, ByteString unknownFields) {
    super(ADAPTER, unknownFields);
    this.bar = bar;
  }

  @Override
  public Builder newBuilder() {
    Builder builder = new Builder();
    builder.bar = bar;
    builder.addUnknownFields(unknownFields());
    return builder;
  }

  @Override
  public boolean equals(Object other) {
    if (other == this) return true;
    if (!(other instanceof Foo)) return false;
    Foo o = (Foo) other;
    return unknownFields().equals(o.unknownFields())
        && Internal.equals(bar, o.bar);
  }

  @Override
  public int hashCode() {
    int result = super.hashCode;
    if (result == 0) {
      result = unknownFields().hashCode();
      result = result * 37 + (bar != null ? bar.hashCode() : 0);
      super.hashCode = result;
    }
    return result;
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    if (bar != null) builder.append(", bar=").append(bar);
    return builder.replace(0, 2, "Foo{").append('}').toString();
  }

  public static final class Builder extends Message.Builder<Foo, Builder> {
    public Integer bar;

    public Builder() {
    }

    public Builder bar(Integer bar) {
      this.bar = bar;
      return this;
    }

    @Override
    public Foo build() {
      return new Foo(bar, super.buildUnknownFields());
    }
  }

  private static final class ProtoAdapter_Foo extends ProtoAdapter<Foo> {
    public ProtoAdapter_Foo() {
      super(FieldEncoding.LENGTH_DELIMITED, Foo.class, "type.googleapis.com/single_level.Foo", Syntax.PROTO_2, null, "single_level.proto");
    }

    @Override
    public int encodedSize(Foo value) {
      int result = 0;
      result += ProtoAdapter.INT32.encodedSizeWithTag(1, value.bar);
      result += value.unknownFields().size();
      return result;
    }

    @Override
    public void encode(ProtoWriter writer, Foo value) throws IOException {
      ProtoAdapter.INT32.encodeWithTag(writer, 1, value.bar);
      writer.writeBytes(value.unknownFields());
    }

    @Override
    public void encode(ReverseProtoWriter writer, Foo value) throws IOException {
      writer.writeBytes(value.unknownFields());
      ProtoAdapter.INT32.encodeWithTag(writer, 1, value.bar);
    }

    @Override
    public Foo decode(ProtoReader reader) throws IOException {
      Builder builder = new Builder();
      long token = reader.beginMessage();
      for (int tag; (tag = reader.nextTag()) != -1;) {
        switch (tag) {
          case 1: builder.bar(ProtoAdapter.INT32.decode(reader)); break;
          default: {
            reader.readUnknownField(tag);
          }
        }
      }
      builder.addUnknownFields(reader.endMessageAndGetUnknownFields(token));
      return builder.build();
    }

    @Override
    public Foo redact(Foo value) {
      Builder builder = value.newBuilder();
      builder.clearUnknownFields();
      return builder.build();
    }
  }
}


text:
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Media.Imaging;

namespace WpfPostItDetector
{
    static class BitmapHelpers
    {
        public static BitmapImage ToBitmapImage(this Bitmap bitmap)
        {
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, ImageFormat.Bmp);
            ms.Seek(0, SeekOrigin.Begin);
            bi.StreamSource = ms;
            bi.EndInit();
            return bi;
        }

        public static void CopyPixels(this BitmapSource source, PixelColor[,] pixels, int stride, int offset)
        {
            var height = source.PixelHeight;
            var width = source.PixelWidth;
            var pixelBytes = new byte[height * width * 4];
            source.CopyPixels(pixelBytes, stride, 0);
            int y0 = offset / width;
            int x0 = offset - width * y0;
            for (int y = 0; y < height; y++)
                for (int x = 0; x < width; x++)
                    pixels[x + x0, y + y0] = new PixelColor
                    {
                        Blue = pixelBytes[(y * width + x) * 4 + 0],
                        Green = pixelBytes[(y * width + x) * 4 + 1],
                        Red = pixelBytes[(y * width + x) * 4 + 2],
                        Alpha = pixelBytes[(y * width + x) * 4 + 3],
                    };
        }
    }

    public struct PixelColor
    {
        public byte Blue;
        public byte Green;
        public byte Red;
        public byte Alpha;
    }
}


text:
csgo-server-deathmatch-docker
============

# What is Counter-Strike: Global Offensive?

Counter-Strike: Global Offensive (CS:GO) is an online first-person shooter developed by Hidden Path Entertainment and Valve Corporation. It is the fourth game in the main Counter-Strike franchise.

## Deathmatch Plugin

This Docker image uses [SourceMod](http://www.sourcemod.net/) and [Maxximou5](http://www.maxximou5.com/)'s [csgo-deathmatch plugin](https://github.com/Maxximou5/csgo-deathmatch).

# How to use this image

## Running CSGO Dedicated Server

1. Create a Steam account token here: http://steamcommunity.com/dev/managegameservers.

2. Run the container:

    $ docker run -d -P -e STEAM_GAME_SERVER_TOKEN=1234567890 brandonstevens/csgo-server-deathmatch

### Specifying a SourceMod Admin Config

    $ docker run -d -P -e STEAM_GAME_SERVER_TOKEN=1234567890 -v /home/ubuntu/admins.cfg:/home/daemon/csgo/server/csgo/addons/sourcemod/configs/admins.cfg brandonstevens/csgo-server-deathmatch

### Specifying a Deathmatch Config

    $ docker run -d -P -e STEAM_GAME_SERVER_TOKEN=1234567890 -v /home/ubuntu/admins.cfg:/home/daemon/csgo/server/csgo/addons/sourcemod/configs/admins.cfg -v /home/ubuntu/gamemode_deathmatch_server.cfg:/home/daemon/csgo/server/csgo/cfg/gamemode_deathmatch_server.cfg brandonstevens/csgo-server-deathmatch

## Environment Variables

The CSGO Dedicated Server image that the Deathmatch image builds on uses several environment variables which are easy to miss. Please see https://github.com/brandonstevens/csgo-server-docker for more information on the environment variables.


text:
require 'date'

module Overclock
  module Aws
    module RDS
      SERIALIZE_ATTRS = [
        :allocated_storage            ,
        :auto_minor_version_upgrade   ,
        :availability_zone            ,
        :backup_retention_period      ,
        :character_set_name           ,
        :db_instance_class            ,
        :db_instance_identifier       ,
        :db_name                      ,
        :db_parameter_group_name      ,
        :db_subnet_group_name         ,
        :db_security_groups           ,
        :db_subnet_group_name         ,
        :engine                       ,
        :engine_version               ,
        :iops                         ,
        :license_model                ,
        :master_user_password         ,
        :master_username              ,
        :multi_az                     ,
        :option_group_name            ,
        :port                         ,
        :preferred_backup_window      ,
        :preferred_maintenance_window ,
        :publicly_accessible          ,
        :storage_type                 ,
        :tags                         ,
        :vpc_security_group_ids
      ]

      DESERIALIZE_ATTRS = [
        :allocated_storage            ,
        :auto_minor_version_upgrade   ,
        :backup_retention_period      ,
        :character_set_name           ,
        :db_instance_class            ,
        :db_instance_identifier       ,
        :db_name                      ,
        :engine                       ,
        :engine_version               ,
        :iops                         ,
        :license_model                ,
        :master_username              ,
        :multi_az                     ,
        :preferred_backup_window      ,
        :preferred_maintenance_window ,
        :endpoint_address
      ]

      def instance(id = new_resource.id)
        @instance ||= rds.db_instances[id]
      end

      def rds(key = new_resource.aws_access_key, secret = new_resource.aws_secret_access_key)
        begin
          require 'aws-sdk-v1'
        rescue LoadError
          Chef::Log.error("Missing gem 'aws-sdk'. Use the default aws-rds recipe to install it first.")
        end
        @rds ||= AWS::RDS.new(access_key_id: key, secret_access_key: secret, region: region)
      end

      def create_instance(id = new_resource.id)
        if @instance = rds.db_instances.create(id, serialize_attrs)
          while (instance.status != 'available') do
            sleep 1
          end
        end
      end

      def delete_instance(id = new_resource.id, skip_final_snapshot = new_resource.skip_final_snapshot)
        @instance ||= rds.db_instances[id]
        if @instance
          if skip_final_snapshot
            options = {
              skip_final_snapshot: true
            }
          else
            time = Time.now.to_s
            theDate = DateTime.parse(time).strftime("%Y%m%d-%H%M")
            options = {
              skip_final_snapshot: false,
              final_db_snapshot_identifier: "#{new_resource.id}-#{theDate}"
            }
          end
          @instance.delete(options=options)
        end
      end

      def update_instance(id = new_resource.id)
        # placeholder for update instance
      end

      def set_node_attrs
        node.override[:aws_rds][new_resource.id] = deserialize_attrs
      end

      def region
        new_resource.region || determine_region
      end

      private

      # Determine the current region or fail gracefully
      def determine_region
        `curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | grep -Po "(us|sa|eu|ap)-(north|south)?(east|west)?-[0-9]+"`.strip
      rescue
        new_resource.region
      end

      def serialize_attrs
        SERIALIZE_ATTRS.inject({}) do | result, key |
          if value = new_resource.send(key)
            result[key] = value
          end
          result
        end
      end

      def deserialize_attrs
        DESERIALIZE_ATTRS.inject({}) do |result, attr|
          result[attr] = instance.send(attr)
          result
        end
      end
    end
  end
end


text:
class AutofillField;

namespace autofill {

// This struct describes a single input control for the imperative autocomplete
// dialog.
struct DetailInput {
  // Multiple DetailInput structs with the same row_id go on the same row. The
  // actual order of the rows is determined by their order of appearance in
  // kBillingInputs.
  int row_id;
  AutofillFieldType type;
  // Placeholder text resource ID.
  int placeholder_text_rid;
  // The section suffix that the field must have to match up to this input.
  const char* section_suffix;
  // A number between 0 and 1.0 that describes how much of the horizontal space
  // in the row should be allotted to this input. 0 is equivalent to 1.
  float expand_weight;
  // When non-empty, indicates the starting value for this input. This will be
  // used when the user is editing existing data.
  string16 initial_value;
};

// Determines whether |input| and |field| match.
typedef base::Callback<bool(const DetailInput& input,
                            const AutofillField& field)> InputFieldComparator;

// Sections of the dialog --- all fields that may be shown to the user fit under
// one of these sections.
enum DialogSection {
  SECTION_EMAIL,
  // The Autofill-backed dialog uses separate CC and billing sections.
  SECTION_CC,
  SECTION_BILLING,
  // The wallet-backed dialog uses a combined CC and billing section.
  SECTION_CC_BILLING,
  SECTION_SHIPPING,
};

// Used by UpdateSection() to indicate what to do with data that the user has
// already input into textfields.
enum UserInputAction {
  CLEAR_USER_INPUT,
  KEEP_USER_INPUT,
};

// A notification to show in the autofill dialog. Ranges from information to
// seriously scary security messages, and will give you the color it should be
// displayed (if you ask it).
class DialogNotification {
 public:
  enum Type {
    NONE,
    AUTOCHECKOUT_ERROR,
    EXPLANATORY_MESSAGE,
    REQUIRED_ACTION,
    SECURITY_WARNING,
    VALIDATION_ERROR,
    WALLET_ERROR,
    WALLET_SIGNIN_PROMO,
    WALLET_USAGE_CONFIRMATION,
  };

  DialogNotification();
  DialogNotification(Type type, const string16& display_text);

  // Returns the appropriate background or text color for the view's
  // notification area based on |type_|.
  SkColor GetBackgroundColor() const;
  SkColor GetTextColor() const;

  // Whether this notification has an arrow pointing up at the account chooser.
  bool HasArrow() const;

  // Whether this notifications has the "Save details to wallet" checkbox.
  bool HasCheckbox() const;

  const string16& display_text() const { return display_text_; }
  Type type() const { return type_; }

  void set_checked(bool checked) { checked_ = checked; }
  bool checked() const { return checked_; }

  void set_interactive(bool interactive) { interactive_ = interactive; }
  bool interactive() const { return interactive_; }

 private:
  Type type_;
  string16 display_text_;

  // Whether the dialog notification's checkbox should be checked. Only applies
  // when |HasCheckbox()| is true.
  bool checked_;

  // When false, this disables user interaction with the notification. For
  // example, WALLET_USAGE_CONFIRMATION notifications set this to false after
  // the submit flow has started.
  bool interactive_;
};

enum DialogSignedInState {
  REQUIRES_RESPONSE,
  REQUIRES_SIGN_IN,
  REQUIRES_PASSIVE_SIGN_IN,
  SIGNED_IN,
};

struct SuggestionState {
  SuggestionState(const string16& text,
                  const gfx::Image& icon,
                  const string16& extra_text,
                  const gfx::Image& extra_icon,
                  bool editable);
  ~SuggestionState();
  string16 text;
  gfx::Image icon;
  string16 extra_text;
  gfx::Image extra_icon;
  bool editable;
};

typedef std::vector<DetailInput> DetailInputs;
typedef std::map<const DetailInput*, string16> DetailOutputMap;

}  // namespace autofill

#endif  // CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_DIALOG_TYPES_H_


text:
import Ember from 'ember';
import {module, test} from 'qunit';
import startApp from '../helpers/start-app';
import destroyApp from '../helpers/destroy-app';
import FIXTURES from '../helpers/fixtures/crud';
import MOCK_FIXTURES from '../helpers/fixtures/mock';

var App;
var store;
var adapter;
var run = Ember.run;
var get = Ember.get;

module('CRUD', {
  beforeEach: function(assert) {
    let done = assert.async();
    run(function() {
      window.localforage.setItem('DS.LFAdapter', FIXTURES).then(function() {
        window.localforage.setItem('MockAdapter', MOCK_FIXTURES).then(function() {
          done();
        });
      });
    });

    run(function() {
      App = startApp();
      store = App.__container__.lookup('service:store');
      adapter = App.__container__.lookup('adapter:application');
      adapter.get('cache').clear();
    });
  },

  afterEach: function() {
    destroyApp(App);
  }
});

// Lifecycle methods
// -----------------------------------------------------------------------------

test('push', function(assert) {
  assert.expect(3);
  let done = assert.async();

  run(function() {
    var list = store.push({
      data: {
        type: 'list',
        id: adapter.generateIdForRecord(),
        attributes: {
          name: 'Rambo'
        }
      }
    });

    list.save().then(function() {
      return store.query('list', {
        name: 'Rambo'
      });
    }).then(function(records) {
      var record = records.objectAt(0);
      assert.equal(get(records, 'length'), 1, 'Only Rambo was found');
      assert.equal(get(record, 'name'), 'Rambo', 'Correct name');
      assert.equal(get(record, 'id'), list.id, 'Correct, original id');
      done();
    });
  });
});

test('createRecord', function(assert) {
  assert.expect(3);
  let done = assert.async();

  run(function() {
    var list = store.createRecord('list', {
      name: 'Rambo'
    });

    list.save().then(function() {
      return store.query('list', {
        name: 'Rambo'
      });
    }).then(function(records) {
      var record = records.objectAt(0);
      assert.equal(get(records, 'length'), 1, 'Only Rambo was found');
      assert.equal(get(record, 'name'), 'Rambo', 'Correct name');
      assert.equal(get(record, 'id'), list.id, 'Correct, original id');
      done();
    });
  });
});

test('updateRecord', function(assert) {
  assert.expect(3);
  let done = assert.async();

  run(function() {
    var list = store.createRecord('list', {
      name: 'Rambo'
    });

    var UpdateList = function() {
      return store.query('list', {
        name: 'Rambo'
      }).then(function(records) {
        var record = records.objectAt(0);
        record.set('name', 'Macgyver');
        return record.save();
      });
    };

    var AssertListIsUpdated = function() {
      return store.query('list', {
        name: 'Macgyver'
      }).then(function(records) {
        var record = records.objectAt(0);
        assert.equal(get(records, 'length'), 1, 'Only one record was found');
        assert.equal(get(record, 'name'), 'Macgyver', 'Updated name shows up');
        assert.equal(get(record, 'id'), list.id, 'Correct, original id');
        done();
      });
    };

    list.save().then(UpdateList).then(AssertListIsUpdated);
  });
});

test('deleteRecord', function(assert) {
  assert.expect(2);
  let done = assert.async();

  run(function() {
    var AssertListIsDeleted = function() {
      return store.query('list', {
        name: 'one'
      }).then(function(records) {
        assert.equal(get(records, 'length'), 0, 'No record was found');
        done();
      });
    };

    store.query('list', {
      name: 'one'
    }).then(function(lists) {
      var list = lists.objectAt(0);
      assert.equal(get(list, 'id'), 'l1', 'Item exists');
      list.deleteRecord();
      list.on('didDelete', AssertListIsDeleted);
      list.save();
    });
  });
});

// Find methods
// -----------------------------------------------------------------------------

test('findAll', function(assert) {
  assert.expect(7);

  let done = assert.async();
  run(function() {
    store.findAll('list').then(function(records) {
      var firstRecord = records.objectAt(0);
      var secondRecord = records.objectAt(1);
      var thirdRecord = records.objectAt(2);

      assert.equal(get(records, 'length'), 3, '3 items were found');

      assert.equal(get(firstRecord, 'name'), 'one', 'First item\'s name is one');
      assert.equal(get(secondRecord, 'name'), 'two', 'Second item\'s name is two');
      assert.equal(get(thirdRecord, 'name'), 'three', 'Third item\'s name is three');

      assert.equal(get(firstRecord, 'day'), 1, 'First item\'s day is 1');
      assert.equal(get(secondRecord, 'day'), 2, 'Second item\'s day is 2');
      assert.equal(get(thirdRecord, 'day'), 3, 'Third item\'s day is 3');

      done();
    });
  });
});

test('findRecord', function(assert) {
  assert.expect(4);

  let done = assert.async();
  run(function() {
    store.findRecord('list', 'l1').then(function(list) {
      assert.equal(get(list, 'id'), 'l1', 'id is loaded correctly');
      assert.equal(get(list, 'name'), 'one', 'name is loaded correctly');
      assert.equal(get(list, 'b'), true, 'b is loaded correctly');
      assert.equal(get(list, 'day'), 1, 'day is loaded correctly');
      done();
    });
  });
});

// Query methods
// -----------------------------------------------------------------------------

test('query', function(assert) {
  assert.expect(7);

  let done1 = assert.async();
  run(function() {
    store.query('list', {
      name: /one|two/
    }).then(function(records) {
      assert.equal(get(records, 'length'), 2, 'found results for /one|two/');
      done1();
    });
  });

  let done2 = assert.async();
  run(function() {
    store.query('list', {
      name: /.+/,
      id: /l1/
    }).then(function(records) {
      assert.equal(get(records, 'length'), 1, 'found results for { name: /.+/, id: /l1/ }');
      done2();
    });
  });

  let done3 = assert.async();
  run(function() {
    store.query('list', {
      name: 'one'
    }).then(function(records) {
      assert.equal(get(records, 'length'), 1, 'found results for name \'one\'');
      done3();
    });
  });

  let done4 = assert.async();
  run(function() {
    store.query('list', {
      b: true
    }).then(function(records) {
      assert.equal(get(records, 'length'), 1, 'found results for { b: true }');
      done4();
    });
  });

  let done5 = assert.async();
  run(function() {
    store.query('list', {
      name: 'two',
      b: false
    }).then(function(records) {
      assert.equal(get(records, 'length'), 1, 'found results for multiple criteria');
      done5();
    });
  });

  let done6 = assert.async();
  run(function() {
    store.query('list', {
      name: 'four',
      b: false
    }).then(function(records) {
      assert.equal(get(records, 'length'), 0, 'found no results when only criteria matches');
      done6();
    });
  });

  let done7 = assert.async();
  run(function() {
    store.query('list', {
      whatever: 'dude'
    }).then(function(records) {
      assert.equal(get(records, 'length'), 0, 'didn\'t find results for nonsense');
      done7();
    });
  });
});

test('queryRecord', function(assert) {
  assert.expect(5);

  let done1 = assert.async();
  run(function() {
    store.queryRecord('list', {
      name: 'two'
    }).then(function(list) {
      assert.equal(get(list, 'id'), 'l2', 'id is loaded correctly');
      assert.equal(get(list, 'name'), 'two', 'name is loaded correctly');
      assert.equal(get(list, 'b'), false, 'b is loaded correctly');
      assert.equal(get(list, 'day'), 2, 'day is loaded correctly');
      done1();
    });
  });

  let done2 = assert.async();
  run(function() {
    store.queryRecord('list', {
      whatever: 'dude'
    }).catch(function() {
      assert.ok(true, 'didn\'t find record for nonsense');
      done2();
    });
  });
});

// Relationship loading
//------------------------------------------------------------------------------

function assertionsForHasManyRelationships(assert, done, items) {
  assert.expect(4);
  var item1 = items.get('firstObject');
  var item2 = items.get('lastObject');
  assert.equal(get(item1, 'id'), 'i1', 'first item id is loaded correctly');
  assert.equal(get(item1, 'name'), 'one', 'first item name is loaded correctly');
  assert.equal(get(item2, 'id'), 'i2', 'first item id is loaded correctly');
  assert.equal(get(item2, 'name'), 'two', 'first item name is loaded correctly');
  done();
}

test('load hasMany relationships when finding a single record', function(assert) {
  let done = assert.async();

  run(function() {
    store.findRecord('list', 'l1').then(function(list) {
      list.get('items').then(function(items) {
        assertionsForHasManyRelationships(assert, done, items);
      });
    });
  });
});
test('load hasMany relationships when finding multiple records', function(assert) {
  let done = assert.async();

  run(function() {
    store.findAll('list').then(function(lists) {
      lists.get('firstObject.items').then(function(items) {
        assertionsForHasManyRelationships(assert, done, items);
      });
    });
  });
});

function assertionsForMissingHasManyRelationships(assert, done, post) {
  assert.expect(2);
  var p1 = post.get('comments').catch(function() {
    assert.ok(true, 'Missing comments prevent all comments from being loaded');
  });
  var p2 = post.get('subscribers').catch(function() {
    assert.ok(true, 'Missing external subscribers prevent all comments from being loaded');
  });
  Ember.RSVP.all([p1, p2]).then(function() {
    done();
  });
}

test('load with missing hasMany relationships when finding a single record', function(assert) {
  let done = assert.async();

  run(function() {
    store.findRecord('post', 'p1').then(function(post) {
      assertionsForMissingHasManyRelationships(assert, done, post);
    });
  });
});

test('load with missing hasMany relationships when finding multiple records', function(assert) {
  let done = assert.async();

  run(function() {
    store.findAll('post').then(function(posts) {
      assertionsForMissingHasManyRelationships(assert, done, posts.get('firstObject'));
    });
  });
});

function assertionsForBelongsToRelationships(assert, done, list) {
  assert.equal(get(list, 'id'), 'l1', 'id is loaded correctly');
  assert.equal(get(list, 'name'), 'one', 'name is loaded correctly');
  done();
}

test('load belongsTo relationships when finding a single record', function(assert) {
  let done = assert.async();
  run(function() {
    store.findRecord('item', 'i1').then(function(item) {
      item.get('list').then(function(list) {
        assertionsForBelongsToRelationships(assert, done, list);
      });
    });
  });
});

test('load belongsTo relationships when finding multiple records', function(assert) {
  let done = assert.async();

  run(function() {
    store.findAll('item').then(function(items) {
      items.get('firstObject.list').then(function(list) {
        assertionsForBelongsToRelationships(assert, done, list);
      });
    });
  });
});

test('load with missing belongsTo relationships when finding a single record', function(assert) {
  assert.expect(2);
  let done = assert.async();

  run(function() {
    var p1 = store.findRecord('comment', 'c2').then(function(comment) {
      return comment.get('post').catch(function() {
        assert.ok(true, 'Related post can\'t be resolved');
      });
    });
    var p2 = store.findRecord('comment', 'c4').then(function(comment) {
      return comment.get('author').catch(function() {
        assert.ok(true, 'External related author can\'t be resolved');
      });
    });
    Ember.RSVP.all([p1, p2]).then(function() {
      done();
    });
  });
});

test('load with missing belongsTo relationships when finding multiple records', function(assert) {
  assert.expect(2);
  let done = assert.async();

  run(function() {
    store.findAll('comment').then(function(comments) {
      var p1 = comments.objectAt(1).get('post').catch(function() {
        assert.ok(true, 'Related post can\'t be resolved');
      });
      var p2 = comments.objectAt(3).get('author').catch(function() {
        assert.ok(true, 'External related author can\'t be resolved');
      });
      Ember.RSVP.all([p1, p2]).then(function() {
        done();
      });
    });
  });
});

test('load embedded hasMany relationships when finding a single record', function(assert) {
  assert.expect(5);

  let done = assert.async();

  run(function() {
    store.findRecord('customer', '1').then(function(customer) {
      var addresses = customer.get('addresses');
      assert.equal(addresses.length, 2);

      var address1 = addresses.get('firstObject');
      var address2 = addresses.get('lastObject');
      assert.equal(get(address1, 'id'), '1',
        'first address id is loaded correctly');
      assert.equal(get(address1, 'addressNumber'), '12345',
        'first address number is loaded correctly');
      assert.equal(get(address2, 'id'), '2',
        'first address id is loaded correctly');
      assert.equal(get(address2, 'addressNumber'), '54321',
        'first address number is loaded correctly');

      done();
    });
  });
});

test('load embedded hasMany relationships when finding multiple records', function(assert) {
  assert.expect(6);

  let done = assert.async();

  run(function() {
    store.findAll('customer').then(function(customers) {
      assert.equal(get(customers, 'length'), 1, 'one customer was retrieved');

      var customer = customers.objectAt(0);
      var addresses = customer.get('addresses');
      assert.equal(addresses.length, 2);

      var address1 = addresses.get('firstObject');
      var address2 = addresses.get('lastObject');
      assert.equal(get(address1, 'id'), '1',
        'first address id is loaded correctly');
      assert.equal(get(address1, 'addressNumber'), '12345',
        'first address number is loaded correctly');
      assert.equal(get(address2, 'id'), '2',
        'first address id is loaded correctly');
      assert.equal(get(address2, 'addressNumber'), '54321',
        'first address number is loaded correctly');

      done();
    });
  });
});

test('load embedded hasMany relationships when querying multiple records', function(assert) {
  assert.expect(6);

  let done = assert.async();

  run(function() {
    store.query('customer', {
      customerNumber: '123'
    }).then(function(customers) {
      assert.equal(get(customers, 'length'), 1);

      var customer = customers.objectAt(0);
      var addresses = customer.get('addresses');
      assert.equal(addresses.length, 2);

      var address1 = addresses.get('firstObject');
      var address2 = addresses.get('lastObject');
      assert.equal(get(address1, 'id'), '1',
        'first address id is loaded correctly');
      assert.equal(get(address1, 'addressNumber'), '12345',
        'first address number is loaded correctly');
      assert.equal(get(address2, 'id'), '2',
        'first address id is loaded correctly');
      assert.equal(get(address2, 'addressNumber'), '54321',
        'first address number is loaded correctly');

      done();
    });
  });
});

test('load embedded belongsTo relationships when finding a single record', function(assert) {
  assert.expect(2);

  let done = assert.async();

  run(function() {
    store.findRecord('customer', '1').then(function(customer) {
      var hour = customer.get('hour');
      assert.equal(get(hour, 'id'), 'h5',
        'hour id is loaded correctly');
      assert.equal(get(hour, 'name'), 'five',
        'hour name is loaded correctly');

      done();
    });
  });
});

test('load hasMany relationships when querying multiple records', function(assert) {
  assert.expect(11);
  let done = assert.async();
  run(function() {
    store.query('order', {
      b: true
    }).then(function(records) {
      var firstRecord = records.objectAt(0);
      var secondRecord = records.objectAt(1);
      var thirdRecord = records.objectAt(2);
      assert.equal(get(records, 'length'), 3, '3 orders were found');
      assert.equal(get(firstRecord, 'name'), 'one', 'First order\'s name is one');
      assert.equal(get(secondRecord, 'name'), 'three', 'Second order\'s name is three');
      assert.equal(get(thirdRecord, 'name'), 'four', 'Third order\'s name is four');

      Ember.RSVP.all([
        firstRecord.get('hours'),
        secondRecord.get('hours'),
        thirdRecord.get('hours')
      ]).then(function(hours) {
        var firstHours = hours[0];
        var secondHours = hours[1];
        var thirdHours = hours[2];
        assert.equal(get(firstHours, 'length'), 2, 'Order one has two hours');
        assert.equal(get(secondHours, 'length'), 2, 'Order three has two hours');
        assert.equal(get(thirdHours, 'length'), 0, 'Order four has no hours');

        var hourOne = firstHours.objectAt(0);
        var hourTwo = firstHours.objectAt(1);
        var hourThree = secondHours.objectAt(0);
        var hourFour = secondHours.objectAt(1);
        assert.equal(get(hourOne, 'amount'), 4, 'Hour one has amount of 4');
        assert.equal(get(hourTwo, 'amount'), 3, 'Hour two has amount of 3');
        assert.equal(get(hourThree, 'amount'), 2, 'Hour three has amount of 2');
        assert.equal(get(hourFour, 'amount'), 1, 'Hour four has amount of 1');

        done();
      });
    });
  });
});

// Relationship saving
//------------------------------------------------------------------------------

test('save belongsTo relationships', function(assert) {
  var listId = 'l2';

  let done = assert.async();
  run(function() {
    store.findRecord('list', listId).then(function(list) {
      var item = store.createRecord('item', {
        name: 'three thousand'
      });
      item.set('list', list);
      return item.save();
    }).then(function(item) {
      store.unloadAll('item');
      return store.findRecord('item', item.get('id'));
    }).then(function(item) {
      item.get('list').then(function(list) {
        assert.ok(item.get('list'), 'list is present');
        assert.equal(list.id, listId, 'list is retrieved correctly');
        done();
      });
    });
  });
});

test('save hasMany relationships', function(assert) {
  var listId = 'l2';

  let done = assert.async();
  run(function() {
    store.findRecord('list', listId).then(function(list) {
      var item = store.createRecord('item', {
        name: 'three thousand'
      });
      return list.get('items').then(function(items) {
        items.pushObject(item);
        return item.save().then(function() {
          return list.save();
        });
      });
    }).then(function() {
      store.unloadAll('list');
      return store.findRecord('list', listId);
    }).then(function(list) {
      list.get('items').then(function(items) {
        var item1 = items.objectAt(0);
        assert.equal(item1.get('name'), 'three thousand', 'item is saved');
        done();
      });
    });
  });
});

// Bulk operations
//------------------------------------------------------------------------------

test('perform multiple changes in bulk', function(assert) {
  const done = assert.async();
  run(function() {

    let promises = [];

    promises.push(
      store.findRecord('list', 'l1').then(function(list) {
        list.set('name', 'updated');
        return list.save();
      })
    );

    promises.push(
      store.createRecord('list', { name: 'Rambo' }).save()
    );

    promises.push(
      store.findRecord('list', 'l2').then(function(list) {
        return list.destroyRecord();
      })
    );

    Ember.RSVP.all(promises).then(function() {

      promises = [];

      promises.push(
        store.findRecord('list', 'l1').then(function(list) {
          assert.equal(get(list, 'name'), 'updated', 'Record was updated successfully');
        })
      );

      promises.push(
        store.query('list', {
          name: 'Rambo'
        }).then(function(lists) {
          assert.equal(get(lists, 'length'), 1, 'Record was created successfully');
        })
      );

      promises.push(
        store.findRecord('list', 'l2').catch(function() {
          assert.ok(true, 'Record was deleted successfully');
        })
      );

      Ember.RSVP.all(promises).then(function() {
        done();
      });
    });
  });
});


text:
package config

import (
	"reflect"
	"testing"
)

func TestSetDefaults(t *testing.T) {
	defer Store.Reset()

	expValues := map[string]string{
		"bar/baz": "key1",
		"boo":     "key2",
	}

	err := SetDefaults("/test/provider/defaults", expValues)
	if err != nil {
		t.Fatal(err)
	}

	values, _ := Store.Get("/test/provider/defaults")
	if !reflect.DeepEqual(values, expValues) {
		t.Fatalf("expected Store.Get to return:\n%v\n\ngot:\n%v", expValues, values)
	}
}


text:
--TEST--
Test gmstrftime() function : usage variation - Checking Preferred date and time representation other than on Windows.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
    die("skip Test is not valid for Windows");
}
if (!setlocale(LC_TIME, "POSIX")) {
    die("skip Locale POSIX is required to run this test");
}
?>
--FILE--
<?php
/* Prototype  : string gmstrftime(string format [, int timestamp])
 * Description: Format a GMT/UCT time/date according to locale settings
 * Source code: ext/date/php_date.c
 * Alias to functions:
 */

echo "*** Testing gmstrftime() : usage variation ***\n";

// Initialise function arguments not being substituted (if any)
$timestamp = gmmktime(8, 8, 8, 8, 8, 2008);
putenv("LC_TIME=POSIX");
date_default_timezone_set("Asia/Calcutta");

//array of values to iterate over
$inputs = array(
      'Preferred date and time representation' => "%c",
	  'Preferred date representation' => "%x",
	  'Preferred time representation' => "%X",
);

// loop through each element of the array for timestamp

foreach($inputs as $key =>$value) {
      echo "\n--$key--\n";
      var_dump( $value );
      var_dump( gmstrftime($value, $timestamp) );
};

?>
===DONE===
--EXPECT--
*** Testing gmstrftime() : usage variation ***

--Preferred date and time representation--
string(2) "%c"
string(24) "Fri Aug  8 08:08:08 2008"

--Preferred date representation--
string(2) "%x"
string(8) "08/08/08"

--Preferred time representation--
string(2) "%X"
string(8) "08:08:08"
===DONE===


text:
export default function not(pred: Function, thisArg: any): Function {
  function notPred(): any {
    return !((<any> notPred).pred.apply((<any> notPred).thisArg, arguments));
  }
  (<any> notPred).pred = pred;
  (<any> notPred).thisArg = thisArg;
  return notPred;
}


text:
//
//  LMTabBarController.m
//  LMLive
//
//  Created by iOSDev on 17/5/10.
//  Copyright © 2017年 linhongmin. All rights reserved.
//

#import "LMTabBarController.h"
#import "LMNavigationViewController.h"
#import "LMHomeViewController.h"
#import "LMLiveViewController.h"
#import "LMMyLiveViewController.h"
#import "LMMineViewController.h"
@interface LMTabBarController ()

@end

@implementation LMTabBarController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupChildControllers];
    CGRect frame=self.tabBar.frame;
    frame.size.height=100;
    frame.origin.y=self.view.height-frame.size.height;
    self.tabBar.frame=frame;
    LMLog(@"tabbar.height%f",self.tabBar.frame.size.height);
    LMLog(@"%s---%@",__func__,self.view.subviews);
}
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    CGRect frame=self.tabBar.frame;
    frame.size.height=100;
    frame.origin.y=self.view.height-frame.size.height;
    self.tabBar.frame=frame;
    LMLog(@"%f",self.tabBar.frame.size.height);
    LMLog(@"%s---%@",__func__,self.view.subviews);

}
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    CGRect frame=self.tabBar.frame;
    frame.size.height=100;
    frame.origin.y=self.view.height-frame.size.height;
    self.tabBar.frame=frame;
    LMLog(@"%f",self.tabBar.frame.size.height);
    LMLog(@"%s---%@",__func__,self.view.subviews);

}
-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    LMLog(@"%f",self.tabBar.frame.size.height);
    LMLog(@"%s---%@",__func__,self.view.subviews);

}
-(void)viewDidLayoutSubviews{
    [super viewDidLayoutSubviews];
    LMLog(@"%f",self.tabBar.frame.size.height);
    LMLog(@"%s---%@",__func__,self.view.subviews);

}
-(void)setupChildControllers{
    //首页
    LMHomeViewController *homeController=[[LMHomeViewController alloc]init];

    [self addOneChildControllerToTabBar:homeController
                                  title:@"首页"
                        normalImageName:@"btn_tabbar_home_normal"
                      selectedImageName:@"btn_tabbar_home_selected"];

    //直播
    LMLiveViewController *liveController=[[LMLiveViewController alloc]init];
    [self addOneChildControllerToTabBar:liveController
                                  title:@"直播"
                        normalImageName:@"btn_tabbar_guanzhu_normal"
                      selectedImageName:@"btn_tabbar_guanzhu_selected"];
    //主播
    LMMyLiveViewController *myLiveController=[[LMMyLiveViewController alloc]init];
    [self addOneChildControllerToTabBar:myLiveController
                                  title:@"主播"
                        normalImageName:@"btn_tabbar_zhibo_normal"
                      selectedImageName:@"btn_tabbar_zhibo_selected"];
    //我的
    LMMineViewController *mineController=[[LMMineViewController alloc]init];
    [self addOneChildControllerToTabBar:mineController
                                  title:@"我的"
                        normalImageName:@"btn_tabbar_wode_normal"
                      selectedImageName:@"btn_tabbar_wode_selected"];

}

-(void)addOneChildControllerToTabBar:(UIViewController *)controller
                               title:(NSString *)title
                     normalImageName:(NSString *)normalName
                   selectedImageName:(NSString *)selectedName{
    //标题
    controller.tabBarItem.title=title;
    controller.navigationItem.title=title;

    //默认图片
    controller.tabBarItem.image=[UIImage imageNamed:normalName];

    //选择图片 苹果默认渲染 取消渲染
    UIImage *selectedImage=[[UIImage imageNamed:selectedName] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

    controller.tabBarItem.selectedImage=selectedImage;

    //选中文字颜色
    NSMutableDictionary *dict=[NSMutableDictionary dictionary];
    dict[NSForegroundColorAttributeName]=[UIColor redColor];
    [controller.tabBarItem setTitleTextAttributes:dict forState:UIControlStateSelected];

    //添加到导航控制器
    LMNavigationViewController *naviController=[[LMNavigationViewController alloc]initWithRootViewController:controller];
    naviController.navigationBar.translucent=NO;
    [self addChildViewController:naviController];

}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end


text:
package org.apache.ignite.internal.pagemem;

import org.apache.ignite.internal.util.typedef.internal.U;

/**
 * Utility class for page ID parts manipulation.
 *
 * @see FullPageId
 */
public final class PageIdUtils {
    /** */
    public static final int PAGE_IDX_SIZE = 32;

    /** */
    public static final int PART_ID_SIZE = 16;

    /** */
    public static final int FLAG_SIZE = 8;

    /** */
    public static final int OFFSET_SIZE = 8;

    /** */
    public static final int TAG_SIZE = 16;

    /** */
    public static final long PAGE_IDX_MASK = ~(-1L << PAGE_IDX_SIZE);

    /** */
    public static final long OFFSET_MASK = ~(-1L << OFFSET_SIZE);

    /** */
    public static final long TAG_MASK = ~(-1L << TAG_SIZE);

    /** Page Index is a monotonically growing number within each partition */
    public static final long PART_ID_MASK = ~(-1L << PART_ID_SIZE);

    /** Flags mask. Flags consists from a number of reserved bits, and page type (data/index page) */
    public static final long FLAG_MASK = ~(-1L << FLAG_SIZE);

    /** */
    private static final long EFFECTIVE_PAGE_ID_MASK = ~(-1L << (PAGE_IDX_SIZE + PART_ID_SIZE));

    /** */
    private static final long PAGE_ID_MASK = ~(-1L << (PAGE_IDX_SIZE + PART_ID_SIZE + FLAG_SIZE));

    /** Max itemid number. */
    public static final int MAX_ITEMID_NUM = 0xFE;

    /** Maximum page number. */
    public static final long MAX_PAGE_NUM = (1L << PAGE_IDX_SIZE) - 1;

    /** Maximum page number. */
    public static final int MAX_PART_ID = (1 << PART_ID_SIZE) - 1;

    /**
     *
     */
    private PageIdUtils() {
        // No-op.
    }

    /**
     * Constructs a page link by the given page ID and 8-byte words within the page.
     *
     * @param pageId Page ID.
     * @param itemId Item ID.
     * @return Page link.
     */
    public static long link(long pageId, int itemId) {
        assert itemId >= 0 && itemId <= MAX_ITEMID_NUM : itemId;
        assert (pageId >> (FLAG_SIZE + PART_ID_SIZE + PAGE_IDX_SIZE)) == 0 : U.hexLong(pageId);

        return pageId | (((long)itemId) << (FLAG_SIZE + PART_ID_SIZE + PAGE_IDX_SIZE));
    }

    /**
     * Extracts a page index from the given page ID.
     *
     * @param pageId Page ID.
     * @return Page index.
     */
    public static int pageIndex(long pageId) {
        return (int)(pageId & PAGE_IDX_MASK); // 4 bytes
    }

    /**
     * Extracts a page ID from the given page link.
     *
     * @param link Page link.
     * @return Page ID.
     */
    public static long pageId(long link) {
        return flag(link) == PageIdAllocator.FLAG_IDX ? link : link & PAGE_ID_MASK;
    }

    /**
     * @param link Page link.
     * @return Effective page id.
     */
    public static long effectivePageId(long link) {
        return link & EFFECTIVE_PAGE_ID_MASK;
    }

    /**
     * @param pageId Page id.
     * @return {@code True} if page id is equal to effective page id.
     */
    public static boolean isEffectivePageId(long pageId) {
        return (pageId & ~EFFECTIVE_PAGE_ID_MASK) == 0;
    }

    /**
     * Index of the item inside of data page.
     *
     * @param link Page link.
     * @return Offset in 8-byte words.
     */
    public static int itemId(long link) {
        return (int)((link >> (PAGE_IDX_SIZE + PART_ID_SIZE + FLAG_SIZE)) & OFFSET_MASK);
    }

    /**
     * Tag of pageId
     *
     * @param link Page link.
     * @return tag - item id + flags
     */
    public static int tag(long link) {
        return (int)((link >> (PAGE_IDX_SIZE + PART_ID_SIZE)) & TAG_MASK);
    }

    /**
     * @param partId Partition ID.
     * @param flag Flags (a number of reserved bits, and page type (data/index page))
     * @param pageIdx Page index, monotonically growing number within each partition
     * @return Page ID constructed from the given pageIdx and partition ID, see {@link FullPageId}
     */
    public static long pageId(int partId, byte flag, int pageIdx) {
        long pageId = flag & FLAG_MASK;

        pageId = (pageId << PART_ID_SIZE) | (partId & PART_ID_MASK);
        pageId = (pageId << (PAGE_IDX_SIZE)) | (pageIdx & PAGE_IDX_MASK);

        return pageId;
    }

    /**
     * @param pageId Page ID.
     * @return Flag.
     */
    public static byte flag(long pageId) {
        return (byte)((pageId >>> (PART_ID_SIZE + PAGE_IDX_SIZE)) & FLAG_MASK);
    }

    /**
     * @param pageId Page ID.
     * @return Partition.
     */
    public static int partId(long pageId) {
        return (int)((pageId >>> PAGE_IDX_SIZE ) & PART_ID_MASK);
    }

    /**
     * @param pageId Page ID.
     * @return New page ID.
     */
    public static long rotatePageId(long pageId) {
        long updatedRotationId = (pageId >>> PAGE_IDX_SIZE + PART_ID_SIZE + FLAG_SIZE) + 1;

        if (updatedRotationId > MAX_ITEMID_NUM)
            updatedRotationId = 1; // We always want non-zero updatedRotationId

        return (pageId & PAGE_ID_MASK) |
            (updatedRotationId << (PAGE_IDX_SIZE + PART_ID_SIZE + FLAG_SIZE));
    }

    /**
     * Masks partition ID from full page ID.
     * @param pageId Page ID to mask partition ID from.
     */
    public static long maskPartitionId(long pageId) {
        return pageId & ~((-1L << PAGE_IDX_SIZE) & (~(-1L << PAGE_IDX_SIZE + PART_ID_SIZE)));
    }

    /**
     * Change page type.
     *
     * @param pageId Old page ID.
     * @param type New page type.
     * @return Changed page ID.
     */
    public static long changeType(long pageId, byte type) {
        return pageId(partId(pageId), type, pageIndex(pageId));
    }

    /**
     * @param pageId Page id.
     */
    public static String toDetailString(long pageId) {
        return "pageId=" + pageId +
            "(offset=" + itemId(pageId) +
            ", flags=" + Integer.toBinaryString(flag(pageId)) +
            ", partId=" + partId(pageId) +
            ", index=" + pageIndex(pageId) +
            ")";
    }

    /**
     * @param pageId Page ID.
     * @param partId Partition ID.
     */
    public static long changePartitionId(long pageId, int partId) {
        byte flag = flag(pageId);
        int pageIdx = pageIndex(pageId);

        return pageId(partId, flag, pageIdx);
    }
}


text:
require 'rubygems'
require 'zip/zip'

class Record < ActiveRecord::Base
  has_many :creators
  has_many :contributors
  has_many :descriptions
  has_many :subjects
  has_many :alternateIdentifiers
  has_many :datauploads
  has_many :relations
  has_many :submissionLogs
  has_many :uploads

  belongs_to :user
  attr_accessible :identifier, :identifierType, :publicationyear, :publisher, :resourcetype, :rights, :title, :local_id

  def set_local_id
    self.local_id = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join
  end

  def create_record_directory
    FileUtils.mkdir("#{Rails.root}/#{DATASHARE_CONFIG['uploads_dir']}/#{self.local_id}")
  end

  def review

    # can we define the character encoding at UTF without a byte recorder marker
    # ANSI encoding right now

    # note - for now, removing the tags to contain multiple XML entries.  This produces invalid XML.
    # however, it appears to be necessary for the XTF index to work properly.

     f = File.new("#{Rails.root}/#{DATASHARE_CONFIG['uploads_dir']}/#{self.local_id}/datacite.xml", "w:ASCII-8BIT")

     f.puts "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
     f.puts "<resource xmlns=\"http://datacite.org/schema/kernel-3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://datacite.org/schema/kernel-3 http://schema.datacite.org/meta/kernel-3/metadata.xsd\">"

     # identifier - datacite: single, mandatory
     # left empty because it will be set by EZID on the merritt side
     f.puts "<identifier identifierType=\"DOI\"></identifier>"

     # creators - datacite: multiple, mandatory
     f.puts "<creators>"
     self.creators.each { |a| f.puts "<creator><creatorName>#{a.creatorName.gsub(/\r/,"")}</creatorName></creator>"}
     f.puts "</creators>"

     # should we allow multiple titles?  datacite does...
     # we're only allowing one title per record

     # titles - datacite: multiple, mandatory
     # datacite - title has an option type attribute that we are not using
     f.puts "<titles>"
     f.puts "<title>#{self.title}</title>"
     f.puts "</titles>"

     # publisher - datacite: single, mandatory
     f.puts "<publisher>#{self.publisher}</publisher>"

     # publication year - datacite: single, mandatory
     f.puts "<publicationYear>#{self.publicationyear}</publicationYear>"

     # subjects - datacite: multiple, optional
     f.puts "<subjects>"
     # subject scheme is optional and open
     #self.subjects.each { |a| f.puts "<subject subjectScheme=\"#{a.subjectScheme.gsub(/\r/,"")}\">#{a.subjectName.gsub(/\r/,"")}</subject>"}
     # for now, just use the subject without a scheme
     self.subjects.each { |a| f.puts "<subject>#{a.subjectName.gsub(/\r/,"")}</subject>"}
     f.puts "</subjects>"

     #contributors - datacite: multiple, optional, mandatory contributorType attribute
     # do we have a default value for contributorType?
     # is this something we plan to use?
     f.puts "<contributors>"
     #self.contributors.each { |a| f.puts "<contributor contributorType=\"#{a.contributorType}\"><contributorName>#{a.contributorName.gsub(/\r/,"")}</contributorName></contributor>"}
     self.contributors.each { |a| f.puts "<contributor contributorType=\"ResearchGroup\"><contributorName>#{a.contributorName.gsub(/\r/,"")}</contributorName></contributor>"}
     f.puts "</contributors>"

     # resourceType - datacite: optional
     # should have a resourceTypeGeneral and a resourceType, may need to modify this
     #f.puts "<resourceType resourceTypeGeneral=\"#{self.resourcetype}\">#{self.resourcetype}</resourceType>"
     f.puts "<resourceType resourceTypeGeneral=\"Dataset\">Dataset</resourceType>"

     # alternate Identifiers - datacite: optional
     # this will be the localID
     #f.puts "<alternateIdentifiers>"
     #self.alternateIdentifiers.each { |a| f.puts "<alternateIdentifier alternateIdentifierType=\"#{a.alternateIdentifierType}\">#{a.alternateIdentifierName}</alternateIdentifier>"}
     #f.puts "</alternateIdentifiers>"

     # relatedIdentifiers - datacite: optional, multiple
     # going to use this for citations
     # and then relations doesn't exist in the datacite schema
     # is this valid without the relatedIdentifiersType?
     # should I be using a different description for this?  N
     # not sure if this is a valid mapping...
     #f.puts "<relatedIdentifiers>"
     #self.relations.each { |a| f.puts "<relatedIdentifier>#{a.relationText.gsub(/\r/,"")}</relatedIdentifier>"}
     #f.puts "</relatedIdentifiers>"

     #<sizes>... this will be exported from merritt, but do we need it in the metadata?

     # formats ?

     # version?

     #rights
     #not required
     #f.puts "<rights>#{self.rights}</rights>"

     #descriptions
     f.puts "<descriptions>"

     # abstract
     if !self.abstract.nil?
       f.puts "<description descriptionType=\"Abstract\">#{CGI::escapeHTML(self.abstract.gsub(/\r/,""))}</description>"
     end

     #methods
     if !self.methods.nil?
       f.puts "<description descriptionType=\"Methods\">#{CGI::escapeHTML(self.methods.gsub(/\r/,""))}</description>"
     end

     # citation

     self.descriptions.each { |a| f.puts "<description descriptionType=\"SeriesInformation\">#{CGI::escapeHTML(a.descriptionText.gsub(/\r/,""))}</description>" }

     f.puts "</descriptions>"

     f.puts "</resource>"

     f.close

     #return contents of file as string
     File.open("#{Rails.root}/#{DATASHARE_CONFIG['uploads_dir']}/#{self.local_id}/datacite.xml", "rb").read
   end

   def generate_merritt_zip
     file_path = "#{Rails.root}/#{DATASHARE_CONFIG['uploads_dir']}/#{self.local_id}"

     if File.exists?("#{file_path}/#{self.local_id}.zip")
       File.delete("#{file_path}/#{self.local_id}.zip")
     end

     zipfile_name = "#{file_path}/#{self.local_id}.zip"

     # target link and doi are generated by merritt
     # they are included here only for testing
     # uncomment if you need them in the archive (ie, if your repository does not supply these)
     f = File.new("#{file_path}/target_link", "w")
     f.puts "http://localhost:3000/download_merritt_file/#{self.local_id}.zip"
     f.close

     f = File.new("#{file_path}/doi", "w")
     f.puts "doi:10.7272/Q6057CV6"
     f.close

     f = File.new("#{file_path}/mrt-datacite.xml", "wb")
     f.puts self.review
     f.close

     Zip::ZipFile.open(zipfile_name, Zip::ZipFile::CREATE) do |zipfile|
       zipfile.add("mrt-datacite.xml", "#{file_path}/mrt-datacite.xml")

       self.purge_temp_files

       self.uploads.each do |d|
          zipfile.add("#{d.upload_file_name}", "#{file_path}/#{d.upload_file_name}")
       end
     end

     # clean up all temp files (again, required because of the glitch in chunked file uploads)
     FileUtils.rm Dir[file_path + "/temp_*"]

   end

   # keep metadata records, but get rid of files that are no longer needed for local storate
   # (storage is intended only until records are uploaded to merritt)
   def purge_files(submission_log_id)

    uploads = Upload.find_all_by_record_id(self.id)

     # archive the file information for submission logs
    uploads.each do |u|
       upload_archive = UploadArchive.new
       upload_archive.submission_log_id = submission_log_id
       upload_archive.upload_file_name = u.upload_file_name
       upload_archive.upload_file_size = u.upload_file_size
       upload_archive.upload_content_type = u.upload_content_type
       upload_archive.save
     end

     Upload.delete_all(:record_id => self.id)

     file_path = "#{Rails.root}/#{DATASHARE_CONFIG['uploads_dir']}/#{self.local_id}"

     # delete the files from local storage now that they have been submitted to merritt
     if File.exists?("#{file_path}")
       FileUtils.rm_rf Dir.glob("#{file_path}/*")
     end
   end

   def send_archive_to_merritt

     # tics will execute, for now, just print to screen
      # note that the 2>&1 is to redirect sterr to stout

     sys_output = "curl --insecure --verbose -u #{MERRITT_CONFIG['merritt_username']}:#{MERRITT_CONFIG['merritt_password']} -F \"file=@./#{DATASHARE_CONFIG['uploads_dir']}/#{self.local_id}/#{self.local_id}.zip\" -F \"notification=#{self.user.email}\" -F \"type=container\" -F \"submitter=#{self.user.external_id}\" -F \"responseForm=xml\" -F \"profile=#{MERRITT_CONFIG['merritt_profile']}\" -F \"localIdentifier=#{self.local_id}\" #{MERRITT_CONFIG['merritt_endpoint']} 2>&1"

     return sys_output
   end

   def required_fields

      required_fields = Array.new

      if self.creators.nil? || self.creators.empty?
        required_fields << "Record must specify at least one creator"
      end

      # should we allow multiple titles?  datacite does...
      # we're only allowing one title per record

      if self.title.nil? || self.title.blank?
        required_fields << "Record must have a title"
      end

      # publisher - datacite: single, mandatory
      if self.publisher.nil? || self.publisher.blank?
        required_fields << "Record must have a publisher"
      end

      # publication year - datacite: single, mandatory
      if self.publicationyear.nil?
        required_fields << "Record must have a publication year"
      end

      #contributors - datacite: multiple, optional, mandatory contributorType attribute
      # we will require contributors for datashare

      if self.contributors.nil? || self.contributors.empty?
        required_fields << "Record must specify at least one contributor"
      end

      return required_fields
   end

   def recommended_fields

      recommended_fields = Array.new

      # subjects - datacite: multiple, optional
      if self.subjects.nil? || self.subjects.empty?
        recommended_fields << "Subject data is strongly recommended.  Your record may be ommitted from search and browse results withough a subject"
      end

      #descriptions

      if self.abstract == "" || self.methods == ""
        recommended_fields << "While not required, an abstract and technical description are strongly recommended."
      end

      return recommended_fields

   end

  # temp files created for multipart uploads
  def purge_temp_files

    file_path = "#{Rails.root}/#{DATASHARE_CONFIG['uploads_dir']}/#{self.local_id}"

    self.uploads.each do |d|

        # a temporary terrible hack to avoid the file corruption problem
        # on chunked uploads

        if File.exist?(file_path + "/temp_" + d.upload_file_name)
          File.delete(file_path + "/" + d.upload_file_name)
          File.rename(file_path + "/temp_" + d.upload_file_name, file_path + "/" + d.upload_file_name)
        end
     end
  end

end


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.junkchen.blelib.sample.MainActivity">

    <Button
        android:id="@+id/btn_singleBle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Ble单设备连接测试"
        android:onClick="doClick"/>

    <Button
        android:id="@+id/btn_multipleBle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Ble多设备连接测试"
        android:onClick="doClick" />

</LinearLayout>


text:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rest-adapter</artifactId>
        <groupId>com.pushtechnology.adapters.rest</groupId>
        <version>5.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>adapter-client</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.pushtechnology.adapters.rest</groupId>
            <artifactId>adapter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-processing</artifactId>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-simple-http</artifactId>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.inject</groupId>
            <artifactId>jersey-hk2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <transformers>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <manifestEntries>
                                <Main-Class>com.pushtechnology.adapters.rest.client.RESTAdapterClientEntry</Main-Class>
                            </manifestEntries>
                        </transformer>
                    </transformers>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-pmd-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <!-- Enable integration tests only when the DIFFUSION_HOME environmental variable is set -->
        <!-- Only runs the embedded services test category by default -->
        <profile>
            <id>integration-test</id>
            <activation>
                <property>
                    <name>env.DIFFUSION_HOME</name>
                </property>
            </activation>

            <build>
                <plugins>
                    <plugin>
                        <artifactId>diffusion-maven-plugin</artifactId>
                        <groupId>com.pushtechnology.diffusion.maven.plugin</groupId>
                        <configuration>
                            <systemProperties>
                                <systemProperty>
                                    <name>diffusion.home</name>
                                    <value>${env.DIFFUSION_HOME}</value>
                                </systemProperty>
                            </systemProperties>
                        </configuration>
                        <executions>
                            <execution>
                                <id>start-diffusion</id>
                                <phase>pre-integration-test</phase>
                                <goals>
                                    <goal>start</goal>
                                </goals>
                                <configuration>
                                    <serverStartTimeout>10000</serverStartTimeout>
                                </configuration>
                            </execution>
                            <execution>
                                <id>stop-diffusion</id>
                                <phase>post-integration-test</phase>
                                <goals>
                                    <goal>stop</goal>
                                </goals>
                            </execution>
                        </executions>
                        <dependencies>
                            <dependency>
                                <groupId>com.pushtechnology.diffusion</groupId>
                                <artifactId>diffusion</artifactId>
                                <version>local-installation</version>
                                <scope>system</scope>
                                <systemPath>${env.DIFFUSION_HOME}/lib/diffusion.jar</systemPath>
                            </dependency>
                        </dependencies>
                    </plugin>

                    <plugin>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>test</id>
                                <phase>integration-test</phase>
                                <goals>
                                    <goal>integration-test</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>verify</id>
                                <phase>post-integration-test</phase>
                                <goals>
                                    <goal>verify</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <groups>com.pushtechnology.adapters.rest.EmbeddedServices</groups>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <!-- Run only the live services test when requested -->
        <profile>
            <id>live-services-test</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>

            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <configuration>
                            <groups>com.pushtechnology.adapters.rest.LiveServices</groups>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <!-- Run both the embedded and live services tests when requested -->
        <profile>
            <id>all-tests</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>

            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <configuration>
                            <groups>com.pushtechnology.adapters.rest.EmbeddedServices,com.pushtechnology.adapters.rest.LiveServices</groups>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>


text:
import sys, json, time, urllib2
from pyquery import PyQuery

# TODO remove this
import pprint as pp

def getPyQueryFromUrl(url):
    opener = urllib2.build_opener()
    opener.addheaders = [('User-agent', 'mozilla 3.6')] #fake agent
    return PyQuery(opener.open(url).read())

def printProgressBar(current,maximum):
    percentage = int(float(current)/float(maximum)*100.0)
    blockNum = percentage/2
    blockStr = '['
    for i in range(0,blockNum):
        blockStr += "■"
    for i in range(0,50-blockNum):
        blockStr += " "
    blockStr += "]"
    sys.stdout.write("\r%d%% %s " % (percentage, blockStr))
    sys.stdout.flush()
    if current >= maximum:
        print

def writeDictionary(dict, fileName):
    text = json.dumps(dic, sort_keys=True, ensure_ascii=False, indent=4)
    with open(fileName, 'w') as f:
        f.write(text.encode("utf-8"))

def numberPageUrl(url):
    # example url: http://www.brainyquote.com/quotes/topics/topic_success.html
    if i == 1:
        page = ''
    else:
        page = str(i)
    return url[:len(url)-5] + page + '.html'

dic = { "results" :[]}

BRAINYQUOTE_URL = "https://www.brainyquote.com"
TOPIC_URL = "https://www.brainyquote.com/quotes/topics.html"
ORIGINAL_URL = 'http://www.brainyquote.com/quotes/topics/topic_success.html'
OUTPUT_FILENAME = 'englishQuotes.json'

# find how many topics exist
q = getPyQueryFromUrl(TOPIC_URL)
topicATags = q.find(".topicIndexChicklet")
for topicATag in topicATags.items():
    pp.pprint(topicATag.attr['href'])
    break
'''
# iterate through topics

# find the last page number on the topic
q = getPyQueryFromURL(ORIGINAL_URL)
pagingUl = q.find(".pagination, .bqNPgn, .pagination-sm")
pagingUlQ = PyQuery(pagingUl)
aTags = pagingUlQ.find('a')
aTags.pop()
lastPage = int(PyQuery(aTags.pop()).text())

print "There are " + str(lastPage) + " pages in this topic"

for i in range(1,lastPage+1):

    printProgressBar(i,lastPage)

    url = numberPageUrl(ORIGINAL_URL)

    q = getPyQueryFromURL(url)

    # filter out quote and info
    for quoteDiv in q.find('.bqQt'):

        tempDict = {}
        quoteDivQ = PyQuery(quoteDiv)
        quoteText = quoteDivQ.find('.b-qt')[0]
        author = quoteDivQ.find(".bq-aut")[0]
        tagDiv = quoteDivQ.find(".kw-box")
        tags = PyQuery(tagDiv).find('a')
        tempDict['quote'] = PyQuery(quoteText).text()
        tempDict['source'] = PyQuery(author).text()
        tempDict['tags'] = []
        for tag in tags:
                txt = PyQuery(tag).text()
                tempDict['tags'].append(txt)
        tempDict['views'] = 0
        tempDict['category'] = 'Success'
        dic["results"].append(tempDict)

# convert into json and write
writeDictionary(dic, OUTPUT_FILENAME)
'''