diff --git a/src/content/blogs/2024-05-30-js-range.md b/src/content/blogs/2024-05-30-js-range.md new file mode 100644 index 0000000..a898689 --- /dev/null +++ b/src/content/blogs/2024-05-30-js-range.md @@ -0,0 +1,7 @@ +--- +title: JavaScriptの連番生成のパフォーマンス +description: JavaScriptの連番生成をtinybenchで測定して比較します +author: miyaji +category: tech +tags: [javascript] +--- diff --git a/src/content/blogs/2024-05-30-js-range/bun.csv b/src/content/blogs/2024-05-30-js-range/bun.csv new file mode 100644 index 0000000..662f0fc --- /dev/null +++ b/src/content/blogs/2024-05-30-js-range/bun.csv @@ -0,0 +1,49 @@ +"length","Task Name","ops/sec","Average Time (ns)","Margin","Samples" +"16","Array.from({ length }, func)","12,457,152","80.27516541932673","±1.31%","6228577" +"16","Array(length) + spread + map","5,088,392","196.52571222833308","±2.16%","2544198" +"16","Array(length) + fill + map","11,088,713","90.18178863436107","±1.92%","5544362" +"16","Array(length) + for","23,357,627","42.81256769718978","±2.28%","11678814" +"16","Array(length) + spread + for","5,036,486","198.55110386653178","±1.95%","2518244" +"16","Array(length) + spread + forEach","5,211,119","191.89735603875351","±1.85%","2605560" +"16","Array(length) + fill + forEach","14,916,640","67.03922196458265","±0.93%","7458321" +"16","[] + push","18,325,849","54.56773029933011","±2.10%","9162930" +"256","Array.from({ length }, func)","1,827,001","547.3448706260276","±1.97%","913502" +"256","Array(length) + spread + map","372,313","2685.9058106926514","±2.07%","186157" +"256","Array(length) + fill + map","996,287","1003.7265108044211","±2.16%","498144" +"256","Array(length) + for","2,400,180","416.63525515889086","±2.16%","1200091" +"256","Array(length) + spread + for","403,667","2477.2840403617724","±1.56%","201834" +"256","Array(length) + spread + forEach","408,757","2446.435465494052","±1.62%","204379" +"256","Array(length) + fill + forEach","1,760,790","567.9267579686273","±1.93%","882294" +"256","[] + push","1,417,101","705.6656533312768","±2.09%","708552" +"4096","Array.from({ length }, func)","135,048","7404.720696041756","±4.36%","67525" +"4096","Array(length) + spread + map","26,425","37841.781427399685","±3.13%","13213" +"4096","Array(length) + fill + map","82,668","12096.524882068175","±3.97%","41335" +"4096","Array(length) + for","211,928","4718.572075688416","±3.90%","105965" +"4096","Array(length) + spread + for","26,829","37273.024301198195","±2.76%","13415" +"4096","Array(length) + spread + forEach","25,911","38592.35751776824","±2.65%","12956" +"4096","Array(length) + fill + forEach","104,925","9530.54844365384","±3.69%","52463" +"4096","[] + push","80,943","12354.306434105096","±4.23%","40472" +"65536","Array.from({ length }, func)","9,175","108990.43591981127","±2.64%","4588" +"65536","Array(length) + spread + map","1,484","673493.1251681887","±3.26%","743" +"65536","Array(length) + fill + map","4,575","218570.55002181852","±3.90%","2289" +"65536","Array(length) + for","10,979","91074.86612018177","±4.00%","5490" +"65536","Array(length) + spread + for","1,581","632222.6010099736","±2.72%","792" +"65536","Array(length) + spread + forEach","1,566","638176.7372448738","±2.84%","784" +"65536","Array(length) + fill + forEach","8,479","117937.75548223165","±2.94%","4241" +"65536","[] + push","6,893","145062.69045556508","±3.50%","3447" +"1048576","Array.from({ length }, func)","485","2061154.4855970433","±4.22%","243" +"1048576","Array(length) + spread + map","92","10807839.880000465","±2.81%","100" +"1048576","Array(length) + fill + map","254","3928565.9140624604","±2.87%","128" +"1048576","Array(length) + for","676","1477830.7227136747","±1.88%","339" +"1048576","Array(length) + spread + for","108","9203761.549999908","±2.56%","100" +"1048576","Array(length) + spread + forEach","96","10355419.989999937","±3.07%","100" +"1048576","Array(length) + fill + forEach","427","2339520.5700937505","±3.58%","214" +"1048576","[] + push","279","3581277.05714261","±4.34%","140" +"16777216","Array.from({ length }, func)","35","28076712.80000017","±4.58%","100" +"16777216","Array(length) + spread + map","6","165038801.1600005","±1.68%","100" +"16777216","Array(length) + fill + map","15","64089513.089999676","±2.97%","100" +"16777216","Array(length) + for","39","25379640.84000094","±1.85%","100" +"16777216","Array(length) + spread + for","6","162071490.79999974","±1.50%","100" +"16777216","Array(length) + spread + forEach","5","186792892.31000105","±2.24%","100" +"16777216","Array(length) + fill + forEach","16","59684912.360000454","±3.71%","100" +"16777216","[] + push","7","128359421.61000057","±2.78%","100" diff --git a/src/content/blogs/2024-05-30-js-range/bun.svg b/src/content/blogs/2024-05-30-js-range/bun.svg new file mode 100644 index 0000000..f58893f --- /dev/null +++ b/src/content/blogs/2024-05-30-js-range/bun.svg @@ -0,0 +1,2494 @@ + + + + + + + + 2024-05-30T10:56:26.708521 + image/svg+xml + + + Matplotlib v3.8.2, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/content/blogs/2024-05-30-js-range/spidermonkey.csv b/src/content/blogs/2024-05-30-js-range/spidermonkey.csv new file mode 100644 index 0000000..8d5a0b3 --- /dev/null +++ b/src/content/blogs/2024-05-30-js-range/spidermonkey.csv @@ -0,0 +1,49 @@ +"length","Task Name","ops/sec","Average Time (ns)","Margin","Samples" +"16","Array.from({ length }, func)","7,339,738","136.24462979543162","±0.37%","3669873" +"16","Array(length) + spread + map","2,734,297","365.7246791419135","±0.39%","1367164" +"16","Array(length) + fill + map","4,550,127","219.7740478362706","±0.46%","2275065" +"16","Array(length) + for","12,092,024","82.69914053151125","±0.39%","6046015" +"16","Array(length) + spread + for","4,886,003","204.66624238309367","±0.34%","2443003" +"16","Array(length) + spread + forEach","2,925,610","341.80905862367166","±0.42%","1462805" +"16","Array(length) + fill + forEach","4,644,785","215.29518425410373","±0.37%","2322394" +"16","[] + push","12,233,638","81.74183328215616","±0.39%","6116822" +"256","Array.from({ length }, func)","1,404,095","712.2023624319492","±0.41%","702048" +"256","Array(length) + spread + map","252,358","3962.6144043974873","±0.37%","126180" +"256","Array(length) + fill + map","430,683","2321.8925084865004","±0.70%","215342" +"256","Array(length) + for","1,795,954","556.8071342584499","±0.45%","897977" +"256","Array(length) + spread + for","419,180","2385.609101848958","±0.32%","209591" +"256","Array(length) + spread + forEach","222,383","4496.743948530469","±13.46%","111192" +"256","Array(length) + fill + forEach","422,341","2367.751671779032","±0.26%","211171" +"256","[] + push","1,078,549","927.1708300805154","±0.57%","539276" +"4096","Array.from({ length }, func)","66,159","15115.020641248488","±1.69%","33080" +"4096","Array(length) + spread + map","16,448","60794.815017097266","±0.74%","8225" +"4096","Array(length) + fill + map","26,830","37270.69779670729","±0.69%","13416" +"4096","Array(length) + for","141,821","7051.140823088828","±0.68%","70912" +"4096","Array(length) + spread + for","32,367","30894.771166738752","±0.71%","16184" +"4096","Array(length) + spread + forEach","16,847","59356.37065601259","±0.66%","8424" +"4096","Array(length) + fill + forEach","25,518","39187.32550450627","±0.52%","12760" +"4096","[] + push","80,035","12494.499545517017","±1.62%","40018" +"65536","Array.from({ length }, func)","3,045","328311.77076533943","±5.32%","1532" +"65536","Array(length) + spread + map","781","1278779.246922954","±5.08%","391" +"65536","Array(length) + fill + map","1,318","758206.8241003788","±0.88%","660" +"65536","Array(length) + for","4,234","236152.1086003895","±4.97%","2118" +"65536","Array(length) + spread + for","1,646","607412.0975235134","±0.95%","824" +"65536","Array(length) + spread + forEach","843","1184983.963085012","±6.12%","422" +"65536","Array(length) + fill + forEach","1,429","699580.3512893356","±1.10%","715" +"65536","[] + push","3,227","309798.8825464396","±7.62%","1615" +"1048576","Array.from({ length }, func)","199","5019667.96875","±11.74%","100" +"1048576","Array(length) + spread + map","43","22935134.27734375","±5.76%","100" +"1048576","Array(length) + fill + map","58","17110600.5859375","±5.29%","100" +"1048576","Array(length) + for","179","5577714.84375","±11.23%","100" +"1048576","Array(length) + spread + for","66","14965319.82421875","±8.06%","100" +"1048576","Array(length) + spread + forEach","47","21184399.4140625","±6.24%","100" +"1048576","Array(length) + fill + forEach","75","13222280.2734375","±11.39%","100" +"1048576","[] + push","121","8234272.4609375","±9.51%","100" +"16777216","Array.from({ length }, func)","3","283509414.0625","±3.05%","100" +"16777216","Array(length) + spread + map","1","524090136.71875006","±2.42%","100" +"16777216","Array(length) + fill + map","2","368505659.1796875","±1.10%","100" +"16777216","Array(length) + for","7","132926987.3046875","±1.94%","100" +"16777216","Array(length) + spread + for","4","201675393.06640625","±1.35%","100" +"16777216","Array(length) + spread + forEach","3","307277463.37890625","±0.86%","100" +"16777216","Array(length) + fill + forEach","4","246321958.0078125","±2.08%","100" +"16777216","[] + push","9","109690786.1328125","±1.84%","100" diff --git a/src/content/blogs/2024-05-30-js-range/spidermonkey.svg b/src/content/blogs/2024-05-30-js-range/spidermonkey.svg new file mode 100644 index 0000000..16db97a --- /dev/null +++ b/src/content/blogs/2024-05-30-js-range/spidermonkey.svg @@ -0,0 +1,2562 @@ + + + + + + + + 2024-05-30T10:56:27.228220 + image/svg+xml + + + Matplotlib v3.8.2, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/content/blogs/2024-05-30-js-range/v8.csv b/src/content/blogs/2024-05-30-js-range/v8.csv new file mode 100644 index 0000000..8ad92ab --- /dev/null +++ b/src/content/blogs/2024-05-30-js-range/v8.csv @@ -0,0 +1,49 @@ +"length","Task Name","ops/sec","Average Time (ns)","Margin","Samples" +"16","Array.from({ length }, func)","1,556,472","642.4782650038306","±0.47%","778238" +"16","Array(length) + spread + map","11,723,367","85.29971932984385","±0.83%","5861684" +"16","Array(length) + fill + map","11,862,788","84.29721384768528","±0.82%","5931406" +"16","Array(length) + for","22,369,267","44.70418969460425","±0.84%","11184634" +"16","Array(length) + spread + for","15,072,447","66.34622389226534","±1.04%","7536239" +"16","Array(length) + spread + forEach","15,519,455","64.43524824582745","±0.80%","7759728" +"16","Array(length) + fill + forEach","12,574,723","79.5246082538539","±0.88%","6287362" +"16","[] + push","16,939,637","59.03313872483812","±1.43%","8469819" +"256","Array.from({ length }, func)","115,091","8688.718590342149","±0.56%","57546" +"256","Array(length) + spread + map","1,221,777","818.4795953453137","±2.85%","610890" +"256","Array(length) + fill + map","1,662,687","601.4357474167572","±1.79%","831344" +"256","Array(length) + for","4,402,209","227.1586731958497","±2.13%","2201109" +"256","Array(length) + spread + for","2,245,507","445.3335280929638","±2.08%","1122754" +"256","Array(length) + spread + forEach","2,438,719","410.0513219203455","±1.96%","1219362" +"256","Array(length) + fill + forEach","2,243,261","445.7795018511339","±1.39%","1121633" +"256","[] + push","1,525,696","655.4381595320178","±0.85%","762850" +"4096","Array.from({ length }, func)","7,752","128983.49239105107","±0.46%","3877" +"4096","Array(length) + spread + map","145,217","6886.226225400864","±0.72%","72609" +"4096","Array(length) + fill + map","134,099","7457.136465320318","±0.83%","67050" +"4096","Array(length) + for","423,420","2361.7170009144406","±0.74%","211718" +"4096","Array(length) + spread + for","216,377","4621.541931255524","±0.92%","108189" +"4096","Array(length) + spread + forEach","200,238","4994.037155420087","±1.12%","100120" +"4096","Array(length) + fill + forEach","164,244","6088.4770405435875","±0.85%","82123" +"4096","[] + push","124,816","8011.759993584348","±0.89%","62415" +"65536","Array.from({ length }, func)","473","2110645.5696202456","±1.54%","237" +"65536","Array(length) + spread + map","3,150","317369.3864642024","±7.33%","1581" +"65536","Array(length) + fill + map","3,889","257072.49357322798","±6.48%","1945" +"65536","Array(length) + for","9,091","109991.86097672624","±7.30%","4546" +"65536","Array(length) + spread + for","4,523","221083.55437655828","±7.97%","2262" +"65536","Array(length) + spread + forEach","4,757","210211.85372007074","±7.65%","2379" +"65536","Array(length) + fill + forEach","6,270","159476.08418371703","±5.84%","3136" +"65536","[] + push","3,154","317047.5285171099","±3.02%","1578" +"1048576","Array.from({ length }, func)","30","32878739.99999989","±0.81%","100" +"1048576","Array(length) + spread + map","182","5485919.999999897","±5.62%","100" +"1048576","Array(length) + fill + map","216","4617513.761467767","±5.15%","109" +"1048576","Array(length) + for","665","1503657.6576575069","±2.77%","333" +"1048576","Array(length) + spread + for","249","4001671.999999962","±4.25%","125" +"1048576","Array(length) + spread + forEach","256","3893837.2093021586","±3.73%","129" +"1048576","Array(length) + fill + forEach","524","1906627.3764257976","±1.10%","263" +"1048576","[] + push","130","7665149.999999849","±7.37%","100" +"16777216","Array.from({ length }, func)","1","542183530.0000001","±0.86%","100" +"16777216","Array(length) + spread + map","7","131584569.99999966","±2.54%","100" +"16777216","Array(length) + fill + map","13","76649420.00000054","±1.41%","100" +"16777216","Array(length) + for","33","29859180.000000633","±1.22%","100" +"16777216","Array(length) + spread + for","14","66729830.0000024","±4.09%","100" +"16777216","Array(length) + spread + forEach","16","60932629.9999989","±2.51%","100" +"16777216","Array(length) + fill + forEach","22","44835340.000001594","±1.17%","100" +"16777216","[] + push","7","134587069.99999908","±4.18%","100" diff --git a/src/content/blogs/2024-05-30-js-range/v8.svg b/src/content/blogs/2024-05-30-js-range/v8.svg new file mode 100644 index 0000000..1806258 --- /dev/null +++ b/src/content/blogs/2024-05-30-js-range/v8.svg @@ -0,0 +1,2576 @@ + + + + + + + + 2024-05-30T10:56:26.995772 + image/svg+xml + + + Matplotlib v3.8.2, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +