text:
<!DOCTYPE HTML>

    <meta charset="utf-8">
    <meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,menu-scalable=no" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />

    <link href="{$responseAdmin}/css/H-ui.min.css" rel="stylesheet"
          type="text/css" />
    <link href="{$responseAdmin}/css/H-ui.admin.css" rel="stylesheet"
          type="text/css" />
    <link href="{$responseAdmin}/lib/Hui-iconfont/1.0.1/iconfont.css"
          rel="stylesheet" type="text/css" />

    <title>流失回流</title>

     运营查询 >
    流失用户 >生命周期 

    <form action="" method="get">

            创建时间:<input type="text"
                         onfocus="<literal>WdatePicker({maxDate:'\'%y-%M-{%d}\'}'})</literal>"
                         id="datemin" value="{$search['datemin']}" name="datemin"
                         class="input-text Wdate" style="width: 120px;">

                <select size="1" name="Channel" class="select">
                        <option value="">渠道</option>
                        <volist name = "Channel" id = "val">
                              <option  value="{$val['account']}"   <if condition  = "$search['Channel'] eq $val['account']"> selected = "true"</if>   >{$val['name']}</option>
                        </volist>
				</select>

            <button type="submit" class="btn btn-success" id="" name="">
                 搜索
            </button>

    </form>

        <form action="/Jy_statistics/LossBackflow/excelData" id="excel" method="post">
            <textarea  style="display: none;" name = "data">{$info|json_encode}</textarea>
			 
					导出excel

        </form>

            区间
            用户数
            百分比

        <volist name = "info" id ="val">

                {$val['Name']}
                {$val['Loss']}
                {$val['Rate']*100|round=2}%

        </volist>

{$page}


text:
namespace cc {
namespace {

TEST(DrawQuadTest, CopySharedQuadState) {
  gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0);
  gfx::Size content_bounds(26, 28);
  gfx::Rect visible_content_rect(10, 12, 14, 16);
  gfx::Rect clip_rect(19, 21, 23, 25);
  bool is_clipped = true;
  float opacity = 0.25f;

  scoped_ptr<SharedQuadState> state(SharedQuadState::Create());
  state->SetAll(quad_transform,
                content_bounds,
                visible_content_rect,
                clip_rect,
                is_clipped,
                opacity);

  scoped_ptr<SharedQuadState> copy(state->Copy());
  EXPECT_EQ(quad_transform, copy->content_to_target_transform);
  EXPECT_RECT_EQ(visible_content_rect, copy->visible_content_rect);
  EXPECT_EQ(opacity, copy->opacity);
  EXPECT_RECT_EQ(clip_rect, copy->clip_rect);
  EXPECT_EQ(is_clipped, copy->is_clipped);
}

scoped_ptr<SharedQuadState> CreateSharedQuadState() {
  gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0);
  gfx::Size content_bounds(26, 28);
  gfx::Rect visible_content_rect(10, 12, 14, 16);
  gfx::Rect clip_rect(19, 21, 23, 25);
  bool is_clipped = false;
  float opacity = 1.f;

  scoped_ptr<SharedQuadState> state(SharedQuadState::Create());
  state->SetAll(quad_transform,
                content_bounds,
                visible_content_rect,
                clip_rect,
                is_clipped,
                opacity);
  return state.Pass();
}

void CompareDrawQuad(DrawQuad* quad,
                     DrawQuad* copy,
                     SharedQuadState* copy_shared_state) {
  EXPECT_EQ(quad->material, copy->material);
  EXPECT_RECT_EQ(quad->rect, copy->rect);
  EXPECT_RECT_EQ(quad->visible_rect, copy->visible_rect);
  EXPECT_RECT_EQ(quad->opaque_rect, copy->opaque_rect);
  EXPECT_EQ(quad->needs_blending, copy->needs_blending);
  EXPECT_EQ(copy_shared_state, copy->shared_quad_state);
}

#define CREATE_SHARED_STATE() \
    scoped_ptr<SharedQuadState> shared_state(CreateSharedQuadState()); \
    scoped_ptr<SharedQuadState> copy_shared_state(shared_state->Copy()); \

#define QUAD_DATA \
    gfx::Rect quad_rect(30, 40, 50, 60); \
    gfx::Rect quad_visible_rect(40, 50, 30, 20); \
    gfx::Rect quad_opaque_rect(60, 55, 10, 10); \
    bool needs_blending = true;

#define SETUP_AND_COPY_QUAD_NEW(Type, quad) \
    scoped_ptr<DrawQuad> copy_new(quad_new->Copy(copy_shared_state.get())); \
    CompareDrawQuad(quad_new.get(), copy_new.get(), copy_shared_state.get()); \
    const Type* copy_quad = Type::MaterialCast(copy_new.get());

#define SETUP_AND_COPY_QUAD_ALL(Type, quad) \
    scoped_ptr<DrawQuad> copy_all(quad_all->Copy(copy_shared_state.get())); \
    CompareDrawQuad(quad_all.get(), copy_all.get(), copy_shared_state.get()); \
    copy_quad = Type::MaterialCast(copy_all.get());

#define SETUP_AND_COPY_QUAD_NEW_1(Type, quad, a) \
    scoped_ptr<DrawQuad> copy_new(quad_new->Copy(copy_shared_state.get(), a)); \
    CompareDrawQuad(quad_new.get(), copy_new.get(), copy_shared_state.get()); \
    const Type* copy_quad = Type::MaterialCast(copy_new.get());

#define SETUP_AND_COPY_QUAD_ALL_1(Type, quad, a) \
    scoped_ptr<DrawQuad> copy_all(quad_all->Copy(copy_shared_state.get(), a)); \
    CompareDrawQuad(quad_all.get(), copy_all.get(), copy_shared_state.get()); \
    copy_quad = Type::MaterialCast(copy_all.get());

#define CREATE_QUAD_1_NEW(Type, a) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a); \
    } \
    SETUP_AND_COPY_QUAD_NEW(Type, quad_new);

#define CREATE_QUAD_1_ALL(Type, a) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, a); \
    } \
    SETUP_AND_COPY_QUAD_ALL(Type, quad_all);

#define CREATE_QUAD_2_NEW(Type, a, b) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a, b); \
    } \
    SETUP_AND_COPY_QUAD_NEW(Type, quad_new);

#define CREATE_QUAD_2_ALL(Type, a, b) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, a, b); \
    } \
    SETUP_AND_COPY_QUAD_ALL(Type, quad_all);

#define CREATE_QUAD_3_NEW(Type, a, b, c) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a, b, c); \
    } \
    SETUP_AND_COPY_QUAD_NEW(Type, quad_new);

#define CREATE_QUAD_3_ALL(Type, a, b, c) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, a, b, c); \
    } \
    SETUP_AND_COPY_QUAD_ALL(Type, quad_all);

#define CREATE_QUAD_4_NEW(Type, a, b, c, d) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d); \
    } \
    SETUP_AND_COPY_QUAD_NEW(Type, quad_new);

#define CREATE_QUAD_4_ALL(Type, a, b, c, d) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, a, b, c, d); \
    } \
    SETUP_AND_COPY_QUAD_ALL(Type, quad_all);

#define CREATE_QUAD_5_NEW(Type, a, b, c, d, e) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e); \
    } \
    SETUP_AND_COPY_QUAD_NEW(Type, quad_new);

#define CREATE_QUAD_5_ALL(Type, a, b, c, d, e) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, a, b, c, d, e); \
    } \
    SETUP_AND_COPY_QUAD_ALL(Type, quad_all);

#define CREATE_QUAD_5_NEW_1(Type, a, b, c, d, e, copyA) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e); \
    } \
    SETUP_AND_COPY_QUAD_NEW_1(Type, quad_new, copyA);

#define CREATE_QUAD_5_ALL_1(Type, a, b, c, d, e, copyA) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, a, b, c, d, e); \
    } \
    SETUP_AND_COPY_QUAD_ALL_1(Type, quad_all, copyA);

#define CREATE_QUAD_6_NEW(Type, a, b, c, d, e, f) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e, f); \
    } \
    SETUP_AND_COPY_QUAD_NEW(Type, quad_new);

#define CREATE_QUAD_6_ALL(Type, a, b, c, d, e, f) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, a, b, c, d, e, f); \
    } \
    SETUP_AND_COPY_QUAD_ALL(Type, quad_all);

#define CREATE_QUAD_7_NEW(Type, a, b, c, d, e, f, g) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e, f, g); \
    } \
    SETUP_AND_COPY_QUAD_NEW(Type, quad_new);

#define CREATE_QUAD_7_ALL(Type, a, b, c, d, e, f, g) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, \
                       a, b, c, d, e, f, g); \
    } \
    SETUP_AND_COPY_QUAD_ALL(Type, quad_all);

#define CREATE_QUAD_8_NEW(Type, a, b, c, d, e, f, g, h) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e, f, g, h); \
    } \
    SETUP_AND_COPY_QUAD_NEW(Type, quad_new);

#define CREATE_QUAD_8_ALL(Type, a, b, c, d, e, f, g, h) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, \
                       a, b, c, d, e, f, g, h); \
    } \
    SETUP_AND_COPY_QUAD_ALL(Type, quad_all);

#define CREATE_QUAD_8_NEW_1(Type, a, b, c, d, e, f, g, h, copyA) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, a, b, c, d, e, f, g, h); \
    } \
    SETUP_AND_COPY_QUAD_NEW_1(Type, quad_new, copyA);

#define CREATE_QUAD_8_ALL_1(Type, a, b, c, d, e, f, g, h, copyA) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, \
                       a, b, c, d, e, f, g, h); \
    } \
    SETUP_AND_COPY_QUAD_ALL_1(Type, quad_all, copyA);

#define CREATE_QUAD_9_NEW(Type, a, b, c, d, e, f, g, h, i) \
    scoped_ptr<Type> quad_new(Type::Create()); \
    { \
      QUAD_DATA \
      quad_new->SetNew(shared_state.get(), quad_rect, \
                       a, b, c, d, e, f, g, h, i); \
    } \
    SETUP_AND_COPY_QUAD_NEW(Type, quad_new);

#define CREATE_QUAD_9_ALL(Type, a, b, c, d, e, f, g, h, i) \
    scoped_ptr<Type> quad_all(Type::Create()); \
    { \
      QUAD_DATA \
      quad_all->SetAll(shared_state.get(), quad_rect, quad_opaque_rect, \
                       quad_visible_rect, needs_blending, \
                       a, b, c, d, e, f, g, h, i); \
    } \
    SETUP_AND_COPY_QUAD_ALL(Type, quad_all);

TEST(DrawQuadTest, CopyCheckerboardDrawQuad) {
  SkColor color = 0xfabb0011;
  CREATE_SHARED_STATE();

  CREATE_QUAD_1_NEW(CheckerboardDrawQuad, color);
  EXPECT_EQ(DrawQuad::CHECKERBOARD, copy_quad->material);
  EXPECT_EQ(color, copy_quad->color);

  CREATE_QUAD_1_ALL(CheckerboardDrawQuad, color);
  EXPECT_EQ(DrawQuad::CHECKERBOARD, copy_quad->material);
  EXPECT_EQ(color, copy_quad->color);
}

TEST(DrawQuadTest, CopyDebugBorderDrawQuad) {
  SkColor color = 0xfabb0011;
  int width = 99;
  CREATE_SHARED_STATE();

  CREATE_QUAD_2_NEW(DebugBorderDrawQuad, color, width);
  EXPECT_EQ(DrawQuad::DEBUG_BORDER, copy_quad->material);
  EXPECT_EQ(color, copy_quad->color);
  EXPECT_EQ(width, copy_quad->width);

  CREATE_QUAD_2_ALL(DebugBorderDrawQuad, color, width);
  EXPECT_EQ(DrawQuad::DEBUG_BORDER, copy_quad->material);
  EXPECT_EQ(color, copy_quad->color);
  EXPECT_EQ(width, copy_quad->width);
}

TEST(DrawQuadTest, CopyIOSurfaceDrawQuad) {
  gfx::Rect opaque_rect(3, 7, 10, 12);
  gfx::Size size(58, 95);
  unsigned texture_id = 72;
  IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;
  CREATE_SHARED_STATE();

  CREATE_QUAD_4_NEW(
      IOSurfaceDrawQuad, opaque_rect, size, texture_id, orientation);
  EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material);
  EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect);
  EXPECT_EQ(size, copy_quad->io_surface_size);
  EXPECT_EQ(texture_id, copy_quad->io_surface_texture_id);
  EXPECT_EQ(orientation, copy_quad->orientation);

  CREATE_QUAD_3_ALL(IOSurfaceDrawQuad, size, texture_id, orientation);
  EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material);
  EXPECT_EQ(size, copy_quad->io_surface_size);
  EXPECT_EQ(texture_id, copy_quad->io_surface_texture_id);
  EXPECT_EQ(orientation, copy_quad->orientation);
}

TEST(DrawQuadTest, CopyRenderPassDrawQuad) {
  RenderPass::Id render_pass_id(22, 64);
  bool is_replica = true;
  ResourceProvider::ResourceId mask_resource_id = 78;
  gfx::Rect contents_changed_since_last_frame(42, 11, 74, 24);
  gfx::RectF mask_u_v_rect(-45.f, -21.f, 33.f, 19.f);
  WebKit::WebFilterOperations filters;
  filters.append(WebKit::WebFilterOperation::createBlurFilter(1.f));
  WebKit::WebFilterOperations background_filters;
  background_filters.append(
      WebKit::WebFilterOperation::createGrayscaleFilter(1.f));
  skia::RefPtr<SkImageFilter> filter =
      skia::AdoptRef(new SkBlurImageFilter(SK_Scalar1, SK_Scalar1));

  RenderPass::Id copied_render_pass_id(235, 11);
  CREATE_SHARED_STATE();

  CREATE_QUAD_8_NEW_1(RenderPassDrawQuad,
                      render_pass_id,
                      is_replica,
                      mask_resource_id,
                      contents_changed_since_last_frame,
                      mask_u_v_rect,
                      filters,
                      filter,
                      background_filters,
                      copied_render_pass_id);
  EXPECT_EQ(DrawQuad::RENDER_PASS, copy_quad->material);
  EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id);
  EXPECT_EQ(is_replica, copy_quad->is_replica);
  EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id);
  EXPECT_RECT_EQ(contents_changed_since_last_frame,
                 copy_quad->contents_changed_since_last_frame);
  EXPECT_EQ(mask_u_v_rect.ToString(), copy_quad->mask_uv_rect.ToString());
  EXPECT_EQ(filters, copy_quad->filters);
  EXPECT_EQ(filter, copy_quad->filter);
  EXPECT_EQ(background_filters, copy_quad->background_filters);

  CREATE_QUAD_8_ALL_1(RenderPassDrawQuad,
                      render_pass_id,
                      is_replica,
                      mask_resource_id,
                      contents_changed_since_last_frame,
                      mask_u_v_rect,
                      filters,
                      filter,
                      background_filters,
                      copied_render_pass_id);
  EXPECT_EQ(DrawQuad::RENDER_PASS, copy_quad->material);
  EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id);
  EXPECT_EQ(is_replica, copy_quad->is_replica);
  EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id);
  EXPECT_RECT_EQ(contents_changed_since_last_frame,
                 copy_quad->contents_changed_since_last_frame);
  EXPECT_EQ(mask_u_v_rect.ToString(), copy_quad->mask_uv_rect.ToString());
  EXPECT_EQ(filters, copy_quad->filters);
  EXPECT_EQ(filter, copy_quad->filter);
  EXPECT_EQ(background_filters, copy_quad->background_filters);
}

TEST(DrawQuadTest, CopySolidColorDrawQuad) {
  SkColor color = 0x49494949;
  CREATE_SHARED_STATE();

  CREATE_QUAD_1_NEW(SolidColorDrawQuad, color);
  EXPECT_EQ(DrawQuad::SOLID_COLOR, copy_quad->material);
  EXPECT_EQ(color, copy_quad->color);

  CREATE_QUAD_1_ALL(SolidColorDrawQuad, color);
  EXPECT_EQ(DrawQuad::SOLID_COLOR, copy_quad->material);
  EXPECT_EQ(color, copy_quad->color);
}

TEST(DrawQuadTest, CopyStreamVideoDrawQuad) {
  gfx::Rect opaque_rect(3, 7, 10, 12);
  unsigned texture_id = 64;
  gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
  CREATE_SHARED_STATE();

  CREATE_QUAD_3_NEW(StreamVideoDrawQuad, opaque_rect, texture_id, matrix);
  EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
  EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect);
  EXPECT_EQ(texture_id, copy_quad->texture_id);
  EXPECT_EQ(matrix, copy_quad->matrix);

  CREATE_QUAD_2_ALL(StreamVideoDrawQuad, texture_id, matrix);
  EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
  EXPECT_EQ(texture_id, copy_quad->texture_id);
  EXPECT_EQ(matrix, copy_quad->matrix);
}

TEST(DrawQuadTest, CopyTextureDrawQuad) {
  gfx::Rect opaque_rect(3, 7, 10, 12);
  unsigned resource_id = 82;
  bool premultiplied_alpha = true;
  gfx::PointF uv_top_left(0.5f, 224.f);
  gfx::PointF uv_bottom_right(51.5f, 260.f);
  const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  bool flipped = true;
  CREATE_SHARED_STATE();

  CREATE_QUAD_7_NEW(TextureDrawQuad,
                    opaque_rect,
                    resource_id,
                    premultiplied_alpha,
                    uv_top_left,
                    uv_bottom_right,
                    vertex_opacity,
                    flipped);
  EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material);
  EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect);
  EXPECT_EQ(resource_id, copy_quad->resource_id);
  EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha);
  EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
  EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
  EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4);
  EXPECT_EQ(flipped, copy_quad->flipped);

  CREATE_QUAD_6_ALL(TextureDrawQuad,
                    resource_id,
                    premultiplied_alpha,
                    uv_top_left,
                    uv_bottom_right,
                    vertex_opacity,
                    flipped);
  EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material);
  EXPECT_EQ(resource_id, copy_quad->resource_id);
  EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha);
  EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
  EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
  EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4);
  EXPECT_EQ(flipped, copy_quad->flipped);
}

TEST(DrawQuadTest, ClipTextureDrawQuad) {
  gfx::Rect opaque_rect(3, 7, 10, 12);
  unsigned resource_id = 82;
  bool premultiplied_alpha = true;
  bool flipped = true;
  CREATE_SHARED_STATE();
  // The original quad position is (30, 40) its size is 50*60.
  shared_state->content_to_target_transform =
      gfx::Transform(1.f, 0.f, 0.f, 1.f, 10.f, 20.f);
  // After transformation, the quad position is (40, 60) its size is 50*60.
  shared_state->clip_rect = gfx::Rect(50, 70, 30, 20);

  // The original quad is 'ABCD', the clipped quad is 'abcd':
  //40 50       90
  // B--:-------C 60
  // |  b----c -|-70
  // |  |    |  |
  // |  a----d -|-90
  // |          |
  // A----------D 120
  // UV and vertex opacity are stored per vertex on the parent rectangle 'ABCD'.

  // This is the UV value for vertex 'B'.
  gfx::PointF uv_top_left(0.1f, 0.2f);
  // This is the UV value for vertex 'D'.
  gfx::PointF uv_bottom_right(0.9f, 0.8f);
  // This the vertex opacity for the vertices 'ABCD'.
  const float vertex_opacity[] = { 0.3f, 0.4f, 0.7f, 0.8f };
  {
    CREATE_QUAD_7_NEW(TextureDrawQuad,
                      opaque_rect,
                      resource_id,
                      premultiplied_alpha,
                      uv_top_left,
                      uv_bottom_right,
                      vertex_opacity,
                      flipped);
    CREATE_QUAD_6_ALL(TextureDrawQuad,
                      resource_id,
                      premultiplied_alpha,
                      uv_top_left,
                      uv_bottom_right,
                      vertex_opacity,
                      flipped);
    EXPECT_TRUE(quad_all->PerformClipping());

    // This is the expected UV value for vertex 'b'.
    // uv(b) = uv(B) + (Bb / BD) * (uv(D) - uv(B))
    // 0.3 = 0.2 + (10 / 60) * (0.8 - 0.2)
    gfx::PointF uv_top_left_clipped(0.26f, 0.3f);
    // This is the expected UV value for vertex 'd'.
    // uv(d) = uv(B) + (Bd / BD) * (uv(D) - uv(B))
    gfx::PointF uv_bottom_right_clipped(0.74f, 0.5f);
    // This the expected vertex opacity for the vertices 'abcd'.
    // They are computed with a bilinear interpolation of the corner values.
    const float vertex_opacity_clipped[] = { 0.43f, 0.45f, 0.65f, 0.67f };

    EXPECT_EQ(uv_top_left_clipped, quad_all->uv_top_left);
    EXPECT_EQ(uv_bottom_right_clipped, quad_all->uv_bottom_right);
    EXPECT_FLOAT_ARRAY_EQ(vertex_opacity_clipped, quad_all->vertex_opacity, 4);
  }

  uv_top_left = gfx::PointF(0.8f, 0.7f);
  uv_bottom_right = gfx::PointF(0.2f, 0.1f);
  {
    CREATE_QUAD_7_NEW(TextureDrawQuad,
                      opaque_rect,
                      resource_id,
                      premultiplied_alpha,
                      uv_top_left,
                      uv_bottom_right,
                      vertex_opacity,
                      flipped);
    CREATE_QUAD_6_ALL(TextureDrawQuad,
                      resource_id,
                      premultiplied_alpha,
                      uv_top_left,
                      uv_bottom_right,
                      vertex_opacity,
                      flipped);
    EXPECT_TRUE(quad_all->PerformClipping());

    // This is the expected UV value for vertex 'b'.
    gfx::PointF uv_top_left_clipped(0.68f, 0.6f);
    // This is the expected UV value for vertex 'd'.
    gfx::PointF uv_bottom_right_clipped(0.32f, 0.4f);

    EXPECT_EQ(uv_top_left_clipped, quad_all->uv_top_left);
    EXPECT_EQ(uv_bottom_right_clipped, quad_all->uv_bottom_right);
  }
}

TEST(DrawQuadTest, CopyTileDrawQuad) {
  gfx::Rect opaque_rect(33, 44, 22, 33);
  unsigned resource_id = 104;
  gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
  gfx::Size texture_size(85, 32);
  bool swizzle_contents = true;
  CREATE_SHARED_STATE();

  CREATE_QUAD_5_NEW(TileDrawQuad,
                    opaque_rect,
                    resource_id,
                    tex_coord_rect,
                    texture_size,
                    swizzle_contents);
  EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material);
  EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect);
  EXPECT_EQ(resource_id, copy_quad->resource_id);
  EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
  EXPECT_EQ(texture_size, copy_quad->texture_size);
  EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents);

  CREATE_QUAD_4_ALL(TileDrawQuad,
                    resource_id,
                    tex_coord_rect,
                    texture_size,
                    swizzle_contents);
  EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material);
  EXPECT_EQ(resource_id, copy_quad->resource_id);
  EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
  EXPECT_EQ(texture_size, copy_quad->texture_size);
  EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents);
}

TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
  gfx::Rect opaque_rect(3, 7, 10, 12);
  gfx::SizeF tex_scale(0.75f, 0.5f);
  VideoLayerImpl::FramePlane y_plane;
  y_plane.resource_id = 45;
  y_plane.size = gfx::Size(34, 23);
  y_plane.format = 8;
  VideoLayerImpl::FramePlane u_plane;
  u_plane.resource_id = 532;
  u_plane.size = gfx::Size(134, 16);
  u_plane.format = 2;
  VideoLayerImpl::FramePlane v_plane;
  v_plane.resource_id = 4;
  v_plane.size = gfx::Size(456, 486);
  v_plane.format = 46;
  CREATE_SHARED_STATE();

  CREATE_QUAD_5_NEW(
      YUVVideoDrawQuad, opaque_rect, tex_scale, y_plane, u_plane, v_plane);
  EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
  EXPECT_RECT_EQ(opaque_rect, copy_quad->opaque_rect);
  EXPECT_EQ(tex_scale, copy_quad->tex_scale);
  EXPECT_EQ(y_plane.resource_id, copy_quad->y_plane.resource_id);
  EXPECT_EQ(y_plane.size, copy_quad->y_plane.size);
  EXPECT_EQ(y_plane.format, copy_quad->y_plane.format);
  EXPECT_EQ(u_plane.resource_id, copy_quad->u_plane.resource_id);
  EXPECT_EQ(u_plane.size, copy_quad->u_plane.size);
  EXPECT_EQ(u_plane.format, copy_quad->u_plane.format);
  EXPECT_EQ(v_plane.resource_id, copy_quad->v_plane.resource_id);
  EXPECT_EQ(v_plane.size, copy_quad->v_plane.size);
  EXPECT_EQ(v_plane.format, copy_quad->v_plane.format);

  CREATE_QUAD_4_ALL(YUVVideoDrawQuad, tex_scale, y_plane, u_plane, v_plane);
  EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
  EXPECT_EQ(tex_scale, copy_quad->tex_scale);
  EXPECT_EQ(y_plane.resource_id, copy_quad->y_plane.resource_id);
  EXPECT_EQ(y_plane.size, copy_quad->y_plane.size);
  EXPECT_EQ(y_plane.format, copy_quad->y_plane.format);
  EXPECT_EQ(u_plane.resource_id, copy_quad->u_plane.resource_id);
  EXPECT_EQ(u_plane.size, copy_quad->u_plane.size);
  EXPECT_EQ(u_plane.format, copy_quad->u_plane.format);
  EXPECT_EQ(v_plane.resource_id, copy_quad->v_plane.resource_id);
  EXPECT_EQ(v_plane.size, copy_quad->v_plane.size);
  EXPECT_EQ(v_plane.format, copy_quad->v_plane.format);
}

class DrawQuadIteratorTest : public testing::Test {
 protected:
  ResourceProvider::ResourceId IncrementResourceId(
      ResourceProvider::ResourceId id) {
    ++num_resources_;
    return id + 1;
  }

  int IterateAndCount(DrawQuad* quad) {
    num_resources_ = 0;
    quad->IterateResources(base::Bind(
        &DrawQuadIteratorTest::IncrementResourceId, base::Unretained(this)));
    return num_resources_;
  }

 private:
  int num_resources_;
};

TEST_F(DrawQuadIteratorTest, CheckerboardDrawQuad) {
  SkColor color = 0xfabb0011;

  CREATE_SHARED_STATE();
  CREATE_QUAD_1_NEW(CheckerboardDrawQuad, color);
  EXPECT_EQ(0, IterateAndCount(quad_new.get()));
}

TEST_F(DrawQuadIteratorTest, DebugBorderDrawQuad) {
  SkColor color = 0xfabb0011;
  int width = 99;

  CREATE_SHARED_STATE();
  CREATE_QUAD_2_NEW(DebugBorderDrawQuad, color, width);
  EXPECT_EQ(0, IterateAndCount(quad_new.get()));
}

TEST_F(DrawQuadIteratorTest, IOSurfaceDrawQuad) {
  gfx::Rect opaque_rect(3, 7, 10, 12);
  gfx::Size size(58, 95);
  unsigned texture_id = 72;
  IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;

  CREATE_SHARED_STATE();
  CREATE_QUAD_4_NEW(
      IOSurfaceDrawQuad, opaque_rect, size, texture_id, orientation);
  EXPECT_EQ(0, IterateAndCount(quad_new.get()));
}

TEST_F(DrawQuadIteratorTest, RenderPassDrawQuad) {
  RenderPass::Id render_pass_id(22, 64);
  bool is_replica = true;
  ResourceProvider::ResourceId mask_resource_id = 78;
  gfx::Rect contents_changed_since_last_frame(42, 11, 74, 24);
  gfx::RectF mask_u_v_rect(-45.f, -21.f, 33.f, 19.f);
  WebKit::WebFilterOperations filters;
  filters.append(WebKit::WebFilterOperation::createBlurFilter(1.f));
  WebKit::WebFilterOperations background_filters;
  background_filters.append(
      WebKit::WebFilterOperation::createGrayscaleFilter(1.f));
  skia::RefPtr<SkImageFilter> filter =
      skia::AdoptRef(new SkBlurImageFilter(SK_Scalar1, SK_Scalar1));

  RenderPass::Id copied_render_pass_id(235, 11);

  CREATE_SHARED_STATE();
  CREATE_QUAD_8_NEW_1(RenderPassDrawQuad,
                      render_pass_id,
                      is_replica,
                      mask_resource_id,
                      contents_changed_since_last_frame,
                      mask_u_v_rect,
                      filters,
                      filter,
                      background_filters,
                      copied_render_pass_id);
  EXPECT_EQ(mask_resource_id, quad_new->mask_resource_id);
  EXPECT_EQ(1, IterateAndCount(quad_new.get()));
  EXPECT_EQ(mask_resource_id + 1, quad_new->mask_resource_id);
}

TEST_F(DrawQuadIteratorTest, SolidColorDrawQuad) {
  SkColor color = 0x49494949;

  CREATE_SHARED_STATE();
  CREATE_QUAD_1_NEW(SolidColorDrawQuad, color);
  EXPECT_EQ(0, IterateAndCount(quad_new.get()));
}

TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) {
  gfx::Rect opaque_rect(3, 7, 10, 12);
  unsigned texture_id = 64;
  gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);

  CREATE_SHARED_STATE();
  CREATE_QUAD_3_NEW(StreamVideoDrawQuad, opaque_rect, texture_id, matrix);
  EXPECT_EQ(0, IterateAndCount(quad_new.get()));
}

TEST_F(DrawQuadIteratorTest, TextureDrawQuad) {
  gfx::Rect opaque_rect(3, 7, 10, 12);
  unsigned resource_id = 82;
  bool premultiplied_alpha = true;
  gfx::PointF uv_top_left(0.5f, 224.f);
  gfx::PointF uv_bottom_right(51.5f, 260.f);
  const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  bool flipped = true;

  CREATE_SHARED_STATE();
  CREATE_QUAD_7_NEW(TextureDrawQuad,
                    opaque_rect,
                    resource_id,
                    premultiplied_alpha,
                    uv_top_left,
                    uv_bottom_right,
                    vertex_opacity,
                    flipped);
  EXPECT_EQ(resource_id, quad_new->resource_id);
  EXPECT_EQ(1, IterateAndCount(quad_new.get()));
  EXPECT_EQ(resource_id + 1, quad_new->resource_id);
}

TEST_F(DrawQuadIteratorTest, TileDrawQuad) {
  gfx::Rect opaque_rect(33, 44, 22, 33);
  unsigned resource_id = 104;
  gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
  gfx::Size texture_size(85, 32);
  bool swizzle_contents = true;

  CREATE_SHARED_STATE();
  CREATE_QUAD_5_NEW(TileDrawQuad,
                    opaque_rect,
                    resource_id,
                    tex_coord_rect,
                    texture_size,
                    swizzle_contents);
  EXPECT_EQ(resource_id, quad_new->resource_id);
  EXPECT_EQ(1, IterateAndCount(quad_new.get()));
  EXPECT_EQ(resource_id + 1, quad_new->resource_id);
}

TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) {
  gfx::Rect opaque_rect(3, 7, 10, 12);
  gfx::SizeF tex_scale(0.75f, 0.5f);
  VideoLayerImpl::FramePlane y_plane;
  y_plane.resource_id = 45;
  y_plane.size = gfx::Size(34, 23);
  y_plane.format = 8;
  VideoLayerImpl::FramePlane u_plane;
  u_plane.resource_id = 532;
  u_plane.size = gfx::Size(134, 16);
  u_plane.format = 2;
  VideoLayerImpl::FramePlane v_plane;
  v_plane.resource_id = 4;
  v_plane.size = gfx::Size(456, 486);
  v_plane.format = 46;

  CREATE_SHARED_STATE();
  CREATE_QUAD_5_NEW(
      YUVVideoDrawQuad, opaque_rect, tex_scale, y_plane, u_plane, v_plane);
  EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
  EXPECT_EQ(y_plane.resource_id, quad_new->y_plane.resource_id);
  EXPECT_EQ(u_plane.resource_id, quad_new->u_plane.resource_id);
  EXPECT_EQ(v_plane.resource_id, quad_new->v_plane.resource_id);
  EXPECT_EQ(3, IterateAndCount(quad_new.get()));
  EXPECT_EQ(y_plane.resource_id + 1, quad_new->y_plane.resource_id);
  EXPECT_EQ(u_plane.resource_id + 1, quad_new->u_plane.resource_id);
  EXPECT_EQ(v_plane.resource_id + 1, quad_new->v_plane.resource_id);
}

}  // namespace
}  // namespace cc

redpajama_set_name: RedPajamaGithub


text:
Imports Dynamo.Entities

Public Class DynamoContext(Of provider As DynamoProvider)
    Implements IDisposable

    Protected ReadOnly CustomProvider As DynamoProvider
    Public ReadOnly Conventions As DynamoConventions
    Private _DatabaseName As String

    Public Event MappingDataToEntity As EventHandler(Of DynamoMappingDataToEntityEventArgs)

    Public Sub New(ByVal ConnectionStringName As String)
        Me.Conventions = New DynamoConventions
        Me.CustomProvider = Activator.CreateInstance(GetType(provider), {ConnectionStringName, Conventions})
        AddHandler Me.CustomProvider.MappingDataToEntity, Sub(s, e) RaiseEvent MappingDataToEntity(s, e)
    End Sub

    Public Function Db(ByVal DatabaseName As String) As DynamoQueryable(Of Entity)
        _DatabaseName = DatabaseName
        Return New DynamoQueryable(Of Entity)(CustomProvider)
    End Function

#Region "IDisposable Support"
    Private disposedValue As Boolean ' To detect redundant calls

    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                CustomProvider.Dispose()
            End If

        End If
        Me.disposedValue = True
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

End Class

Public Class DynamoMappingDataToEntityEventArgs
    Inherits EventArgs

    Public Entity As Entity
    Public DataSchema As Object

End Class

Public Class DynamoConventions

    Public Property AutodetectEntityFieldID As Boolean
    Public Property EntityFieldID As String
    Public Property EntityFieldName As String

    Sub New()
        _AutodetectEntityFieldID = False
        _EntityFieldID = ""
        _EntityFieldName = ""
    End Sub

End Class


text:
<?php
/**
 * Created by PhpStorm.
 * User: hong
 * Date: 11/10/16
 * Time: 1:52 PM
 */

namespace O\DesignPatterns\Behavioral\TemplateMethod;

abstract class Journey
{
    private $stringToDo = [];

    final public function takeATrip()
    {
        $this->thingsToDo[] = $this->buyAFlight();
        $this->thingsToDo[] = $this->takePlane();
        $this->thingsToDo[] = $this->enjoyVacation();
        $buyGift = $this->buyGift();

        if ($buyGift !== null) {
            $this->thingsToDo[] = $buyGift;
        }

        $this->thingsToDo[] = $this->takePlane();
    }

    abstract protected function enjoyVacation(): string;

    protected function buyGift()
    {
        return null;
    }

    private function buyAFlight(): string
    {
        return 'Buy a flight ticket';
    }

    private function takePlane(): string
    {
        return 'Taking the plane';
    }

    /**
     * @return string[]
     */
    public function getThingsToDo(): array
    {
        return $this->thingsToDo;
    }
}


text:
<?php

namespace alxmsl\Odnoklassniki\API\Exception;

/**
 * Unknown Odnoklassniki API client exception
 * @author alxmsl
 */
final class UnknownClientErrorException extends ClientException {}


text:
package gov.nih.nci.cabig.caaers.event;

import gov.nih.nci.cabig.ctms.domain.DomainObject;
import org.acegisecurity.Authentication;

/**
 * Raised when Study is modified.
 * @author: Biju Joseph
 */
public class ResearchStaffModificationEvent extends EntityModificationEvent {

    public ResearchStaffModificationEvent(Authentication authentication, DomainObject entity) {
        super(authentication, entity, EventType.RESEARCH_STAFF);
    }
}


text:
__author__ = 'Jace Xu'
__version__ = "0.5"

from .autoit import options, properties, commands
from .autoit import AutoItError

from .autoit import error
from .autoit import auto_it_set_option
from .autoit import clip_get
from .autoit import clip_put
from .autoit import is_admin
from .autoit import drive_map_add
from .autoit import drive_map_del
from .autoit import drive_map_get
from .autoit import mouse_click
from .autoit import mouse_click_drag
from .autoit import mouse_down
from .autoit import mouse_get_cursor
from .autoit import mouse_get_pos
from .autoit import mouse_move
from .autoit import mouse_up
from .autoit import mouse_wheel
from .autoit import opt
from .autoit import pixel_checksum
from .autoit import pixel_get_color
from .autoit import pixel_search
from .autoit import send
from .autoit import tooltip

from .process import run
from .process import run_wait
from .process import process_close
from .process import process_exists
from .process import process_set_priority
from .process import process_wait
from .process import process_wait_close
from .process import run_as
from .process import run_as_wait
from .process import shutdown

from .win import win_activate
from .win import win_activate_by_handle
from .win import win_active
from .win import win_active_by_handle
from .win import win_close
from .win import win_close_by_handle
from .win import win_exists
from .win import win_exists_by_handle
from .win import win_get_caret_pos
from .win import win_get_class_list
from .win import win_get_class_list_by_handle
from .win import win_get_client_size
from .win import win_get_client_size_by_handle
from .win import win_get_handle
from .win import win_get_handle_as_text
from .win import win_get_pos
from .win import win_get_pos_by_handle
from .win import win_get_process
from .win import win_get_process_by_handle
from .win import win_get_state
from .win import win_get_state_by_handle
from .win import win_get_text
from .win import win_get_text_by_handle
from .win import win_get_title
from .win import win_get_title_by_handle
from .win import win_kill
from .win import win_kill_by_handle
from .win import win_menu_select_item
from .win import win_menu_select_item_by_handle
from .win import win_minimize_all
from .win import win_minimize_all_undo
from .win import win_move
from .win import win_move_by_handle
from .win import win_set_on_top
from .win import win_set_on_top_by_handle
from .win import win_set_state
from .win import win_set_state_by_handle
from .win import win_set_title
from .win import win_set_title_by_handle
from .win import win_set_trans
from .win import win_set_trans_by_handle
from .win import win_wait
from .win import win_wait_by_handle
from .win import win_wait_active
from .win import win_wait_active_by_handle
from .win import win_wait_close
from .win import win_wait_close_by_handle
from .win import win_wait_not_active
from .win import win_wait_not_active_by_handle

from .control import control_click
from .control import control_click_by_handle
from .control import control_command
from .control import control_command_by_handle
from .control import control_list_view
from .control import control_list_view_by_handle
from .control import control_disable
from .control import control_disable_by_handle
from .control import control_enable
from .control import control_enable_by_handle
from .control import control_focus
from .control import control_focus_by_handle
from .control import control_get_focus
from .control import control_get_focus_by_handle
from .control import control_get_handle
from .control import control_get_handle_as_text
from .control import control_get_pos
from .control import control_get_pos_by_handle
from .control import control_get_text
from .control import control_get_text_by_handle
from .control import control_hide
from .control import control_hide_by_handle
from .control import control_move
from .control import control_move_by_handle
from .control import control_send
from .control import control_send_by_handle
from .control import control_set_text
from .control import control_set_text_by_handle
from .control import control_show
from .control import control_show_by_handle
from .control import control_tree_view
from .control import control_tree_view_by_handle
from .control import statusbar_get_text
from .control import statusbar_get_text_by_handle


text:
@implementation NSString (URLEncoding)

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding
{
	return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
                                                               (__bridge CFStringRef)self,
                                                               NULL,
                                                               (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                               CFStringConvertNSStringEncodingToEncoding(encoding));
}

@end


text:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using log4net;
using OpenMetaverse;
using OpenMetaverse.StructuredData;

namespace OpenSim.Framework
{
    public enum ProfileShape : byte
    {
        Circle = 0,
        Square = 1,
        IsometricTriangle = 2,
        EquilateralTriangle = 3,
        RightTriangle = 4,
        HalfCircle = 5
    }

    public enum HollowShape : byte
    {
        Same = 0,
        Circle = 16,
        Square = 32,
        Triangle = 48
    }

    public enum PCodeEnum : byte
    {
        Primitive = 9,
        Avatar = 47,
        Grass = 95,
        NewTree = 111,
        ParticleSystem = 143,
        Tree = 255
    }

    public enum Extrusion : byte
    {
        Straight = 16,
        Curve1 = 32,
        Curve2 = 48,
        Flexible = 128
    }

    [Serializable]
    public class PrimitiveBaseShape
    {
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        public static readonly UUID DEFAULT_TEXTURE_ID = new UUID("89556747-24cb-43ed-920b-47caed15465f");

        #region Properties

        // TextureEntries
        Primitive.TextureEntry m_textures;

        [XmlIgnore]
        public Primitive.TextureEntry Textures
        {
            get { return m_textures; }
            set
            {
                m_textures = value;
                m_textureEntryBytes = null;  // parallel data no longer in sync
            }
        }

        // Provided for better documentation/readability to document places where byte array accessors are used
        byte[] m_textureEntryBytes;  // persisted byte version of m_textures

        [XmlIgnore]
        public byte[] TextureEntryBytes
        {
            get
            {
                // Already calculated the bytes
                if (m_textureEntryBytes != null)
                    return m_textureEntryBytes;
                // need to recalc the bytes
                return m_textures.GetBytes();
            }
            set
            {
                m_textureEntryBytes = value;
                // Now initialize m_textures to match the byte[] m_textureEntry
                if (value == null)
                    m_textures = new Primitive.TextureEntry(UUID.Zero);
                else
                    m_textures = BytesToTextureEntry(value);
            }
        }

        // Called only during during serialization/deserialization/viewer packets
        // Provided for serialization compatibility, use Textures/TextureEntryBytes instead.
        public byte[] TextureEntry
        {
            get { return TextureEntryBytes; }
            set { TextureEntryBytes = value; }
        }

        public ushort PathBegin { set; get; }
        public byte PathCurve { get; set; }
        public ushort PathEnd { get; set; }
        public sbyte PathRadiusOffset { get; set; }
        public byte PathRevolutions { get; set; }
        public byte PathScaleX { get; set; }
        public byte PathScaleY { get; set; }
        public byte PathShearX { get; set; }
        public byte PathShearY { get; set; }
        public sbyte PathSkew { get; set; }
        public sbyte PathTaperX { get; set; }
        public sbyte PathTaperY { get; set; }
        public sbyte PathTwist { get; set; }
        public sbyte PathTwistBegin { get; set; }
        public byte PCode { get; set; }
        public ushort ProfileBegin { get; set; }
        public ushort ProfileEnd { get; set; }

        public byte ProfileCurve
        {
            get { return (byte)((byte)HollowShape | (byte)ProfileShape); }

            set
            {
                // Handle hollow shape component
                byte hollowShapeByte = (byte)(value & 0xf0);

                if (!Enum.IsDefined(typeof(HollowShape), hollowShapeByte))
                {
                    m_log.WarnFormat(
                        "[SHAPE]: Attempt to set a ProfileCurve with a hollow shape value of {0}, which isn't a valid enum.  Replacing with default shape.",
                        hollowShapeByte);

                    this.HollowShape = HollowShape.Same;
                }
                else
                {
                    this.HollowShape = (HollowShape)hollowShapeByte;
                }

                // Handle profile shape component
                byte profileShapeByte = (byte)(value & 0xf);

                if (!Enum.IsDefined(typeof(ProfileShape), profileShapeByte))
                {
                    m_log.WarnFormat(
                        "[SHAPE]: Attempt to set a ProfileCurve with a profile shape value of {0}, which isn't a valid enum.  Replacing with square.",
                        profileShapeByte);

                    this.ProfileShape = ProfileShape.Square;
                }
                else
                {
                    this.ProfileShape = (ProfileShape)profileShapeByte;
                }
            }
        }

        public ushort ProfileHollow { get; set; }
        public ProfileShape ProfileShape { get; set; }
        public HollowShape HollowShape { get; set; }

        public Vector3 Scale { get; set; }
        public byte State { get; set; }

        // Physics
        public PhysicsShapeType PreferredPhysicsShape { get; set; }

        // Materials
        [XmlIgnore]
        public RenderMaterials RenderMaterials { get; set; }

        // Used for XML Serialization
        public byte[] RenderMaterialsBytes
        {
            get { return RenderMaterials.ToBytes(); }
            set { RenderMaterials = RenderMaterials.FromBytes(value, 0); }
        }

        // Sculpted
        public bool SculptEntry { get; set; }
        public UUID SculptTexture { get; set; }
        public byte SculptType { get; set; }

        [XmlIgnore]
        public byte[] SculptData { get; set; }

        // Mesh
        public int VertexCount { get; set; }
        public int HighLODBytes { get; set; }
        public int MidLODBytes { get; set; }
        public int LowLODBytes { get; set; }
        public int LowestLODBytes { get; set; }

        // Flexi
        public bool FlexiEntry { get; set; }
        public int FlexiSoftness { get; set; }
        public float FlexiTension { get; set; }
        public float FlexiDrag { get; set; }
        public float FlexiGravity { get; set; }
        public float FlexiWind { get; set; }
        public float FlexiForceX { get; set; }
        public float FlexiForceY { get; set; }
        public float FlexiForceZ { get; set; }

        //Bright n sparkly
        public bool LightEntry { get; set; }
        public float LightColorR { get; set; }
        public float LightColorG { get; set; }
        public float LightColorB { get; set; }

        float _lightColorA = 1f;
        public float LightColorA
        {
            get { return _lightColorA; }
            set { _lightColorA = value; }
        }

        public float LightRadius { get; set; }
        public float LightCutoff { get; set; }
        public float LightFalloff { get; set; }

        float _lightIntensity = 1f;
        public float LightIntensity
        {
            get { return _lightIntensity; }
            set { _lightIntensity = Math.Min(value, 1.0f); }
        }

        // Light Projection Filter
        public bool ProjectionEntry { get; set; }

        /// <summary>
        /// Gets or sets the UUID of the texture the projector emits.
        /// </summary>
        /// <value>The projection texture UUID.</value>
        public UUID ProjectionTextureUUID { get; set; }

        /// <summary>
        /// Gets or sets the projection Field of View in radians.
        /// Valid range is from 0.0 to 3.0. Invalid values are clamped to the valid range.
        /// </summary>
        /// <value>The projection FOV.</value>
        float _projectionFOV;
        public float ProjectionFOV
        {
            get { return _projectionFOV; }
            set { _projectionFOV = Util.Clip(value, 0.0f, 3.0f); }
        }

        /// <summary>
        /// Gets or sets the projection focus - aka how far away from the source prim the texture will be sharp.  Beyond this value the texture and its border will gradually get blurry out to the limit of the effective range.
        /// </summary>
        /// <value>The projection focus distance in meters.</value>
        public float ProjectionFocus { get; set; }

        /// <summary>
        /// Gets or sets the projection ambiance - the brightness of a very blurred edition of the projected texture that is placed on all faces of all objects within the projector's FOV and effective range.
        /// Valid range is from 0.0 on up. Invalid values are clamped to the valid range.
        /// </summary>
        /// <value>The projection ambiance brightness.</value>
        float _projectionAmb;
        public float ProjectionAmbiance
        {
            get { return _projectionAmb; }
            set { _projectionAmb = Math.Max(0.0f, value); }
        }

        /// <summary>
        /// Entries to store media textures on each face
        /// </summary>
        /// Do not change this value directly - always do it through an IMoapModule.
        /// Lock before manipulating.
        public PrimMedia Media { get; set; }

        #endregion

        #region Constructors

        public PrimitiveBaseShape()
        {
            SculptTexture = UUID.Zero;
            SculptData = new byte[0];
            PCode = (byte)PCodeEnum.Primitive;
            ExtraParams = new byte[1];
            Textures = new Primitive.TextureEntry(DEFAULT_TEXTURE_ID);
            RenderMaterials = new RenderMaterials();
        }

        /// <summary>
        /// Construct a PrimitiveBaseShape object from a OpenMetaverse.Primitive object
        /// </summary>
        /// <param name="prim"></param>
        public PrimitiveBaseShape(Primitive prim)
        {
            //            m_log.DebugFormat("[PRIMITIVE BASE SHAPE]: Creating from {0}", prim.ID);
            PCode = (byte)prim.PrimData.PCode;
            ExtraParams = new byte[1];

            State = prim.PrimData.State;
            PathBegin = Primitive.PackBeginCut(prim.PrimData.PathBegin);
            PathEnd = Primitive.PackEndCut(prim.PrimData.PathEnd);
            PathScaleX = Primitive.PackPathScale(prim.PrimData.PathScaleX);
            PathScaleY = Primitive.PackPathScale(prim.PrimData.PathScaleY);
            PathShearX = (byte)Primitive.PackPathShear(prim.PrimData.PathShearX);
            PathShearY = (byte)Primitive.PackPathShear(prim.PrimData.PathShearY);
            PathSkew = Primitive.PackPathTwist(prim.PrimData.PathSkew);
            ProfileBegin = Primitive.PackBeginCut(prim.PrimData.ProfileBegin);
            ProfileEnd = Primitive.PackEndCut(prim.PrimData.ProfileEnd);
            Scale = prim.Scale;
            PathCurve = (byte)prim.PrimData.PathCurve;
            ProfileCurve = (byte)prim.PrimData.ProfileCurve;
            ProfileHollow = Primitive.PackProfileHollow(prim.PrimData.ProfileHollow);
            PathRadiusOffset = Primitive.PackPathTwist(prim.PrimData.PathRadiusOffset);
            PathRevolutions = Primitive.PackPathRevolutions(prim.PrimData.PathRevolutions);
            PathTaperX = Primitive.PackPathTaper(prim.PrimData.PathTaperX);
            PathTaperY = Primitive.PackPathTaper(prim.PrimData.PathTaperY);
            PathTwist = Primitive.PackPathTwist(prim.PrimData.PathTwist);
            PathTwistBegin = Primitive.PackPathTwist(prim.PrimData.PathTwistBegin);

            Textures = prim.Textures;   // also updates TextureEntry (and TextureEntryBytes)

            if (prim.Sculpt != null)
            {
                SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None);
                SculptData = prim.Sculpt.GetBytes();
                SculptTexture = prim.Sculpt.SculptTexture;
                SculptType = (byte)prim.Sculpt.Type;
            }
            else
            {
                SculptType = (byte)OpenMetaverse.SculptType.None;
                SculptTexture = UUID.Zero;
                SculptData = new byte[0];
            }

            RenderMaterials = new RenderMaterials();
        }

        #endregion

        private Primitive.TextureEntry BytesToTextureEntry(byte[] data)
        {
            try
            {
                return new Primitive.TextureEntry(data, 0, data.Length);
            }
            catch
            {
                m_log.WarnFormat("[SHAPE]: Failed to decode texture entries, length={0}", (data == null) ? 0 : data.Length);
                return new Primitive.TextureEntry(UUID.Zero);
            }
        }

        public static PrimitiveBaseShape Default
        {
            get
            {
                PrimitiveBaseShape boxShape = CreateBox();

                boxShape.SetScale(0.5f);

                return boxShape;
            }
        }

        public static PrimitiveBaseShape Create()
        {
            PrimitiveBaseShape shape = new PrimitiveBaseShape();
            return shape;
        }

        public static PrimitiveBaseShape CreateBox()
        {
            PrimitiveBaseShape shape = Create();

            shape.PathCurve = (byte) Extrusion.Straight;
            shape.ProfileShape = ProfileShape.Square;
            shape.PathScaleX = 100;
            shape.PathScaleY = 100;

            return shape;
        }

        public static PrimitiveBaseShape CreateSphere()
        {
            PrimitiveBaseShape shape = Create();

            shape.PathCurve = (byte) Extrusion.Curve1;
            shape.ProfileShape = ProfileShape.HalfCircle;
            shape.PathScaleX = 100;
            shape.PathScaleY = 100;

            return shape;
        }

        public static PrimitiveBaseShape CreateCylinder()
        {
            PrimitiveBaseShape shape = Create();

            shape.PathCurve = (byte) Extrusion.Curve1;
            shape.ProfileShape = ProfileShape.Square;

            shape.PathScaleX = 100;
            shape.PathScaleY = 100;

            return shape;
        }

        public void SetScale(float side)
        {
            Scale = new Vector3(side, side, side);
        }

        public void SetHeight(float height)
        {
            Scale = new Vector3(Scale.X, Scale.Y, height);
        }

        public void SetRadius(float radius)
        {
            float diameter = radius * 2f;
            Scale = new Vector3(diameter, diameter, Scale.Z);
        }

        public PrimitiveBaseShape Copy()
        {
            PrimitiveBaseShape shape = (PrimitiveBaseShape)MemberwiseClone();
            shape.TextureEntryBytes = (byte[])TextureEntryBytes.Clone();
            shape.Media = new PrimMedia(Media);
            shape.RenderMaterials = RenderMaterials.Copy();

            return shape;
        }

        public static PrimitiveBaseShape CreateCylinder(float radius, float height)
        {
            PrimitiveBaseShape shape = CreateCylinder();

            shape.SetHeight(height);
            shape.SetRadius(radius);

            return shape;
        }

        public void SetPathRange(Vector3 pathRange)
        {
            PathBegin = Primitive.PackBeginCut(pathRange.X);
            PathEnd = Primitive.PackEndCut(pathRange.Y);
        }

        public void SetPathRange(float begin, float end)
        {
            PathBegin = Primitive.PackBeginCut(begin);
            PathEnd = Primitive.PackEndCut(end);
        }

        public void SetSculptProperties(byte sculptType, UUID SculptTextureUUID)
        {
            SculptType = sculptType;
            SculptTexture = SculptTextureUUID;
        }

        public void SetProfileRange(Vector3 profileRange)
        {
            ProfileBegin = Primitive.PackBeginCut(profileRange.X);
            ProfileEnd = Primitive.PackEndCut(profileRange.Y);
        }

        public void SetProfileRange(float begin, float end)
        {
            ProfileBegin = Primitive.PackBeginCut(begin);
            ProfileEnd = Primitive.PackEndCut(end);
        }

        [XmlIgnore]
        public byte[] ExtraParams
        {
            get
            {
                return ExtraParamsToBytes();
            }
            set
            {
                ReadInExtraParamsBytes(value);
            }
        }

        /// <summary>
        /// Calculate a hash value over fields that can affect the underlying physics shape.
        /// Things like RenderMaterials and TextureEntry data are not included.
        /// </summary>
        /// <param name="size"></param>
        /// <param name="lod"></param>
        /// <returns>ulong - a calculated hash value</returns>
        public ulong GetMeshKey(Vector3 size, float lod)
        {
            ulong hash = 5381;

            hash = djb2(hash, this.PathCurve);
            hash = djb2(hash, (byte)((byte)this.HollowShape | (byte)this.ProfileShape));
            hash = djb2(hash, this.PathBegin);
            hash = djb2(hash, this.PathEnd);
            hash = djb2(hash, this.PathScaleX);
            hash = djb2(hash, this.PathScaleY);
            hash = djb2(hash, this.PathShearX);
            hash = djb2(hash, this.PathShearY);
            hash = djb2(hash, (byte)this.PathTwist);
            hash = djb2(hash, (byte)this.PathTwistBegin);
            hash = djb2(hash, (byte)this.PathRadiusOffset);
            hash = djb2(hash, (byte)this.PathTaperX);
            hash = djb2(hash, (byte)this.PathTaperY);
            hash = djb2(hash, this.PathRevolutions);
            hash = djb2(hash, (byte)this.PathSkew);
            hash = djb2(hash, this.ProfileBegin);
            hash = djb2(hash, this.ProfileEnd);
            hash = djb2(hash, this.ProfileHollow);

            // TODO: Separate scale out from the primitive shape data (after
            // scaling is supported at the physics engine level)
            byte[] scaleBytes = size.GetBytes();
            for (int i = 0; i < scaleBytes.Length; i++)
                hash = djb2(hash, scaleBytes[i]);

            // Include LOD in hash, accounting for endianness
            byte[] lodBytes = new byte[4];
            Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(lodBytes, 0, 4);
            }
            for (int i = 0; i < lodBytes.Length; i++)
                hash = djb2(hash, lodBytes[i]);

            // include sculpt UUID
            if (this.SculptEntry)
            {
                scaleBytes = this.SculptTexture.GetBytes();
                for (int i = 0; i < scaleBytes.Length; i++)
                    hash = djb2(hash, scaleBytes[i]);

                hash = djb2(hash, this.SculptType);
            }

            return hash;
        }

        private ulong djb2(ulong hash, byte c)
        {
            return ((hash << 5) + hash) + (ulong)c;
        }

        private ulong djb2(ulong hash, ushort c)
        {
            hash = ((hash << 5) + hash) + (ulong)((byte)c);
            return ((hash << 5) + hash) + (ulong)(c >> 8);
        }

        public byte[] ExtraParamsToBytes()
        {
//            m_log.DebugFormat("[EXTRAPARAMS]: Called ExtraParamsToBytes()");

            bool hasSculptEntry = false;

            ushort FlexiEP = 0x10;
            ushort LightEP = 0x20;
            ushort SculptEP = 0x30;
            ushort ProjectionEP = 0x40;

            int i = 0;
            uint TotalBytesLength = 1; // ExtraParamsNum

            uint ExtraParamsNum = 0;
            if (FlexiEntry)
            {
                ExtraParamsNum++;
                TotalBytesLength += 16;// data
                TotalBytesLength += 2 + 4; // type
            }

            if (LightEntry)
            {
                ExtraParamsNum++;
                TotalBytesLength += 16;// data
                TotalBytesLength += 2 + 4; // type
            }

            if (SculptEntry)
            {
                hasSculptEntry = true;
                ExtraParamsNum++;
                TotalBytesLength += 17;// data
                TotalBytesLength += 2 + 4; // type
            }

            if (ProjectionEntry)
            {
                ExtraParamsNum++;
                TotalBytesLength += 28;// data
                TotalBytesLength += 2 + 4;// type
            }

            byte[] returnbytes = new byte[TotalBytesLength];

            // uint paramlength = ExtraParamsNum;

            // Stick in the number of parameters
            returnbytes[i++] = (byte)ExtraParamsNum;

            if (FlexiEntry)
            {
                byte[] FlexiData = GetFlexiBytes();

                returnbytes[i++] = (byte)(FlexiEP % 256);
                returnbytes[i++] = (byte)((FlexiEP >> 8) % 256);

                returnbytes[i++] = (byte)(FlexiData.Length % 256);
                returnbytes[i++] = (byte)((FlexiData.Length >> 8) % 256);
                returnbytes[i++] = (byte)((FlexiData.Length >> 16) % 256);
                returnbytes[i++] = (byte)((FlexiData.Length >> 24) % 256);
                Array.Copy(FlexiData, 0, returnbytes, i, FlexiData.Length);
                i += FlexiData.Length;
            }

            if (LightEntry)
            {
                byte[] LightData = GetLightBytes();

                returnbytes[i++] = (byte)(LightEP % 256);
                returnbytes[i++] = (byte)((LightEP >> 8) % 256);

                returnbytes[i++] = (byte)(LightData.Length % 256);
                returnbytes[i++] = (byte)((LightData.Length >> 8) % 256);
                returnbytes[i++] = (byte)((LightData.Length >> 16) % 256);
                returnbytes[i++] = (byte)((LightData.Length >> 24) % 256);
                Array.Copy(LightData, 0, returnbytes, i, LightData.Length);
                i += LightData.Length;
            }

            if (hasSculptEntry)
            {
                byte[] SculptData = GetSculptBytes();

                returnbytes[i++] = (byte)(SculptEP % 256);
                returnbytes[i++] = (byte)((SculptEP >> 8) % 256);

                returnbytes[i++] = (byte)(SculptData.Length % 256);
                returnbytes[i++] = (byte)((SculptData.Length >> 8) % 256);
                returnbytes[i++] = (byte)((SculptData.Length >> 16) % 256);
                returnbytes[i++] = (byte)((SculptData.Length >> 24) % 256);
                Array.Copy(SculptData, 0, returnbytes, i, SculptData.Length);
                i += SculptData.Length;
            }

            if (ProjectionEntry)
            {
                byte[] ProjectionData = GetProjectionBytes();

                returnbytes[i++] = (byte)(ProjectionEP % 256);
                returnbytes[i++] = (byte)((ProjectionEP >> 8) % 256);
                returnbytes[i++] = (byte)((ProjectionData.Length) % 256);
                returnbytes[i++] = (byte)((ProjectionData.Length >> 16) % 256);
                returnbytes[i++] = (byte)((ProjectionData.Length >> 20) % 256);
                returnbytes[i++] = (byte)((ProjectionData.Length >> 24) % 256);
                Array.Copy(ProjectionData, 0, returnbytes, i, ProjectionData.Length);
                i += ProjectionData.Length;
            }

            if (!FlexiEntry && !LightEntry && !SculptEntry && !ProjectionEntry)
            {
                byte[] returnbyte = new byte[1];
                returnbyte[0] = 0;
                return returnbyte;
            }

            return returnbytes;
        }

        public void ReadInUpdateExtraParam(ushort type, bool inUse, byte[] data)
        {
            const ushort FlexiEP = 0x10;
            const ushort LightEP = 0x20;
            const ushort SculptEP = 0x30;
            const ushort ProjectionEP = 0x40;

            switch (type)
            {
                case FlexiEP:
                    if (!inUse)
                    {
                        FlexiEntry = false;
                        return;
                    }
                    ReadFlexiData(data, 0);
                    break;

                case LightEP:
                    if (!inUse)
                    {
                        LightEntry = false;
                        return;
                    }
                    ReadLightData(data, 0);
                    break;

                case SculptEP:
                    if (!inUse)
                    {
                        SculptEntry = false;
                        return;
                    }
                    ReadSculptData(data, 0);
                    break;
                case ProjectionEP:
                    if (!inUse)
                    {
                        ProjectionEntry = false;
                        return;
                    }
                    ReadProjectionData(data, 0);
                    break;
            }
        }

        public void ReadInExtraParamsBytes(byte[] data)
        {
            if (data == null || data.Length == 1)
                return;

            const ushort FlexiEP = 0x10;
            const ushort LightEP = 0x20;
            const ushort SculptEP = 0x30;
            const ushort ProjectionEP = 0x40;

            bool lGotFlexi = false;
            bool lGotLight = false;
            bool lGotSculpt = false;
            bool lGotFilter = false;

            int i = 0;
            byte extraParamCount = 0;
            if (data.Length > 0)
            {
                extraParamCount = data[i++];
            }

            for (int k = 0; k < extraParamCount; k++)
            {
                ushort epType = Utils.BytesToUInt16(data, i);

                i += 2;
                // uint paramLength = Helpers.BytesToUIntBig(data, i);

                i += 4;
                switch (epType)
                {
                    case FlexiEP:
                        ReadFlexiData(data, i);
                        i += 16;
                        lGotFlexi = true;
                        break;

                    case LightEP:
                        ReadLightData(data, i);
                        i += 16;
                        lGotLight = true;
                        break;

                    case SculptEP:
                        ReadSculptData(data, i);
                        i += 17;
                        lGotSculpt = true;
                        break;
                    case ProjectionEP:
                        ReadProjectionData(data, i);
                        i += 28;
                        lGotFilter = true;
                        break;
                }
            }

            if (!lGotFlexi)
                FlexiEntry = false;
            if (!lGotLight)
                LightEntry = false;
            if (!lGotSculpt)
                SculptEntry = false;
            if (!lGotFilter)
                ProjectionEntry = false;
        }

        public void ReadSculptData(byte[] data, int pos)
        {
            byte[] SculptTextureUUID = new byte[16];
            UUID SculptUUID = UUID.Zero;
            byte SculptTypel = data[16+pos];

            if (data.Length+pos >= 17)
            {
                SculptEntry = true;
                SculptTextureUUID = new byte[16];
                SculptTypel = data[16 + pos];
                Array.Copy(data, pos, SculptTextureUUID,0, 16);
                SculptUUID = new UUID(SculptTextureUUID, 0);
            }
            else
            {
                SculptEntry = false;
                SculptUUID = UUID.Zero;
                SculptTypel = 0x00;
            }

            if (SculptEntry)
            {
                if (SculptType != (byte)1 && SculptType != (byte)2 && SculptType != (byte)3 && SculptType != (byte)4)
                    SculptType = 4;
            }

            SculptTexture = SculptUUID;
            SculptType = SculptTypel;
            //m_log.Info("[SCULPT]:" + SculptUUID.ToString());
        }

        public byte[] GetSculptBytes()
        {
            byte[] data = new byte[17];

            SculptTexture.GetBytes().CopyTo(data, 0);
            data[16] = (byte)SculptType;

            return data;
        }

        /// <summary>
        /// Simple routine that clamps a float value to a min/max
        /// </summary>
        /// <param name="b"></param>
        /// <param name="bmin"></param>
        /// <param name="bmax"></param>
        /// <returns>The calculated value in min/max range.</returns>
        private static float llclamp(float b, float bmin, float bmax)
        {
            if (b < bmin) b = bmin;
            if (b > bmax) b = bmax;
            return b;
        }

        /// <summary>
        /// Get Server Weight for a Mesh based on the vertex count against an average # of vertices.
        /// </summary>
        /// <returns>A floating point server weight cost "score" </returns>
        public float GetServerWeight()
        {
            return (GetServerWeight(VertexCount));
        }

        /// <summary>
        /// Get Server Weight for a Mesh based on the vertex count against an average # of vertices.
        /// </summary>
        /// <returns>A floating point server weight cost "score" </returns>
        public static float GetServerWeight(int vertexCount)
        {
            const int AverageVerticesPerPrim = 422;
            return ((float)vertexCount / (float)AverageVerticesPerPrim);
        }

        /// <summary>
        /// Get Streaming Cost for a Mesh based on the byte count (which corresponds to tri-count) for each of the LOD
        /// levels we stored when the mesh was uploaded.
        /// </summary>
        /// <returns>A floating point streaming cost "score" </returns>
        public float GetStreamingCost()
        {
            return (GetStreamingCost(Scale, HighLODBytes, MidLODBytes, LowestLODBytes, LowestLODBytes));
        }

        /// <summary>
        /// Get Streaming Cost for a Mesh based on the byte count (which corresponds to tri-count) for each of the LOD
        /// levels we stored when the mesh was uploaded.
        /// </summary>
        /// <returns>A floating point streaming cost "score" </returns>
        public static float GetStreamingCost(Vector3 scale, int hibytes, int midbytes, int lowbytes, int lowestbytes)
        {
            float streaming_cost = 0.0f;

            const float MAX_AREA = 102932.0f;           // The area of a circle that encompasses a region.
            const float MIN_AREA = 1.0f;                // Minimum area we will consider.
            const float MAX_DISTANCE = 512.0f;          // Distance in meters
            const float METADATA_DISCOUNT = 128.0f;     // Number of bytes to deduct for metadata when determining streaming cost.
            const float MINIMUM_SIZE = 16.0f;           // Minimum number of bytes per LoD block when determining streaming cost
            const float BYTES_PER_TRIANGLE = 16.0f;     // Approximation of bytes per triangle to use for determining mesh streaming cost.
            const float TRIANGLE_BUDGET = 250000.0f;    // Target visible triangle budget to use when estimating streaming cost.
            const float MESH_COST_SCALAR = 15000.0f;    // Prim budget. Prims per region max

            try
            {
                float radius = (Vector3.Mag(scale) / (float)2.0);

                // LOD Distances
                float dlowest = Math.Min(radius / 0.03f, MAX_DISTANCE);
                float dlow = Math.Min(radius / 0.06f, MAX_DISTANCE);
                float dmid = Math.Min(radius / 0.24f, MAX_DISTANCE);

                int bytes_high = hibytes;
                int bytes_mid = midbytes;
                int bytes_low = lowbytes;
                int bytes_lowest = lowestbytes;

                if (bytes_high <= 0)
                    return 0.0f;
                if (bytes_mid <= 0)
                    bytes_mid = bytes_high;
                if (bytes_low <= 0)
                    bytes_low = bytes_mid;
                if (bytes_lowest <= 0)
                    bytes_lowest = bytes_low;

                float triangles_lowest = Math.Max((float)bytes_lowest - METADATA_DISCOUNT, MINIMUM_SIZE) / BYTES_PER_TRIANGLE;
                float triangles_low = Math.Max((float)bytes_low - METADATA_DISCOUNT, MINIMUM_SIZE) / BYTES_PER_TRIANGLE;
                float triangles_mid = Math.Max((float)bytes_mid - METADATA_DISCOUNT, MINIMUM_SIZE) / BYTES_PER_TRIANGLE;
                float triangles_high = Math.Max((float)bytes_high - METADATA_DISCOUNT, MINIMUM_SIZE) / BYTES_PER_TRIANGLE;

                float high_area = Math.Min((float)Math.PI * dmid * dmid, MAX_AREA);
                float mid_area = Math.Min((float)Math.PI * dlow * dlow, MAX_AREA);
                float low_area = Math.Min((float)Math.PI * dlowest * dlowest, MAX_AREA);
                float lowest_area = MAX_AREA;

                lowest_area -= low_area;
                low_area -= mid_area;
                mid_area -= high_area;

                high_area = llclamp(high_area, MIN_AREA, MAX_AREA);
                mid_area = llclamp(mid_area, MIN_AREA, MAX_AREA);
                low_area = llclamp(low_area, MIN_AREA, MAX_AREA);
                lowest_area = llclamp(lowest_area, MIN_AREA, MAX_AREA);

                float total_area = high_area + mid_area + low_area + lowest_area;

                high_area /= total_area;
                mid_area /= total_area;
                low_area /= total_area;
                lowest_area /= total_area;

                float weighted_average = (triangles_high * high_area) + (triangles_mid * mid_area) +
                                         (triangles_low * low_area) + (triangles_lowest * lowest_area);

                streaming_cost = weighted_average / TRIANGLE_BUDGET * MESH_COST_SCALAR;
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("[MESH]: exception calculating streaming cost: {0}", e);
                streaming_cost = 0.0f;
            }

            return streaming_cost;
        }

        public void ReadFlexiData(byte[] data, int pos)
        {
            if (data.Length-pos >= 16)
            {
                FlexiEntry = true;
                FlexiSoftness = ((data[pos] & 0x80) >> 6) | ((data[pos + 1] & 0x80) >> 7);

                FlexiTension = (float)(data[pos++] & 0x7F) / 10.0f;
                FlexiDrag = (float)(data[pos++] & 0x7F) / 10.0f;
                FlexiGravity = (float)(data[pos++] / 10.0f) - 10.0f;
                FlexiWind = (float)data[pos++] / 10.0f;
                Vector3 lForce = new Vector3(data, pos);
                FlexiForceX = lForce.X;
                FlexiForceY = lForce.Y;
                FlexiForceZ = lForce.Z;
            }
            else
            {
                FlexiEntry = false;
                FlexiSoftness = 0;

                FlexiTension = 0.0f;
                FlexiDrag = 0.0f;
                FlexiGravity = 0.0f;
                FlexiWind = 0.0f;
                FlexiForceX = 0f;
                FlexiForceY = 0f;
                FlexiForceZ = 0f;
            }
        }

        public byte[] GetFlexiBytes()
        {
            byte[] data = new byte[16];
            int i = 0;

            // Softness is packed in the upper bits of tension and drag
            data[i] = (byte)((FlexiSoftness & 2) << 6);
            data[i + 1] = (byte)((FlexiSoftness & 1) << 7);

            data[i++] |= (byte)((byte)(FlexiTension * 10.01f) & 0x7F);
            data[i++] |= (byte)((byte)(FlexiDrag * 10.01f) & 0x7F);
            data[i++] = (byte)((FlexiGravity + 10.0f) * 10.01f);
            data[i++] = (byte)(FlexiWind * 10.01f);
            Vector3 lForce = new Vector3(FlexiForceX, FlexiForceY, FlexiForceZ);
            lForce.GetBytes().CopyTo(data, i);

            return data;
        }

        public void ReadLightData(byte[] data, int pos)
        {
            if (data.Length - pos >= 16)
            {
                LightEntry = true;
                Color4 lColor = new Color4(data, pos, false);
                LightIntensity = Math.Min(lColor.A, 1.0f);
                LightColorA = 1f;
                LightColorR = lColor.R;
                LightColorG = lColor.G;
                LightColorB = lColor.B;

                LightRadius = Utils.BytesToFloat(data, pos + 4);
                LightCutoff = Utils.BytesToFloat(data, pos + 8);
                LightFalloff = Utils.BytesToFloat(data, pos + 12);
            }
            else
            {
                LightEntry = false;
                LightColorA = 1f;
                LightColorR = 0f;
                LightColorG = 0f;
                LightColorB = 0f;
                LightRadius = 0f;
                LightCutoff = 0f;
                LightFalloff = 0f;
                LightIntensity = 0f;
            }
        }

        public byte[] GetLightBytes()
        {
            byte[] data = new byte[16];

            // Alpha channel in color is intensity
            Color4 tmpColor = new Color4(LightColorR,LightColorG,LightColorB, Math.Min(LightIntensity, 1.0f));

            tmpColor.GetBytes().CopyTo(data, 0);
            Utils.FloatToBytes(LightRadius).CopyTo(data, 4);
            Utils.FloatToBytes(LightCutoff).CopyTo(data, 8);
            Utils.FloatToBytes(LightFalloff).CopyTo(data, 12);

            return data;
        }

        public void ReadProjectionData(byte[] data, int pos)
        {
            byte[] projectionTextureUUID = new byte[16];

            if (data.Length - pos >= 28)
            {
                ProjectionEntry = true;
                Array.Copy(data, pos, projectionTextureUUID,0, 16);
                ProjectionTextureUUID = new UUID(projectionTextureUUID, 0);

                ProjectionFOV = Utils.BytesToFloat(data, pos + 16);
                ProjectionFocus = Utils.BytesToFloat(data, pos + 20);
                ProjectionAmbiance = Utils.BytesToFloat(data, pos + 24);
            }
            else
            {
                ProjectionEntry = false;
                ProjectionTextureUUID = UUID.Zero;
                ProjectionFOV = 0f;
                ProjectionFocus = 0f;
                ProjectionAmbiance = 0f;
            }
        }

        public byte[] GetProjectionBytes()
        {
            byte[] data = new byte[28];

            ProjectionTextureUUID.GetBytes().CopyTo(data, 0);
            Utils.FloatToBytes(ProjectionFOV).CopyTo(data, 16);
            Utils.FloatToBytes(ProjectionFocus).CopyTo(data, 20);
            Utils.FloatToBytes(ProjectionAmbiance).CopyTo(data, 24);

            return data;
        }

        /// <summary>
        /// Return a single MaterialID for a given Face
        /// </summary>
        /// <returns>The UUID of the Material or UUID.Zero if none is set</returns>
        public UUID GetMaterialID(int face)
        {
            UUID id;

            if (face < 0)
            {
                return Textures.DefaultTexture.MaterialID;
            }
            else
            {
                var faceEntry = Textures.CreateFace((uint)face);
                return faceEntry.MaterialID;
            }
        }

        /// <summary>
        /// Return a list of deduplicated materials ids from the texture entry.
        /// We remove duplicates because a materialid may be used across faces and we only
        /// need to represent it here once.
        /// </summary>
        /// <returns>The List of UUIDs found, possibly empty if no materials are in use.</returns>
        public List<UUID> GetMaterialIDs()
        {
            List<UUID> matIds = new List<UUID>();

            if (Textures != null)
            {
                if ((Textures.DefaultTexture != null) &&
                    (Textures.DefaultTexture.MaterialID != UUID.Zero))
                {
                    matIds.Add(Textures.DefaultTexture.MaterialID);
                }

                foreach (var face in Textures.FaceTextures)
                {
                    if ((face != null) && (face.MaterialID != UUID.Zero))
                    {
                        if (matIds.Contains(face.MaterialID) == false)
                            matIds.Add(face.MaterialID);
                    }
                }
            }

            return matIds;
        }

        /// <summary>
        /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values
        /// </summary>
        /// <returns></returns>
        public Primitive ToOmvPrimitive()
        {
            // position and rotation defaults here since they are not available in PrimitiveBaseShape
            return ToOmvPrimitive(new Vector3(0.0f, 0.0f, 0.0f),
                new Quaternion(0.0f, 0.0f, 0.0f, 1.0f));
        }

        /// <summary>
        /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values
        /// </summary>
        /// <param name="position"></param>
        /// <param name="rotation"></param>
        /// <returns></returns>
        public Primitive ToOmvPrimitive(Vector3 position, Quaternion rotation)
        {
            OpenMetaverse.Primitive prim = new OpenMetaverse.Primitive();

            prim.Scale = this.Scale;
            prim.Position = position;
            prim.Rotation = rotation;

            if (this.SculptEntry)
            {
                prim.Sculpt = new Primitive.SculptData();
                prim.Sculpt.Type = (OpenMetaverse.SculptType)this.SculptType;
                prim.Sculpt.SculptTexture = this.SculptTexture;
            }

            prim.PrimData.PathShearX = Primitive.UnpackPathShear((sbyte)this.PathShearX);
            prim.PrimData.PathShearY = Primitive.UnpackPathShear((sbyte)this.PathShearY);
            prim.PrimData.PathBegin = (float)this.PathBegin * 2.0e-5f;
            prim.PrimData.PathEnd = 1.0f - (float)this.PathEnd * 2.0e-5f;

            prim.PrimData.PathScaleX = (200 - this.PathScaleX) * 0.01f;
            prim.PrimData.PathScaleY = (200 - this.PathScaleY) * 0.01f;

            prim.PrimData.PathTaperX = this.PathTaperX * 0.01f;
            prim.PrimData.PathTaperY = this.PathTaperY * 0.01f;

            prim.PrimData.PathTwistBegin = this.PathTwistBegin * 0.01f;
            prim.PrimData.PathTwist = this.PathTwist * 0.01f;

            prim.PrimData.ProfileBegin = (float)this.ProfileBegin * 2.0e-5f;
            prim.PrimData.ProfileEnd = 1.0f - (float)this.ProfileEnd * 2.0e-5f;
            prim.PrimData.ProfileHollow = (float)this.ProfileHollow * 2.0e-5f;

            prim.PrimData.profileCurve = this.ProfileCurve;
            prim.PrimData.ProfileHole = (HoleType)this.HollowShape;

            prim.PrimData.PathCurve = (PathCurve)this.PathCurve;
            prim.PrimData.PathRadiusOffset = 0.01f * this.PathRadiusOffset;
            prim.PrimData.PathRevolutions = 1.0f + 0.015f * this.PathRevolutions;
            prim.PrimData.PathSkew = 0.01f * this.PathSkew;

            prim.PrimData.PCode = OpenMetaverse.PCode.Prim;
            prim.PrimData.State = 0;

            if (this.FlexiEntry)
            {
                prim.Flexible = new Primitive.FlexibleData();
                prim.Flexible.Drag = this.FlexiDrag;
                prim.Flexible.Force = new Vector3(this.FlexiForceX, this.FlexiForceY, this.FlexiForceZ);
                prim.Flexible.Gravity = this.FlexiGravity;
                prim.Flexible.Softness = this.FlexiSoftness;
                prim.Flexible.Tension = this.FlexiTension;
                prim.Flexible.Wind = this.FlexiWind;
            }

            if (this.LightEntry)
            {
                prim.Light = new Primitive.LightData();
                prim.Light.Color = new Color4(this.LightColorR, this.LightColorG, this.LightColorB, this.LightColorA);
                prim.Light.Cutoff = this.LightCutoff;
                prim.Light.Falloff = this.LightFalloff;
                prim.Light.Intensity = this.LightIntensity;
                prim.Light.Radius = this.LightRadius;
            }

            prim.Textures = this.Textures;

            prim.Properties = new Primitive.ObjectProperties();
            prim.Properties.Name = "Primitive";
            prim.Properties.Description = String.Empty;
            prim.Properties.CreatorID = UUID.Zero;
            prim.Properties.GroupID = UUID.Zero;
            prim.Properties.OwnerID = UUID.Zero;
            prim.Properties.Permissions = new Permissions();
            prim.Properties.SalePrice = 10;
            prim.Properties.SaleType = new SaleType();

            return prim;
        }

        /// <summary>
        /// Encapsulates a list of media entries.
        /// </summary>
        /// This class is necessary because we want to replace auto-serialization of PrimMedia with something more
        /// OSD like and less vulnerable to change.
        public class PrimMedia : IXmlSerializable
        {
            public const string MEDIA_TEXTURE_TYPE = "sl";

            // keys are 0-based (face number - 1)
//            protected Dictionary<int,MediaEntry> m_MediaList = new Dictionary<int,MediaEntry>();
            [NonSerialized]
            protected MediaEntry[] m_MediaFaces = null;

            public PrimMedia() : base()
            {
                New(0);
            }
            public PrimMedia(int capacity) : base()
            {
                New(capacity);
            }
            public PrimMedia(MediaEntry[] entries) : base()
            {
                m_MediaFaces = entries.Clone() as MediaEntry[];
            }
            public PrimMedia(PrimMedia other) : base()
            {
                if ((other == null) || (other.m_MediaFaces == null))
                {
                    New(0);
                }
                else
                {
                    lock (this)
                    {
                        m_MediaFaces = other.CopyArray();
                    }
                }
            }

            public int Count
            {
                get { return (m_MediaFaces == null) ? 0 : m_MediaFaces.Length; }
            }

            public MediaEntry this[int face]
            {
                get { lock (this) return m_MediaFaces[face]; }
                set { lock (this) m_MediaFaces[face] = value; }
            }

            public void Resize(int newSize)
            {
                lock (this)
                {
                    if (m_MediaFaces == null)
                    {
                        New(newSize);
                        return;
                    }

                    Array.Resize<MediaEntry>(ref m_MediaFaces, newSize);
                }
            }

            // This should be implemented in OpenMetaverse.MediaEntry but isn't.
            private MediaEntry MediaEntryCopy(MediaEntry entry)
            {
                if (entry == null) return null;

                MediaEntry newEntry = new MediaEntry();
                newEntry.AutoLoop = entry.AutoLoop;
                newEntry.AutoPlay = entry.AutoPlay;
                newEntry.AutoScale = entry.AutoScale;
                newEntry.AutoZoom = entry.AutoZoom;
                newEntry.ControlPermissions = entry.ControlPermissions;
                newEntry.Controls = entry.Controls;
                newEntry.CurrentURL = entry.CurrentURL;
                newEntry.EnableAlterntiveImage = entry.EnableAlterntiveImage;
                newEntry.EnableWhiteList = entry.EnableWhiteList;
                newEntry.Height = entry.Height;
                newEntry.HomeURL = entry.HomeURL;
                newEntry.InteractOnFirstClick = entry.InteractOnFirstClick;
                newEntry.InteractPermissions = entry.InteractPermissions;
                newEntry.Width = entry.Width;
                if (entry.WhiteList != null)
                    entry.WhiteList.CopyTo(newEntry.WhiteList, 0);
                else
                    entry.WhiteList = null;
                newEntry.Width = entry.Width;

                return newEntry;
            }

            public MediaEntry[] CopyArray()
            {
                lock (this)
                {
                    if (m_MediaFaces == null)
                        return null;

                    int len = m_MediaFaces.Length;
                    MediaEntry[] copyFaces = new MediaEntry[len];
                    for (int x=0; x<len; x++)
                    {
                        copyFaces[x] = MediaEntryCopy(m_MediaFaces[x]);
                    }
                    return copyFaces;
                }
            }

            /// <summary>
            /// This method frees the media array if capacity is less than 1 (media list with no entries), otherwise allocates a new array of the specified size.
            /// </summary>
            /// <param name="capacity"></param>
            public void New(int capacity)
            {
                lock (this)
                {
                    // m_MediaList = new Dictionary<int, MediaEntry>();
                    if (capacity <= 0)
                        m_MediaFaces = null;
                    else
                        m_MediaFaces = new MediaEntry[capacity];
                }
            }

            public XmlSchema GetSchema()
            {
                return null;
            }

            public string ToXml()
            {
                lock (this)
                {
                    using (StringWriter sw = new StringWriter())
                    {
                        using (XmlTextWriter xtw = new XmlTextWriter(sw))
                        {
                            xtw.WriteStartElement("OSMedia");
                            xtw.WriteAttributeString("type", MEDIA_TEXTURE_TYPE);
                            xtw.WriteAttributeString("version", "0.1");

                            OSDArray meArray = new OSDArray();
                            lock (this)
                            {
                                if (m_MediaFaces != null)
                                {
                                    foreach (MediaEntry me in m_MediaFaces)
                                    {
                                        OSD osd = (null == me ? new OSD() : me.GetOSD());
                                        meArray.Add(osd);
                                    }
                                }
                            }

                            xtw.WriteStartElement("OSData");
                            xtw.WriteRaw(OSDParser.SerializeLLSDXmlString(meArray));
                            xtw.WriteEndElement();

                            xtw.WriteEndElement();

                            xtw.Flush();
                            return sw.ToString();
                        }
                    }
                }
            }

            public void WriteXml(XmlWriter writer)
            {
                writer.WriteRaw(ToXml());
            }

            public static PrimMedia FromXml(string rawXml)
            {
                PrimMedia ml = new PrimMedia();
                ml.ReadXml(rawXml);
                return ml;
            }

            public void ReadXml(string rawXml)
            {
                if (rawXml.StartsWith("<"))
                {
                    rawXml = rawXml.Replace("<", "<").Replace(">", ">");
                }

                using (StringReader sr = new StringReader(rawXml))
                {
                    using (XmlTextReader xtr = new XmlTextReader(sr))
                    {
                        xtr.MoveToContent();

                        string type = xtr.GetAttribute("type");
                        //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type);

                        if (type != MEDIA_TEXTURE_TYPE)
                            return;

                        xtr.ReadStartElement("OSMedia");

                        OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml());
                        lock (this)
                        {
                            this.New(osdMeArray.Count);
                            int index = 0;
                            foreach (OSD osdMe in osdMeArray)
                            {
                                m_MediaFaces[index++] = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry());
                            }
                        }

                        xtr.ReadEndElement();
                    }
                }
            }

            public void ReadXml(XmlReader reader)
            {
                if (reader.IsEmptyElement)
                    return;

                ReadXml(reader.ReadInnerXml());
            }
        }
    }
}


text:
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('game', '0006_auto_20160214_2303'),
    ]

    operations = [
        migrations.AlterField(
            model_name='room',
            name='exits',
            field=models.ManyToManyField(blank=True, null=True, to='game.Exit'),
        ),
    ]