import bSpline from './bspline';
import * as THREE from 'three';

//rgb转换

function decimalToRGBHex(decimalValue) {
  // Ensure the input is a valid integer
  if (!Number.isInteger(decimalValue)) {
    throw new Error('Input must be an integer.');
  }

  // Ensure the input is within the valid range for 24-bit colors
  if (decimalValue < 0 || decimalValue > 0xffffff) {
    throw new Error('Input must be between 0 and 16777215 (0xFFFFFF).');
  }

  // Extract the red, green, and blue components
  var red = (decimalValue >> 16) & 0xff;
  var green = (decimalValue >> 8) & 0xff;
  var blue = decimalValue & 0xff;

  // Convert the RGB components to hexadecimal and format as a string
  var hex =
    '#' +
    red.toString(16).padStart(2, '0') +
    green.toString(16).padStart(2, '0') +
    blue.toString(16).padStart(2, '0');

  return {
    red: red,
    green: green,
    blue: blue,
    hex: hex.toUpperCase(),
  };
}
export function handleFn(functionName, recordDxf, entity, group, key, configParams, konvaLayer) {
  console.log(functionName);

  switch (functionName) {
    case 'LINE':
      drawLine(recordDxf, entity, group, key, configParams);
      break;
    case 'TEXT':
      drawText(recordDxf, entity, group, key, configParams);
      break;
    case 'LWPOLYLINE':
      drawLwLine(recordDxf, entity, group, key, configParams);
      break;
    case 'ARC':
      drawArc(recordDxf, entity, group, key, configParams);
      break;
    case 'CIRCLE':
      drawArc(recordDxf, entity, group, key, configParams);
      break;
    case 'ELLIPSE':
      drawEllpse(recordDxf, entity, group, key, configParams);
      break;
    case 'HATCH':
      drawHatch(recordDxf, entity, group, key, configParams);
      break;
    //case 'MTEXT': drawMtext(recordDxf, entity, group, key, configParams)
    //break;
    case 'SPLINE':
      drawSpline(recordDxf, entity, group, key, configParams);
      break;
    //  case 'INSERT': drawInsert(recordDxf, entity, group, key, configParams, konvaLayer)
    //  break;
  }
}
export function formatEntity(entities) {
  var obj = {};
  for (let i = 0; i < entities.length; i++) {
    if (obj.hasOwnProperty(entities[i].layer)) {
      obj[entities[i].layer].push(entities[i]);
    } else {
      obj[entities[i].layer] = [];
      obj[entities[i].layer].push(entities[i]);
    }
  }
  return obj;
}
export function getAbsolutePoints(points) {
  let x = 0;
  let y = 0;
  points.forEach((point, index) => {
    if (index % 2 === 0) {
      x = x + point;
    } else {
      y = y + point;
    }
  });
  return {
    x: Math.ceil(x / (points.length / 2)),
    y: Math.ceil(y / (points.length / 2)),
  };
}
export function getColors() {
  return colors;
}
// 居中定位
export function centering(obj, container, konvaStage, scaleBy) {
  // 由于图纸结构解析的变更 可能最外层的group x y 都是0所以 需要拿到x y有值的group
  const filterGroup = obj.filter(item => item.attrs.isGroup && !item.attrs.isMix);
  if (filterGroup.length > 0) {
    if (filterGroup[0].attrs.hasOwnProperty('isBlock') && filterGroup[0].attrs.isBlock) {
      computedCenter(
        filterGroup[0].attrs.x,
        filterGroup[0].attrs.y,
        container,
        konvaStage,
        scaleBy
      );
    } else {
      const target = obj.filter(item => !item.attrs.isGroup);
      if (target[0].className === 'Text') {
        computedCenter(target[0].x(), target[0].y(), container, konvaStage, scaleBy);
      } else if (target[0].className === 'Line') {
        const p = getAbsolutePoints(target[0].getPoints());
        computedCenter(p.x, p.y, container, konvaStage, scaleBy);
      }
    }
  } else {
    const target = obj.filter(item => !item.attrs.isGroup);
    if (target[0].className === 'Text') {
      computedCenter(target[0].x(), target[0].y(), container, konvaStage, scaleBy);
    } else if (target[0].className === 'Line') {
      const p = getAbsolutePoints(target[0].getPoints());
      computedCenter(p.x, p.y, container, konvaStage, scaleBy);
    }
  }
}
// 计算居中位置
function computedCenter(x, y, container, konvaStage, scaleBy) {
  let newX = container.clientWidth / 2 - x * scaleBy;
  let newY = container.clientHeight / 2 - y * scaleBy;
  konvaStage.position({ x: newX, y: newY });
}

function getBSplinePolyline(controlPoints, degree, knots, interpolationsPerSplineSegment, weights) {
  const polyline = [];
  const controlPointsForLib = controlPoints.map(function (p) {
    return [p.x, p.y];
  });
  const segmentTs = [knots[degree]];
  const domain = [knots[degree], knots[knots.length - 1 - degree]];
  for (let k = degree + 1; k < knots.length - degree; ++k) {
    if (segmentTs[segmentTs.length - 1] !== knots[k]) {
      segmentTs.push(knots[k]);
    }
  }
  interpolationsPerSplineSegment = interpolationsPerSplineSegment || 25;
  for (let i = 1; i < segmentTs.length; ++i) {
    const uMin = segmentTs[i - 1];
    const uMax = segmentTs[i];
    for (let k = 0; k <= interpolationsPerSplineSegment; ++k) {
      const u = (k / interpolationsPerSplineSegment) * (uMax - uMin) + uMin;
      let t = (u - domain[0]) / (domain[1] - domain[0]);
      t = Math.max(t, 0);
      t = Math.min(t, 1);
      const p = bSpline(t, degree, controlPointsForLib, knots, weights);
      polyline.push(new THREE.Vector2(p[0], p[1]));
    }
  }
  return polyline;
}
function mtextContentAndFormattingToTextAndStyle(textAndControlChars, entity, configParams) {
  let activeStyle = {
    horizontalAlignment: 'left',
    textHeight: entity.height,
  };
  var text = [];
  for (let item of textAndControlChars) {
    if (typeof item === 'string') {
      if (item.startsWith('pxq') && item.endsWith(';')) {
        if (item.indexOf('c') !== -1) activeStyle.horizontalAlignment = 'center';
        else if (item.indexOf('l') !== -1) activeStyle.horizontalAlignment = 'left';
        else if (item.indexOf('r') !== -1) activeStyle.horizontalAlignment = 'right';
        else if (item.indexOf('j') !== -1) activeStyle.horizontalAlignment = 'justify';
      } else {
        text.push(item);
      }
    } else if (Array.isArray(item)) {
      var nestedFormat = mtextContentAndFormattingToTextAndStyle(item, entity, configParams);
      text.push(nestedFormat.text);
    } else if (typeof item === 'object') {
      if (item['S'] && item['S'].length === 3) {
        text.push(item['S'][0] + '/' + item['S'][2]);
      } else {
        // not yet supported.
      }
    }
  }
  return {
    text: text.join(),
    style: activeStyle,
  };
}

function drawArc(recordDxf, entity, group, key, configParams) {
  let color = entity.color;
  let rgb = decimalToRGBHex(color);
  console.log(rgb);
  let hex = rgb.hex;
  let startAngle, endAngle;
  if (entity.type === 'CIRCLE') {
    startAngle = entity.startAngle || 0;
    endAngle = startAngle + 2 * Math.PI;
  } else {
    startAngle = entity.startAngle;
    endAngle = entity.endAngle;
  }
  let curve = new THREE.ArcCurve(
    entity.center.x,
    parseFloat(entity.center.y),
    entity.radius,
    startAngle,
    endAngle
  );
  let points = curve.getPoints(32);

  let list = [];
  for (let i = 0; i < points.length; i++) {
    list.push(points[i].x);
    list.push(-parseFloat(points[i].y));
  }
  let width = 0.2;
  group.push({
    type: 'polyline',
    points: list,
    name: key.replace(/\s*/g, ''),
    entityId: key,
    stroke: hex,
    customColor: configParams ? configParams.color : '',
    strokeWidth: width,
    visible: configParams ? configParams.visible : true,
    oldstrokeLength: width,
  });
  // if(group.attrs.isBlock){
  //   let scale=group.scale();
  //   width=width/Math.abs(scale.x);
  // }
  // let line = new Konva.Line({
  //   name: key.replace(/\s*/g, ""),
  //   entityId: key,
  //   isGroup: false,
  //   points: list,
  //   stroke: configParams ? configParams.color : "#000",
  //   customColor: configParams ? configParams.color : "",
  //   strokeWidth: width,
  //   lineCap: "round",
  //   lineJoin: "round",
  //   visible: configParams ? configParams.visible :true,
  //   oldstrokeLength:width
  // });
  // group.add(line);
}

function drawEllpse(recordDxf, entity, group, key, configParams) {
  let xrad = Math.sqrt(
    Math.pow(parseFloat(entity.majorAxisEndPoint.x), 2) +
      Math.pow(parseFloat(entity.majorAxisEndPoint.y), 2)
  );
  let yrad = xrad * parseFloat(entity.axisRatio);
  let rotation = Math.atan2(
    parseFloat(entity.majorAxisEndPoint.y),
    parseFloat(entity.majorAxisEndPoint.x)
  );
  console.log(entity.startAngle);
  console.log(entity.endAngle);
  let curve = new THREE.EllipseCurve(
    parseFloat(entity.center.x),
    parseFloat(entity.center.y),
    xrad,
    yrad,
    parseFloat(entity.startAngle),
    parseFloat(entity.endAngle),
    false, // Always counterclockwise
    rotation
  );
  let points = curve.getPoints(200);
  let list = [];
  for (let i = 0; i < points.length; i++) {
    list.push(points[i].x);
    list.push(-parseFloat(points[i].y));
  }
  let width = 0.2;

  group.push({
    type: 'polyline',
    points: list,
    name: key.replace(/\s*/g, ''),
    entityId: key,
    stroke: configParams ? configParams.color : '#000',
    customColor: configParams ? configParams.color : '',
    strokeWidth: width,
    visible: configParams ? configParams.visible : true,
    oldstrokeLength: width,
  });
  // let line = new Konva.Line({
  //   name: key.replace(/\s*/g, ""),
  //   entityId: key,
  //   isGroup: false,
  //   points: list,
  //   stroke: configParams ? configParams.color : "#000",
  //   customColor: configParams ? configParams.color : "",
  //   strokeWidth: width,
  //   lineCap: "round",
  //   lineJoin: "round",
  //   visible: configParams ? configParams.visible : true,
  //   oldstrokeLength:width

  // });
  // group.add(line);
}
function drawLine(recordDxf, entity, group, key, configParams) {
  let color = entity.color;
  let rgb = decimalToRGBHex(color);
  console.log(rgb);
  let hex = rgb.hex;
  let x1 = entity.vertices[0].x;
  let y1 = entity.vertices[0].y;
  let x2 = entity.vertices[1].x;
  let y2 = entity.vertices[1].y;
  let width = 0.2;
  group.push({
    type: 'line',
    x1: x1,
    x2: x2,
    y1: y1,
    y2: y2,
    name: key.replace(/\s*/g, ''),
    entityId: key,
    isGroup: false,
    stroke: hex,
    customColor: configParams ? configParams.color : '',
    strokeWidth: width,
    visible: configParams ? configParams.visible : true,
    oldstrokeLength: width,
  });
  // if(group.attrs.isBlock){
  //     let scale=group.scale();
  //     width=width/Math.abs(scale.x);
  // }
  // let line = new Konva.Line({
  //   name: key.replace(/\s*/g, ""),
  //   entityId: key,
  //   isGroup: false,
  //   points: [x1, -parseFloat(y1), parseFloat(x2), -parseFloat(y2)],
  //   stroke: configParams ? configParams.color : "#000",
  //   customColor: configParams ? configParams.color : "",
  //   strokeWidth: width,
  //   //lineCap: "round",
  //   //lineJoin: "round",
  //   visible: configParams ? configParams.visible : true,
  //   oldstrokeLength:width,
  //   handle:entity.handle

  // });

  // group.add(line);
}

function drawText(recordDxf, entity, group, key, configParams) {
  let color = entity.color;
  let rgb = decimalToRGBHex(color);
  console.log(rgb);
  let hex = rgb.hex;

  if (hex == '#FFFFFF') {
    hex = '#000';
  }
  let text = entity.text;
  const fontSize = entity.textHeight;

  // 与 AutoCAD TEXT 一致：绕插入点对齐锚点旋转；Y 轴翻转后角度用 360°-θ
  const insert =
    entity.endPoint && (entity.halign !== undefined || entity.valign !== undefined)
      ? entity.endPoint
      : entity.startPoint;

  const dim = new Konva.Text({
    x: 0,
    y: 0,
    text: text,
    fontSize: fontSize,
    align: 'left',
    verticalAlign: 'top',
    fill: hex,
    customColor: configParams ? configParams.color : '',
    name: key.replace(/\s*/g, ''),
    entityId: key,
    fontFamily: 'SimSun',
    visible: configParams ? configParams.visible : true,
    stroke: hex,
    strokeWidth: 0.1,
  });

  if (entity.xScale) {
    dim.scaleX(entity.xScale);
  }

  const tw = dim.width();
  const th = dim.height();
  const lh = dim.lineHeight() || 1;
  // 用字体度量计算锚点，避免 valign=2(中线) 与 baseline 近似重合
  let ascent = fontSize * lh * 0.8;
  let descent = fontSize * lh * 0.2;
  try {
    const metrics = dim.measureSize(text || 'M');
    const mAscent = metrics?.fontBoundingBoxAscent ?? metrics?.actualBoundingBoxAscent;
    const mDescent = metrics?.fontBoundingBoxDescent ?? metrics?.actualBoundingBoxDescent;
    if (typeof mAscent === 'number' && mAscent > 0) {
      ascent = mAscent;
    }
    if (typeof mDescent === 'number' && mDescent >= 0) {
      descent = mDescent;
    }
  } catch (e) {
    // ignore
  }
  const baselineOffset = ascent;

  const halign = entity.halign != null ? Number(entity.halign) : 0;
  const valign = entity.valign != null ? Number(entity.valign) : 0;

  let anchorX = 0;
  if (halign === 1 || halign === 4) {
    anchorX = tw / 2;
  } else if (halign === 2) {
    anchorX = tw;
  }

  let anchorY = baselineOffset;
  if (valign === 3) {
    anchorY = 0;
  } else if (valign === 2) {
    // DXF Middle: 使用字形上下边界中心，而不是 Konva 文本框中心
    anchorY = (ascent + descent) / 2;
  } else if (valign === 1) {
    anchorY = ascent + descent;
  }

  dim.x(-anchorX);
  dim.y(-anchorY);

  const rotation = Number(entity.rotation || 0);
  const g = new Konva.Group({
    x: parseFloat(insert.x),
    y: -parseFloat(insert.y),
    rotation: 360 - rotation,
    name: key.replace(/\s*/g, ''),
    entityId: key,
    visible: configParams ? configParams.visible : true,
    customColor: configParams ? configParams.color : '',
  });
  g.add(dim);

  group.push({
    type: 'text',
    obj: g,
  });
  // group.add(dim);
}

function drawHatch(recordDxf, entity, group, key, configParams) {
  console.log('hatch');
}

function drawLwLine(recordDxf, entity, group, key, configParams) {
  let color = entity.color;
  let rgb = decimalToRGBHex(color);
  console.log(rgb);
  let hex = rgb.hex;

  if (hex == '#FFFFFF') {
    hex = '#000';
  }
  let closed = entity.shape;
  let list = [];
  for (let i = 0; i < entity.vertices.length; i++) {
    list.push(entity.vertices[i].x);
    list.push(-parseFloat(entity.vertices[i].y));
  }
  let width = 0.2;
  if (entity.width) {
    width = width + parseFloat(entity.width);
  } else {
    width = 0.2;
  }
  group.push({
    type: 'polyline',
    points: list,
    closed: closed,
    name: key.replace(/\s*/g, ''),
    entityId: key,
    stroke: hex,
    customColor: configParams ? configParams.color : '',
    strokeWidth: width,
    visible: configParams ? configParams.visible : true,
    oldstrokeLength: width,
  });
  // let line = new Konva.Line({
  //   name: key.replace(/\s*/g, ""),
  //   entityId: key,
  //   isGroup: false,
  //   points: list,
  //   stroke: configParams ? configParams.color : "#000",
  //   customColor: configParams ? configParams.color : "",
  //   strokeWidth: width,
  //   visible: configParams ? configParams.visible : true,
  //   closed:closed,
  //   oldstrokeLength:width,
  //   handle:entity.handle

  // });
  // group.add(line);
}
function drawSpline(recordDxf, entity, group, key, configParams) {
  let points = getBSplinePolyline(
    entity.controlPoints,
    entity.degreeOfSplineCurve,
    entity.knotValues,
    100
  );
  let list = [];
  for (let i = 0; i < points.length; i++) {
    list.push(points[i].x);
    list.push(-parseFloat(points[i].y));
  }
  let width = 0.1;
  group.push({
    type: 'polyline',
    points: list,
    name: key.replace(/\s*/g, ''),
    entityId: key,
    isGroup: false,
    stroke: configParams ? configParams : '#000',
    customColor: configParams ? configParams.color : '',
    strokeWidth: width,
    visible: configParams ? configParams.visible : true,
    oldstrokeLength: width,
  });
  // let line = new Konva.Line({
  //   name: key.replace(/\s*/g, ""),
  //   entityId: key,
  //   isGroup: false,
  //   points: list,
  //   stroke: configParams ? configParams : "#000",
  //   customColor: configParams ? configParams.color : "",
  //   strokeWidth: width,
  //   lineCap: "round",
  //   lineJoin: "round",
  //   visible: configParams ? configParams.visible : true,
  //   oldstrokeLength:width
  // });
  // group.add(line);
}
function drawInsert(recordDxf, entities, group, key, configParams, konvaLayer) {
  if (recordDxf.blocks[entities.name]) {
    let group2 = new Konva.Group({
      x: 0,
      y: 0,
      name: key.replace(/\s*/g, ''),
      isBlock: true,
      blockName: entities.name,
      entityId: key,
      isGroup: true,
      visible: true,
    });
    let entity = entities;
    let block = recordDxf.blocks[entities.name];
    if (entity.rotation) {
      group2.rotation(360 - entity.rotation);
    }

    if (entity.xScale) {
      group2.scale({ x: entity.xScale, y: entity.yScale });
    }
    if (entity.yScale) {
      group2.scale({ x: entity.xScale, y: entity.yScale });
    }
    if (entity.position) {
      group2.attrs.x = parseFloat(entity.position.x);
      group2.attrs.y = -parseFloat(entity.position.y);
    }
    if (entity.position.x < 0) {
      group2.attrs.x = parseFloat(entity.position.x) * -1;
      if (entity.xScale < 0) {
        group2.scale({ x: Math.abs(entity.xScale), y: entity.yScale });
      }
    }
    if (block.entities == undefined) {
      return;
    }
    for (let j = 0; j < block.entities.length; j++) {
      let type = block.entities[j].type;
      handleFn(type, recordDxf, block.entities[j], group2, key, configParams, konvaLayer);
    }
    group.add(group2);
    // 区分块 因为有的块里面包含块 不区分会对点击定位有影响
    group.attrs.isMix = true;
    konvaLayer.add(group);
  }
}

let color = [
  '0,0,0', //1
  '255,0,0', //2
  '255,255,0', //3
  '0,255,0', //4
  '0,255,255', //5
  '0,0,255', //6
  '255,0,255', //7
  '255,255,255', //8
  '128,128,128', //9
  '192,192,192', //10
  '255,0,0', //11
  '255,120,112', //12
  '192,0,0', //13
  '207,103,96', //14
  '144,0,0', //15
  '144,72,79', //16
  '127,0,0', //17
  '112,56,48', //18
  '79,0,0', //19
  '79,39,32', //20
  '255,56,0', //21
  '255,159,127', //22
  '192,48,0', //23
  '207,127,96', //24
  '144,32,0', //25
  '144,88,64', // 26
  '112,24,0', //27
  '127,72,63', //28
  '79,16,0', //29
  '64,40,31', //30
  '255,127,0', //31
  '255,191,127', //32
  '207,103,0', //33
  '192,151,96', //34
  '159,72,0', //35
  '144,112,79', //36
  '127,63,0', //37
  '127,95,63', //38
  '64,32,0', //39
  '64,55,31', //40
  '255,191,0', // 41
  '255,216,127', //42
  '207,152,0', //43
  '192,175,96', //44
  '144,112,0', //45
  '144,128,64', //46
  '112,88,0', //47
  '127,111,63', //48
  '64,55,0', //49
  '64,63,31', //50
  '255,255,0', //51
  '255,255,112', //52
  '207,200,0', //53
  '192,200,96', //54
  '144,151,0', //55
  '144,151,64', //56
  '144,152,0', //57
  '127,120,63', //58
  '79,72,0', //59
  '79,72,32', //60
  '191,255,0', //61
  '208,255,112', //62
  '144,200,0', //63
  '176,200,96', //64
  '111,151,0', //65
  '128,151,79', //66
  '95,127,0', //67
  '111,127,63', //68
  '48,72,0', //69
  '63,72,31', //70
  '127,255,0', //71
  '191,255,127', //72
  '95,200,0', //73
  '159,200,96', //74
  '64,151,0', //75
  '111,151,64', //76
  '63,120,0', //77
  '95,127,63', //78
  '31,72,0', //79
  '48,72,32', //80
  '63,255,0', //81
  '159,255,127', //82
  '47,200,0', //83
  '127,200,96', //84
  '31,151,0', //85
  '80,151,64', //86
  '31,127,0', //87
  '79,127,63', //88
  '15,72,0', //89
  '47,72,32', //90
  '0,255,0', //91
  '127,255,127', //92
  '0,200,0', //93
  '95,200,95', //94
  '0,151,0', //95
  '79,151,79', //96
  '0,127,0', //97
  '63,127,63', //98
  '0,72,0', //99
  '32,72,32', //100
  '0,255,63', //101
  '127,255,159', //102
  '0,200,47', //103
  '95,200,112', //104
  '0,151,32', //105
  '64,151,95', //106
  '0,120,31', //107
  '63,127,79', //108
  '0,72,15', //109
  '32,72,47', //110
  '0,255,127', //111
  '127,255,191', //112
  '0,200,96', //113
  '95,200,144', //114
  '0,151,64', //115
  '79,151,111', //116
  '0,127,63', //117
  '63,127,95', //118
  '0,72,32', //119
  '31,72,48', //120
  '0,255,191', //121
  '127,255,223', //122
  '0,200,144', //123
  '95,200,175', //124
  '0,151,111', //125
  '79,151,128', //126
  '0,120,95', //127
  '63,127,111', //128
  '0,72,48', //129
  '32,72,63', //130
  '0,255,255', //131
  '127,255,255', //132
  '0,200,207', //133
  '96,200,207', //134
  '0,151,144', //135
  '64,151,144', //136
  '0,127,127', //137
  '63,127,127', //138
  '0,72,79', //139
  '32,72,79', //140
  '0,191,255', //141
  '127,223,255', //142
  '0,152,207', //143
  '96,176,207', //144
  '0,111,144', //145
  '64,128,144', //146
  '0,95,127', //147
  '63,111,127', //148
  '0,55,64', //149
  '31,63,64', //150
  '0,127,255', //151
  '112,184,255', //152
  '0,96,192', //153
  '96,151,207', //154
  '0,72,159', //155
  '79,112,144', //156
  '0,63,127', //157
  '63,95,127', //158
  '0,39,79', //159
  '32,56,79', //160
  '0,63,255', //161
  '127,159,255', //162
  '0,48,207', //163
  '96,127,207', //164
  '0,39,159', //165
  '64,95,144', //166
  '0,24,127', //167
  '63,79,127', //168
  '0,15,64', //169
  '32,47,79', //170
  '0,0,255', //171
  '127,127,255', //172
  '0,0,207', //173
  '95,96,192', //174
  '0,0,144', //175
  '79,72,159', //176
  '0,0,127', //177
  '63,63,127', //178
  '0,0,64', //179
  '32,39,79', //180
  '63,0,255', //181
  '159,127,255', //182
  '47,0,192', //183
  '127,103,207', //184
  '32,0,144', //185
  '80,72,144', //186
  '31,0,127', //187
  '79,63,127', //188
  '15,0,79', //189
  '47,39,79', //190
  '127,0,255', //191
  '191,127,255', //192
  '96,0,207', //193
  '144,103,207', //194
  '79,0,144', //195
  '111,72,144', //196
  '63,0,127', //197
  '95,63,127', //198
  '31,0,64', //199
  '48,39,79', //200
  '191,0,255', //201
  '223,127,255', //202
  '144,0,207', //203
  '175,96,192', //204
  '111,0,144', //205
  '128,72,159', //206
  '95,0,127', //207
  '96,56,112', //208
  '48,0,64', //209
  '64,39,79', //210
  '255,0,255', //211
  '255,127,255', //212
  '192,0,192', //213
  '192,96,192', //214
  '144,0,144', //215
  '144,72,144', //216
  '127,0,127', //217
  '127,63,127', //218
  '79,0,79', //219
  '64,32,64', //220
  '255,0,191', //221
  '255,127,223', //222
  '192,0,144', //223
  '192,96,175', //224
  '144,0,111', //225
  '144,72,128', //226
  '127,0,95', //227
  '127,56,111', //228
  '64,0,48', //229
  '79,39,63', //230
  '255,0,127', //231
  '255,127,191', //232
  '192,0,95', //233
  '192,96,144', //234
  '159,0,79', //235
  '144,72,111', //236
  '127,0,63', //237
  '127,63,95', //238
  '64,0,31', //239
  '64,32,48', //240
  '255,0,63', //241
  '255,127,159', //242
  '207,0,48', //243
  '207,103,127', //244
  '144,0,32', //245
  '144,72,95', //246
  '127,0,31', //247
  '127,63,79', //248
  '79,0,15', //249
  '64,32,47', //250
  '47,47,47', //251
  '80,88,80', //252
  '128,128,128', //253
  '175,175,175', //254
  '208,215,208', //255
  '255,255,255', //256
];
