adding more moons and updating position to today

adding controls for pause/reset/reset camera
adding help for controls
adding client to download from JPL horizon
This commit is contained in:
Sheldan
2024-03-17 23:51:43 +01:00
parent e34d86a2fa
commit e13d2a4712
4 changed files with 1405 additions and 741 deletions

View File

@@ -11,12 +11,30 @@
.container { .container {
height: 100%; height: 100%;
} }
.timeContainer {
position: absolute;
color: yellow;
top: 50px
}
.help {
position: absolute;
color: yellow;
top: 65px
}
</style> </style>
</head> </head>
<body> <body>
<script type="module" src="js/main.js"></script> <script type="module" src="js/main.js"></script>
<div class="container" id="container"> <div class="container" id="container">
<div class="timeContainer">
Current time
<span id="currentTime"></span>
</div>
<span class="help">
R -> reset to 2024-03-17 <br>
F -> reset camera <br>
P -> toggle pause
</span>
</div> </div>
</body> </body>
</html> </html>

View File

@@ -13,26 +13,30 @@ const config = {
gravitationalConstant: 6.67430e-11, gravitationalConstant: 6.67430e-11,
timeStep: 1 * 3600, timeStep: 1 * 3600,
AU: 149_597_870_700, AU: 149_597_870_700,
lines: true pause: false,
lines: true,
currentTime: 1710633600 // Sun Mar 17 2024 00:00:00 GMT+0000
} }
const maxPoints = 100_000; const maxPoints = 100_000;
const scene = new THREE.Scene(); const scene = new THREE.Scene();
const container = document.getElementById( 'container' ); const container = document.getElementById( 'container' );
const currentTimeSpan = document.getElementById( 'currentTime' );
const renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true }); const renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true });
renderer.setPixelRatio(window.devicePixelRatio); renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(container.offsetWidth, container.offsetHeight); renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild(renderer.domElement); container.appendChild(renderer.domElement);
const stats = new Stats(); const stats = new Stats();
container.appendChild( stats.dom ); container.appendChild( stats.dom );
const camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, config.AU / 25, 150 * config.AU); const camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 150 * config.AU);
const controls = new OrbitControls(camera, renderer.domElement); const controls = new OrbitControls(camera, renderer.domElement);
const texts = []; const texts = [];
const lines = {} let lines = {}
let axesHelper; let axesHelper;
const spheres = createSpheres() const spheres = createSpheres();
const initialSpheres = JSON.parse(JSON.stringify(spheres));
loader.load( loader.load(
// resource URL // resource URL
"https://threejs.org/examples/fonts/helvetiker_regular.typeface.json", function(font) { "https://threejs.org/examples/fonts/helvetiker_regular.typeface.json", function(font) {
@@ -48,13 +52,61 @@ function animate() {
render(); render();
} }
function reset() {
config.currentTime = 1710633600;
spheres.spheres.forEach(sphereConfig => {
sphereConfig.line.material.dispose();
sphereConfig.line.geometry.dispose();
sphereConfig.group.remove(sphereConfig.line)
scene.remove(sphereConfig.line)
const oldSphere = initialSpheres.spheres.find((sphere => sphere.name === sphereConfig.name))
sphereConfig.x = oldSphere.x;
sphereConfig.y = oldSphere.y;
sphereConfig.z = oldSphere.z;
sphereConfig.vx = oldSphere.vx;
sphereConfig.vy = oldSphere.vy;
sphereConfig.vz = oldSphere.vz;
sphereConfig.group.position.x = sphereConfig.x;
sphereConfig.group.position.y = sphereConfig.y;
sphereConfig.group.position.z = sphereConfig.z;
const textMesh = sphereConfig.text;
const labelLine = [];
labelLine.push(new THREE.Vector3(textMesh.position.x, textMesh.position.y, textMesh.position.z));
labelLine.push(new THREE.Vector3(0, 0, 0 ));
const lineMaterial = new THREE.LineBasicMaterial({color: sphereConfig.sphereColor});
const lineGeometry = new THREE.BufferGeometry().setFromPoints(labelLine);
sphereConfig.line = new THREE.Line( lineGeometry, lineMaterial);;
sphereConfig.group.add(sphereConfig.line);
lines = {}
})
}
function render() { function render() {
act() act()
renderer.render(scene, camera); renderer.render(scene, camera);
} }
function formatDateTime(input) {
var epoch = new Date(0);
epoch.setSeconds(parseInt(input));
var date = epoch.toISOString();
date = date.replace('T', ' ');
return date.split('.')[0].split(' ')[0];
}
function act() { function act() {
axesHelper.position.copy(controls.target);
texts.forEach(text => {
text.lookAt(camera.position)
})
if(config.pause) {
return;
}
spheresAct(spheres.spheres, config.timeStep) spheresAct(spheres.spheres, config.timeStep)
config.currentTime += config.timeStep;
currentTimeSpan.innerText = formatDateTime(config.currentTime)
if(config.lines) { if(config.lines) {
spheres.spheres.forEach(sphere => { spheres.spheres.forEach(sphere => {
if(!(sphere.name in lines)) { if(!(sphere.name in lines)) {
@@ -86,17 +138,21 @@ function act() {
sphere.group.position.y = sphere.y; sphere.group.position.y = sphere.y;
sphere.group.position.z = sphere.z; sphere.group.position.z = sphere.z;
}) })
texts.forEach(text => {
text.lookAt(camera.position)
})
axesHelper.position.copy(controls.target);
} }
function getSphereColor(sphereConfig) { function getSphereColor(sphereConfig) {
return new THREE.Color(sphereConfig.color.r / 255, sphereConfig.color.g / 255, sphereConfig.color.b / 255); return new THREE.Color(sphereConfig.color.r / 255, sphereConfig.color.g / 255, sphereConfig.color.b / 255);
} }
function resetControls() {
const sun = spheres.sphereObj.sun;
camera.position.set(sun.x, sun.y, sun.z + config.AU)
camera.lookAt(sun.x, sun.y, sun.z)
controls.target.set(sun.x, sun.y, sun.z)
controls.update();
axesHelper.position.copy(controls.target);
}
function initScene(font) { function initScene(font) {
const geometry = new THREE.SphereGeometry(0.5, 24, 12); const geometry = new THREE.SphereGeometry(0.5, 24, 12);
let scale = config.AU / 10; let scale = config.AU / 10;
@@ -126,11 +182,13 @@ function initScene(font) {
} }
const textMesh = new THREE.Mesh(label, material); const textMesh = new THREE.Mesh(label, material);
textMesh.scale.set( scale, scale, scale ); textMesh.scale.set( scale, scale, scale );
textMesh.position.x = textDistance * objectRadius * (Math.random() * textDistance - textDistance); textMesh.position.x = textDistance * objectRadius * (Math.random() * textDistance - textDistance) + Math.random() * config.AU / 10;
textMesh.position.y = textDistance * objectRadius * (Math.random() * textDistance - textDistance); textMesh.position.y = textDistance * objectRadius * (Math.random() * textDistance - textDistance) + Math.random() * config.AU / 10;
texts.push(textMesh) texts.push(textMesh)
group.add(textMesh); group.add(textMesh);
sphereConfig.text = textMesh;
sphereConfig.group = group; sphereConfig.group = group;
sphereConfig.sphereColor = sphereColor;
const labelLine = []; const labelLine = [];
labelLine.push(new THREE.Vector3(textMesh.position.x, textMesh.position.y, textMesh.position.z)); labelLine.push(new THREE.Vector3(textMesh.position.x, textMesh.position.y, textMesh.position.z));
@@ -138,6 +196,7 @@ function initScene(font) {
const lineMaterial = new THREE.LineBasicMaterial({color: sphereColor}); const lineMaterial = new THREE.LineBasicMaterial({color: sphereColor});
const lineGeometry = new THREE.BufferGeometry().setFromPoints(labelLine); const lineGeometry = new THREE.BufferGeometry().setFromPoints(labelLine);
const line = new THREE.Line( lineGeometry, lineMaterial); const line = new THREE.Line( lineGeometry, lineMaterial);
sphereConfig.line = line;
group.add(line); group.add(line);
scene.add(group); scene.add(group);
}) })
@@ -149,11 +208,22 @@ function initScene(font) {
light.position.set(sun.x, sun.y, sun.z); light.position.set(sun.x, sun.y, sun.z);
scene.add(light); scene.add(light);
scene.position.set(sun.x, sun.y, sun.z) scene.position.set(sun.x, sun.y, sun.z)
camera.position.set(sun.x, sun.y, sun.z + config.AU)
camera.lookAt(sun.x, sun.y, sun.z)
controls.update();
axesHelper = new THREE.AxesHelper(config.AU / 5); axesHelper = new THREE.AxesHelper(config.AU / 5);
axesHelper.position.copy(controls.target); resetControls();
scene.add(axesHelper) scene.add(axesHelper)
} }
function keyPress(event) {
let keyCode = event.which;
if(keyCode === 82) {
reset()
} else if(keyCode === 70) {
resetControls()
} else if(keyCode === 80) {
config.pause = !config.pause;
}
}
document.addEventListener("keydown", keyPress, false);

File diff suppressed because it is too large Load Diff

406
utils/client.js Normal file
View File

@@ -0,0 +1,406 @@
var https = require("https");
const fs = require('fs');
var parameter = [
{ key: 'COMMAND', value: '\'506\''},
{ key: 'CENTER', value: '\'500@0\''},
{ key: 'MAKE_EPHEM', value: '\'YES\''},
{ key: 'TABLE_TYPE', value: '\'VECTORS\''},
{ key: 'START_TIME', value: '\'2024-03-17\''},
{ key: 'STOP_TIME', value: '\'2024-03-18\''},
{ key: 'STEP_SIZE', value: '\'1 d\''},
{ key: 'OUT_UNITS', value: '\'AU-D\''},
{ key: 'REF_PLANE', value: '\'ECLIPTIC\''},
{ key: 'REF_SYSTEM', value: '\'J2000\''},
{ key: 'VECT_CORR', value: '\'NONE\''},
{ key: 'VEC_LABELS', value: '\'YES\''},
{ key: 'VEC_DELTA_T', value: '\'NO\''},
{ key: 'CSV_FORMAT', value: '\'YES\''},
{ key: 'OBJ_DATA', value: '\'YES\''},
{ key: 'VEC_TABLE', value: '\'3\''}
];
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
var fetched = {}
var toFetch = []
function moonformat(name, object){
planetformat(object, name)
fs.appendFileSync('planets.js', `${name}.isMoon = true; \n`);
}
function planetformat(values, planetName){
var x = 'let {0} = generateBasicPlanet();\n \
{0}.radius = {1} * 1000; \n \
{0}.name = \'{0}\'; \n \
{0}.mass = {2}; \n \
{0}.x = {3} * config.AU; \n \
{0}.y = {4} * config.AU; \n \
{0}.z = {5} * config.AU; \n \
\n \
{0}.vx = auPerDayToMPerSecond({6}); \n \
{0}.vy = auPerDayToMPerSecond({7}); \n \
{0}.vz = auPerDayToMPerSecond({8}); \n \
';
fs.appendFileSync('planets.js', x.format(planetName, values.radius, values.mass, values.x, values.y, values.z, values.vx, values.vy, values.vz));
}
function getObjectIndex(planet, moonIndex) {
return '\'' + (planets.indexOf(planet)) + ((moonIndex > 9) ? '' : '0') + moonIndex + '\'';
}
function getPlanetIndex(planet){
if(planet === 'sun') {
return '10'
} else {
let index = '\'' + (planets.indexOf(planet)) + '99' + '\'';
console.log(`name: ${planet} index ${index}`)
return index;
}
}
function fetchMoonOfPlanet(planetName, moonIndex, moonName, callback){
parameter[0].value = getObjectIndex(planetName, moonIndex);
var url = '/horizons_batch.cgi?batch=l';
parameter.forEach(function(param){
url += '&' + param.key + '=' + encodeURIComponent(param.value).replace(/'/g, '%27');
});
var options = {
host: 'ssd.jpl.nasa.gov',
path: url
};
var req = https.get(options, function(res){
var body = [];
res.on('data', function(chunk){
body.push(chunk);
});
res.on('end', function(){
try {
var responseString = Buffer.concat(body).toString('binary');
if(responseString.includes('There was an unexpected problem with server')) {
// console.log(moonName + ' failed')
return;
}
var lines = responseString.split(/\r?\n/);
var vectorLine = '';
var radiusRegex = /Radius\s*\(km\)\s*=\s*~?(\d*\.?\d?)/;
let otherRadiusRegex = /Radius\s*\(gravity\),\s*km\s*=\s*~?(\d*\.?\d?)/;
let volRadiusRegex = /mean\s*radius,?\s*\(?km\)?\s*=\s*~?(\d*)/i;
let meanRadius = /Radius\s*\(km\),\s*mean\s*=\s*~?(\d*\.?\d?)/;
var massRegex = /Mass,?\s*\(?10\^(\d*)\s*kg\s*\)?\s*=\s*~?(\d*\.?\d?)/;
var otherMassRegex = /Mass,?\s*x10\^(\d*)\s*\(?kg\)?\s*\s*=\s*~?(\d*\.?\d*)/;
var gramRegex = /Mass,?\s*\(?10\^(\d*\s*)\s*g\s*\)?\s*=\s*~?(\d*\.?\d*)/;
var gramRegexPara = /Mass,?\s*x\s*10\^(\d*)\s*\(g\)\s*=\s*~?(\d*)/;
var mass = 0;
var radius = 0;
lines.forEach(function(line, index, array){
// moon and planes return two radius, just take the first one
if(line.toUpperCase().indexOf('RADIUS') !== -1 && radius === 0 && line.indexOf('Equat. radius') === -1 && line.indexOf('PHYSICAL') === -1){
var radiusMatch;
if(line.indexOf('gravity') !== -1){
radiusMatch = otherRadiusRegex.exec(line);
} else if(line.toUpperCase().indexOf('MEAN RADIUS') !==-1) {
radiusMatch = volRadiusRegex.exec(line);
} else if(line.indexOf('mean') !== -1){
radiusMatch = meanRadius.exec(line);
} else {
radiusMatch = radiusRegex.exec(line);
}
radius = radiusMatch[1];
}
if(line.indexOf('Mass') !== -1 && mass === 0 && line.indexOf('Mass ratio') === -1){
var massMatch;
if(line.indexOf('x10') !== -1){
massMatch = otherMassRegex.exec(line);
mass = massMatch[2] + ' * Math.pow(10, ' + massMatch[1] + ')'
} else if(line.indexOf('kg') !== -1){
massMatch = massRegex.exec(line);
mass = massMatch[2] + ' * Math.pow(10, ' + massMatch[1] + ')'
} else if(line.indexOf('(g)') !== -1) {
massMatch = gramRegexPara.exec(line);
mass = (parseInt(massMatch[2]) / 1000) + ' * Math.pow(10, ' + (parseInt(massMatch[1])) + ')';
} else {
massMatch = gramRegex.exec(line);
mass = (parseInt(massMatch[2]) / 1000) + ' * Math.pow(10, ' + (parseInt(massMatch[1])) + ')';
}
}
if(line.indexOf('$$SOE') !== -1) {
vectorLine = array[index + 1];
}
});
var values = vectorLine.split(',');
var x = values[2];
var y = values[3];
var z = values[4];
var vx = values[5];
var vy = values[6];
var vz = values[7];
var moonStats = {
x: x,
y: y,
z: z,
vx: vx,
vy: vy,
vz: vz,
radius: radius,
mass: mass
};
fetched[moonName] = 1
callback(moonName, moonStats);
} catch (e) {
console.log(responseString)
console.log(e)
}
})
});
req.on('error', function(e){
console.log(e)
});
}
function fetchPlanet(planetName, callback){
parameter[0].value = getPlanetIndex(planetName);
var url = '/horizons_batch.cgi?batch=l';
parameter.forEach(function(param){
url += '&' + param.key + '=' + encodeURIComponent(param.value).replace(/'/g, '%27');
});
var options = {
host: 'ssd.jpl.nasa.gov',
path: url
};
var req = https.get(options, function(res){
var body = [];
res.on('data', function(chunk){
body.push(chunk);
});
res.on('end', function(){
try {
var responseString = Buffer.concat(body).toString('binary');
if(responseString.includes('There was an unexpected problem with server')) {
// console.log(planetName + ' failed')
return;
}
var lines = responseString.split(/\r?\n/);
var vectorLine = '';
var radiusRegex = /Radius\s*\(km\)\s*=\s*(\d*\.?\d?)/;
let otherRadiusRegex = /Radius\s*\(gravity\),\s*km\s*=\s*~?(\d*\.?\d?)/;
let volRadiusRegex = /mean\s*radius,?\s*\(?km\)?\s*=\s*~?(\d*)/i;
var massRegex = /Mass,?\s*\(?10\^(\d*)\s*kg\s*\)?\s*=\s*~?(\d*\.?\d?)/;
var otherMassRegex = /Mass,?\s*x10\^(\d*)\s*\(?kg\)?\s*\s*=\s*~?(\d*\.?\d*)/;
var gramRegex = /Mass,?\s*\(?10\^(\d*\s*)\s*g\s*\)?\s*=\s*~?(\d*\.?\d*)/;
var gramRegexPara = /Mass,?\s*x\s*10\^(\d*)\s\(g\)\s*=\s*~?(\d*)/;
var mass = 0;
var radius = 0;
lines.forEach(function(line, index, array){
// moon and planes return two radius, just take the first one
if(line.toUpperCase().indexOf('RADIUS') !== -1 && radius === 0 && line.indexOf('Equat. radius') === -1 && line.indexOf('PHYSICAL') === -1){
var radiusMatch;
try {
if (line.indexOf('gravity') !== -1) {
radiusMatch = otherRadiusRegex.exec(line);
} else if (line.toUpperCase().indexOf('MEAN RADIUS') !== -1) {
radiusMatch = volRadiusRegex.exec(line);
} else {
radiusMatch = radiusRegex.exec(line);
}
radius = radiusMatch[1];
} catch (e) {
console.log(e)
console.log(line)
console.log(responseString)
}
}
if(line.indexOf('Mass') !== -1 && mass === 0 && line.indexOf('Mass ratio') === -1){
if(planetName == 'sun') {
console.log(line)
}
var massMatch;
if(line.indexOf('x10') !== -1){
massMatch = otherMassRegex.exec(line);
mass = massMatch[2] + ' * Math.pow(10, ' + massMatch[1] + ')'
} else if(line.indexOf('kg') !== -1){
massMatch = massRegex.exec(line);
mass = massMatch[2] + ' * Math.pow(10, ' + massMatch[1] + ')'
} else if(line.indexOf('(g)') !== -1) {
massMatch = gramRegexPara.exec(line);
mass = (parseInt(massMatch[2]) / 1000) + ' * Math.pow(10, ' + (parseInt(massMatch[1])) + ')';
} else {
massMatch = gramRegex.exec(line);
mass = (parseInt(massMatch[2]) / 1000) + ' * Math.pow(10, ' + (parseInt(massMatch[1])) + ')';
}
}
if(line.indexOf('$$SOE') !== -1) {
vectorLine = array[index + 1];
}
});
var values = vectorLine.split(',');
var x = values[2];
var y = values[3];
var z = values[4];
var vx = values[5];
var vy = values[6];
var vz = values[7];
var planet = {
x: x,
y: y,
z: z,
vx: vx,
vy: vy,
vz: vz,
radius: radius,
mass: mass
};
fetched[planetName] = 1
callback(planet, planetName);
} catch (e) {
console.log(responseString)
console.log(e)
}
})
});
req.on('error', function(e){
console.log(e)
});
}
var planets = ['sun','mercury', 'venus', 'earth', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune', 'pluto'];
let planetsToDo = []
planets.forEach(plan => planetsToDo.push(plan))
var moons = {
'luna': () => fetchMoonOfPlanet('earth', 1, 'luna', moonformat),
'phobos': () => fetchMoonOfPlanet('mars', 1, 'phobos', moonformat),
'deimos': () => fetchMoonOfPlanet('mars', 2, 'deimos', moonformat),
'io': () => fetchMoonOfPlanet('jupiter', 1, 'io', moonformat),
'europa': () => fetchMoonOfPlanet('jupiter', 2, 'europa', moonformat),
'ganymede': () => fetchMoonOfPlanet('jupiter', 3, 'ganymede', moonformat),
'callisto': () => fetchMoonOfPlanet('jupiter', 4, 'callisto', moonformat),
'amalthea': () => fetchMoonOfPlanet('jupiter', 5, 'amalthea', moonformat),
'himalia': () => fetchMoonOfPlanet('jupiter', 6, 'himalia', moonformat),
'elara': () => fetchMoonOfPlanet('jupiter', 7, 'elara', moonformat),
'pasiphae': () => fetchMoonOfPlanet('jupiter', 8, 'pasiphae', moonformat),
'sinope': () => fetchMoonOfPlanet('jupiter', 9, 'sinope', moonformat),
'lysithea': () => fetchMoonOfPlanet('jupiter', 10, 'lysithea', moonformat),
'carme': () => fetchMoonOfPlanet('jupiter', 11, 'carme', moonformat),
'nemausa': () => fetchMoonOfPlanet('jupiter', 12, 'nemausa', moonformat),
'ananke': () => fetchMoonOfPlanet('jupiter', 13, 'ananke', moonformat),
'thebe': () => fetchMoonOfPlanet('jupiter', 14, 'thebe', moonformat),
'adrastea': () => fetchMoonOfPlanet('jupiter', 14, 'adrastea', moonformat),
'mimas': () => fetchMoonOfPlanet('saturn', 1, 'mimas', moonformat),
'enceladus': () => fetchMoonOfPlanet('saturn', 2, 'enceladus', moonformat),
'tethys': () => fetchMoonOfPlanet('saturn', 3, 'tethys', moonformat),
'dione': () => fetchMoonOfPlanet('saturn', 4, 'dione', moonformat),
'rhea': () => fetchMoonOfPlanet('saturn', 5, 'rhea', moonformat),
'titan': () => fetchMoonOfPlanet('saturn', 6, 'titan', moonformat),
'hyperion': () => fetchMoonOfPlanet('saturn', 7, 'hyperion', moonformat),
'iapetus': () => fetchMoonOfPlanet('saturn', 8, 'iapetus', moonformat),
'phoebe': () => fetchMoonOfPlanet('saturn', 9, 'phoebe', moonformat),
'janus': () => fetchMoonOfPlanet('saturn', 10, 'janus', moonformat),
'epimetheus': () => fetchMoonOfPlanet('saturn', 11, 'epimetheus', moonformat),
'helene': () => fetchMoonOfPlanet('saturn', 12, 'helene', moonformat),
'telesto': () => fetchMoonOfPlanet('saturn', 13, 'telesto', moonformat),
'calypso': () => fetchMoonOfPlanet('saturn', 14, 'calypso', moonformat),
'atlas': () => fetchMoonOfPlanet('saturn', 15, 'atlas', moonformat),
'prometheus': () => fetchMoonOfPlanet('saturn', 16, 'prometheus', moonformat),
'ariel': () => fetchMoonOfPlanet('uranus', 1, 'ariel', moonformat),
'umbriel': () => fetchMoonOfPlanet('uranus', 2, 'umbriel', moonformat),
'titania': () => fetchMoonOfPlanet('uranus', 3, 'titania', moonformat),
'oberon': () => fetchMoonOfPlanet('uranus', 4, 'oberon', moonformat),
'miranda': () => fetchMoonOfPlanet('uranus', 5, 'miranda', moonformat),
'cordelia': () => fetchMoonOfPlanet('uranus', 6, 'cordelia', moonformat),
'ophelia': () => fetchMoonOfPlanet('uranus', 7, 'ophelia', moonformat),
'bianca': () => fetchMoonOfPlanet('uranus', 8, 'bianca', moonformat),
'cressida': () => fetchMoonOfPlanet('uranus', 9, 'cressida', moonformat),
'desdemona': () => fetchMoonOfPlanet('uranus', 10, 'desdemona', moonformat),
'juliet': () => fetchMoonOfPlanet('uranus', 11, 'juliet', moonformat),
'portia': () => fetchMoonOfPlanet('uranus', 12, 'portia', moonformat),
'rosalind': () => fetchMoonOfPlanet('uranus', 13, 'rosalind', moonformat),
'belinda': () => fetchMoonOfPlanet('uranus', 14, 'belinda', moonformat),
'puck': () => fetchMoonOfPlanet('uranus', 15, 'puck', moonformat),
'caliban': () => fetchMoonOfPlanet('uranus', 16, 'caliban', moonformat),
'sycorax': () => fetchMoonOfPlanet('uranus', 17, 'sycorax', moonformat),
'triton': () => fetchMoonOfPlanet('neptune', 1, 'triton', moonformat),
'nereid': () => fetchMoonOfPlanet('neptune', 2, 'nereid', moonformat),
'naiad': () => fetchMoonOfPlanet('neptune', 3, 'naiad', moonformat),
'thalassa': () => fetchMoonOfPlanet('neptune', 4, 'thalassa', moonformat),
'despina': () => fetchMoonOfPlanet('neptune', 5, 'despina', moonformat),
'galatea': () => fetchMoonOfPlanet('neptune', 6, 'galatea', moonformat),
'larissa': () => fetchMoonOfPlanet('neptune', 7, 'larissa', moonformat),
'proteus': () => fetchMoonOfPlanet('neptune', 8, 'proteus', moonformat),
'halimede': () => fetchMoonOfPlanet('neptune', 9, 'halimede', moonformat),
'psamathe': () => fetchMoonOfPlanet('neptune', 10, 'psamathe', moonformat),
'charon': () => fetchMoonOfPlanet('pluto', 1, 'charon', moonformat)
}
let moonNames = []
for (const [key, value] of Object.entries(moons)) {
moonNames.push(key)
}
let totalToDo = moonNames.length + planets.length;
console.log(`Todo ${totalToDo}`)
const intervalObj = setInterval(() => {
//console.log('triggering retry')
// console.log(fetched)
planetsToDo.forEach(planetName => {
if(!(planetName in fetched)) {
// console.log('retrying planet ' + planetName)
fetchPlanet(planetName, planetformat)
} else {
var index = planetsToDo.indexOf(planetName);
if (index !== -1) {
planetsToDo.splice(index, 1);
}
}
})
moonNames.forEach(moonName => {
if(!(moonName in fetched)) {
// console.log('retrying moon ' + moonName)
moons[moonName]()
} else {
var index = moonNames.indexOf(moonName);
if (index !== -1) {
moonNames.splice(index, 1);
}
}
})
let currentlyFetched = Object.keys(fetched).length;
console.log(`Progress ${ currentlyFetched}/${totalToDo}`)
console.log(fetched)
if(currentlyFetched === totalToDo) {
clearInterval(intervalObj)
}
}, 5000 * 2)