Bandwidth Calc CTA Test 1

Main
Glenwing 6 years ago
parent f5d05c0816
commit 701a071aa0

@ -0,0 +1,163 @@
Rev,VIC,Alt,H,V,Scan,H tot,H bl,V tot,V bl,H freq (kHz),V freq (Hz),Px CLK,HF,HS,HB,VF,VS,VB,Hpol,Vpol
A,1,,640,480,p,800,160,525,45,31.469,59.94,25.175,16,96,48,10,2,33,n,n
A,1,,640,480,p,800,160,525,45,31.5,60,25.2,16,96,48,10,2,33,n,n
A,2,3,720,480,p,858,138,525,45,31.469,59.94,27,16,62,60,8,6,31,n,n
A,2,3,720,480,p,858,138,525,45,31.5,60,27.027,16,62,60,8,6,31,p,p
A,4,69,1280,720,p,1650,370,750,30,44.955,59.939,74.175,110,40,220,5,5,20,p,p
A,4,69,1280,720,p,1650,370,750,30,45,60,74.25,110,40,220,5,5,20,p,p
A,5,,1920,1080,i,2200,280,1125,22.5,33.716,59.939,74.175,88,44,148,2,5,15,p,p
A,5,,1920,1080,i,2200,280,1125,22.5,33.75,60,74.25,88,44,148,2,5,15,p,p
A,6,7,1440,480,i,1716,276,525,22.5,15.734,59.94,27,38,124,114,4,3,15,n,n
A,6,7,1440,480,i,1716,276,525,22.5,15.75,60,27.027,38,124,114,4,3,15,n,n
B,8,9,1440,240,p,1716,276,262,22,15.734,60.054,27,38,124,114,4,3,15,n,n
B,8,9,1440,240,p,1716,276,263,23,15.734,59.826,27,38,124,114,5,3,15,n,n
B,10,11,2880,480,i,3432,552,525,22.5,15.734,59.94,54,76,248,228,4,3,15,n,n
B,12,13,2880,240,p,3432,552,525,22,15.734,60.054,54,76,248,228,4,3,15,n,n
B,12,13,2880,240,p,3432,552,525,23,15.734,59.826,54,76,248,228,5,3,15,n,n
B,14,15,1440,480,p,1716,276,525,45,31.469,59.94,54,32,124,120,9,6,30,n,n
B,14,15,1440,480,p,1716,276,525,45,31.5,60,54.054,32,124,120,9,6,30,n,n
B,16,76,1920,1080,p,2200,280,1125,45,67.432,59.939,148.35,88,44,148,4,5,36,p,p
B,16,76,1920,1080,p,2200,280,1125,45,67.5,60,148.5,88,44,148,4,5,36,p,p
A,17,18,720,576,p,864,144,625,49,31.25,50,27,12,64,68,5,5,39,n,n
A,19,68,1280,720,p,1980,700,750,30,37.5,50,74.25,440,40,220,5,5,20,p,p
A,20,,1920,1080,i,2640,720,1125,22.5,28.125,50,74.25,528,44,148,2,5,15,p,p
A,21,22,1440,576,i,1728,288,625,24.5,15.625,50,27,24,126,138,2,3,19,n,n
B,23,24,1440,288,p,1728,288,312,24,15.625,50.08,27,24,126,138,2,3,19,n,n
B,23,24,1440,288,p,1728,288,313,25,15.625,49.92,27,24,126,138,3,3,19,n,n
B,23,24,1440,288,p,1728,288,314,26,15.625,49.761,27,24,126,138,4,3,19,n,n
B,25,26,2880,576,i,3456,576,625,24.5,15.625,50,54,48,252,276,2,3,19,n,n
B,27,28,2880,288,p,3456,576,312,24,15.625,50.08,54,48,252,276,2,3,19,n,n
B,27,28,2880,288,p,3456,576,313,25,15.625,49.92,54,48,252,276,3,3,19,n,n
B,27,28,2880,288,p,3456,576,314,26,15.625,49.761,54,48,252,276,4,3,19,n,n
B,29,30,1440,576,p,1728,288,625,49,31.25,50,54,24,128,136,5,5,39,n,n
B,31,75,1920,1080,p,2640,720,1125,45,56.25,50,148.5,528,44,148,4,5,36,p,p
B,32,72,1920,1080,p,2750,830,1125,45,26.973,23.976,74.175,638,44,148,4,5,36,p,p
B,32,72,1920,1080,p,2750,830,1125,45,27,24,74.25,638,44,148,4,5,36,p,p
B,33,73,1920,1080,p,2640,720,1125,45,28.125,25,74.25,528,44,148,4,5,36,p,p
B,34,74,1920,1080,p,2200,280,1125,45,33.716,29.97,74.175,88,44,148,4,5,36,p,p
B,34,74,1920,1080,p,2200,280,1125,45,33.75,30,74.25,88,44,148,4,5,36,p,p
C,35,36,2880,480,p,3432,552,525,45,31.5,60,108.108,64,248,240,9,6,30,n,n
C,37,38,2880,576,p,3456,576,625,49,31.25,50,108,48,256,272,5,5,39,n,n
C,39,,1920,1080,i,2304,384,1250,85,31.25,50,72,32,168,184,23,5,57,p,n
C,40,,1920,1080,i,2640,720,1125,22.5,56.25,100,148.5,528,44,148,2,5,15,p,p
C,41,,1280,720,p,1980,700,750,30,75,100,148.5,440,40,220,5,5,20,p,p
C,42,43,720,576,p,864,144,625,49,62.5,100,54,12,64,68,5,5,39,n,n
C,44,45,1440,576,i,1728,288,625,24.5,31.25,100,54,24,126,138,2,3,19,n,n
C,46,,1920,1080,i,2200,280,1125,22.5,67.432,119.88,148.352,88,44,148,2,5,15,p,p
C,46,,1920,1080,i,2200,280,1125,22.5,67.5,120,148.5,88,44,148,2,5,15,p,p
C,47,,1280,720,p,1650,370,750,30,89.909,119.88,148.352,110,40,220,5,5,20,p,p
C,47,,1280,720,p,1650,370,750,30,90,120,148.5,110,40,220,5,5,20,p,p
C,48,49,720,480,p,858,138,525,45,62.937,119.88,54,16,62,60,9,6,30,n,n
C,48,49,720,480,p,858,138,525,45,63,120,54.054,16,62,60,9,6,30,n,n
C,50,51,1440,480,i,1716,276,525,22.5,31.469,119.88,54,38,124,114,4,3,15,n,n
C,50,51,1440,480,i,1716,276,525,22.5,31.5,120,54.054,38,124,114,4,3,15,p,p
C,52,53,720,576,p,864,144,625,49,125,200,108,12,64,68,5,5,39,n,n
C,54,55,1440,576,i,1728,288,625,24.5,62.5,200,108,24,126,138,2,3,19,n,n
C,56,57,720,480,p,858,138,525,45,125.874,239.76,108,16,62,60,9,6,30,n,n
C,56,57,720,480,p,858,138,525,45,126,240,108.108,16,62,60,9,6,30,n,n
C,58,59,1440,480,i,1716,276,525,22.5,62.937,239.76,108,38,124,114,4,3,15,n,n
C,58,59,1440,480,i,1716,276,525,22.5,63,240,108.108,38,124,114,4,3,15,n,n
E,60,65,1280,720,p,3300,2020,750,30,17.982,23.976,59.341,1760,40,220,5,5,20,p,p
E,60,65,1280,720,p,3300,2020,750,30,18,24,59.4,1760,40,220,5,5,20,p,p
E,61,66,1280,720,p,3960,2680,750,30,18.75,25,74.25,2420,40,220,5,5,20,p,p
E,62,67,1280,720,p,3300,2020,750,30,22.478,29.97,74.176,1760,40,220,5,5,20,p,p
E,62,67,1280,720,p,3300,2020,750,30,22.5,30,74.25,1760,40,220,5,5,20,p,p
E,63,78,1920,1080,p,2200,280,1125,45,134.865,119.88,296.703,88,44,148,4,5,36,p,p
E,63,78,1920,1080,p,2200,280,1125,45,135,120,297,88,44,148,4,5,36,p,p
E,64,77,1920,1080,p,2640,720,1125,45,112.5,100,297,528,44,148,4,5,36,p,p
F,79,,1680,720,p,3300,1620,750,30,17.982,23.976,59.341,1360,40,220,5,5,20,p,p
F,79,,1680,720,p,3300,1620,750,30,17.982,23.976,59.341,1360,40,220,5,5,20,p,p
F,79,,1680,720,p,3300,1620,750,30,18,24,59.4,1360,40,220,5,5,20,p,p
F,80,,1680,720,p,3168,1488,750,30,18.75,25,59.4,1228,40,220,5,5,20,p,p
F,81,,1680,720,p,2640,960,750,30,22.478,29.970,59.341,700,40,220,5,5,20,p,p
F,81,,1680,720,p,2640,960,750,30,22.5,30,59.4,700,40,220,5,5,20,p,p
F,82,,1680,720,p,2200,520,750,30,37.5,50,82.5,260,40,220,5,5,20,p,p
F,83,,1680,720,p,2200,520,750,30,44.955,59.940,98.901,260,40,220,5,5,20,p,p
F,83,,1680,720,p,2200,520,750,30,45,60,99,260,40,220,5,5,20,p,p
F,84,,1680,720,p,2000,320,825,105,82.5,100,165,60,40,220,5,5,95,p,p
F,85,,1680,720,p,2000,320,825,105,98.901,119.880,197.802,60,40,220,5,5,95,p,p
F,85,,1680,720,p,2000,320,825,105,99,120,198,60,40,220,5,5,95,p,p
F,86,,2560,1080,p,3750,1190,1100,20,26.374,23.976,98.901,998,44,148,4,5,11,p,p
F,86,,2560,1080,p,3750,1190,1100,20,26.4,24,99,998,44,148,4,5,11,p,p
F,87,,2560,1080,p,3200,640,1125,45,28.125,25,90,448,44,148,4,5,36,p,p
F,88,,2560,1080,p,3520,960,1125,45,33.716,29.970,118.681,768,44,148,4,5,36,p,p
F,88,,2560,1080,p,3520,960,1125,45,33.75,30,118.8,768,44,148,4,5,36,p,p
F,89,,2560,1080,p,3300,740,1125,45,56.25,50,185.625,548,44,148,4,5,36,p,p
F,90,,2560,1080,p,3000,440,1100,20,65.934,59.940,197.802,248,44,148,4,5,11,p,p
F,90,,2560,1080,p,3000,440,1100,20,66,60,198,248,44,148,4,5,11,p,p
F,91,,2560,1080,p,2970,410,1250,170,125,100,371.25,218,44,148,4,5,161,p,p
F,92,,2560,1080,p,3300,740,1250,170,149.850,119.880,494.505,548,44,148,4,5,161,p,p
F,92,,2560,1080,p,3300,740,1250,170,150,120,495,548,44,148,4,5,161,p,p
F,93,103,3840,2160,p,5500,1660,2250,90,53.946,23.976,296.703,1276,88,296,8,10,72,p,p
F,93,103,3840,2160,p,5500,1660,2250,90,54,24,297,1276,88,296,8,10,72,p,p
F,94,104,3840,2160,p,5280,1440,2250,90,56.25,25,297,1056,88,296,8,10,72,p,p
F,95,105,3840,2160,p,4400,560,2250,90,67.433,29.970,296.703,176,88,296,8,10,72,p,p
F,95,105,3840,2160,p,4400,560,2250,90,67.5,30,297,176,88,296,8,10,72,p,p
F,96,106,3840,2160,p,5280,1440,2250,90,112.5,50,594,1056,88,296,8,10,72,p,p
F,97,107,3840,2160,p,4400,560,2250,90,134.865,59.940,593.407,176,88,296,8,10,72,p,p
F,97,107,3840,2160,p,4400,560,2250,90,135,60,594,176,88,296,8,10,72,p,p
F,98,,4096,2160,p,5500,1404,2250,90,53.946,23.976,296.703,1020,88,296,8,10,72,p,p
F,98,,4096,2160,p,5500,1404,2250,90,54,24,297,1020,88,296,8,10,72,p,p
F,99,,4096,2160,p,5280,1184,2250,90,56.25,25,297,968,88,128,8,10,72,p,p
F,100,,4096,2160,p,4400,304,2250,90,67.433,29.970,296.703,88,88,128,8,10,72,p,p
F,100,,4096,2160,p,4400,304,2250,90,67.5,30,297,88,88,128,8,10,72,p,p
F,101,,4096,2160,p,5280,1184,2250,90,112.5,50,594,968,88,128,8,10,72,p,p
F,102,,4096,2160,p,4400,304,2250,90,134.865,59.940,593.407,88,88,128,8,10,72,p,p
F,102,,4096,2160,p,4400,304,2250,90,135,60,594,88,88,128,8,10,72,p,p
G,108,109,1280,720,p,2500,1220,750,30,35.964,47.952,89.910,960,40,220,5,5,20,p,p
G,108,109,1280,720,p,2500,1220,750,30,36,48,90,960,40,220,5,5,20,p,p
G,110,,1680,720,p,2750,1070,750,30,35.964,47.952,98.901,810,40,220,5,5,20,p,p
G,110,,1680,720,p,2750,1070,750,30,36,48,99,810,40,220,5,5,20,p,p
G,111,112,1920,1080,p,2750,830,1125,45,53.946,47.952,148.352,638,44,148,4,5,36,p,p
G,111,112,1920,1080,p,2750,830,1125,45,54,48,148.5,638,44,148,4,5,36,p,p
G,113,,2560,1080,p,3750,1190,1100,20,52.747,47.952,197.802,998,44,148,4,5,11,p,p
G,113,,2560,1080,p,3750,1190,1100,20,52.8,48,198,998,44,148,4,5,11,p,p
G,114,116,3840,2160,p,5500,1660,2250,90,107.892,47.952,593.407,1276,88,296,8,10,72,p,p
G,114,116,3840,2160,p,5500,1660,2250,90,108,48,594,1276,88,296,8,10,72,p,p
G,115,,4096,2160,p,5500,1404,2250,90,107.892,47.952,593.407,1020,88,296,8,10,72,p,p
G,115,,4096,2160,p,5500,1404,2250,90,108,48,594,1020,88,296,8,10,72,p,p
G,117,119,3840,2160,p,5280,1440,2250,90,225,100,1188,1056,88,296,8,10,72,p,p
G,118,120,3840,2160,p,4400,560,2250,90,269.730,119.880,1186.813,176,88,296,8,10,72,p,p
G,118,120,3840,2160,p,4400,560,2250,90,270,120,1188,176,88,296,8,10,72,p,p
G,121,,5120,2160,p,7500,2380,2200,40,52.747,23.976,395.604,1996,88,296,8,10,22,p,p
G,121,,5120,2160,p,7500,2380,2200,40,52.8,24,396,1996,88,296,8,10,22,p,p
G,122,,5120,2160,p,7200,2080,2200,40,55,25,396,1696,88,296,8,10,22,p,p
G,123,,5120,2160,p,6000,880,2200,40,65.934,29.970,395.604,664,88,128,8,10,22,p,p
G,123,,5120,2160,p,6000,880,2200,40,66,30,396,664,88,128,8,10,22,p,p
G,124,,5120,2160,p,6250,1130,2475,315,118.681,47.952,741.758,746,88,296,8,10,297,p,p
G,124,,5120,2160,p,6250,1130,2475,315,118.8,48,742.5,746,88,296,8,10,297,p,p
G,125,,5120,2160,p,6600,1480,2250,90,112.5,50,742.5,1096,88,296,8,10,72,p,p
G,126,,5120,2160,p,5500,380,2250,90,134.865,59.940,741.758,164,88,128,8,10,72,p,p
G,126,,5120,2160,p,5500,380,2250,90,135,60,742.5,164,88,128,8,10,72,p,p
G,127,,5120,2160,p,6600,1480,2250,90,225,100,1485,1096,88,296,8,10,72,p,p
G,193,,5120,2160,p,5500,380,2250,90,269.730,119.880,1483.516,164,88,128,8,10,72,p,p
G,193,,5120,2160,p,5500,380,2250,90,270,120,1485,164,88,128,8,10,72,p,p
G,194,202,7680,4320,p,11000,3320,4500,180,107.892,23.976,1186.813,2552,176,592,16,20,144,p,p
G,194,202,7680,4320,p,11000,3320,4500,180,108,24,1188,2552,176,592,16,20,144,p,p
G,195,203,7680,4320,p,10800,3120,4400,80,110,25,1188,2352,176,592,16,20,44,p,p
G,196,204,7680,4320,p,9000,1320,4400,80,131.868,29.970,1186.813,552,176,592,16,20,44,p,p
G,196,204,7680,4320,p,9000,1320,4400,80,132,30,1188,552,176,592,16,20,44,p,p
G,197,205,7680,4320,p,11000,3320,4500,180,215.784,47.952,2373.626,2552,176,592,16,20,144,p,p
G,197,205,7680,4320,p,11000,3320,4500,180,216,48,2376,2552,176,592,16,20,144,p,p
G,198,206,7680,4320,p,10800,3120,4400,80,220,50,2376,2352,176,592,16,20,44,p,p
G,199,207,7680,4320,p,9000,1320,4400,80,263.736,59.940,2373.626,552,176,592,16,20,44,p,p
G,199,207,7680,4320,p,9000,1320,4400,80,264,60,2376,552,176,592,16,20,44,p,p
G,200,208,7680,4320,p,10560,2880,4500,180,450,100,4752,2112,176,592,16,20,144,p,p
G,201,209,7680,4320,p,8800,1120,4500,180,449.550,119.880,4747.253,352,176,592,16,20,144,p,p
G,201,209,7680,4320,p,8800,1120,4500,180,450,120,4752,352,176,592,16,20,144,p,p
G,210,,10240,4320,p,12500,2260,4950,630,118.681,23.976,1483.516,1492,176,592,16,20,594,p,p
G,210,,10240,4320,p,12500,2260,4950,630,118.8,24,1485,1492,176,592,16,20,594,p,p
G,211,,10240,4320,p,13500,3260,4400,80,110,25,1485,2492,176,592,16,20,44,p,p
G,212,,10240,4320,p,11000,760,4500,180,134.865,29.970,1483.516,288,176,296,16,20,144,p,p
G,212,,10240,4320,p,11000,760,4500,180,135,30,1485,288,176,296,16,20,144,p,p
G,213,,10240,4320,p,12500,2260,4950,630,237.363,47.952,0.000,1492,176,592,16,20,594,p,p
G,213,,10240,4320,p,12500,2260,4950,630,237.6,48,,1492,176,592,16,20,594,p,p
G,214,,10240,4320,p,13500,3260,4400,80,220,50,2970,2492,176,592,16,20,44,p,p
G,215,,10240,4320,p,11000,760,4500,180,269.730,59.940,2967.033,288,176,296,16,20,144,p,p
G,215,,10240,4320,p,11000,760,4500,180,270,60,2970,288,176,296,16,20,144,p,p
G,216,,10240,4320,p,13200,2960,4500,180,450,100,5940,2192,176,592,16,20,144,p,p
G,217,,10240,4320,p,11000,760,4500,180,539.461,119.880,5934.066,288,176,296,16,20,144,p,p
G,217,,10240,4320,p,11000,760,4500,180,540,120,5940,288,176,296,16,20,144,p,p
G,218,,4096,2160,p,5280,1184,2250,90,225,100,1188,800,88,296,8,10,72,p,p
G,219,,4096,2160,p,4400,304,2250,90,269.730,119.880,1186.813,88,88,128,8,10,72,p,p
G,219,,4096,2160,p,4400,304,2250,90,270,120,1188,88,88,128,8,10,72,p,p

@ -0,0 +1,40 @@
DebugSettings = {};
function DEBUG(text) {
Fn = DEBUG.caller.name;
proceed_with_msg = false;
if ('all' in DebugSettings) {
if (!DebugSettings['all']) {
return;
} // if All == false, always skip
else if (DebugSettings['all']) {
//printDebug(Fn, arguments);
proceed_with_msg = true;
}
}
else if (Fn in DebugSettings) {
if (DebugSettings[Fn] == false) {
//printDebug(Fn, arguments)
proceed_with_msg = false;
}
}
else {
proceed_with_msg = true;
}
if (proceed_with_msg == true) {
str = 'console.log("[" + Fn + "()] ::"';
for (var i = 0; i < arguments.length; i++) {
str += ', arguments[' + i + ']';
}
str += ');';
eval(str);
}
return;
}
function DebugConfig(settings) {
DebugSettings = settings;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,435 @@
<!DOCTYPE html>
<meta name="viewport" content="width=device-width">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML'></script>
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script>
MathJax.Hub.Config({
jax: ["input/TeX", "output/HTML-CSS"],
displayAlign: "left"
});
WebFont.load({
google: { families: ['Inconsolata'] }
});
</script>
<!----<script src="nice-select.js"></script>-->
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Bandwidth Calculator</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
</head>
<body>
<div class="wrapper">
<div class="main">
<div class="header">
<a href="https://glenwing.github.io"><i class="material-icons back_arrow">subdirectory_arrow_left</i>&nbsp;Video Bandwidth Calculator</a>
<hr />
</div>
<div class="spoiler">
<table id="video_format" class="spoiler">
<tr class="header">
<td class="arrow"><span class="arrow"></span></td>
<td class="title">
Video Format
</td>
<td class="link number"></td>
</tr>
<tr id="video_format_body" style="display:table-row;">
<td colspan="3" class="body">
<table>
<tr>
<td>
<div align="center">
<input id="INPUT_HRES" class="res_input number" style="text-align:right;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange()" onfocus="this.select();" tabindex="2" autofocus />
<span class="res_x">&#10005;</span>
<input id="INPUT_VRES" class="res_input number" style="text-align:left;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange()" onfocus="this.select();" tabindex="2" />
<span>@</span>
<input id="INPUT_F" class="freq_input number" type="text" onchange="submitVar(this.id, this.value), calcMain();" oninput="this.onchange()" onfocus="this.select();" tabindex="3" />
<span>Hz</span>
</div>
<div id="warning_box" style="text-align:left; width:400px; margin-top:32px; border:1px solid black; padding:16px;">
<b>Warning: Non-Standard Refresh Rate</b><br />
<div style="padding:8px;">
The CTA-861 standard only defines timing parameters for this resolution at the following refresh rates:<br />
<ul>
<li>50.000 Hz (VIC: 24)</li>
<li>59.940 Hz (VIC: 25)</li>
<li>60.000 Hz (VIC: 26)</li>
</ul>
This calculator uses the timing parameters from 60 Hz for non-standard refresh rates.
</div>
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div class="spoiler">
<table id="advanced_settings" class="spoiler">
<tr onclick="toggleSpoiler(this)" class="header clickable">
<td class="arrow"><span class="arrow">&#8250;</span></td>
<td class="title">
Advanced Settings
</td>
<td class="link"></td>
</tr>
<tr id="advanced_settings_body" style="display:table-row;">
<td colspan="3" class="body">
<table class="adv_options">
<tr style="vertical-align:top;">
<td>
<b>Color Depth:</b><br />
<form id="COLOR_DEPTH_FORM" onchange="submitVar(this.id, $('input[name=COLOR_DEPTH_SLCT]:checked').val()); calcMain();">
<label><input type="radio" name="COLOR_DEPTH_SLCT" value="24" checked />&nbsp;&nbsp;8 bpc (24 bit/px)</label><br />
<label><input type="radio" name="COLOR_DEPTH_SLCT" value="30" />10 bpc (30 bit/px)</label><br />
<label><input type="radio" name="COLOR_DEPTH_SLCT" value="36" />12 bpc (36 bit/px)</label><br />
<label><input type="radio" name="COLOR_DEPTH_SLCT" value="48" />16 bpc (48 bit/px)</label><br />
<label><input type="radio" name="COLOR_DEPTH_SLCT" value="Custom" />Custom:</label><br />
</form>
<div class="table">
<div class="trow">
<div class="tcell" style="vertical-align:middle; line-height:125%;">
<input id="CUSTOM_COLOR_DEPTH" class="color_depth_input number" type="text" onchange="submitVar('COLOR_DEPTH_FORM', $('input[name=COLOR_DEPTH_SLCT]:checked').val()); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />
</div>
<div class="tcell" style="padding-left:4px; vertical-align:middle; line-height:125%; width:100%;">
<form id="CD_UNIT_FORM" style="line-height:100%;" onchange="document.getElementById('CUSTOM_COLOR_DEPTH').focus(); submitVar('COLOR_DEPTH_FORM', $('input[name=COLOR_DEPTH_SLCT]:checked').val()); calcMain();" disabled>
<label><input type="radio" name="CD_UNIT_SLCT" value="bpc" checked />&nbsp;bpc</label><br />
<label><input type="radio" name="CD_UNIT_SLCT" value="bpp" />&nbsp;bit/px</label>
</form>
</div>
</div>
</div>
</td>
<td>
<b>Pixel Format:</b><br />
<form id="PIXEL_FORMAT_FORM" onchange="submitVar(this.id, $('input[name=PX_FORMAT_SLCT]:checked').val()); calcMain();">
<label><input type="radio" name="PX_FORMAT_SLCT" value="RGB" checked />RGB</label><br />
<label><input type="radio" name="PX_FORMAT_SLCT" value="YCBCR 4:4:4" />YC<sub>B</sub>C<sub>R</sub> 4:4:4</label><br />
<label><input type="radio" name="PX_FORMAT_SLCT" value="YCBCR 4:2:2" />YC<sub>B</sub>C<sub>R</sub> 4:2:2</label><br />
<label><input type="radio" name="PX_FORMAT_SLCT" value="YCBCR 4:2:0" />YC<sub>B</sub>C<sub>R</sub> 4:2:0</label><br />
</form>
</td>
<td>
<b>Compression:</b><br />
<form id="COMPRESSION_FORM" onchange="submitVar(this.id, $('input[name=COMPRESSION_SLCT]:checked').val()); calcMain();">
<label><input type="radio" name="COMPRESSION_SLCT" value="Uncompressed" checked />Uncompressed</label><br />
<label><input type="radio" name="COMPRESSION_SLCT" value="DSC 2.0x" />DSC (2.0×)</label><br />
<label><input type="radio" name="COMPRESSION_SLCT" value="DSC 2.5x" />DSC (2.5×)</label><br />
<label><input type="radio" name="COMPRESSION_SLCT" value="DSC 3.0x" />DSC (3.0×)</label><br />
</form>
</td>
<td>
<b>Scan Type:</b><br />
<form id="SCAN_FORM" onchange="submitVar(this.id, $('input[name=SCAN_SLCT]:checked').val()); calcMain();">
<label><input type="radio" name="SCAN_SLCT" value="p" checked />Progressive</label><br />
<label><input type="radio" name="SCAN_SLCT" value="i" />Interlaced</label><br />
</form>
</td>
<td>
<b>Margins:</b><br />
<form id="MARGINS_FORM" onchange="submitVar(this.id, $('input[name=MARGINS_SLCT]:checked').val()); calcMain();">
<label><input type="radio" name="MARGINS_SLCT" value="n" checked />No</label><br />
<label><input type="radio" name="MARGINS_SLCT" value="y" />Yes</label><br />
</form>
<input id="CUSTOM_MARGINS" class="margins_input number" type="text" onchange="submitVar('MARGINS_FORM', $('input[name=MARGINS_SLCT]:checked').val()); calcMain();" disabled />&nbsp;%
</td>
</tr>
<tr>
<td colspan="5">
<table class="timing_format">
<tr>
<td rowspan="4" style="text-align:left;">
<b>Timing Format:</b><br />
<select id="TIMING_DROP" onchange="submitVar(this.id, this.value); calcMain();" style="padding:4px; margin-top:8px;">
<option value="None">None</option>
<option value="DMT">DMT</option>
<option value="GTF">GTF</option>
<option value="CVT">CVT</option>
<option value="CTA-861">CTA-861</option>
<option value="CVT-RB">CVT-RB</option>
<option value="CVT-R2" selected>CVT-R2</option>
<option value="Custom">Custom</option>
</select><br />
<div style="padding:4px;">
<b>VIC: </b><span id="TIMING_VIC">218</span>
</div>
</td>
<td></td>
<td>Front Porch:</td>
<td>Sync Width:</td>
<td>Back Porch:</td>
<td>Total:</td>
</tr>
<tr style="height:30px;">
<td style="text-align:right; width:100px; padding-right:8px;">
H<sub>blank</sub>
</td>
<td class="timing_field">
<input id="H_FP" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td class="timing_field">
<input id="H_SW" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td class="timing_field">
<input id="H_BP" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td style="text-align:right; min-width:60px;">
<span id="H_BLANK">1234</span>&nbsp;px
</td>
</tr>
<tr style="height:30px;">
<td id="V_BLANK_EVEN_LABEL" style="text-align:right; width:100px; padding-right:8px;">
V<sub>blank</sub>
</td>
<td class="timing_field">
<input id="V_FP" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td class="timing_field">
<input id="V_SW" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td class="timing_field">
<input id="V_BP" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td style="text-align:right; width:100px;">
<span id="V_BLANK">0</span>&nbsp;px
</td>
</tr>
<tr id="Interlaced_Timing_Row" style="height:30px;">
<td id="V_BLANK_ODD_LABEL" style="text-align:right; width:100px; padding-right:8px;">
(Odd)&nbsp;V<sub>blank</sub>
</td>
<td id="V_FP_ODD_CONTAINER">
<input id="V_FP_ODD" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td id="V_SW_ODD_CONTAINER">
<input id="V_SW_ODD" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td id="V_BP_ODD_CONTAINER">
<input id="V_BP_ODD" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td id="V_BLANK_ODD_CONTAINER" style="text-align:right; width:100px;">
<span id="V_BLANK_ODD">0</span>&nbsp;px
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div class="spoiler">
<table id="results" class="spoiler">
<tr class="header">
<td class="arrow"><span class="arrow"></span></td>
<td class="title">
Detailed Results
</td>
<td class="link"></td>
</tr>
<tr id="results_body" style="display:table-row;">
<td colspan="3" class="body">
<table style="border-collapse:collapse; border:0px solid transparent; padding:0px;">
<tr>
<td style="overflow-x:auto; white-space:nowrap; vertical-align:top; width:300px; padding:12px; background-color:#E0E0E0;">
<b>Video Format:</b><br />
<div style="padding-left:16px; padding-top:8px; line-height:140%;">
4096 × 2560 (8:5 ratio), progressive scan<br />
120 Hz vertical refresh rate (frame rate)<br />
10 bpc (30 bit/px) color depth (1,073,741,824 colors)<br />
YC<sub>B</sub>C<sub>R</sub> 4:4:4 pixel format<br />
Uncompressed<br />
CTA-861 timing (VIC: 63)<br />
</div>
</td>
</tr>
</table>
<br />
<table class="results">
<tr>
<td class="label">
Data Rate:
</td>
<td class="value"><b>37.75</b></td>
<td class="unit"><b>Gbit/s</b></td>
</tr>
<tr class="addon">
<td>
Blanking Overhead:
</td>
<td class="value">10.3</td>
<td class="unit">%</td>
</tr>
<tr>
<td class="label" colspan="3">
Bandwidth:
</td>
</tr>
<tr class="addon">
<td>
8b/10b Encoding:
</td>
<td class="value">45.30</td>
<td class="unit">Gbit/s</td>
</tr>
<tr class="addon">
<td>
16b/18b Encoding:
</td>
<td class="value">51.20</td>
<td class="unit">Gbit/s</td>
</tr>
<tr>
<td class="label">
Character Rate ("Pixel Clock"):
</td>
<td class="value">1.26</td>
<td class="unit">GHz</td>
</tr>
<tr>
<td class="label">
Pixel Rate (Actual):
</td>
<td class="value">1.26</td>
<td class="unit">Gpx/s</td>
</tr>
<tr>
<td class="label">
Pixel Rate (Incl. Blank):
</td>
<td class="value">1.58</td>
<td class="unit">Gpx/s</td>
</tr>
<tr>
<td class="label">
Vertical Refresh Frequency (Actual):
</td>
<td class="value">120.001</td>
<td class="unit">Hz</td>
</tr>
<tr class="addon">
<td>
Deviation:
</td>
<td class="value">0.001</td>
<td class="unit">%</td>
</tr>
<tr class="addon">
<td>
Period:
</td>
<td class="value">8.333</td>
<td class="unit">ms</td>
</tr>
<tr>
<td class="label">
Horizontal Refresh Frequency:
</td>
<td class="value">161.25</td>
<td class="unit">kHz</td>
</tr>
<tr class="addon">
<td>Period:</td>
<td class="value">15.2</td>
<td class="unit">µs</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div class="spoiler">
<table id="calculations" class="spoiler">
<tr class="header clickable">
<td class="arrow"><span class="arrow">&#8250;</span></td>
<td class="title">
Calculations
</td>
<td class="link"></td>
</tr>
<tr id="calculations_body" style="display:table-row;">
<td colspan="3" class="body" style="vertical-align:top;">
<div style="overflow-x:auto; white-space:nowrap;">
$$\texttt{Pixels per frame:}$$
<div style="padding-left:20px;">$$\texttt{4,096} \times \texttt{2,560 lines} = \texttt{10,485,760 px (10.5 Mpx)}$$</div>
$$\texttt{Pixels per second:}$$
<div style="padding-left:20px;">$$10\,485\,760\;\mathtt{px/frame} \times 120\;\mathtt{frame/s} = 1\,258\,291\,200\;\mathtt{px/s}\;(1.26\;\mathtt{Gpx/s})$$</div>
$$\texttt{Bits per second:}$$
<div style="padding-left:20px;">$$1\,258\,291\,200\;\mathtt{px/s} \times 30\;\mathtt{bit/px} = 37\,748\,736\,000\;\mathtt{bit/s}\;(37.7\;\mathtt{Gbit/s})$$</div>
<br /><hr /><br />
$$\texttt{Timing Formula:}$$
<div style="padding-left:20px;">
$$\texttt{Constants:}$$
$$\texttt{H = 4,096 px}$$
$$\texttt{V = 2,560 px}$$
$$\texttt{F = 120 Hz}$$
</div>
$$\texttt{Formula:}$$
<div style="padding-left:20px;">$$\texttt{V}_{\texttt{blank}} \texttt{ = } {{\texttt{V × V}_{\texttt{min}}} \over {{\texttt{1} \over \texttt{F}} - \texttt{V}_{\texttt{min}}}}$$</div>
</div>
<div style="padding-left:20px; max-width:100%;">The timing parameters used for these calculations are defined by the <a>CTA-861</a> standard. The definitions for this format are listed under Video Identification Code (VIC) #98, first defined in <a style="white-space:nowrap;">CTA-861-F</a> (formerly CEA-861-F).</div>
</td>
</tr>
</table>
</div>
<div class="spoiler">
<table id="max_refresh" class="spoiler">
<tr class="header clickable">
<td class="arrow"><span class="arrow">&#8250;</span></td>
<td class="title">
Interface Support
</td>
<td class="link"></td>
</tr>
<tr id="max_refresh_body" style="display:table-row;">
<td colspan="3" class="body">
<table class="interface" id="interface_support_table">
<!-- Filled in on page load by JS -->
</table>
</td>
</tr>
</table>
</div>
<br />
<br />
</div>
<div class="footer" onclick="document.getElementById('profile_link').click();">
<a id="profile_link" target="_blank" href="https://linustechtips.com/main/profile/2466-glenwing/">Glenwing</a>
</div>
</div>
</body>
</html>
<script src="DebugControl.js"></script>
<script src="jquery.csv.js"></script>
<script src="bandwidth.js"></script>
<!----
<script>
$(document).ready(function () {
$('select').niceSelect();
});
</script><!---->

@ -0,0 +1,980 @@
/**
* jQuery-csv (jQuery Plugin)
*
* This document is licensed as free software under the terms of the
* MIT License: http://www.opensource.org/licenses/mit-license.php
*
* Acknowledgements:
* The original design and influence to implement this library as a jquery
* plugin is influenced by jquery-json (http://code.google.com/p/jquery-json/).
* If you're looking to use native JSON.Stringify but want additional backwards
* compatibility for browsers that don't support it, I highly recommend you
* check it out.
*
* A special thanks goes out to rwk@acm.org for providing a lot of valuable
* feedback to the project including the core for the new FSM
* (Finite State Machine) parsers. If you're looking for a stable TSV parser
* be sure to take a look at jquery-tsv (http://code.google.com/p/jquery-tsv/).
* For legal purposes I'll include the "NO WARRANTY EXPRESSED OR IMPLIED.
* USE AT YOUR OWN RISK.". Which, in 'layman's terms' means, by using this
* library you are accepting responsibility if it breaks your code.
*
* Legal jargon aside, I will do my best to provide a useful and stable core
* that can effectively be built on.
*
* Copyrighted 2012 by Evan Plaice.
*/
RegExp.escape = function (s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
(function () {
'use strict';
var $;
// to keep backwards compatibility
if (typeof jQuery !== 'undefined' && jQuery) {
$ = jQuery;
} else {
$ = {};
}
/**
* jQuery.csv.defaults
* Encapsulates the method paramater defaults for the CSV plugin module.
*/
$.csv = {
defaults: {
separator: ',',
delimiter: '"',
headers: true
},
hooks: {
castToScalar: function (value, state) {
var hasDot = /\./;
if (isNaN(value)) {
return value;
} else {
if (hasDot.test(value)) {
return parseFloat(value);
} else {
var integer = parseInt(value);
if (isNaN(integer)) {
return null;
} else {
return integer;
}
}
}
}
},
parsers: {
parse: function (csv, options) {
// cache settings
var separator = options.separator;
var delimiter = options.delimiter;
// set initial state if it's missing
if (!options.state.rowNum) {
options.state.rowNum = 1;
}
if (!options.state.colNum) {
options.state.colNum = 1;
}
// clear initial state
var data = [];
var entry = [];
var state = 0;
var value = '';
var exit = false;
function endOfEntry () {
// reset the state
state = 0;
value = '';
// if 'start' hasn't been met, don't output
if (options.start && options.state.rowNum < options.start) {
// update global state
entry = [];
options.state.rowNum++;
options.state.colNum = 1;
return;
}
if (options.onParseEntry === undefined) {
// onParseEntry hook not set
data.push(entry);
} else {
var hookVal = options.onParseEntry(entry, options.state); // onParseEntry Hook
// false skips the row, configurable through a hook
if (hookVal !== false) {
data.push(hookVal);
}
}
// console.log('entry:' + entry);
// cleanup
entry = [];
// if 'end' is met, stop parsing
if (options.end && options.state.rowNum >= options.end) {
exit = true;
}
// update global state
options.state.rowNum++;
options.state.colNum = 1;
}
function endOfValue () {
if (options.onParseValue === undefined) {
// onParseValue hook not set
entry.push(value);
} else {
var hook = options.onParseValue(value, options.state); // onParseValue Hook
// false skips the row, configurable through a hook
if (hook !== false) {
entry.push(hook);
}
}
// console.log('value:' + value);
// reset the state
value = '';
state = 0;
// update global state
options.state.colNum++;
}
// escape regex-specific control chars
var escSeparator = RegExp.escape(separator);
var escDelimiter = RegExp.escape(delimiter);
// compile the regEx str using the custom delimiter/separator
var match = /(D|S|\r\n|\n|\r|[^DS\r\n]+)/;
var matchSrc = match.source;
matchSrc = matchSrc.replace(/S/g, escSeparator);
matchSrc = matchSrc.replace(/D/g, escDelimiter);
match = new RegExp(matchSrc, 'gm');
// put on your fancy pants...
// process control chars individually, use look-ahead on non-control chars
csv.replace(match, function (m0) {
if (exit) {
return;
}
switch (state) {
// the start of a value
case 0:
// null last value
if (m0 === separator) {
value += '';
endOfValue();
break;
}
// opening delimiter
if (m0 === delimiter) {
state = 1;
break;
}
// null last value
if (/^(\r\n|\n|\r)$/.test(m0)) {
endOfValue();
endOfEntry();
break;
}
// un-delimited value
value += m0;
state = 3;
break;
// delimited input
case 1:
// second delimiter? check further
if (m0 === delimiter) {
state = 2;
break;
}
// delimited data
value += m0;
state = 1;
break;
// delimiter found in delimited input
case 2:
// escaped delimiter?
if (m0 === delimiter) {
value += m0;
state = 1;
break;
}
// null value
if (m0 === separator) {
endOfValue();
break;
}
// end of entry
if (/^(\r\n|\n|\r)$/.test(m0)) {
endOfValue();
endOfEntry();
break;
}
// broken paser?
throw new Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
// un-delimited input
case 3:
// null last value
if (m0 === separator) {
endOfValue();
break;
}
// end of entry
if (/^(\r\n|\n|\r)$/.test(m0)) {
endOfValue();
endOfEntry();
break;
}
if (m0 === delimiter) {
// non-compliant data
throw new Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
}
// broken parser?
throw new Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
default:
// shenanigans
throw new Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
}
// console.log('val:' + m0 + ' state:' + state);
});
// submit the last entry
// ignore null last line
if (entry.length !== 0) {
endOfValue();
endOfEntry();
}
return data;
},
// a csv-specific line splitter
splitLines: function (csv, options) {
if (!csv) {
return undefined;
}
options = options || {};
// cache settings
var separator = options.separator || $.csv.defaults.separator;
var delimiter = options.delimiter || $.csv.defaults.delimiter;
// set initial state if it's missing
options.state = options.state || {};
if (!options.state.rowNum) {
options.state.rowNum = 1;
}
// clear initial state
var entries = [];
var state = 0;
var entry = '';
var exit = false;
function endOfLine () {
// reset the state
state = 0;
// if 'start' hasn't been met, don't output
if (options.start && options.state.rowNum < options.start) {
// update global state
entry = '';
options.state.rowNum++;
return;
}
if (options.onParseEntry === undefined) {
// onParseEntry hook not set
entries.push(entry);
} else {
var hookVal = options.onParseEntry(entry, options.state); // onParseEntry Hook
// false skips the row, configurable through a hook
if (hookVal !== false) {
entries.push(hookVal);
}
}
// cleanup
entry = '';
// if 'end' is met, stop parsing
if (options.end && options.state.rowNum >= options.end) {
exit = true;
}
// update global state
options.state.rowNum++;
}
// escape regex-specific control chars
var escSeparator = RegExp.escape(separator);
var escDelimiter = RegExp.escape(delimiter);
// compile the regEx str using the custom delimiter/separator
var match = /(D|S|\n|\r|[^DS\r\n]+)/;
var matchSrc = match.source;
matchSrc = matchSrc.replace(/S/g, escSeparator);
matchSrc = matchSrc.replace(/D/g, escDelimiter);
match = new RegExp(matchSrc, 'gm');
// put on your fancy pants...
// process control chars individually, use look-ahead on non-control chars
csv.replace(match, function (m0) {
if (exit) {
return;
}
switch (state) {
// the start of a value/entry
case 0:
// null value
if (m0 === separator) {
entry += m0;
state = 0;
break;
}
// opening delimiter
if (m0 === delimiter) {
entry += m0;
state = 1;
break;
}
// end of line
if (m0 === '\n') {
endOfLine();
break;
}
// phantom carriage return
if (/^\r$/.test(m0)) {
break;
}
// un-delimit value
entry += m0;
state = 3;
break;
// delimited input
case 1:
// second delimiter? check further
if (m0 === delimiter) {
entry += m0;
state = 2;
break;
}
// delimited data
entry += m0;
state = 1;
break;
// delimiter found in delimited input
case 2:
// escaped delimiter?
var prevChar = entry.substr(entry.length - 1);
if (m0 === delimiter && prevChar === delimiter) {
entry += m0;
state = 1;
break;
}
// end of value
if (m0 === separator) {
entry += m0;
state = 0;
break;
}
// end of line
if (m0 === '\n') {
endOfLine();
break;
}
// phantom carriage return
if (m0 === '\r') {
break;
}
// broken paser?
throw new Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']');
// un-delimited input
case 3:
// null value
if (m0 === separator) {
entry += m0;
state = 0;
break;
}
// end of line
if (m0 === '\n') {
endOfLine();
break;
}
// phantom carriage return
if (m0 === '\r') {
break;
}
// non-compliant data
if (m0 === delimiter) {
throw new Error('CSVDataError: Illegal quote [Row:' + options.state.rowNum + ']');
}
// broken parser?
throw new Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']');
default:
// shenanigans
throw new Error('CSVDataError: Unknown state [Row:' + options.state.rowNum + ']');
}
// console.log('val:' + m0 + ' state:' + state);
});
// submit the last entry
// ignore null last line
if (entry !== '') {
endOfLine();
}
return entries;
},
// a csv entry parser
parseEntry: function (csv, options) {
// cache settings
var separator = options.separator;
var delimiter = options.delimiter;
// set initial state if it's missing
if (!options.state.rowNum) {
options.state.rowNum = 1;
}
if (!options.state.colNum) {
options.state.colNum = 1;
}
// clear initial state
var entry = [];
var state = 0;
var value = '';
function endOfValue () {
if (options.onParseValue === undefined) {
// onParseValue hook not set
entry.push(value);
} else {
var hook = options.onParseValue(value, options.state); // onParseValue Hook
// false skips the value, configurable through a hook
if (hook !== false) {
entry.push(hook);
}
}
// reset the state
value = '';
state = 0;
// update global state
options.state.colNum++;
}
// checked for a cached regEx first
if (!options.match) {
// escape regex-specific control chars
var escSeparator = RegExp.escape(separator);
var escDelimiter = RegExp.escape(delimiter);
// compile the regEx str using the custom delimiter/separator
var match = /(D|S|\n|\r|[^DS\r\n]+)/;
var matchSrc = match.source;
matchSrc = matchSrc.replace(/S/g, escSeparator);
matchSrc = matchSrc.replace(/D/g, escDelimiter);
options.match = new RegExp(matchSrc, 'gm');
}
// put on your fancy pants...
// process control chars individually, use look-ahead on non-control chars
csv.replace(options.match, function (m0) {
switch (state) {
// the start of a value
case 0:
// null last value
if (m0 === separator) {
value += '';
endOfValue();
break;
}
// opening delimiter
if (m0 === delimiter) {
state = 1;
break;
}
// skip un-delimited new-lines
if (m0 === '\n' || m0 === '\r') {
break;
}
// un-delimited value
value += m0;
state = 3;
break;
// delimited input
case 1:
// second delimiter? check further
if (m0 === delimiter) {
state = 2;
break;
}
// delimited data
value += m0;
state = 1;
break;
// delimiter found in delimited input
case 2:
// escaped delimiter?
if (m0 === delimiter) {
value += m0;
state = 1;
break;
}
// null value
if (m0 === separator) {
endOfValue();
break;
}
// skip un-delimited new-lines
if (m0 === '\n' || m0 === '\r') {
break;
}
// broken paser?
throw new Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
// un-delimited input
case 3:
// null last value
if (m0 === separator) {
endOfValue();
break;
}
// skip un-delimited new-lines
if (m0 === '\n' || m0 === '\r') {
break;
}
// non-compliant data
if (m0 === delimiter) {
throw new Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
}
// broken parser?
throw new Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
default:
// shenanigans
throw new Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
}
// console.log('val:' + m0 + ' state:' + state);
});
// submit the last value
endOfValue();
return entry;
}
},
helpers: {
/**
* $.csv.helpers.collectPropertyNames(objectsArray)
* Collects all unique property names from all passed objects.
*
* @param {Array} objects Objects to collect properties from.
*
* Returns an array of property names (array will be empty,
* if objects have no own properties).
*/
collectPropertyNames: function (objects) {
var o = [];
var propName = [];
var props = [];
for (o in objects) {
for (propName in objects[o]) {
if ((objects[o].hasOwnProperty(propName)) &&
(props.indexOf(propName) < 0) &&
(typeof objects[o][propName] !== 'function')) {
props.push(propName);
}
}
}
return props;
}
},
/**
* $.csv.toArray(csv)
* Converts a CSV entry string to a javascript array.
*
* @param {Array} csv The string containing the CSV data.
* @param {Object} [options] An object containing user-defined options.
* @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
* @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
*
* This method deals with simple CSV strings only. It's useful if you only
* need to parse a single entry. If you need to parse more than one line,
* use $.csv2Array instead.
*/
toArray: function (csv, options, callback) {
options = (options !== undefined ? options : {});
var config = {};
config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false);
config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
var state = (options.state !== undefined ? options.state : {});
// setup
options = {
delimiter: config.delimiter,
separator: config.separator,
onParseEntry: options.onParseEntry,
onParseValue: options.onParseValue,
state: state
};
var entry = $.csv.parsers.parseEntry(csv, options);
// push the value to a callback if one is defined
if (!config.callback) {
return entry;
} else {
config.callback('', entry);
}
},
/**
* $.csv.toArrays(csv)
* Converts a CSV string to a javascript array.
*
* @param {String} csv The string containing the raw CSV data.
* @param {Object} [options] An object containing user-defined options.
* @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
* @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
*
* This method deals with multi-line CSV. The breakdown is simple. The first
* dimension of the array represents the line (or entry/row) while the second
* dimension contains the values (or values/columns).
*/
toArrays: function (csv, options, callback) {
options = (options !== undefined ? options : {});
var config = {};
config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false);
config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
// setup
var data = [];
options = {
delimiter: config.delimiter,
separator: config.separator,
onPreParse: options.onPreParse,
onParseEntry: options.onParseEntry,
onParseValue: options.onParseValue,
onPostParse: options.onPostParse,
start: options.start,
end: options.end,
state: {
rowNum: 1,
colNum: 1
}
};
// onPreParse hook
if (options.onPreParse !== undefined) {
options.onPreParse(csv, options.state);
}
// parse the data
data = $.csv.parsers.parse(csv, options);
// onPostParse hook
if (options.onPostParse !== undefined) {
options.onPostParse(data, options.state);
}
// push the value to a callback if one is defined
if (!config.callback) {
return data;
} else {
config.callback('', data);
}
},
/**
* $.csv.toObjects(csv)
* Converts a CSV string to a javascript object.
* @param {String} csv The string containing the raw CSV data.
* @param {Object} [options] An object containing user-defined options.
* @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
* @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
* @param {Boolean} [headers] Indicates whether the data contains a header line. Defaults to true.
*
* This method deals with multi-line CSV strings. Where the headers line is
* used as the key for each value per entry.
*/
toObjects: function (csv, options, callback) {
options = (options !== undefined ? options : {});
var config = {};
config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false);
config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers;
options.start = 'start' in options ? options.start : 1;
// account for headers
if (config.headers) {
options.start++;
}
if (options.end && config.headers) {
options.end++;
}
// setup
var lines = [];
var data = [];
options = {
delimiter: config.delimiter,
separator: config.separator,
onPreParse: options.onPreParse,
onParseEntry: options.onParseEntry,
onParseValue: options.onParseValue,
onPostParse: options.onPostParse,
start: options.start,
end: options.end,
state: {
rowNum: 1,
colNum: 1
},
match: false,
transform: options.transform
};
// fetch the headers
var headerOptions = {
delimiter: config.delimiter,
separator: config.separator,
start: 1,
end: 1,
state: {
rowNum: 1,
colNum: 1
}
};
// onPreParse hook
if (options.onPreParse !== undefined) {
options.onPreParse(csv, options.state);
}
// parse the csv
var headerLine = $.csv.parsers.splitLines(csv, headerOptions);
var headers = $.csv.toArray(headerLine[0], options);
// fetch the data
lines = $.csv.parsers.splitLines(csv, options);
// reset the state for re-use
options.state.colNum = 1;
if (headers) {
options.state.rowNum = 2;
} else {
options.state.rowNum = 1;
}
// convert data to objects
for (var i = 0, len = lines.length; i < len; i++) {
var entry = $.csv.toArray(lines[i], options);
var object = {};
for (var j = 0; j < headers.length; j++) {
object[headers[j]] = entry[j];
}
if (options.transform !== undefined) {
data.push(options.transform.call(undefined, object));
} else {
data.push(object);
}
// update row state
options.state.rowNum++;
}
// onPostParse hook
if (options.onPostParse !== undefined) {
options.onPostParse(data, options.state);
}
// push the value to a callback if one is defined
if (!config.callback) {
return data;
} else {
config.callback('', data);
}
},
/**
* $.csv.fromArrays(arrays)
* Converts a javascript array to a CSV String.
*
* @param {Array} arrays An array containing an array of CSV entries.
* @param {Object} [options] An object containing user-defined options.
* @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
* @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
*
* This method generates a CSV file from an array of arrays (representing entries).
*/
fromArrays: function (arrays, options, callback) {
options = (options !== undefined ? options : {});
var config = {};
config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false);
config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
var output = '';
var line;
var lineValues;
var i;
var j;
for (i = 0; i < arrays.length; i++) {
line = arrays[i];
lineValues = [];
for (j = 0; j < line.length; j++) {
var strValue = (line[j] === undefined || line[j] === null) ? '' : line[j].toString();
if (strValue.indexOf(config.delimiter) > -1) {
strValue = strValue.replace(new RegExp(config.delimiter, 'g'), config.delimiter + config.delimiter);
}
var escMatcher = '\n|\r|S|D';
escMatcher = escMatcher.replace('S', config.separator);
escMatcher = escMatcher.replace('D', config.delimiter);
if (strValue.search(escMatcher) > -1) {
strValue = config.delimiter + strValue + config.delimiter;
}
lineValues.push(strValue);
}
output += lineValues.join(config.separator) + '\n';
}
// push the value to a callback if one is defined
if (!config.callback) {
return output;
} else {
config.callback('', output);
}
},
/**
* $.csv.fromObjects(objects)
* Converts a javascript dictionary to a CSV string.
*
* @param {Object} objects An array of objects containing the data.
* @param {Object} [options] An object containing user-defined options.
* @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
* @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
* @param {Character} [sortOrder] Sort order of columns (named after
* object properties). Use 'alpha' for alphabetic. Default is 'declare',
* which means, that properties will _probably_ appear in order they were
* declared for the object. But without any guarantee.
* @param {Character or Array} [manualOrder] Manually order columns. May be
* a strin in a same csv format as an output or an array of header names
* (array items won't be parsed). All the properties, not present in
* `manualOrder` will be appended to the end in accordance with `sortOrder`
* option. So the `manualOrder` always takes preference, if present.
*
* This method generates a CSV file from an array of objects (name:value pairs).
* It starts by detecting the headers and adding them as the first line of
* the CSV file, followed by a structured dump of the data.
*/
fromObjects: function (objects, options, callback) {
options = (options !== undefined ? options : {});
var config = {};
config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false);
config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers;
config.sortOrder = 'sortOrder' in options ? options.sortOrder : 'declare';
config.manualOrder = 'manualOrder' in options ? options.manualOrder : [];
config.transform = options.transform;
if (typeof config.manualOrder === 'string') {
config.manualOrder = $.csv.toArray(config.manualOrder, config);
}
if (config.transform !== undefined) {
var origObjects = objects;
objects = [];
var i;
for (i = 0; i < origObjects.length; i++) {
objects.push(config.transform.call(undefined, origObjects[i]));
}
}
var props = $.csv.helpers.collectPropertyNames(objects);
if (config.sortOrder === 'alpha') {
props.sort();
} // else {} - nothing to do for 'declare' order
if (config.manualOrder.length > 0) {
var propsManual = [].concat(config.manualOrder);
let p;
for (p = 0; p < props.length; p++) {
if (propsManual.indexOf(props[p]) < 0) {
propsManual.push(props[p]);
}
}
props = propsManual;
}
var o, p, line, output, propName;
if (config.headers) {
output.push(props);
}
for (o = 0; o < objects.length; o++) {
line = [];
for (p = 0; p < props.length; p++) {
propName = props[p];
if (propName in objects[o] && typeof objects[o][propName] !== 'function') {
line.push(objects[o][propName]);
} else {
line.push('');
}
}
output.push(line);
}
// push the value to a callback if one is defined
return $.csv.fromArrays(output, options, config.callback);
}
};
// Maintenance code to maintain backward-compatibility
// Will be removed in release 1.0
$.csvEntry2Array = $.csv.toArray;
$.csv2Array = $.csv.toArrays;
$.csv2Dictionary = $.csv.toObjects;
// CommonJS module is defined
if (typeof module !== 'undefined' && module.exports) {
module.exports = $.csv;
}
}).call(this);

@ -85,6 +85,7 @@
// Returns false if input is a non-integer number or NaN
function isInt(num) {
num = parseNum(num);
if (Array.isArray(num) == true) {
for (a = 0; a < num.length; a++) {
if (Number.isInteger(num[a]) == false) {
@ -97,6 +98,22 @@ function isInt(num) {
return Number.isInteger(num);
}
function isFloat(num) {
num = parseNum(num);
if (Array.isArray(num) == true) {
for (a = 0; a < num.length; a++) {
if (Number.isInteger(num[a]) == true || Number.isNaN(num[a]) == true) {
return false;
}
return true;
}
}
else
return !(Number.isInteger(num) || Number.isNaN(num));
}
// Returns false if input is not a positive number (zero, negative number, or NaN)
function isPositive(num) {
if (Array.isArray(num) == true) {
@ -113,6 +130,30 @@ function isPositive(num) {
return false;
else if (num > 0)
return true;
else {
return false;
}
}
}
function isNonNegative(num) {
if (Array.isArray(num) == true) {
for (a = 0; a < num.length; a++) {
if (Number.isNaN(parseNum(num[a])) == true)
return false;
else if (num[a] < 0)
return false;
}
return true;
}
else {
if (Number.isNaN(parseNum(num)) == true)
return false;
else if (num >= 0)
return true;
else {
return false;
}
}
}

@ -11,8 +11,8 @@
}
body {
font-family: "Consolas", "Inconsolata", "Lucida Console", Monospace;
font-size: 15px;
font-family: "Consolas", "Inconsolata", "Lucida Console", Monospace;
font-size: 15px;
line-height: 120%;
min-height: 100%;
}

Loading…
Cancel
Save