# コピペ: OmegaChart Fibonacciリトレースメント Fibonacci.cs 新規追加 ※差し替え その５

Plain text

2018-08-19 21:13

` using System; using System.Collections; using System.Drawing; using System.Text;  using Zanetti.Data; using Travis.Storage;  namespace Zanetti.UI {     /// <summary>     /// Fibonacci の概要の説明です。     /// </summary>     internal class Fibonacci     {         private PointF _pivot;         private PointF _destination;         private int _id; //SolidFibonacciからの作成時のみセット、それ以外は-1         private LineDrawMode _mode;          public enum LineDrawMode         {             Normal,             Hilight,//☆Fibonacci 20180816 カンマ「,」追加             Move//☆Fibonacci 20180816 追加         }          public Fibonacci(PointF p)         {             _pivot = p;             _destination = p;             _id = -1;         }         public Fibonacci(PointF p1, PointF p2)         {             _pivot = p1;             _destination = p2;             _id = -1;         }         //リサイズしたときなどの再計算         public Fibonacci(DataFarm farm, int firstdateindex, SolidFibonacci fl, Trans value_to_y)         {             int p = Env.Layout.DatePitch;             _pivot = new PointF((farm.DateToIndex(fl._date1) - firstdateindex) * p + p / 2, (float)value_to_y.TransValue(fl._value1));             _destination = new PointF((farm.DateToIndex(fl._date2) - firstdateindex) * p + p / 2, (float)value_to_y.TransValue(fl._value2));             _id = fl._id;         }          public PointF Pivot         {             get             {                 return _pivot;             }             //☆Fibonacci 20180816 setは不要         }         public PointF Destination         {             get             {                 return _destination;             }             set             {                 _destination = value;             }         }         public LineDrawMode DrawMode         {             get             {                 return _mode;             }             set             {                 _mode = value;             }         }         public int ID         {             get             {                 return _id;             }         }          public void SetHighPriceAndLowPrice(DataFarm farm, Trans pricetrans, float x1, float x2, int FirstDateIndex)         {             var range_max = double.MinValue;//☆Fibonacci 20180816 新規追加             var range_min = double.MaxValue;//☆Fibonacci 20180816 新規追加             var y1 = double.MinValue;//☆Fibonacci 20180816 新規追加             var y2 = double.MinValue;//☆Fibonacci 20180816 新規追加             if (x1 > Env.Layout.ChartAreaWidth || x2 > Env.Layout.ChartAreaWidth)                 return;             int ind1 = FirstDateIndex + (int)Math.Floor((double)Math.Min(x1, x2) / Env.Layout.DatePitch);             int ind2 = FirstDateIndex + (int)Math.Floor((double)Math.Max(x1, x2) / Env.Layout.DatePitch);             if (ind1 < 0) ind1 = 0;             if (ind2 < 0) ind2 = 0;             if (ind1 >= farm.FilledLength) ind1 = farm.FilledLength - 1;//☆Fibonacci 20180816 修正             if (ind2 >= farm.FilledLength) ind2 = farm.FilledLength - 1;//☆Fibonacci 20180816 修正             //最高値と最安値の株価             range_max = Max(farm, ind1, ind2);//☆Fibonacci 20180816 修正             range_min = Min(farm, ind1, ind2);//☆Fibonacci 20180816 修正             //最高値と最安値の画面上の位置             //var y1 = pricetrans.TransValue(_pivot.Y > _destination.Y ? Env.Preference.InverseChart ? range_max : range_min : Env.Preference.InverseChart ? range_min : range_max);//☆Fibonacci 20180816 コメントアウト             //var y2 = pricetrans.TransValue(_pivot.Y > _destination.Y ? Env.Preference.InverseChart ? range_min : range_max : Env.Preference.InverseChart ? range_max : range_min);//☆Fibonacci 20180816 コメントアウト             //☆Fibonacci 20180816 新規追加ここから             if (_mode != Fibonacci.LineDrawMode.Move && _id < 0)//モードが移動モード、かつ引いたばかりのフィボナッチラインではない             {                 //_pivot.Y > _destination.Y は下から上に引いた線の意味                 y1 = pricetrans.TransValue(_pivot.Y > _destination.Y ? Env.Preference.InverseChart ? range_max : range_min : Env.Preference.InverseChart ? range_min : range_max);//☆Fibonacci 20180816 変更                 y2 = pricetrans.TransValue(_pivot.Y > _destination.Y ? Env.Preference.InverseChart ? range_min : range_max : Env.Preference.InverseChart ? range_max : range_min);//☆Fibonacci 20180816 変更             }             else             {                 y1 = _pivot.Y < _destination.Y ? Env.Preference.InverseChart ? _pivot.Y : _destination.Y : Env.Preference.InverseChart ? _destination.Y : _pivot.Y;                 y2 = _pivot.Y < _destination.Y ? Env.Preference.InverseChart ? _destination.Y : _pivot.Y : Env.Preference.InverseChart ? _pivot.Y : _destination.Y;             }             //ここまで             //_pivot = new PointF(x1, (float)y1);//☆Fibonacci 20180816 コメントアウト             //_destination = new PointF(x2, (float)y2);//☆Fibonacci 20180816 コメントアウト             _pivot = new PointF(_pivot.X < _destination.X ? Math.Min(x1, x2) : Math.Max(x1, x2), _pivot.Y < _destination.Y ? (float)Math.Min(y1, y2) : (float)Math.Max(y1, y2));//☆Fibonacci 20180816 新規追加             _destination = new PointF(_pivot.X < _destination.X ? Math.Max(x1, x2) : Math.Min(x1, x2), _pivot.Y < _destination.Y ? (float)Math.Max(y1, y2) : (float)Math.Min(y1, y2));//☆Fibonacci 20180816 新規追加         }          private double Max(DataFarm farm, int ind1, int ind2)         {             var pos = ind1;             var max = double.MinValue;             var last = ind2 > farm.FilledLength ? farm.FilledLength - 1 : ind2;             try             {                 while (pos <= last)                 {                     var a = BitConverter.ToInt32(farm.RawDataImage, pos * 32 + 4 * 2) * farm.Brand.PriceScale / (Env.Preference.AdjustSplit ? farm.CalcSplitRatio(BitConverter.ToInt32(farm.RawDataImage, pos * 32)) : 1);                     Console.WriteLine(pos);                     if (max < a) max = a;                     pos++;                 }             }catch(Exception ex)             {                 Console.WriteLine(ex.Message);             }             return max;         }         private double Min(DataFarm farm, int ind1, int ind2)         {             var pos = ind1;             var min = double.MaxValue;             var last = ind2 > farm.FilledLength ? farm.FilledLength - 1 : ind2;             while (pos <= last)             {                 var a = BitConverter.ToInt32(farm.RawDataImage, pos * 32 + 4 * 3) * farm.Brand.PriceScale / (Env.Preference.AdjustSplit ? farm.CalcSplitRatio(BitConverter.ToInt32(farm.RawDataImage, pos * 32)) : 1);                 if (min > a) min = a;                 pos++;             }             return min;         }         public Rectangle GetInclusion(Rectangle rect)         {             if (_pivot == _destination)                 return new Rectangle(new Point((int)_pivot.X, (int)_pivot.Y), new Size(0, 0));             Point[] es = GetEdge(rect, new Point((int)_pivot.X, (int)_pivot.Y), new Point((int)_destination.X, (int)_destination.Y));             return new Rectangle(Math.Min(es[0].X, es[1].X), Math.Min(es[0].Y, es[1].Y), Math.Abs(es[0].X - es[1].X), Math.Abs(es[0].Y - es[1].Y));         }          //十分に離した位置でないと線を確定させないようにする         public bool PivotHasEnoughDistanceTo(PointF pt)         {             return Math.Abs(_pivot.X - pt.X) > 10 || Math.Abs(_pivot.Y - pt.Y) > 10;         }          //☆Fibonacci 20180816 Drawはまるまる書き直し ここから         public void Draw(Trans pricetrans, Rectangle rect, IntPtr hdc)         {             Win32.POINT pt = new Win32.POINT();             //Win32.SelectObject(hdc, _mode == LineDrawMode.Normal ? Env.Preference.FibonacciPen.Handle : Env.Preference.FibonacciBoldPen.Handle);//☆Fibonacci 20180816 コメントアウト             //var fibo = new double[] { -2.618, -1.618, 0, .236, .382, .5, .618, .764, 1, 1.618, 2.618 };             //var fibo = new double[] { 0, .236, .382, .5, .618, .764, 1 };             var fibo = new double[] { 0, .382, .5, .618, 1 };             foreach (var f in fibo)             {                 Win32.SelectObject(hdc, f == 0 ? Env.Preference.FibonacciBoldPen.Handle : f == 1 ? Env.Preference.FibonacciPen.Handle : f == .5 ? Env.Preference.FibonacciPen.Handle : Env.Preference.FibonacciDottedPen.Handle);//☆Fibonacci 20180816 追加                 FibonacciDrawLines fdl = new FibonacciDrawLines(_pivot, _destination, f, fibo);                 fdl.Draw(pricetrans, rect, hdc, out pt);             }         }//ここまで          //☆Fibonacci 20180816 追加         private void DrawTheLine(IntPtr hdc, float px1, float px2, float py, double kabuka, string text, out Win32.POINT pt)         {             Win32.MoveToEx(hdc, (int)px1, (int)py, out pt);             Win32.LineTo(hdc, (int)px2, (int)py);             DrawText(hdc, (int)px2, (int)py, kabuka);             DrawText(hdc, (int)px1 - 30, (int)py, text);         }         private void DrawText(IntPtr hdc, int x, int y, string s)         {             Win32.SetTextColor(hdc, Util.ToCOLORREF(Color.White));             ChartUtil.DrawText(hdc, x + 3, y - 6, s);         }         private void DrawTheLine(IntPtr hdc, float px1, float px2, float py, double kabuka, out Win32.POINT pt)         {             Win32.MoveToEx(hdc, (int)px1, (int)py, out pt);             Win32.LineTo(hdc, (int)px2, (int)py);             DrawText(hdc, (int)px2, (int)py, kabuka);         }         private void DrawText(IntPtr hdc, int x, int y, double d)         {             Win32.SetTextColor(hdc, Util.ToCOLORREF(Color.White));             ChartUtil.DrawText(hdc, x + 3, y - 6, string.Format("{0:N}", d));         }          //p1,p2がrectに入っているとき、p1からp2に伸ばした線とp2からp1に伸ばした線がそれぞれrectと交差するところを返す         private static Point[] GetEdge(Rectangle rect, Point p1, Point p2)         {             Point[] result = new Point[2];             ArrayList ar = GetAllEdges(rect, p1, p2);             if (ar.Count == 2) return (Point[])ar.ToArray(typeof(Point));              result[0] = (Point)(p1.X > p2.X ? ar[1] : ar[2]);             result[1] = (Point)(p1.X > p2.X ? ar[2] : ar[1]);             return result;         }         //p1とp2を結ぶ線がrectを構成する４直線と交差する点を返す。水平・垂直のときは２個になる         private static ArrayList GetAllEdges(Rectangle rect, Point p1, Point p2)         {             ArrayList ar = new ArrayList();             if (p1.X == p2.X)             {                 ar.Add(new Point(p1.X, p1.Y < p2.Y ? rect.Bottom : rect.Top));                 ar.Add(new Point(p1.X, p1.Y > p2.Y ? rect.Bottom : rect.Top));                 return ar;             }             else if (p1.Y == p2.Y)             {                 ar.Add(new Point(p1.X < p2.X ? rect.Right : rect.Left, p1.Y));                 ar.Add(new Point(p1.X > p2.X ? rect.Right : rect.Left, p1.Y));                 return ar;             }              LinearTrans lt = LinearTrans.Solve(p1.X, p1.Y, p2.X, p2.Y);             ar.Add(new Point(rect.Left, (int)lt.TransValue(rect.Left)));             ar.Add(new Point(rect.Right, (int)lt.TransValue(rect.Right)));             ar.Add(new Point((int)lt.Inverse(rect.Top), rect.Top));             ar.Add(new Point((int)lt.Inverse(rect.Bottom), rect.Bottom));             //この４点をX座標の順に並べ、２番目と３番目が答え             ar.Sort(new PointComparer());             return ar;         }         private class PointComparer : IComparer         {              public int Compare(object x, object y)             {                 return ((Point)x).X - ((Point)y).X;             }         }          public SolidFibonacci ToSolid(DataFarm farm, int firstdateindex, Trans value_to_y)         {             SolidFibonacci fl = new SolidFibonacci();             int ind1 = firstdateindex + (int)Math.Floor((double)_pivot.X / Env.Layout.DatePitch);             int ind2 = firstdateindex + (int)Math.Floor((double)_destination.X / Env.Layout.DatePitch);              LinearTrans tr = LinearTrans.Solve(ind1, _pivot.Y, ind2, _destination.Y);             double y1 = _pivot.Y;             if (ind1 >= farm.FilledLength)             {                 ind1 = farm.FilledLength - 1;                 //y1 = tr.TransValue(ind1);//☆Fibonacci 20180816 コメントアウト freelineと違ってy軸、つまり株価は移動しなくていい             }             else if (ind1 < 0)             {                 ind1 = 0;                 y1 = tr.TransValue(ind1);             }             fl._date1 = farm.GetByIndex(ind1).Date;             fl._value1 = value_to_y.Inverse(y1);              double y2 = _destination.Y;             if (ind2 >= farm.FilledLength)             {                 ind2 = farm.FilledLength - 1;                 //y2 = tr.TransValue(ind2);//☆Fibonacci 20180816 コメントアウト freelineと違ってy軸、つまり株価は移動しなくていい             }             else if (ind2 < 0)             {                 ind2 = 0;                 y2 = tr.TransValue(0);             }             fl._date2 = farm.GetByIndex(ind2).Date;             fl._value2 = value_to_y.Inverse(y2);             //_id==-1は作ったばかりのフィボナッチで、0以上は既存フィボナッチ             if (_id == -1)             {                 fl._id = SolidFibonacci.NextID++;                 _id = fl._id;             }             else             {                 fl._id = _id;             }             return fl;         }          //☆Fibonacci 20180816 変更 GetDistanceは全面的に書き直し         public double GetDistance(Point p)         {             return Math.Min(GetDistanceUpside(p), GetDistanceDownside(p));         }         //☆Fibonacci 20180816 新規         //最上部のフィボナッチラインとマウスカーソルとの直線距離         //マウスカーソルがフィボナッチラインの幅内にあった場合のみ、マウスカーソルと最上部フィボナッチラインの縦幅を計測して返す         public double GetDistanceUpside(Point p)         {             var y = Math.Min(_pivot.Y, _destination.Y);             var xl = Math.Min(_pivot.X, _destination.X);             var xr = Math.Max(_pivot.X, _destination.X);             return (p.X < xl || xr < p.X) ? double.MaxValue : Math.Abs(y - p.Y);         }         //☆Fibonacci 20180816 新規         //最下部のフィボナッチラインとマウスカーソルとの直線距離         //マウスカーソルがフィボナッチラインの幅内にあった場合のみ、マウスカーソルと最下部フィボナッチラインの縦幅を計測して返す         public double GetDistanceDownside(Point p)         {             var y = Math.Max(_pivot.Y, _destination.Y);             var xl = Math.Min(_pivot.X, _destination.X);             var xr = Math.Max(_pivot.X, _destination.X);             return (p.X < xl || xr < p.X) ? double.MaxValue : Math.Abs(y - p.Y);         }          //両端を通る直線を ax+by+c=0, a^2+b^2=1 となる形式でa,b,cの配列で返す         private double[] GetNormalizedParam()         {             double a, b, c;             if (_pivot.X == _destination.X)             {                 a = 1;                 b = 0;             }             else             {                 double d = -(_pivot.Y - _destination.Y) / (double)(_pivot.X - _destination.X);                 b = Math.Sqrt(1 / (1 + d * d));                 a = b * d;             }             c = -(a * _pivot.X + b * _pivot.Y);             return new double[] { a, b, c };         }     }      internal class SolidFibonacci     {         public int _id;         public int _code;         public ChartFormat _targetFormat;         public bool _logScale;         public int _date1;         public double _value1;         public int _date2;         public double _value2;           private static int _nextID;         public static int NextID         {             get             {                 return _nextID;             }             set             {                 _nextID = value;             }         }     }      internal class FibonacciCollection     {         private ArrayList _data;         public FibonacciCollection()         {             _data = new ArrayList();         }         public int Count         {             get             {                 return _data.Count;             }         }          public void Add(AbstractBrand br, ChartFormat format, bool logScale, SolidFibonacci fl)         {             fl._code = br.Code;             fl._targetFormat = format;             fl._logScale = logScale;             _data.Add(fl);         }          public SolidFibonacci[] Find(AbstractBrand br, ChartFormat format, bool logScale)         {             ArrayList t = new ArrayList();             foreach (SolidFibonacci fl in _data)             {                 if (fl._code == br.Code && fl._targetFormat == format && fl._logScale == logScale)                     t.Add(fl);             }             return (SolidFibonacci[])t.ToArray(typeof(SolidFibonacci));         }          public void ClearAll()         {             _data.Clear();         }         public void Clear(AbstractBrand br, ChartFormat format, bool logScale)         {             ArrayList temp = new ArrayList();             IEnumerator ie = _data.GetEnumerator();             while (ie.MoveNext())             {                 SolidFibonacci fl = (SolidFibonacci)ie.Current;                 if (!(fl._code == br.Code && fl._targetFormat == format && fl._logScale == logScale))                     temp.Add(fl);             }             _data = temp;         }         public void Remove(int id)         {             for (int i = 0; i < _data.Count; i++)             {                 SolidFibonacci l = (SolidFibonacci)_data[i];                 if (l._id == id)                 {                     _data.RemoveAt(i);                     break;                 }             }         }           public void Load(StorageNode parent)         {             string t = parent["fibonacci-lines"];             if (t == null) return;             foreach (string ee in t.Split(','))             {                 if (ee == null) continue;                 if (ee.Trim() == string.Empty) continue;                 SolidFibonacci fl = new SolidFibonacci();                 string[] e = ee.Split(':');                 fl._code = Int32.Parse(e[0]);                 switch (e[1])                 {                     case "D":                         fl._targetFormat = ChartFormat.Daily;                         fl._logScale = false;                         break;                     case "W":                         fl._targetFormat = ChartFormat.Weekly;                         fl._logScale = false;                         break;                     case "M":                         fl._targetFormat = ChartFormat.Monthly;                         fl._logScale = false;                         break;                     case "Y":                         fl._targetFormat = ChartFormat.Yearly;                         fl._logScale = false;                         break;                     case "DL":                         fl._targetFormat = ChartFormat.Daily;                         fl._logScale = true;                         break;                     case "WL":                         fl._targetFormat = ChartFormat.Weekly;                         fl._logScale = true;                         break;                     case "ML":                         fl._targetFormat = ChartFormat.Monthly;                         fl._logScale = true;                         break;                     case "YL":                         fl._targetFormat = ChartFormat.Yearly;                         fl._logScale = true;                         break;                 }                 fl._date1 = Int32.Parse(e[2]);                 fl._value1 = Double.Parse(e[3]);                 fl._date2 = Int32.Parse(e[4]);                 fl._value2 = Double.Parse(e[5]);                 fl._id = SolidFibonacci.NextID++;                 _data.Add(fl);             }         }         public void SaveTo(StorageNode parent)         {             StringBuilder bld = new StringBuilder();             foreach (SolidFibonacci sl in _data)             {                 if (bld.Length > 0) bld.Append(",");                 String format;                 switch (sl._targetFormat)                 {                     case ChartFormat.Daily:                     default:                         format = "D";                         break;                     case ChartFormat.Weekly:                         format = "W";                         break;                     case ChartFormat.Monthly:                         format = "M";                         break;                     case ChartFormat.Yearly:                         format = "Y";                         break;                 }                 if (sl._logScale)                 {                     format += "L";                 }                 bld.Append(String.Format("{0}:{1}:{2}:{3:F2}:{4}:{5:F2}", sl._code, format, sl._date1, sl._value1, sl._date2, sl._value2));             }             parent["fibonacci-lines"] = bld.ToString();         }     }     //☆Fibonacci 20180816 新規追加     internal class FibonacciDrawLines     {         bool _log = false;         PointF _pivot;         PointF _dest;         double _fibopos = .0;         double[] _fibonacci;         string _text = string.Empty;         public FibonacciDrawLines(PointF pivot, PointF dest, double fibopos, double[] fibonacci)         {             _pivot = pivot;             _dest = dest;             _fibopos = fibopos;             _fibonacci = fibonacci;         }         public void Draw(Trans pricetrans, Rectangle rect, IntPtr hdc, out Win32.POINT pt)         {             var k = retKabuka(pricetrans);             var y = (int)retY(k, pricetrans);             Win32.MoveToEx(hdc, (int)Math.Min(_pivot.X, _dest.X), y, out pt);             Win32.LineTo(hdc, (int)Math.Max(_pivot.X, _dest.X), y);             DrawText(hdc, (int)Math.Max(_pivot.X, _dest.X), y, k);             DrawText(hdc, (int)Math.Min(_pivot.X, _dest.X) - 30, y, retText());         }         private string retText()         {             return _fibopos == 0 ? _pivot.Y < _dest.Y ? "100" : "0" : //マウスが上から下に動いてフィボナッチリトレースメントを作ったとき逆転させる                    _fibopos == 1 ? _pivot.Y < _dest.Y ? "0" : "100" : //マウスが上から下に動いてフィボナッチリトレースメントを作ったとき逆転させる                    string.Format("{0:00.0}", _fibopos * 100);//天底以外の数値(0.618とか）はretKabukaでハンドリングするのでここでは逆転させない         }         private double retKabuka(Trans pricetrans)         {             var ret = .0;             if (_log)//対数チャートの場合             {                 //上下逆転チャートではない、かつマウスを下から上に引いて作った、　もしくは上下逆転チャート、かつマウスを上から下に引いて作った                 if ((!Env.Preference.InverseChart && _pivot.Y > _dest.Y) || (Env.Preference.InverseChart && _pivot.Y < _dest.Y))                 {                     ret = _fibopos == 0 ? pricetrans.Inverse(Math.Min(_pivot.Y, _dest.Y))                         : _fibopos == 1 ? pricetrans.Inverse(Math.Max(_pivot.Y, _dest.Y))                         : pricetrans.Inverse(Math.Max(_pivot.Y, _dest.Y) - Math.Abs(_pivot.Y - _dest.Y) * _fibopos);                 }                 else                 {                     ret = _fibopos == 0 ? pricetrans.Inverse(Math.Min(_pivot.Y, _dest.Y))                     : _fibopos == 1 ? pricetrans.Inverse(Math.Max(_pivot.Y, _dest.Y))                     : pricetrans.Inverse(Math.Min(_pivot.Y, _dest.Y) + Math.Abs(_pivot.Y - _dest.Y) * _fibopos);                 }             }             else             {                 var k1 = pricetrans.Inverse(Math.Min(_pivot.Y, _dest.Y));                 var k5 = pricetrans.Inverse(Math.Max(_pivot.Y, _dest.Y));                 //上下逆転チャートではない、かつマウスを下から上に引いて作った、　もしくは上下逆転チャート、かつマウスを上から下に引いて作った                 if ((!Env.Preference.InverseChart && _pivot.Y > _dest.Y) || (Env.Preference.InverseChart && _pivot.Y < _dest.Y))                 {                     ret = _fibopos == 0 ? k1 : _fibopos == 1 ? k5 : Math.Max(k1, k5) - Math.Abs(k1 - k5) * _fibopos;                 }                 else                 {                     ret = _fibopos == 0 ? k1 : _fibopos == 1 ? k5 : Math.Min(k1, k5) + Math.Abs(k1 - k5) * _fibopos;                 }             }             return ret;         }         private float retY(double k, Trans pricetrans)         {             var ret = 0F;             if (_log)             {                 ret = _fibopos == 0 ? Math.Min(_pivot.Y, _dest.Y)                       : _fibopos == 1 ? Math.Max(_pivot.Y, _dest.Y)                       : (float)(Math.Abs(_pivot.Y - _dest.Y) * _fibopos + Math.Min(_pivot.Y, _dest.Y));             }             else             {                 ret = _fibopos == 0 ? Math.Min(_pivot.Y, _dest.Y)                       : _fibopos == 1 ? Math.Max(_pivot.Y, _dest.Y)                       : (float)pricetrans.TransValue(k);             }             return ret;         }         private void DrawText(IntPtr hdc, int x, int y, string s)         {             Win32.SetTextColor(hdc, Util.ToCOLORREF(Color.White));             ChartUtil.DrawText(hdc, x + 3, y - 6, s);         }         private void DrawText(IntPtr hdc, int x, int y, double d)         {             Win32.SetTextColor(hdc, Util.ToCOLORREF(Color.White));             ChartUtil.DrawText(hdc, x + 3, y - 6, string.Format("{0:N}", d));         }     } }`