diff --git a/app.arc b/app.arc
index 22e3266..949f7c7 100644
--- a/app.arc
+++ b/app.arc
@@ -18,3 +18,9 @@ plugin-remix
runtime nodejs18.x
region us-east-1
architecture arm64
+
+@tables
+notes
+ userId *String
+ noteId **String
+ PointInTimeRecovery true
\ No newline at end of file
diff --git a/app/lib/utils.ts b/app/lib/utils.ts
new file mode 100644
index 0000000..711ac64
--- /dev/null
+++ b/app/lib/utils.ts
@@ -0,0 +1,6 @@
+// This is just for example. Typically you would get a user from the session.
+// By making it reusable, you would only have to get the userId from the session
+// in one place. This makes it portable.
+export function getUserId() {
+ return 'test'
+}
diff --git a/app/root.tsx b/app/root.tsx
index c6e1aa3..22f5685 100644
--- a/app/root.tsx
+++ b/app/root.tsx
@@ -4,11 +4,12 @@ import {
Links,
LiveReload,
Meta,
+ NavLink,
Outlet,
Scripts,
ScrollRestoration,
} from '@remix-run/react'
-import { GovBanner, GridContainer } from '@trussworks/react-uswds'
+import { GovBanner, GridContainer, PrimaryNav } from '@trussworks/react-uswds'
import theme from './theme.css'
import favicon_16 from '~/../node_modules/@uswds/uswds/dist/img/favicons/favicon-16.png'
@@ -51,6 +52,17 @@ export default function App() {
+
+ Data
+ ,
+
+ Home
+ ,
+ ]}
+ >
Skip to main content
diff --git a/app/routes/data._index.tsx b/app/routes/data._index.tsx
new file mode 100644
index 0000000..64064d6
--- /dev/null
+++ b/app/routes/data._index.tsx
@@ -0,0 +1,14 @@
+import { Link } from '@remix-run/react'
+
+export default function () {
+ return (
+
+
Instrument Data
+
+
+ New Data Gathering Session
+
+
+
+ )
+}
diff --git a/app/routes/data.new.tsx b/app/routes/data.new.tsx
new file mode 100644
index 0000000..6f14bb6
--- /dev/null
+++ b/app/routes/data.new.tsx
@@ -0,0 +1,270 @@
+import type { DataFunctionArgs } from '@remix-run/node'
+import { Link, useFetcher, useLoaderData } from '@remix-run/react'
+import {
+ Button,
+ ButtonGroup,
+ FormGroup,
+ Grid,
+ GridContainer,
+ Icon,
+ Label,
+ Select,
+ TextInput,
+ Textarea,
+} from '@trussworks/react-uswds'
+import { getUserId } from 'app/lib/utils'
+import { useEffect, useRef, useState } from 'react'
+
+import { createNewNote, getInstrumentData, getNotes } from './data/data.server'
+import { tableOptions } from './data/data.table-options'
+
+function validateResultCountInput(input: string) {
+ const numericalInput = parseFloat(input)
+ return numericalInput.toString() === input && numericalInput <= 100
+}
+
+export async function loader({ request }: DataFunctionArgs) {
+ const userID = getUserId()
+ return await getNotes(userID)
+}
+
+export async function action({ request }: DataFunctionArgs) {
+ const userID = getUserId()
+ const data = await request.formData()
+ const intent = data.get('intent')?.toString()
+
+ if (intent === 'get-data') {
+ const format = data.get('format')?.toString()
+ const resultCount = data.get('resultCount')?.toString()
+ const instrument = data.get('instrument')?.toString()
+ const ra = data.get('ra')?.toString()
+ const dec = data.get('dec')?.toString()
+ const radius = data.get('radius')?.toString()
+
+ if (!instrument || !format || !resultCount || !ra || !dec || !radius)
+ return null
+ const res = await getInstrumentData(
+ instrument,
+ format,
+ parseInt(resultCount),
+ parseFloat(ra),
+ parseFloat(dec),
+ parseInt(radius)
+ )
+ return res
+ } else if (intent === 'new-note') {
+ const noteTitle = data.get('title')?.toString()
+ const noteBody = data.get('notes')?.toString()
+ if (!noteBody || !noteTitle) {
+ return null
+ }
+ await createNewNote(noteTitle, noteBody, userID)
+
+ return null
+ } else {
+ return null
+ }
+}
+
+export default function () {
+ const [instrument, setInstrument] = useState('')
+ const [format, setFormat] = useState('')
+ const [ra, setRa] = useState('')
+ const [dec, setDec] = useState('')
+ const [radius, setRadius] = useState('')
+ const [resultCount, setResultCount] = useState('')
+ const isValid = validateResultCountInput(resultCount)
+ const [noteTitle, setNoteTitle] = useState('')
+ const [noteBody, setNoteBody] = useState('')
+
+ const noteRef = useRef(null)
+
+ const fetcher = useFetcher()
+ const results = fetcher.data
+ const fetchNotes = useFetcher()
+ const notes = useLoaderData()
+ const resultArray = results?.request || ['no results']
+
+ const shouldDisableForm =
+ !instrument || !format || !resultCount || !isValid || !ra || !dec || !radius
+ const shouldDisableNotes = !noteTitle || !noteBody
+
+ useEffect(() => {
+ if (
+ fetchNotes.state === 'idle' &&
+ fetchNotes.data === null &&
+ noteRef.current
+ ) {
+ noteRef.current.reset()
+ }
+ }, [fetchNotes.state, fetchNotes.data])
+
+ return (
+
+ )
+}
diff --git a/app/routes/data/data.server.ts b/app/routes/data/data.server.ts
new file mode 100644
index 0000000..9efa591
--- /dev/null
+++ b/app/routes/data/data.server.ts
@@ -0,0 +1,86 @@
+import { tables } from '@architect/functions'
+import { v4 as uuidv4 } from 'uuid'
+
+async function fetchData(
+ instrument: string,
+ format: string,
+ resultCount: number,
+ ra: number,
+ dec: number,
+ radius: number
+) {
+ const heasarc_api_url = 'https://heasarc.gsfc.nasa.gov/xamin/QueryServlet'
+ const formData = new FormData()
+
+ formData.append('table', instrument)
+ formData.append('format', format)
+ formData.append('resultmax', resultCount.toString())
+ formData.append('radius', radius.toString())
+ formData.append('position[]', ra.toString())
+ formData.append('position[]', dec.toString())
+
+ try {
+ const response = await fetch(heasarc_api_url, {
+ method: 'POST',
+ body: formData,
+ })
+ const data =
+ format === 'json' ? await response.json() : await response.text()
+ return data
+ } catch (error) {
+ console.log(error)
+ }
+}
+
+export async function getInstrumentData(
+ instrument: string,
+ format: string,
+ resultCount: number,
+ ra: number,
+ dec: number,
+ radius: number
+) {
+ try {
+ const response = await fetchData(
+ instrument,
+ format,
+ resultCount,
+ ra,
+ dec,
+ radius
+ )
+ return response
+ } catch (error) {
+ console.log(error)
+ }
+}
+
+export async function createNewNote(
+ noteTitle: string,
+ noteBody: string,
+ userId: string
+) {
+ const db = await tables()
+ const noteId = uuidv4()
+
+ await db.notes.put({
+ userId,
+ noteId,
+ noteTitle,
+ noteBody,
+ })
+}
+
+export async function getNotes(userId: string) {
+ const db = await tables()
+ const results = await db.notes.query({
+ KeyConditionExpression: '#userId = :userId',
+ ExpressionAttributeNames: {
+ '#userId': 'userId',
+ },
+ ExpressionAttributeValues: {
+ ':userId': userId,
+ },
+ })
+ return results.Items
+}
diff --git a/app/routes/data/data.table-options.ts b/app/routes/data/data.table-options.ts
new file mode 100644
index 0000000..9c49dc8
--- /dev/null
+++ b/app/routes/data/data.table-options.ts
@@ -0,0 +1,1009 @@
+export const tableOptions = [
+ 'a1',
+ 'a1point',
+ 'a2lcpoint',
+ 'a2lcscan',
+ 'a2led',
+ 'a2pic',
+ 'a2point',
+ 'a2rtraw',
+ 'a2specback',
+ 'a2spectra',
+ 'a3',
+ 'a4',
+ 'a4spectra',
+ 'aavsovsx',
+ 'abell',
+ 'abellzcat',
+ 'acceptcat',
+ 'acrs',
+ 'actegsrcat',
+ 'actmadcows',
+ 'actssrcat',
+ 'actszclust',
+ 'aegis20',
+ 'aegis20id',
+ 'aegisx',
+ 'aegisxdcxo',
+ 'agilecat',
+ 'agileupvar',
+ 'agnsdssxm2',
+ 'agnsdssxmm',
+ 'akaribsc',
+ 'akaripsc',
+ 'aknepdfcxo',
+ 'alfperxmm',
+ 'allwiseagn',
+ 'ami10c15gz',
+ 'amigps16gh',
+ 'ansuvpscat',
+ 'arcquincxo',
+ 'ariel3a',
+ 'ariel5',
+ 'arxa',
+ 'ascaegclus',
+ 'ascagis',
+ 'ascagps',
+ 'ascalss',
+ 'ascamaster',
+ 'ascao',
+ 'ascaprspec',
+ 'ascasis',
+ 'asiagosn',
+ 'askapbeta',
+ 'at20g',
+ 'at20g1fgl',
+ 'at20gbspol',
+ 'at20gbss',
+ 'at20gharc',
+ 'at2fglus',
+ 'atats',
+ 'atcaadfs20',
+ 'atcdfsss82',
+ 'atesp1p4gh',
+ 'athdfs1p4g',
+ 'athdfs3frq',
+ 'athdfsccat',
+ 'athdfsoid',
+ 'atlas2p3gh',
+ 'atlas5p5gh',
+ 'atlascscpt',
+ 'atlascsid',
+ 'atlasd2cpt',
+ 'atlasescpt',
+ 'atlasesid',
+ 'atlasspecz',
+ 'atlbs1p4gh',
+ 'atlgds2p1g',
+ 'atnfpulsar',
+ 'atpmncat',
+ 'axis',
+ 'bat5bgrbsp',
+ 'batse4b',
+ 'batsedaily',
+ 'batseeocat',
+ 'batsegrb',
+ 'batsegrbsp',
+ 'batsepulsr',
+ 'batsetrigs',
+ 'baxgalclus',
+ 'bbxrt',
+ 'bestars',
+ 'bhrfscid',
+ 'bmwchancat',
+ 'bmwhricat',
+ 'bnmdspecat',
+ 'boof153mhz',
+ 'bootesdf',
+ 'bsc5p',
+ 'caixa',
+ 'calchdmstr',
+ 'calgbmmstr',
+ 'candelscxo',
+ 'cargm31cxo',
+ 'carinaclas',
+ 'carinacxo',
+ 'carinaxmm',
+ 'cbatpicagn',
+ 'cbfgrxecxo',
+ 'ccosmoscat',
+ 'ccosmosoid',
+ 'ccosmphotz',
+ 'ccosrssfag',
+ 'cdfn2msnew',
+ 'cdfn2msoi2',
+ 'cdfn2msoid',
+ 'cdfsagncxo',
+ 'cenacxo',
+ 'cepaxmm',
+ 'cepbob3cxo',
+ 'cepbob3oid',
+ 'cfa2s',
+ 'cfhtlsgxmm',
+ 'cg12cxo',
+ 'cgmw',
+ 'cgpsngpcat',
+ 'cgrabs',
+ 'cgroprspec',
+ 'cgrotl',
+ 'chainthcxo',
+ 'champhxagn',
+ 'champlane',
+ 'champlanex',
+ 'champpsc',
+ 'champsdssa',
+ 'chandfn1ms',
+ 'chandfn2ms',
+ 'chandfs1ms',
+ 'chandfs2ms',
+ 'chandfs4ms',
+ 'chandfs7ms',
+ 'chanextdfs',
+ 'changalxrb',
+ 'changbscat',
+ 'chanmaster',
+ 'channsgpsc',
+ 'chansexagn',
+ 'chansexoid',
+ 'chansexsi',
+ 'chansngcat',
+ 'chantypgpr',
+ 'chanulxcat',
+ 'chanvguide',
+ 'chasfrxray',
+ 'chesscat',
+ 'chicagocxo',
+ 'chngpscliu',
+ 'chpngptsrc',
+ 'clans',
+ 'clansoid',
+ 'class',
+ 'clasxs',
+ 'clasxsoid',
+ 'clscat',
+ 'cma',
+ 'cmaimage',
+ 'cmaob1nir',
+ 'cmaob1xmm',
+ 'cmar1xray',
+ 'cmascreen',
+ 'cmbmaster',
+ 'cns3',
+ 'cocd',
+ 'cocdext1',
+ 'coll69oid',
+ 'coll69xmm',
+ 'comptel',
+ 'corotexlog',
+ 'cosbmaps',
+ 'cosbraw',
+ 'cosmosvlba',
+ 'cosxfirmwc',
+ 'coup',
+ 'cpstars',
+ 'cr261cxo',
+ 'cr261oid',
+ 'crabtime',
+ 'crates',
+ 'cratesocrap',
+ 'csc',
+ 'cvcat',
+ 'cxogsgsrc',
+ 'cxoxassist',
+ 'cyder',
+ 'cygob2cxo',
+ 'cygob2cxo2',
+ 'cygob2xmm',
+ 'cygtevcxo',
+ 'denisigal',
+ 'dirbepsc',
+ 'dixon',
+ 'dncvobcat',
+ 'duerbeck',
+ 'dxrbs',
+ 'ecdfscxo',
+ 'ecdfsnew',
+ 'ecdfsoid',
+ 'ecdfsoid2',
+ 'ecdfsrssam',
+ 'efedshard',
+ 'efedsmain',
+ 'egrcat',
+ 'egret3',
+ 'egretdata',
+ 'eingalcat',
+ 'eingalclus',
+ 'einopslgal',
+ 'einstein2e',
+ 'elaiscxo',
+ 'elaisfbmc',
+ 'elaiss1oid',
+ 'elaiss1xmm',
+ 'emss',
+ 'erosxmm',
+ 'esouppsala',
+ 'etachahard',
+ 'etachamain',
+ 'etgalcxo',
+ 'etgalxray',
+ 'euv',
+ 'euvebsl',
+ 'euvecat2',
+ 'euvemaster',
+ 'euverap1',
+ 'euverap2',
+ 'euverap3',
+ 'euvexrtcat',
+ 'exgalemobj',
+ 'exms',
+ 'exofot',
+ 'exogps',
+ 'exohgls',
+ 'exolog',
+ 'exomaster',
+ 'exoplanets',
+ 'exoplanodb',
+ 'exopubs',
+ 'exss',
+ 'faust',
+ 'fbsbsocat',
+ 'feedback',
+ 'fer2fusrid',
+ 'fermi2favs',
+ 'fermi3fgl',
+ 'fermi3fhl',
+ 'fermifhl',
+ 'fermigbrst',
+ 'fermigdays',
+ 'fermigsol',
+ 'fermigtrig',
+ 'fermil2psr',
+ 'fermilac',
+ 'fermilasp',
+ 'fermilatra',
+ 'fermilblaz',
+ 'fermilbsl',
+ 'fermilgrb',
+ 'fermilhesc',
+ 'fermille',
+ 'fermilpsc',
+ 'fermiltrns',
+ 'fermilweek',
+ 'flarestars',
+ 'fornaxacxo',
+ 'fornaxxmm',
+ 'fpcsfits',
+ 'fricat',
+ 'friicat',
+ 'fsvsclustr',
+ 'fuselog',
+ 'galccxonid',
+ 'galcencxo',
+ 'galcenpspc',
+ 'galexlog',
+ 'galextdsc',
+ 'galobstars',
+ 'gb6',
+ 'gbt31ghz',
+ 'gc47tuccx2',
+ 'gc47tuccxo',
+ 'gcps',
+ 'gcptsrccxo',
+ 'gcscat',
+ 'gcvs',
+ 'gcvsegvars',
+ 'gcvsnsvars',
+ 'gingaasmlc',
+ 'gingabgd',
+ 'gingalac',
+ 'gingalog',
+ 'gingamode',
+ 'gingaraw',
+ 'gleamegcat',
+ 'gliese2mas',
+ 'globclust',
+ 'glxsdssqs2',
+ 'glxsdssqso',
+ 'gmrt1hxcsf',
+ 'gmrt4f150m',
+ 'gmrtas150m',
+ 'gmrtelain1',
+ 'gmrtelain2',
+ 'gmrtha325m',
+ 'gmrtj0916',
+ 'gmrtk2f1lf',
+ 'gmrtlbdsly',
+ 'gmrtlhcat',
+ 'gmrtlhcat2',
+ 'gmrtlhcat3',
+ 'gmrtspxfls',
+ 'gmrtvvdsvl',
+ 'gmrtxl240m',
+ 'gmrtxl610m',
+ 'goscat',
+ 'gp7c151mhz',
+ 'gpa',
+ 'grbcat',
+ 'grbcatag',
+ 'grbcatann',
+ 'grbcatbox',
+ 'grbcatcirc',
+ 'grbcatdual',
+ 'grbcatflux',
+ 'grbcatint',
+ 'grbcatinta',
+ 'grbcatirr',
+ 'gs',
+ 'gusbad',
+ 'gwsstrpcxo',
+ 'halomaster',
+ 'halotimelg',
+ 'hbc',
+ 'hcg',
+ 'hcggalaxy',
+ 'hcgxrbs',
+ 'hdec',
+ 'heabib',
+ 'hers82cat',
+ 'herschllog',
+ 'hesscat',
+ 'hete2gcn',
+ 'hete2grb',
+ 'hete2tl',
+ 'hic',
+ 'hiiregion',
+ 'hipnewcat',
+ 'hipparcos',
+ 'hitomaster',
+ 'hmxbcat',
+ 'hperseicxo',
+ 'hrasscat',
+ 'hrassoptid',
+ 'hricfa',
+ 'hrideep',
+ 'hriexo',
+ 'hriimage',
+ 'hriphot',
+ 'hstpaec',
+ 'hubbleudf',
+ 'hyadesxray',
+ 'ibiscat',
+ 'ic10cxo',
+ 'ic10xmmcxo',
+ 'ic1396acxo',
+ 'ic1396ncxo',
+ 'ic1805xmm',
+ 'ic2944xmm',
+ 'ic348cxo',
+ 'ic348cxo2',
+ 'icecubepsc',
+ 'infrared',
+ 'intagncat',
+ 'intbsc',
+ 'integralao',
+ 'intgccat',
+ 'intibisag2',
+ 'intibisagn',
+ 'intibisass',
+ 'intibisgal',
+ 'intibisvhd',
+ 'intomcvs',
+ 'intpublic',
+ 'intrefcat',
+ 'intscw',
+ 'intscwpub',
+ 'intspiagrb',
+ 'intvarcat',
+ 'ipc',
+ 'ipcdeep',
+ 'ipcimage',
+ 'ipclxlbol',
+ 'ipcostars',
+ 'ipcphot',
+ 'ipcslew',
+ 'ipcultsoft',
+ 'ipcunscrnd',
+ 'ipngrb',
+ 'ir20126cxo',
+ 'iram30mlog',
+ 'iramnoelog',
+ 'irampdblog',
+ 'irasfsc',
+ 'iraspsc',
+ 'iraspscz',
+ 'irasssc',
+ 'iraszsurv',
+ 'isgri4yrct',
+ 'isolog',
+ 'iuelog',
+ 'ixmaster',
+ 'kaporixmm',
+ 'kommersgrb',
+ 'konus',
+ 'kuehr',
+ 'kvttmcomis',
+ 'l1641ioxmm',
+ 'lalaboocxo',
+ 'lalacetcxo',
+ 'lamorixmm',
+ 'lbn',
+ 'lbqs',
+ 'lcrscat',
+ 'ld7c151mhz',
+ 'ldn',
+ 'le',
+ 'lkha101cxo',
+ 'lmc30drcxo',
+ 'lmcclustrs',
+ 'lmcextobj',
+ 'lmchrixray',
+ 'lmcn11cxo',
+ 'lmcrosxray',
+ 'lmcxray',
+ 'lmxbcat',
+ 'lockmanoir',
+ 'lockmanxm2',
+ 'lockmanxmm',
+ 'lof3c29534',
+ 'lof3c29546',
+ 'lof3c29562',
+ 'lofarbf62m',
+ 'lofhatlas',
+ 'lorcat',
+ 'lotssprcat',
+ 'lowzvlqvla',
+ 'lpffiles',
+ 'lqac',
+ 'lspmnorth',
+ 'lupus3xmm',
+ 'lyngaclust',
+ 'm101cxo',
+ 'm101xmm',
+ 'm108cxo',
+ 'm16cxo',
+ 'm17cxo',
+ 'm31cfcxo',
+ 'm31clustrs',
+ 'm31cxo2',
+ 'm31cxohrc2',
+ 'm31cxoxray',
+ 'm31deepxmm',
+ 'm31phatcxo',
+ 'm31phatsfh',
+ 'm31rbcgc',
+ 'm31rosxray',
+ 'm31stars',
+ 'm31stars2',
+ 'm31xmm2',
+ 'm31xmmxray',
+ 'm33chase',
+ 'm33cxoxray',
+ 'm33deepxmm',
+ 'm33snrxmm',
+ 'm33xmm2',
+ 'm33xmmxray',
+ 'm37cxo',
+ 'm51cxo',
+ 'm51cxo2',
+ 'm67cxo',
+ 'm71cxo',
+ 'm81cxo',
+ 'm81cxo2',
+ 'm83cxo',
+ 'm83xmm',
+ 'm83xrbcxo',
+ 'm87cxo',
+ 'macs',
+ 'maghmxbcat',
+ 'magpis',
+ 'maranoxmm',
+ 'markarian',
+ 'markarian2',
+ 'mashpncat',
+ 'maxigsc7yr',
+ 'maxigschgl',
+ 'maximaster',
+ 'maxissccat',
+ 'mcg',
+ 'mcksion',
+ 'mcxc',
+ 'mdwarfasc',
+ 'mdwf10pcux',
+ 'me',
+ 'messier',
+ 'metainfo',
+ 'mggammacat',
+ 'mggammadet',
+ 'mgps2',
+ 'milliquas',
+ 'mitgb6cm',
+ 'monr2cxo',
+ 'morbbincat',
+ 'morx',
+ 'mostatlas',
+ 'mostsnrcat',
+ 'moxc',
+ 'mpcraw',
+ 'mrc',
+ 'msxpsc',
+ 'msxuvpsc',
+ 'mwa32thgl',
+ 'mwacs',
+ 'mwak2f1lfc',
+ 'mwmc',
+ 'mwp1bubble',
+ 'mwsc',
+ 'mystixires',
+ 'mystixmidi',
+ 'mystixmpcm',
+ 'mystixxray',
+ 'napexmmcxo',
+ 'narcscat',
+ 'ncp21cma',
+ 'neargalcat',
+ 'newmdwarfs',
+ 'ngc1068cxo',
+ 'ngc1291cxo',
+ 'ngc1332cxo',
+ 'ngc1333cxo',
+ 'ngc1399cxo',
+ 'ngc1512xmm',
+ 'ngc1600cxo',
+ 'ngc1893cxo',
+ 'ngc2000',
+ 'ngc2024cxo',
+ 'ngc2237cxo',
+ 'ngc2244cxo',
+ 'ngc2264cx2',
+ 'ngc2264cxo',
+ 'ngc2264xmm',
+ 'ngc2362cxo',
+ 'ngc2403cx2',
+ 'ngc2403cxo',
+ 'ngc2516cxo',
+ 'ngc2516xmm',
+ 'ngc253xmm',
+ 'ngc2547xmm',
+ 'ngc2808cxo',
+ 'ngc2808xmm',
+ 'ngc2903cxo',
+ 'ngc300cxo',
+ 'ngc3115cxo',
+ 'ngc3293cxo',
+ 'ngc404cxo',
+ 'ngc4214cxo',
+ 'ngc4278cxo',
+ 'ngc4365cxo',
+ 'ngc4382cxo',
+ 'ngc4472cxo',
+ 'ngc4636cxo',
+ 'ngc4649cx2',
+ 'ngc4649cxo',
+ 'ngc55cxo',
+ 'ngc5866cxo',
+ 'ngc6231cx2',
+ 'ngc6231cxo',
+ 'ngc6231xmm',
+ 'ngc6334cxo',
+ 'ngc6357cxo',
+ 'ngc6357oid',
+ 'ngc6530cxo',
+ 'ngc6530oid',
+ 'ngc6530xmm',
+ 'ngc6791cxo',
+ 'ngc752cxo',
+ 'ngc752xmm',
+ 'nicermastr',
+ 'nltt',
+ 'noras',
+ 'north20cm',
+ 'north6cm',
+ 'nuaftl',
+ 'nucosmosfc',
+ 'nuecdfscat',
+ 'nugalcen',
+ 'numaster',
+ 'nustarssc',
+ 'nustarssc2',
+ 'nuvbemdcat',
+ 'nvss',
+ 'nwayawgros',
+ 'nwayawgxmm',
+ 'omc2p3cxo',
+ 'omegcencx2',
+ 'omegcencxo',
+ 'omegcenxmm',
+ 'onccxoopt',
+ 'onccxoxray',
+ 'openclust',
+ 'orionffcxo',
+ 'orionxray',
+ 'orionxstar',
+ 'oriysoir',
+ 'oso8alc',
+ 'oso8bclc',
+ 'oso8pharaw',
+ 'oso8rtraw',
+ 'osqsonvss',
+ 'osrilqxray',
+ 'osse',
+ 'ostars',
+ 'ovro31ghz',
+ 'pacobscat',
+ 'pacofscat',
+ 'pccs030ghz',
+ 'pccs044ghz',
+ 'pccs070ghz',
+ 'pccs100ghz',
+ 'pccs143ghz',
+ 'pccs217ghz',
+ 'pccs353ghz',
+ 'pccs545ghz',
+ 'pccs857ghz',
+ 'pds1p4ghz',
+ 'pdsoid',
+ 'pdsoid2',
+ 'pg',
+ 'pgc2003',
+ 'phebus',
+ 'pigssboofd',
+ 'pigsselcnf',
+ 'pkscat90',
+ 'planckeszc',
+ 'planckgcc',
+ 'planckhzsc',
+ 'plancksz',
+ 'plancksz2',
+ 'pleiadxray',
+ 'plnebulae',
+ 'pmn',
+ 'pmpulsar',
+ 'pmsucat',
+ 'ppm',
+ 'ppmxlbmd',
+ 'pulsar',
+ 'pvogrb',
+ 'qorgcat',
+ 'qso',
+ 'radio',
+ 'rass2foid',
+ 'rass2fxray',
+ 'rass2mass',
+ 'rass2rxs',
+ 'rass6dfgs',
+ 'rassaeqso',
+ 'rassasaseb',
+ 'rassasaspv',
+ 'rassbsc',
+ 'rassbscpgc',
+ 'rasscals',
+ 'rasscndins',
+ 'rasscns3',
+ 'rassdssagn',
+ 'rassdsstar',
+ 'rassdwarf',
+ 'rassebcs',
+ 'rassfirst',
+ 'rassfsc',
+ 'rassgb',
+ 'rassgiant',
+ 'rasshgsft2',
+ 'rasshgsoft',
+ 'rassmaster',
+ 'rassnorsam',
+ 'rassob',
+ 'rasssdssgc',
+ 'rassusnoid',
+ 'rassvars',
+ 'rasswd',
+ 'rbs',
+ 'rbscnvss',
+ 'rc3',
+ 'rcw108cxo',
+ 'rcw38cxo',
+ 'rcw38cxo2',
+ 'rcw38yso',
+ 'rcw49cxo',
+ 'reflex',
+ 'refnebulae',
+ 'revisedlhs',
+ 'rhessigrb',
+ 'rhoophcxo',
+ 'rittercv',
+ 'ritterlmxb',
+ 'ritterrbin',
+ 'rixos',
+ 'romabzcat',
+ 'ros13hrcxo',
+ 'ros13hrvla',
+ 'ros13hrxmm',
+ 'ros400gcls',
+ 'rosathard',
+ 'rosatlog',
+ 'rosatrlq',
+ 'rosatrqq',
+ 'rosatxuv',
+ 'rosettecxo',
+ 'rosgalclus',
+ 'roshri',
+ 'roshritotal',
+ 'rosmaster',
+ 'rosnepagn',
+ 'rosnepoid',
+ 'rosnepxray',
+ 'rosprspec',
+ 'rospspc',
+ 'rospspcf',
+ 'rospspcftot',
+ 'rospspctotal',
+ 'roswfc2re',
+ 'rotxraycat',
+ 'roxa',
+ 'rrs8c38mhz',
+ 'rssgrbag',
+ 'rt9cc15ghz',
+ 'rtv9c15ghz',
+ 's254258cxo',
+ 'sa57xmm',
+ 'sacshpscat',
+ 'sacssescat',
+ 'sacsspscat',
+ 'sacstpscat',
+ 'sacy',
+ 'saisncat',
+ 'sao',
+ 'sas2maps',
+ 'sas2raw',
+ 'sas3ylog',
+ 'sax2to10',
+ 'saxao',
+ 'saxgrbmgrb',
+ 'saxhellas',
+ 'saxhellasr',
+ 'saxnfilog',
+ 'saxwfccat',
+ 'saxwfccat2',
+ 'saxwfclog',
+ 'sborbitcat',
+ 'sbsggencat',
+ 'scubafemoc',
+ 'sdssbalqs2',
+ 'sdssbalqso',
+ 'sdsscvcat',
+ 'sdsscxoqso',
+ 'sdssdr10wd',
+ 'sdssdr7wd',
+ 'sdsslasqso',
+ 'sdssnbckde',
+ 'sdssnbcqsc',
+ 'sdssquasar',
+ 'sdsss82cxo',
+ 'sdsss82xmm',
+ 'sdssunuqsr',
+ 'sdsswdsd',
+ 'sdsswhlgc',
+ 'sdssxmmqso',
+ 'selhcgcxo',
+ 'sfgalhmxb',
+ 'sfincspcm',
+ 'sfincsxray',
+ 'sgraregcsc',
+ 'shk',
+ 'shkgalaxy',
+ 'sigorixmm',
+ 'sixdfgs',
+ 'sixsrvycat',
+ 'smc1400mhz',
+ 'smc4800mhz',
+ 'smc843mhz',
+ 'smc8640mhz',
+ 'smcclustrs',
+ 'smcdfscxo',
+ 'smcpscxmm',
+ 'smcradio',
+ 'smcrosxray',
+ 'smcrosxry2',
+ 'smcstars',
+ 'smcstars2',
+ 'smcwingcxo',
+ 'smcxray',
+ 'smmgrs',
+ 'snrgreen',
+ 'spass2p3gh',
+ 'spicescxo',
+ 'spidersros',
+ 'spidersxmm',
+ 'spitzmastr',
+ 'sporiabyso',
+ 'sptmm87sd',
+ 'sptszgalcl',
+ 'sptszspsc',
+ 'ssa22cxo',
+ 'sss',
+ 'sssraw',
+ 'sterngrb',
+ 'subpfclog',
+ 'subtab',
+ 'sumss',
+ 'suzakuwam',
+ 'suzamaster',
+ 'suzaxislog',
+ 'swbat105m',
+ 'swbatagn60',
+ 'swbatmontr',
+ 'swbatsfxt',
+ 'swif1swxrt',
+ 'swift2sxps',
+ 'swiftbalog',
+ 'swiftft',
+ 'swiftgrb',
+ 'swiftguano',
+ 'swiftmastr',
+ 'swifttdrss',
+ 'swiftuvlog',
+ 'swiftxrlog',
+ 'swirecxo',
+ 'swirelhcxo',
+ 'swsdssqso',
+ 'swuvotssc',
+ 'swuvotssob',
+ 'swxcscat',
+ 'swxcsoxid',
+ 'swxrt1fgl',
+ 'sxdscat',
+ 'symbiotics',
+ 'sza31ghz',
+ 'table_classes',
+ 'tabledocs',
+ 'tartarus',
+ 'taurusxmm',
+ 'td1',
+ 'tevcat',
+ 'texas',
+ 'tgs',
+ 'tgs2',
+ 'tramisuboo',
+ 'trifidcxo',
+ 'twodfqsoz',
+ 'twomassrsc',
+ 'twosigma',
+ 'tycho2',
+ 'uc7c151mhz',
+ 'ugc',
+ 'uhuru4',
+ 'uit',
+ 'uitmaster',
+ 'ulxngcat',
+ 'ulxrbcat',
+ 'upprscoxmm',
+ 'uvotbscat',
+ 'uvqs',
+ 'uzc',
+ 'vela5b',
+ 'verimaster',
+ 'veroncat',
+ 'vla23901p4',
+ 'vla3701p4',
+ 'vla74mhzdp',
+ 'vlacdfscat',
+ 'vlacomacat',
+ 'vlacos324m',
+ 'vlacos3ghz',
+ 'vlacosmjsc',
+ 'vlacosmos',
+ 'vlacosxoid',
+ 'vlaecdfs1p4',
+ 'vlaecdfscls',
+ 'vlaecdfsoi',
+ 'vlaen20cm',
+ 'vlagbsoph',
+ 'vlagbsori',
+ 'vlagbsper',
+ 'vlagbsser',
+ 'vlagbstau',
+ 'vlagoodsn',
+ 'vlahdf20cm',
+ 'vlalh1400m',
+ 'vlalhn3ghz',
+ 'vlam311p4g',
+ 'vlam31325m',
+ 'vlanep',
+ 'vlaonccat',
+ 'vlasdf20cm',
+ 'vlasdf90cm',
+ 'vlass821p4',
+ 'vlasxdf1p4',
+ 'vlasxdfoid',
+ 'vlaxl325mh',
+ 'vlaxl74mhz',
+ 'vlssr',
+ 'vlulxcat',
+ 'vvds20cm',
+ 'w2ragncat',
+ 'w40sfrcxo',
+ 'wackerling',
+ 'warps',
+ 'warps2',
+ 'wbhgp20cm',
+ 'wbhgp6cm',
+ 'wbl',
+ 'wblgalaxy',
+ 'wd1cxo',
+ 'wds',
+ 'wenss',
+ 'wfcpoint',
+ 'wgacat',
+ 'wibrals',
+ 'wisehspcat',
+ 'wish',
+ 'wmapcmbfps',
+ 'wmapitnpts',
+ 'wmapptsrc',
+ 'woodebcat',
+ 'woolley',
+ 'wrcat',
+ 'wsrt20anep',
+ 'wsrtgp',
+ 'xbootes',
+ 'xbootesoid',
+ 'xcopraw',
+ 'xcs',
+ 'xdeep2',
+ 'xmdsvvds4s',
+ 'xmmao',
+ 'xmmatlas',
+ 'xmmbss',
+ 'xmmbssagn',
+ 'xmmcdfs210',
+ 'xmmcdfs510',
+ 'xmmcfrscat',
+ 'xmmcfrsoid',
+ 'xmmcosmagn',
+ 'xmmcosmoid',
+ 'xmmcosmos',
+ 'xmmcphotz',
+ 'xmmcty2agn',
+ 'xmmgps',
+ 'xmmlss',
+ 'xmmlss10ks',
+ 'xmmlssclas',
+ 'xmmlssdeep',
+ 'xmmlssoid',
+ 'xmmmaster',
+ 'xmmobstars',
+ 'xmmomcat',
+ 'xmmomcdfs',
+ 'xmmomsuob',
+ 'xmmomsuss',
+ 'xmmsdssgce',
+ 'xmmsdssgcs',
+ 'xmmslewcln',
+ 'xmmslewegs',
+ 'xmmslewful',
+ 'xmmssc',
+ 'xmmsscgps',
+ 'xmmssclwbd',
+ 'xmmssclwbs',
+ 'xmmstack',
+ 'xmmstackob',
+ 'xmmt2flare',
+ 'xmmvaragn',
+ 'xmmxassist',
+ 'xms',
+ 'xray',
+ 'xrayselbll',
+ 'xrbcat',
+ 'xshzagncxo',
+ 'xteao',
+ 'xteasmlong',
+ 'xteassagn',
+ 'xteasscat',
+ 'xteindex',
+ 'xtemaster',
+ 'xtemlcat',
+ 'xteslew',
+ 'xwas',
+ 'zcat',
+ 'zwclusters',
+ 'zzbib',
+]