From 9689906d70cfe3305cff9dbdd9dbe876e5b27a01 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Fri, 20 Oct 2023 14:52:19 +0000 Subject: [PATCH 001/128] fix manual workflow [CE-314] --- .github/workflows/manual.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index 18cbb09b..b4e06952 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: jobs: test: - uses: ./.github/workflows/reusable_test-crats.yml + uses: ./.github/workflows/reusable_test.yml build-push: needs: test uses: ./.github/workflows/reusable_build-push.yml From 384a8a9623be1498b0b39b8d3459f0ea66748d81 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Fri, 20 Oct 2023 14:58:18 +0000 Subject: [PATCH 002/128] a little bit of cleanup [CE-314] --- .gitignore | 1 + .../Notifications/Notifications.css | 174 ----------- .../Notifications/Notifications.tsx | 128 --------- .../Notifications/NotificationsMain.tsx | 270 ------------------ react-app-todo/Notifications/readme.md | 32 --- react-app-todo/SystemAlertBanner/data.tsx | 160 ----------- react-app-todo/SystemAlertBanner/style.css | 60 ---- react-app-todo/SystemAlertBanner/view.tsx | 230 --------------- react-app-todo/SystemAlertToggle/data.js | 201 ------------- react-app-todo/SystemAlertToggle/style.css | 12 - react-app-todo/SystemAlertToggle/view.js | 116 -------- react-app-todo/services/feeds.ts | 165 ----------- react-app-todo/session.ts | 210 -------------- 13 files changed, 1 insertion(+), 1758 deletions(-) delete mode 100644 react-app-todo/Notifications/Notifications.css delete mode 100644 react-app-todo/Notifications/Notifications.tsx delete mode 100644 react-app-todo/Notifications/NotificationsMain.tsx delete mode 100644 react-app-todo/Notifications/readme.md delete mode 100644 react-app-todo/SystemAlertBanner/data.tsx delete mode 100644 react-app-todo/SystemAlertBanner/style.css delete mode 100644 react-app-todo/SystemAlertBanner/view.tsx delete mode 100644 react-app-todo/SystemAlertToggle/data.js delete mode 100644 react-app-todo/SystemAlertToggle/style.css delete mode 100644 react-app-todo/SystemAlertToggle/view.js delete mode 100644 react-app-todo/services/feeds.ts delete mode 100644 react-app-todo/session.ts diff --git a/.gitignore b/.gitignore index 20bcc427..e52b8570 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ yarn.lock # /react-app/public/data # !/react-app/public/data/README.md _working/ +_todo/ # General purpose temp directory /temp/* diff --git a/react-app-todo/Notifications/Notifications.css b/react-app-todo/Notifications/Notifications.css deleted file mode 100644 index a87f994d..00000000 --- a/react-app-todo/Notifications/Notifications.css +++ /dev/null @@ -1,174 +0,0 @@ -.Notifications { - position: relative; - display: inline-block; - height: 100%; - vertical-align: top; - border: 1px silver solid; - font-size: 90%; - width: 80px -} - -.Notifications .-summary { - cursor: pointer; - font-size: 10px; - padding: 0; - margin: 0; -} - -.Notifications .-summary .-item { - padding: 0; - margin: 0; -} - -.Notifications .-summary .-item>.-count { - display: inline-block; - width: 30%; - text-align: right; - padding-right: 3px; - line-height: 1 -} - -.Notifications .-summary .-item>.-label { - display: inline-block; - width: 60%; -} - -.Notifications .-container { - background-color: white; - position: absolute; - top: 0; - left: 0; -} - -.Notifications .-notification-set { - padding: 3px; - position: relative; - background-color: silver; - - position: absolute; - top: 0px; - right: 20px; - z-index: 100; - width: 200px; - text-align: center -} - -.Notifications .-notification-set .-triangle { - position: absolute; - top: -3px; - left: 196px; - font-size: 25px; - color: silver; -} - -.Notifications .-notification-set .-pointer { - position: absolute; - top: 0px; - left: 200px; - height: 25px; - width: 25px; -} - -.Notifications .-notification-set .-notifications-container { - max-height: 50vh; - overflow-y: auto; - overflow-x: hidden; - text-align: left; -} - -.Notifications .-notification { - padding: 4px; - color: black; - margin: 2px; - position: relative; -} - -.Notifications .-notification .-message { - padding-right: 1em; -} - -.Notifications a.-button { - padding: 0 4px; - background-color: rgba(255, 255, 255, 0.5); - color: black; - user-select: none; -} - -.Notifications .-notification a.-close-button .fa::before { - color: rgb(143, 46, 46); -} - -.Notifications .-notification a.-close-button { - position: absolute; - right: 2px; - top: 2px; -} - -.Notifications a.-button { - text-decoration: none; - color: black; -} - -.Notifications a.-button:hover, -.Notifications a.-button:hover { - color: black; -} - -.Notifications a.-button:hover, -.Notifications a.-button:active { - background-color: rgba(255, 255, 255, 1); - color: black; -} - - -/* new */ - -.Notifications .-notification.-success { - /* bootstrap is dff0d8 */ - background-color: #dff0d8; -} - -.Notifications .-notification.-success:hover { - /* bootstrap is #c1e2b3 */ - background-color: #c1e2b3; -} - -.Notifications .-item.-success.-has-items { - background-color: #c1e2b3; -} - -.Notifications .-notification.-info { - background-color: #d9edf7; -} - -.Notifications .-notification.-info:hover { - background-color: #afd9ee; -} - -.Notifications .-item.-info.-has-items { - background-color: #afd9ee; -} - -.Notifications .-notification.-warning { - background-color: #fcf8e3; -} - -.Notifications .-notification.-warning:hover { - background-color: #f7ecb5; -} - -.Notifications .-item.-warning.-has-items { - background-color: #f7ecb5; -} - -.Notifications .-notification.-error { - background-color: #f2dede; -} - -.Notifications .-notification.-error:hover { - background-color: #e4b9b9; -} - -.Notifications .-item.-error.-has-items { - background-color: #e4b9b9; -} \ No newline at end of file diff --git a/react-app-todo/Notifications/Notifications.tsx b/react-app-todo/Notifications/Notifications.tsx deleted file mode 100644 index 373539ce..00000000 --- a/react-app-todo/Notifications/Notifications.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import { Component } from 'react'; -import './Notifications.css'; -// define([ -// 'preact', -// 'htm', - -// 'css!./Notifications.css' -// ], ( -// preact, -// htm -// ) => { - -export interface NotificationsProps { - closeNotifications: () => void; -} - -interface NotificationsState { - -} - - -export default class Notifications extends Component { - renderSummaryItem(name: string) { - const summary = this.props.summary[name]; - const activeClass = summary ? ' -has-items' : ''; - return
-
- ${summary} -
-
- ${name} -
-
- } - - renderSummary() { - return
- {this.renderSummaryItem('success')} - {this.renderSummaryItem('info')} - {this.renderSummaryItem('warning')} - {this.renderSummaryItem('error')} -
- } - - doCloseNotifications() { - this.props.closeNotifications(); - } - - doClearNotification(notification) { - this.props.clearNotification(notification); - } - - doToggleNotifications() { - this.props.toggleNotifications(); - } - - renderNotifications() { - return this.props.notifications.map((notification) => { - const typeClass = (() => { - switch (notification.type) { - case 'success': return '-success'; - case 'info': return '-info'; - case 'warning': return '-warning'; - case 'error': return '-error'; - } - })(); - return
- -
- ${notification.message} -
-
- }); - } - - renderNotificationDisplay() { - const activeStyle = (this.props.show ? ' -active' : ''); - return
-
-
- - - - -
- -
- ${this.renderNotifications()} -
-
-
- `; - } - - render() { - if (!this.props.notifications || this.props.notifications.length === 0) { - return; - } - return html` -
- ${this.renderSummary()} - ${this.renderNotificationDisplay()} -
- `; - } -} \ No newline at end of file diff --git a/react-app-todo/Notifications/NotificationsMain.tsx b/react-app-todo/Notifications/NotificationsMain.tsx deleted file mode 100644 index cf9851cd..00000000 --- a/react-app-todo/Notifications/NotificationsMain.tsx +++ /dev/null @@ -1,270 +0,0 @@ -import { Component } from 'react'; -import uuid from 'uuid'; - -// define([ -// 'preact', -// 'htm', -// 'uuid', -// './Notifications' -// ], ( -// preact, -// htm, -// {v4: uuidv4}, -// Notifications -// ) => { - -// const {h, Component} = preact; -// const html = htm.bind(h); - -const AUTODISMISSER_INTERVAL = 1000; - -export class Notification { - id: String; - constructor({ notification, parent }) { - const newNotification = notification; - this.id = newNotification.id || uuid.v4(); - this.message = newNotification.message; - this.description = newNotification.description; - this.autodismiss = newNotification.autodismiss; - this.icon = newNotification.icon; - this.autodismissStartedAt = newNotification.autodismiss - ? new Date().getTime() - : null; - this.type = newNotification.type; - this.parent = parent; - - // this.type.subscribeChanged((newVal, oldVal) => { - // this.parent.summary[oldVal].count(this.parent.summary[oldVal].count() - 1); - // this.parent.summary[newVal].count(this.parent.summary[newVal].count() + 1); - // }); - - // this.autodismiss.subscribe((newVal) => { - // if (newVal) { - // // TODO: this - // this.autodismissStartedAt = new Date().getTime(); - // this.parent.startAutoDismisser(); - // } - // }); - } -} - -class AutoDismisser { - constructor({ runner }) { - this.runner = runner; - } - - run() { - if (this.runner()) { - this.loop(); - } - } - - loop() { - this.autoDismisser = window.setTimeout(() => { - this.run(); - }, AUTODISMISSER_INTERVAL); - } - - startLoop(force) { - if (this.autoDismisser && !force) { - return; - } - this.run(); - } -} - -export default class NotificationsMain extends Component { - constructor(props) { - super(props); - - this.runtime = this.props.runtime; - this.sendingChannel = uuidv4(); - this.autoDismisser = new AutoDismisser({ - runner: this.autodismissRunner.bind(this), - }); - - this.state = { - notifications: [], - summary: { - info: 0, - success: 0, - warning: 0, - error: 0, - }, - show: false, - }; - } - - closeNotifications() { - this.setState({ - show: false, - }); - } - - showNotifications() { - this.setState({ - show: true, - }); - } - - toggleNotifications() { - this.setState({ - show: !this.state.show, - }); - } - - autodismissRunner() { - const toRemove = []; - const now = new Date().getTime(); - let autodismissLeft = 0; - this.state.notifications.forEach((item) => { - if (item.autodismiss) { - const elapsed = now - item.autodismissStartedAt; - if (item.autodismiss < elapsed) { - toRemove.push(item); - } else { - autodismissLeft += 1; - } - } - }); - - toRemove.forEach((item) => { - this.removeNotification(item); - }); - - // Return true to keep on truckin' - return autodismissLeft > 0; - } - - componentDidMount() { - this.runtime.send('notification', 'ready', { - channel: this.sendingChannel, - }); - - this.runtime.receive(this.sendingChannel, 'new', (message) => { - this.processMessage(message); - }); - } - - // TODO: without observables, we need to force the - // component to update when the notification is modified. - updateNotification(newMessage) { - const { summary, notifications } = this.state; - - const notification = notifications.filter((notification) => { - return notification.id === newMessage.id; - })[0]; - - if (!notification) { - // console.error('Cannot update message, not found: ' + newMessage.id, newMessage); - // return; - return false; - } - - if (notification.type !== newMessage.type) { - summary[notification.type] -= 1; - summary[newMessage.type] += 1; - } - - notification.type = newMessage.type; - notification.message = newMessage.message; - notification.autodismiss = newMessage.autodismiss; - if (newMessage.autodismiss) { - notification.autodismissStartedAt = new Date().getTime(); - } - - this.setState( - { - notifications, - summary, - }, - () => { - this.autoDismisser.run(); - } - ); - - return true; - } - - addNotification(newMessage) { - const notification = new Notification({ - notification: newMessage, - parent: this, - }); - const { summary, notifications } = this.state; - // const summaryItem = summary[notification.type]; - // if (summaryItem) { - // summaryItem.count += 1; - // } - - summary[notification.type] += 1; - - notifications.unshift(notification); - // this.notificationMap[notification.id] = notification; - this.setState({ - notifications, - summary, - }); - } - - removeNotification(notificationToRemove) { - const { summary, notifications: currentNotifications } = this.state; - const notifications = currentNotifications.filter((notification) => { - return notification.id !== notificationToRemove.id; - }); - // const summaryItem = summary[notificationToRemove.type]; - // if (summaryItem) { - // summaryItem.count -= 1; - // } - - summary[notificationToRemove.type] -= 1; - - this.setState({ - notifications, - summary, - }); - } - - clearNotification(notification) { - this.removeNotification(notification); - } - - processMessage(message) { - if (!message.type) { - console.error('Message not processed - no type', message); - return; - } - if ( - ['success', 'info', 'warning', 'error'].indexOf(message.type) === -1 - ) { - console.error('Message not processed - invalid type', message); - return; - } - - if (!this.updateNotification(message)) { - this.addNotification(message); - } - this.setState({ - show: true, - }); - } - - render() { - const props = { - notifications: this.state.notifications, - summary: this.state.summary, - show: this.state.show, - closeNotifications: this.closeNotifications.bind(this), - toggleNotifications: this.toggleNotifications.bind(this), - clearNotification: this.clearNotification.bind(this), - }; - return html` -
- <${Notifications} ...${props} /> -
- `; - } -} diff --git a/react-app-todo/Notifications/readme.md b/react-app-todo/Notifications/readme.md deleted file mode 100644 index 9e72ccc2..00000000 --- a/react-app-todo/Notifications/readme.md +++ /dev/null @@ -1,32 +0,0 @@ -Allows ui components to provide a notification to the user. - -Notifications are classified as info, warn, and error. - -Notifications are displayed as soon as the are received, and may be removed, or the container closed. - -Notification counts are displayed in the title bar until the notification is dismissed. - -Notifications are displayed in a container per type, closing the container does not remove the notification. - -Some notifications will auto-remove themselves after a period of time, because it is annoying to have to dismiss informational alerts. - -Notifications do though have a history which will reveal recently dismissed notifiations. - -Receives notification messages at ('notification', 'add', ) - -Notifications have ids. A notification received with the same id will update the notification and force it to be displayed. - -A notification looks like this: - -id: string -type: string (info, warn, error) -icon: string (a font awesome icon name -- the part of the class name following the "fa-") -title: string -description: string -dismissable: boolean -autodismiss: integer (time until auto dismiss) - -Implementation - -Notifications are implemented via a knockout viewmodel. -Subscriptions are via our mini-pub-sub system since it is included in the runtime available to all widgets via the runtime parameter (or in the global env sometimes) diff --git a/react-app-todo/SystemAlertBanner/data.tsx b/react-app-todo/SystemAlertBanner/data.tsx deleted file mode 100644 index be071091..00000000 --- a/react-app-todo/SystemAlertBanner/data.tsx +++ /dev/null @@ -1,160 +0,0 @@ -// define([ -// 'preact', -// 'htm', -// 'kb_lib/poller', -// './view', -// 'css!./style.css' -// ], ( -// preact, -// htm, -// poller, -// SystemAlertBanner -// ) => { -import { Component } from 'react'; -import Poller, { Job, Task } from '../../lib/poller'; -import SystemAlertBanner from './view'; - -// const {h, Component } = preact; -// const html = htm.bind(h); - -const POLL_INTERVAL = 10000; - -export default class LoadNotificationsJob extends Job { - callback: () => void; - constructor({ callback }: { callback: () => void }) { - super({ - description: 'Load notifications', - }); - this.callback = callback; - // this.state = { - // alerts: null, - // showAlertBanner: false, - // error: null - // }; - } - run() { - return this.callback(); - } -} - -export interface Alert {} - -export interface SystemAlertsDataProps {} - -interface SystemAlertsDataState { - showAlertBanner: boolean; - alerts: Array; - error: string | null; - hideAlerts: boolean; -} - -export class SystemAlertData extends Component< - SystemAlertsDataProps, - SystemAlertsDataState -> { - newAlertsPoller: Poller; - constructor(props: SystemAlertsDataProps) { - super(props); - this.newAlertsPoller = this.setupPolling(); - this.state = { - showAlertBanner: false, - hideAlerts: true, - alerts: [], - error: null, - }; - } - - setupPolling() { - const job = new LoadNotificationsJob({ - callback: () => { - this.loadNotifications(); - }, - }); - - const task = new Task({ - interval: POLL_INTERVAL, - runInitially: true, - }); - task.addJob(job); - - return new Poller({ task }); - } - - componentDidMount() { - this.newAlertsPoller.start(); - - // TODO: the system alert should be a ui service, probably is, - // hook it up here... - - // this.props.runtime.receive('system-alert', 'toggle-banner', () => { - // this.setState({ - // showAlertBanner: !this.state.showAlertBanner, - // }); - // }); - // this.props.runtime.receive('system-alert', 'close-banner', () => { - // this.setState({ - // showAlertBanner: true, - // }); - // }); - // this.props.runtime.receive('system-alert', 'open-banner', () => { - // this.setState({ - // showAlertBanner: false, - // }); - // }); - } - - getActiveAlerts() { - return Promise.resolve([ - { - type: 'maintenance', - title: 'Maintenance sample 1', - startAt: new Date(), - endAt: new Date(Date.now() + 1000 * 60 * 60), - read: false, - }, - { - type: 'maintenance', - title: 'Maintenance sample 2', - startAt: new Date(Date.now() + 1000 * 60 * 60), - endAt: new Date(Date.now() + 1000 * 60 * 60 * 2), - read: false, - }, - ]); - // const client = this.props.runtime.service('rpc').newClient({ - // module: 'UIService' - // }); - - // return client.callFunc('get_active_alerts', []) - // .then(([result]) => { - // return result; - // }); - } - - loadNotifications() { - return this.getActiveAlerts() - .then((data) => { - this.setState({ - alerts: data, - error: null, - }); - }) - .catch((err) => { - console.error('ERROR', err); - this.setState({ - alerts: [], - error: err.message, - }); - }); - } - - render() { - if (this.state.showAlertBanner) { - const props = { - // runtime: this.props.runtime, - alerts: this.state.alerts, - hideAlerts: this.state.hideAlerts, - }; - return ; - } - } -} diff --git a/react-app-todo/SystemAlertBanner/style.css b/react-app-todo/SystemAlertBanner/style.css deleted file mode 100644 index 281710b6..00000000 --- a/react-app-todo/SystemAlertBanner/style.css +++ /dev/null @@ -1,60 +0,0 @@ -.SystemAlert {} - -.SystemAlert .wrapper { - margin: 4px 10px 10px 10px; - box-shadow: 4px 4px 4px silver; -} - -.SystemAlert .itemsWrapper { - border: 2px #f2dede solid; -} - -.SystemAlert .title1 { - background-color: rgba(169, 68, 68, 1); - color: white; -} - -.SystemAlert .title2 { - background-color: white; - color: rgba(169, 68, 68, 1); -} - -.SystemAlert .-header { - padding: 10px 15px; - position: relative; - display: flex; - flex-direction: row -} - -.SystemAlert .-alert { - border-radius: 0; - margin-bottom: 0; - border-top: 2px solid #f2dede; -} - -.SystemAlert .-alert>.-row { - display: flex; - flex-direction: row; -} - -.SystemAlert .-alert>.-row>.-col1 { - flex: 1 1 0px; - padding: 4px; - display: flex; - flex-direction: column; - justify-content: center; -} - -.SystemAlert .-alert>.-row>.-col2 { - flex: 1 1 0px; - padding: 4px; - display: flex; - flex-direction: row; - align-items: center; -} - -.SystemAlert .-alert .-icon { - width: 1.5em; - font-size: 120%; - text-align: center; -} \ No newline at end of file diff --git a/react-app-todo/SystemAlertBanner/view.tsx b/react-app-todo/SystemAlertBanner/view.tsx deleted file mode 100644 index 21804365..00000000 --- a/react-app-todo/SystemAlertBanner/view.tsx +++ /dev/null @@ -1,230 +0,0 @@ -import UserProfileClient from '@kbase/ui-lib/lib/comm/coreServices/UserProfile'; -import { Component } from 'react'; - -import CountdownClock from '../CountdownClock'; - -// define([ -// 'preact', -// 'htm', -// '../CountdownClock', -// 'css!./style.css' -// ], ( -// preact, -// htm, -// CountdownClock -// ) => { - -// const {h, Component } = preact; -// const html = htm.bind(h); - -function plural(amount: number, singular: string, plural: string) { - if (amount === 1) { - return singular; - } - return plural; -} - -export interface AlertInfo { - startAt: number; - endAt: number; - title: string; - message: string; - hash: string; - now: number; -} - -export class Alert { - startAt: Date; - endAt: Date | null; - title: string; - message: string; - hash: string; - now: number; - read: boolean; - showMessage: boolean; - constructor({ startAt, endAt, title, message, hash, now }: AlertInfo) { - this.startAt = new Date(startAt); - if (endAt === null || endAt === undefined) { - this.endAt = null; - } else { - this.endAt = new Date(endAt); - } - this.title = title; - this.message = message; - this.hash = hash; - this.now = now; - - this.read = false; - this.showMessage = false; - - this.countdownToStart = (() => { - if (!this.now()) { - return null; - } - return this.startAt - this.now(); - })(); - - this.countdownToEnd = (() => { - if (!this.now()) { - return null; - } - if (this.endAt === null) { - return Infinity; - } - return this.endAt - this.now(); - })(); - } - - toggleMessage() { - this.showMessage(!this.showMessage()); - } -} - -export default class SystemAlertBanner extends Component { - constructor(props) { - super(props); - this.state = {}; - } - - componentDidMount() {} - - doShowHidden() { - // this.props.alerts.forEach((alert) => { - // alert.read(false); - // }); - } - - doHide() {} - - renderHiddenCount() { - if (!this.props.hiddenAlertCount) { - return; - } - return ( - - ${this.props.hiddenAlertCount})$ hidden - - - ); - } - - renderHeader() { - return ( -
-
- - System${' '} - {plural(this.props.alerts.length, 'Alert', 'Alerts')} - -
-
- {this.props.alerts.length}{' '} - {plural(this.props.alerts.length, 'alert', 'alerts')}{' '} - {this.renderHiddenCount()} - -
-
- ); - } - - renderAlertIcon(alert) { - const now = Date.now(); - const startsIn = alert.startAt - now; - const endsIn = alert.endsAt === null ? Infinity : alert.endsAt - now; - const iconClass = (() => { - if (startsIn > 0) { - return 'fa-clock-o'; - } else if (startsIn <= 0 && endsIn > 0) { - return 'fa-exclamation-triangle'; - } - })(); - const iconColor = (() => { - if (startsIn > 0) { - return 'fa-color-warning'; - } else if (startsIn <= 0 && endsIn > 0) { - return 'fa-color-danger'; - } - })(); - return ( - - - - ); - } - - renderAlert(alert) { - return ( -
-
-
-
- {alert.title || '** untitled **'} -
-
-
- {this.renderAlertIcon(alert)} -
- -
-
-
-
- ); - } - - renderAlerts() { - if ( - !this.props.alerts.some((alert) => { - return !alert.read; - }) - ) { - return; - } - const alerts = this.props.alerts.map((alert) => { - return this.renderAlert(alert); - }); - return
{alerts}
; - } - - renderAlertsPanel() { - if (this.props.alerts && this.props.alerts.length > 0) { - return ( -
- {this.renderHeader()} - {this.renderAlerts()} -
- ); - } - } - - render() { - return ( -
- {this.renderAlertsPanel()} -
- ); - } -} diff --git a/react-app-todo/SystemAlertToggle/data.js b/react-app-todo/SystemAlertToggle/data.js deleted file mode 100644 index ac3c8b6b..00000000 --- a/react-app-todo/SystemAlertToggle/data.js +++ /dev/null @@ -1,201 +0,0 @@ -define([ - 'bluebird', - 'knockout', - 'uuid', - '../../lib/searchApi', - 'yaml!../../data/stopWords.yml' -], function ( - Promise, - ko, - Uuid, - SearchAPI, - stopWordsDb -) { - 'use strict'; - - function isStopWord(word) { - if (stopWordsDb.warn.indexOf(word) >= 0) { - return true; - } - if (stopWordsDb.ignore.indexOf(word) >= 0) { - return true; - } - return false; - } - - // TODO: configure this somewhere - function isBlacklistedHighlightField(fieldName) { - return ['tags'].includes(fieldName); - } - - function encodeHTML(possibleHTML) { - const node = document.createElement('div'); - node.innerHTML = possibleHTML; - return node.innerText; - } - - - // For now, this fakes the search... - function factory(params) { - const maxSearchResults = params.maxSearchItems; - - const types = params.types; - - const searchConfig = { - // max number of search result items to hold in the buffer - // before we start removing those out of view - maxBufferSize: params.maxBufferSize || 100, - // number of search items to fetch at one time. - fetchSize: params.pageSize || 20 - }; - - function objectToViewModel(obj) { - const type = types.getTypeForObject(obj); - if (!type) { - console.error('ERROR cannot type object', obj); - throw new Error('Cannot type this object'); - } - - const icon = type.getIcon(type); - - const ref = type.getRef(); - const detail = type.detail(); - const detailMap = detail.reduce(function (m, field) { - m[field.id] = field; - return m; - }, {}); - - const matches = Object.keys(obj.highlight).reduce((matches, field) => { - if (isBlacklistedHighlightField(field)) { - console.warn('highlight field ' + field + ' ignored'); - return matches; - } - - let label = type.getSearchFieldLabel(field); - if (!label) { - label = field; - console.warn('highlight field ' + field + ' not found in type spec', obj); - } - - const emStart = new Uuid(4).format(); - const emFinish = new Uuid(4).format(); - - matches - .push({ - id: field, - label: label, - highlights: obj.highlight[field] - .map((highlight) => { - const safe1 = highlight.replace('', emStart).replace('', emFinish); - const safe2 = encodeHTML(safe1); - const safe3 = safe2.replace(emStart, '').replace(emFinish, ''); - return { - highlight: safe3 - }; - }) - }); - return matches; - }, []); - - // Uncomment to re-enable highlights merging into details - // detail.forEach(function (field) { - // if (matchMap[field.id]) { - // field.highlights = matchMap[field.id].highlights; - // } - // }); - - const vm = { - type: { - id: obj.type, - label: type.getLabel(), - icon: icon - }, - // TODO: I don't remember why I named this "matchClass", but it confuses me now. - matchClass: { - id: type.getUIClass(), - copyable: type.isCopyable(), - viewable: type.isViewable(), - ref - }, - - // Detail, type-specific - detail: detail, - - url: window.location.origin + '#dataview/' + ref.workspaceId + '/' + ref.objectId + '/' + ref.version, - - // should be different per object type? E.g. narrative - nice name, others object name?? - // Generic fields - name: obj.object_name, - date: new Date(obj.modified_at), - scientificName: detailMap.scientificName ? detailMap.scientificName.value || '' : '', - - matches: matches, - selected: ko.observable(), - showMatches: ko.observable(false), - showDetails: ko.observable(false), - active: ko.observable(false) - }; - return vm; - } - - function search(query) { - const searchApi = SearchAPI.make({ - runtime: params.runtime - }); - return Promise.all([ - searchApi.referenceObjectSearch({ - query: query.terms.join(' '), - page: query.start || 0, - pageSize: searchConfig.fetchSize - }), - searchApi.typeSearch({ - query: query.terms.join(' '), - withPrivateData: 0, - withPublicData: 1, - dataSource: 'referenceData' - }) - ]) - .then(([objectResults, typeResults]) => { - const objects = objectResults.objects.map((object) => { - return objectToViewModel(object); - }); - const totalByType = Object.keys(typeResults.type_to_count).map(function (typeName) { - return { - id: typeName.toLowerCase(), - count: typeResults.type_to_count[typeName] - }; - }); - let totalSearchHits; - if (objectResults.total > maxSearchResults) { - totalSearchHits = maxSearchResults; - } else { - totalSearchHits = objectResults.total; - } - return { - items: objects, - first: query.start, - isTruncated: true, - summary: { - totalByType: totalByType, - totalSearchHits: totalSearchHits, - totalSearchSpace: objectResults.total, - isTruncated: totalSearchHits < objectResults.total - }, - stats: { - objectSearch: objectResults.search_time, - typeSearch: typeResults.search_time - } - }; - }); - } - - return { - search, - isStopWord - }; - } - - return { - make: factory - }; -}); diff --git a/react-app-todo/SystemAlertToggle/style.css b/react-app-todo/SystemAlertToggle/style.css deleted file mode 100644 index 27ff300a..00000000 --- a/react-app-todo/SystemAlertToggle/style.css +++ /dev/null @@ -1,12 +0,0 @@ -.SystemAlertToggle {} - -.SystemAlertToggle .-button { - border: 1px silver solid; - padding: 3px; - margin: 2px; - cursor: pointer -} - -.SystemAlertToggle .-button:hover { - background-color: rgba(200, 200, 200, 0.5); -} \ No newline at end of file diff --git a/react-app-todo/SystemAlertToggle/view.js b/react-app-todo/SystemAlertToggle/view.js deleted file mode 100644 index 7a1ee0c1..00000000 --- a/react-app-todo/SystemAlertToggle/view.js +++ /dev/null @@ -1,116 +0,0 @@ -define([ - 'preact', - 'htm' -], ( - preact, - htm -) => { - - const {h, Component } = preact; - const html = htm.bind(h); - - function plural(amount, singular, plural) { - if (amount === 1) { - return singular; - } - return plural; - } - - class SystemAlertToggle extends Component { - constructor(props) { - super(props); - } - - componentDidMount() { - } - - doToggle() { - this.props.runtime.send('system-alert', 'toggle-banner'); - } - - renderAlertCount() { - if (this.props.alerts && this.props.alerts.length > 0) { - return html` - ${this.props.alerts.length} - ${' '}${plural(this.props.alerts.length, 'alert', 'alerts')} - `; - } else { - return 'no alerts'; - } - } - - renderPresentAlerts() { - if (this.props.summary.present === 0) { - return; - } - return html` -
- -
- `; - } - - renderFutureAlerts() { - if (this.props.summary.future === 0) { - return; - } - return html` -
- -
- `; - } - - doClose() { - this.props.runtime.send('system-alert', 'close-banner'); - } - - renderSummary() { - if (!this.props.alerts || this.props.alerts.length === 0) { - return html` -
- -
- `; - } - - if (!this.props.summary) { - return; - } - return html` - - ${this.renderPresentAlerts()} - ${this.renderFutureAlerts()} - `; - } - - renderButton() { - // - return html` -
-
- ${this.renderAlertCount()} - ${this.renderSummary()} -
-
- `; - } - - render() { - // // We only show the toggle when - // if (!this.props.hideAlerts) { - // return; - // } - return html` -
- ${this.renderButton()} -
- `; - } - } - - return SystemAlertToggle; -}); \ No newline at end of file diff --git a/react-app-todo/services/feeds.ts b/react-app-todo/services/feeds.ts deleted file mode 100644 index 3025dd96..00000000 --- a/react-app-todo/services/feeds.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { DataState } from '../lib/DataState'; -import { Feeds } from '../lib/kb_lib/comm/coreServices/Feeds'; -import { tryPromise } from '../lib/kb_lib/Utils'; -import { Runtime } from '../lib/runtime'; -import { Config } from '../types/config'; - -const MONITORING_INTERVAL = 10000; - -interface FeedsServiceParams { - // params: { - // runtime: Runtime; - // }; - runtime: Runtime; - config: Config; -} - -export interface FeedsNotification { - unseenNotificationsCount?: number; - error?: string; -} - -export default class FeedsService { - runtime: Runtime; - monitoringInterval: number; - monitorRunning: boolean; - monitoringRunCount: number; - monitoringErrorCount: number; - disabled: boolean; - monitoringTimer: number | null; - state: DataState; - - constructor({ config, runtime }: FeedsServiceParams) { - this.runtime = runtime; - - // TODO: move to service config. - this.monitoringInterval = MONITORING_INTERVAL; - - this.monitorRunning = false; - this.monitoringRunCount = 0; - this.monitoringErrorCount = 0; - this.monitoringTimer = null; - - this.disabled = config.ui.coreServices.disabled.includes('Feeds'); - - this.state = new DataState({}); - } - - start() { - return tryPromise(() => { - this.runtime.db().set('feeds', { - notifications: null, - error: null, - }); - - if (this.disabled) { - console.warn( - 'Feeds service disabled; skipping monitoring hooks' - ); - return; - } - - // listen for login and out events... - this.runtime.on('session', 'loggedin', () => { - this.startFeedsMonitoring(); - }); - - this.runtime.on('session', 'loggedout', () => { - this.stopFeedsMonitoring(); - }); - - // if logged in, populate and start monitoring for feeds notifications - if (this.runtime.service('session').getAuthToken()) { - return this.startFeedsMonitoring(); - } - }); - } - - stop() { - return tryPromise(() => { - this.stopFeedsMonitoring(); - }); - } - - startFeedsMonitoring() { - if (this.monitorRunning) { - return; - } - this.monitorRunning = true; - this.monitoringLoop(); - } - - monitoringLoop() { - if (this.monitoringTimer) { - return; - } - - const monitoringJob = () => { - const feedsClient = new Feeds({ - url: this.runtime.config('services.Feeds.url', null), - token: this.runtime.service('session').getAuthToken(), - }); - return feedsClient - .getUnseenNotificationCount() - .then(({ unseen: { global, user } }) => { - const currentUnseen = global + user; - - // are notifications different than the last time? - const unseenNotificationsCount = this.runtime - .db() - .get('feeds.unseenNotificationsCount', 0); - - if (unseenNotificationsCount === currentUnseen) { - return; - } - - this.runtime.db().set('feeds', { - unseenNotificationsCount: currentUnseen, - error: null, - }); - }) - .catch((err) => { - console.error('ERROR', err.message); - this.runtime.db().set('feeds', { - error: err.message, - }); - }); - }; - - const loop = () => { - this.monitoringTimer = window.setTimeout(() => { - monitoringJob() - .then(() => { - this.monitoringRunCount += 1; - if (this.monitorRunning) { - loop(); - } - }) - .catch((err) => { - this.monitoringErrorCount += 1; - console.error('ERROR', err); - }); - }, this.monitoringInterval); - }; - - monitoringJob() - .then(() => { - loop(); - }) - .catch((err) => { - console.error('Error', err); - }); - } - - stopFeedsMonitoring() { - this.monitorRunning = false; - if (this.monitoringTimer !== null) { - window.clearTimeout(this.monitoringTimer); - } - this.monitoringTimer = null; - } - - // pluginHandler() {} -} - -export const ServiceClass = FeedsService; diff --git a/react-app-todo/session.ts b/react-app-todo/session.ts deleted file mode 100644 index 2c9a9e11..00000000 --- a/react-app-todo/session.ts +++ /dev/null @@ -1,210 +0,0 @@ -// define([ -// 'lib/kb_lib/Auth2Session', -// 'kb_lib/observed', -// 'kb_lib/html' -// ], ( -// { Auth2Session }, -// Observed, -// html -// ) => { -// const t = html.tag, -// div = t('div'), -// p = t('p'), -// a = t('a'); - -import { Auth2Session, CookieConfig } from '../lib/kb_lib/Auth2Session'; -import { Observed } from '../lib/kb_lib/observed'; -import { Runtime } from '../lib/runtime'; -import { Config } from '../types/config'; - -export interface SessionServiceState { - loggedIn: boolean; -} - -export class SessionService { - runtime: Runtime; - extraCookies: Array; - auth2Session: Auth2Session; - state: Observed; - constructor(runtime: Runtime, config: Config) { - this.runtime = runtime; - this.extraCookies = []; - if (config.ui.services.session.cookie.backup.enabled) { - this.extraCookies.push({ - name: config.ui.services.session.cookie.backup.name, - domain: config.ui.services.session.cookie.backup.domain, - }); - } - this.auth2Session = new Auth2Session({ - cookieName: config.ui.services.session.cookie.name, - extraCookies: this.extraCookies, - baseUrl: config.services.Auth2.url, - }); - - this.state = new Observed(null); - } - - getAuthToken() { - return this.auth2Session.getToken(); - } - - getUsername() { - return this.auth2Session.getUsername(); - } - - getEmail() { - return this.auth2Session.getEmail(); - } - - getRealname() { - return this.auth2Session.getRealname(); - } - - getRoles() { - return this.auth2Session.getRoles() || []; - } - - getCustomRoles() { - return this.auth2Session.getCustomRoles() || []; - } - - getTokenInfo() { - return this.auth2Session.getTokenInfo(); - } - - getMe() { - return this.auth2Session.getMe(); - } - - isLoggedIn() { - return this.auth2Session.isLoggedIn(); - } - - isAuthorized() { - return this.auth2Session.isAuthorized(); - } - - isAuthenticated() { - return this.auth2Session.isAuthorized(); - } - - getKbaseSession() { - return this.auth2Session.getKbaseSession(); - } - - getLastProvider() { - return this.auth2Session.getLastProvider(); - } - - getProviders() { - return this.auth2Session.getClient().getProviders(); - } - - // Session state change - loginStart(arg) { - // starts an auth login / signup redirect loop - // it _could_ be done inside an iframe ... - this.auth2Session.loginStart(arg); - } - - logout() { - return this.auth2Session.logout().then((result) => { - return result; - }); - } - - notifyError(message) { - this.runtime.send('ui', 'alert', { - type: 'warning', - message: message.message, - description: message.description, - icon: 'exclamation-triangle', - name: 'auth-connection', - }); - } - - notifyOk(message) { - this.runtime.send('ui', 'alert', { - type: 'success', - message: message.message, - description: message.description, - icon: 'check', - name: 'auth-connection', - timeout: 10000, - }); - } - - start() { - return this.auth2Session.start().then(() => { - if (this.auth2Session.isAuthorized()) { - this.state.setItem('loggedin', true); - this.runtime.send('session', 'loggedin'); - } else { - this.state.setItem('loggedin', false); - this.runtime.send('session', 'loggedout'); - } - this.auth2Session.onChange((change) => { - this.runtime.send('session', 'change', { - state: change, - }); - switch (change) { - case 'interrupted': - var description = div([ - p( - 'Your session cannot be verified because the authorization service is currently inaccessible' - ), - p([ - "You may patiently await it's recovery or ", - a( - { - href: '/#signout', - }, - 'signout' - ), - ' and try again later', - ]), - ]); - this.notifyError({ - message: 'Session cannot be verified', - description: description, - }); - return; - case 'restored': - this.notifyOk({ - message: - 'Communication restored -- session has been verified', - description: '', - }); - } - if (this.auth2Session.isAuthorized()) { - if (change === 'newuser') { - // TODO: do something special... - } - this.state.setItem('loggedin', true); - this.runtime.send('session', 'loggedin'); - } else { - this.state.setItem('loggedin', false); - this.runtime.send('session', 'loggedout'); - } - }); - }); - } - - stop() { - return this.auth2Session.stop().then(() => { - // session = null; - }); - } - - onChange(fun) { - this.state.listen('loggedin', { - onSet: (value) => { - fun(value); - }, - }); - } - - getClient() { - return this.auth2Session; - } -} From 09afc23306fe4f354029e3f4d9d2535a96385bfa Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Fri, 20 Oct 2023 21:00:29 +0000 Subject: [PATCH 003/128] a few updates to work better w/integration tests [CE-314] --- vite-app/src/components/Body.tsx | 2 +- vite-app/src/components/Signin/Signin.tsx | 4 ++-- vite-app/src/components/Title.module.css | 1 + vite-app/src/components/Title.tsx | 6 +++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/vite-app/src/components/Body.tsx b/vite-app/src/components/Body.tsx index 8f013947..7a9f449c 100644 --- a/vite-app/src/components/Body.tsx +++ b/vite-app/src/components/Body.tsx @@ -349,7 +349,7 @@ export default class Body extends Component { // Samples new Route( 'samples/view/:sampleId/:sampleVersion?', - { authenticationRequired: true }, + { authenticationRequired: false }, (props: RouteProps) => { return ( { renderAvatar(userProfile: UserProfile) { const avatarURL = this.renderAvatarUrl(userProfile); - return ( {`Avatar @@ -80,7 +80,7 @@ export default class Signin extends Component { renderLoggedIn(authState: AuthenticationStateAuthenticated) { return ( - + {this.renderAvatar(authState.userProfile)} diff --git a/vite-app/src/components/Title.module.css b/vite-app/src/components/Title.module.css index ca6575eb..c6b8828f 100644 --- a/vite-app/src/components/Title.module.css +++ b/vite-app/src/components/Title.module.css @@ -4,4 +4,5 @@ overflow-x: hidden; text-overflow: ellipsis; white-space: nowrap; + margin: 0; } \ No newline at end of file diff --git a/vite-app/src/components/Title.tsx b/vite-app/src/components/Title.tsx index d605f061..d01651cd 100644 --- a/vite-app/src/components/Title.tsx +++ b/vite-app/src/components/Title.tsx @@ -5,7 +5,7 @@ export interface TitleProps { title: string; } -interface TitleState {} +interface TitleState { } export default class Title extends Component { constructor(props: TitleProps) { @@ -19,9 +19,9 @@ export default class Title extends Component { // Note that this allows html to be set in the title. This allows plugins to set // html. return ( -
+

{this.props.title} -

+ ); } } From 8fce761d80f1e1adc3f0b4f855181e20ea65c0a9 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Tue, 24 Oct 2023 14:10:33 -0700 Subject: [PATCH 004/128] support a base path [CE-315] wip - not finished yet, but much in place. --- .devcontainer/docker-compose.yml | 6 +- Dockerfile | 2 +- Taskfile | 2 +- config/README.md | 11 - deployment/templates/config.json.tmpl | 4 +- tools/deno/scripts/hello.ts | 29 -- tools/deno/scripts/install-plugin.ts | 8 - tools/deno/scripts/install-plugins.ts | 8 - tools/dockerize/docker-compose.yml | 1 + tools/dockerize/scripts/render-templates.sh | 1 + tools/proxy/contents/conf/nginx.conf.tmpl | 31 +- vite-app/index.html | 14 +- vite-app/package-lock.json | 239 +++++---- vite-app/package.json | 12 +- .../about/AboutKBaseUI/AboutKBaseUI.tsx | 4 +- .../NarrativeDetails/NarrativeHeader.tsx | 2 +- .../NarrativeDetails/ToolMenu/LinkOrgItem.tsx | 2 +- .../NarrativeDetails/cells/AppCell.tsx | 2 +- .../NarrativeDetails/cells/DataObjectCell.tsx | 6 +- .../components/NarrativeList/CategoryMenu.tsx | 4 +- .../NarrativeList/NarrativeList.tsx | 2 +- .../src/apps/ORCIDLink/continue/Error.tsx | 2 +- .../ORCIDLink/home/LinkPermissions/View.tsx | 2 +- vite-app/src/apps/ORCIDLink/home/View.tsx | 4 +- .../ORCIDLink/manage/linkingSessions/view.tsx | 6 +- .../apps/ORCIDLink/manage/queryLinks/view.tsx | 4 +- .../apps/ORCIDLink/manage/viewLink/view.tsx | 4 +- .../UserProfile/Profile/ProfileEditor.tsx | 2 +- .../apps/UserProfile/Profile/controller.tsx | 2 +- .../src/apps/UserProfile/SearchUsers/view.tsx | 2 +- vite-app/src/apps/gallery/index.tsx | 6 +- vite-app/src/components/HelpLinks.tsx | 8 +- .../NotFoundChecked/NotFoundChecked.tsx | 8 +- .../src/components/Signin/SigninButton.tsx | 2 +- vite-app/src/gtagSupport.ts | 467 ++++++++++++++++++ vite-app/src/lib/kb_lib/Auth2.ts | 1 + .../src/lib/kb_lib/comm/coreServices/Auth.ts | 1 + vite-app/vite.config-og.ts | 89 ++++ vite-app/vite.config.ts | 240 ++++++--- 39 files changed, 917 insertions(+), 323 deletions(-) delete mode 100644 tools/deno/scripts/hello.ts create mode 100644 vite-app/src/gtagSupport.ts create mode 100644 vite-app/vite.config-og.ts diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 62326960..13583fdb 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -44,7 +44,7 @@ services: environment: # - PORT=80 - DEPLOY_ENV=${DEPLOY_ENV:-ci} - # - BASE_PATH= + - BASE_PATH=${BASE_PATH} # Required for a devcontainer -- keeps the container running. # Don't worry, our main interaction with the container is through the # VSC terminal, which for a devcontainer opens a shell within the @@ -95,10 +95,10 @@ services: - 1.1.1.1 - 208.67.222.222 environment: - - BASE_PATH=/ + - BASE_PATH=${BASE_PATH} - # note that this is really a docker env file and is relative to the docker-compose file + # note that this is really aq docker env file and is relative to the docker-compose file # TODO: I think we may need to use an entrypoint which selects the deploy environment # config (env) file based on the DEPLOY_ENV. diff --git a/Dockerfile b/Dockerfile index 3ab6c674..41d2e210 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,4 +50,4 @@ ENTRYPOINT [ "dockerize" ] CMD [ \ "-template", "/kb/deployment/templates/nginx.conf.tmpl:/etc/nginx/nginx.conf", \ "-template", "/kb/deployment/templates/config.json.tmpl:/kb/deployment/app/deploy/config.json", \ - "bash", "/kb/deployment/scripts/start-server.bash" ] + "bash", "-x", "/kb/deployment/scripts/start-server.bash" ] diff --git a/Taskfile b/Taskfile index 94e3f31e..519b6ba8 100755 --- a/Taskfile +++ b/Taskfile @@ -108,7 +108,7 @@ function format { } function render-templates { - env DIR="${PWD}" ENV="${ENV:-ci}" DEFAULT_PATH="${DEFAULT_PATH}" bash tools/dockerize/scripts/render-templates.sh + env DIR="${PWD}" ENV="${ENV:-ci}" DEFAULT_PATH="${DEFAULT_PATH}" BASE_PATH="${BASE_PATH}" bash tools/dockerize/scripts/render-templates.sh } # Optional dev tooling: diff --git a/config/README.md b/config/README.md index 681b1747..0008911e 100644 --- a/config/README.md +++ b/config/README.md @@ -1,14 +1,3 @@ # Configuration This directory contains files necessary to configure kbase ui builds: - -```services.yml`` is a YAML file containing definitions of all service endpoints which need to be known to the ui. Most service endpoints are defined as template strings in which the base url is placeholder which is populated at runtime by the deployment configuration (more about that later.) - - -```npmInstall.yml``` is a YAML file containing declarative instructions for installing each and every package brought into the project via bower. - - -- ```builds``` - one file per named configuration set. -- ```deploy``` - classic KBase deploy configuration: service urls, target dirs, per KBase deploy environment. -- ```ui``` - ui build configurations -- ```bowerInstall``` - master file for importing bower packages into kbase module space. diff --git a/deployment/templates/config.json.tmpl b/deployment/templates/config.json.tmpl index aeeff4e5..ea647346 100644 --- a/deployment/templates/config.json.tmpl +++ b/deployment/templates/config.json.tmpl @@ -2,7 +2,7 @@ "deploy": { "id": "kbase-ui", "target": "/kb/deployment/app", - "basePath": "{{ default "" .Env.deploy_basepath }}", + "basePath": "{{ default "" .Env.BASE_PATH }}", "environment": "{{ .Env.deploy_environment }}", "displayEnvironment": {{ eq .Env.deploy_environment "prod" | ternary true false }}, "hostname": "{{ .Env.deploy_hostname }}", @@ -174,7 +174,7 @@ "defaults": { "path": { "type": "path", - "value": "{{ default "/narratives" .Env.DEFAULT_PATH }}" + "value": "{{ default "#about" .Env.DEFAULT_PATH }}" }, "hideHeader": {{ default "false" .Env.HIDE_HEADER }}, "hideNavigation": {{ default "false" .Env.HIDE_NAVIGATION }}, diff --git a/tools/deno/scripts/hello.ts b/tools/deno/scripts/hello.ts deleted file mode 100644 index 15a0dc97..00000000 --- a/tools/deno/scripts/hello.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Runner } from "./common.ts"; - - -async function main() { - // if (Deno.args.length !== 2) { - // log("Usage: git-info.ts "); - // Deno.exit(1); - // } - // const targetDir = Deno.args[0]; - // const destinationFile = Deno.args[1]; - - // log(`Getting git info from ${targetDir}`, "git-info.ts:main()"); - // log(`Saving git info info to ${destinationFile}`, "git-info.ts:main()"); - - // const info = await getGitInfo(targetDir); - // log(JSON.stringify(info, null, 4), "git-info.ts:main()"); - - // await Deno.writeFile( - // destinationFile, - // new TextEncoder().encode(JSON.stringify(info, null, 4)), - // ); - const runner = new Runner('/app'); - const result = await runner.run('cat', ['Taskfile']); - console.log('RESULT', result); -} - -if (import.meta.main) { - main(); -} diff --git a/tools/deno/scripts/install-plugin.ts b/tools/deno/scripts/install-plugin.ts index 088d59e2..cf9b0ff1 100644 --- a/tools/deno/scripts/install-plugin.ts +++ b/tools/deno/scripts/install-plugin.ts @@ -286,14 +286,6 @@ async function updatePluginManifest( log('done!', 'updatePluginManifest'); } -// async function savePluginManifest(path) { -// const root = state.environment.path; -// const configDest = root.concat(['build', 'client', 'modules', 'config']); -// const manifestPath = configDest.concat(['plugins-manifest.json']); -// await mutant.saveJson(manifestPath, state.pluginsManifest); -// return state; -// } - async function main() { if (Deno.args.length < 4) { log(`Incorrect number of args ${Deno.args.length}`) diff --git a/tools/deno/scripts/install-plugins.ts b/tools/deno/scripts/install-plugins.ts index 6242102b..677bde4d 100644 --- a/tools/deno/scripts/install-plugins.ts +++ b/tools/deno/scripts/install-plugins.ts @@ -307,14 +307,6 @@ async function generatePluginsManifest(uiConfig: string, source: string, dest: s log('done!', 'generatePluginsManifest'); } -// async function savePluginManifest(path) { -// const root = state.environment.path; -// const configDest = root.concat(['build', 'client', 'modules', 'config']); -// const manifestPath = configDest.concat(['plugins-manifest.json']); -// await mutant.saveJson(manifestPath, state.pluginsManifest); -// return state; -// } - async function main() { if (Deno.args.length < 3) { log(`Incorrect number of args ${Deno.args.length}`) diff --git a/tools/dockerize/docker-compose.yml b/tools/dockerize/docker-compose.yml index 2f064c0b..783f710e 100644 --- a/tools/dockerize/docker-compose.yml +++ b/tools/dockerize/docker-compose.yml @@ -6,6 +6,7 @@ services: container_name: dockerize dns: 8.8.8.8 environment: + - BASE_PATH - DEFAULT_PATH - HIDE_HEADER - HIDE_NAVIGATION diff --git a/tools/dockerize/scripts/render-templates.sh b/tools/dockerize/scripts/render-templates.sh index eba413e5..192cef29 100644 --- a/tools/dockerize/scripts/render-templates.sh +++ b/tools/dockerize/scripts/render-templates.sh @@ -3,6 +3,7 @@ echo "Rendering kbase-ui config file from template for environment '${ENV}' usin echo "Parameters (Environment Variables):" echo " ENV=${ENV}" echo " DIR=${DIR}" +echo " BASE_PATH=${BASE_PATH}" echo " DEFAULT_PATH=${DEFAULT_PATH}" echo " HIDE_HEADER=${HIDE_HEADER}" echo " HIDE_NAVIGATION=${HIDE_NAVIGATION}" diff --git a/tools/proxy/contents/conf/nginx.conf.tmpl b/tools/proxy/contents/conf/nginx.conf.tmpl index 30d18dfd..1bfe9664 100644 --- a/tools/proxy/contents/conf/nginx.conf.tmpl +++ b/tools/proxy/contents/conf/nginx.conf.tmpl @@ -153,12 +153,12 @@ http { return 413 "Request entity is too large (> 5GB)"; } - location /__ping__ { + location {{ .Env.BASE_PATH }}/__ping__ { default_type "text/html"; return 204; } - location /data/__perf__ { + location {{ .Env.BASE_PATH }}/data/__perf__ { gzip off; gunzip on; add_header Cache-Control 'no-cache, no-transform'; @@ -226,7 +226,7 @@ http { # proxy_pass https://kbase_navigator/narratives/; # {{ end }} - {{ if .Env.deploy_ui_hostname }} + {{ if .Env.deploy_ui_hostname }} proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; {{ else }} proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; @@ -252,6 +252,20 @@ http { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } + + # This one to handle legacy plugin /modules/plugins paths in dev + location / { + proxy_pass http://kbase_ui; + #proxy_set_header Cache-Control 'no-store'; + #proxy_set_header Cache-Control 'no-cache'; + #expires 0; + # proxy_set_header Connection ""; + # proxy_set_header Upgrade $http_upgrade; + # proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } } {{ end }} @@ -415,7 +429,7 @@ http { # host name as services. {{ if not .Env.deploy_ui_hostname }} - location /__ping__ { + location {{ .Env.BASE_PATH }}/__ping__ { default_type "text/html"; return 204; } @@ -492,6 +506,15 @@ http { proxy_set_header Connection $connection_upgrade; } + # legacy plugins + location / { + proxy_pass http://kbase_ui; + proxy_set_header Connection ""; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } + {{ end }} } } \ No newline at end of file diff --git a/vite-app/index.html b/vite-app/index.html index d06ae8fe..b8abf8c5 100644 --- a/vite-app/index.html +++ b/vite-app/index.html @@ -2,18 +2,16 @@ + + - - - - - - + + KBase @@ -25,14 +23,14 @@
Loading KBase UI ...
- KBase animated logo + KBase animated logo
- + \ No newline at end of file diff --git a/vite-app/package-lock.json b/vite-app/package-lock.json index 9781b3ac..c16f769a 100644 --- a/vite-app/package-lock.json +++ b/vite-app/package-lock.json @@ -9,14 +9,14 @@ "version": "0.0.0", "dependencies": { "@ant-design/icons": "5.2.6", - "antd": "5.10.1", + "antd": "5.10.2", "bootstrap": "5.3.2", "dompurify": "3.0.6", "es-cookie": "1.4.0", "font-awesome": "4.7.0", "marked": "9.1.2", "react": "18.2.0", - "react-bootstrap": "2.9.0", + "react-bootstrap": "2.9.1", "react-bootstrap-icons": "1.10.3", "react-dom": "18.2.0", "react-router-dom": "6.17.0", @@ -30,15 +30,15 @@ "@testing-library/user-event": "14.5.1", "@types/dompurify": "3.0.4", "@types/jest": "29.5.6", - "@types/react": "18.2.30", + "@types/react": "18.2.31", "@types/react-dom": "18.2.14", "@types/react-router-dom": "5.3.3", "@types/uuid": "9.0.6", - "@typescript-eslint/eslint-plugin": "6.8.0", - "@typescript-eslint/parser": "6.8.0", + "@typescript-eslint/eslint-plugin": "6.9.0", + "@typescript-eslint/parser": "6.9.0", "@vitejs/plugin-react": "4.1.0", "@vitest/coverage-v8": "0.34.6", - "eslint": "8.51.0", + "eslint": "8.52.0", "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-react-refresh": "0.4.3", "jsdom": "22.1.0", @@ -594,11 +594,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -1178,9 +1178,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", - "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", + "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1200,12 +1200,12 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -1227,9 +1227,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@istanbuljs/schema": { @@ -1487,17 +1487,16 @@ } }, "node_modules/@rc-component/trigger": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-1.17.0.tgz", - "integrity": "sha512-KN+lKHCi7L4kjuA9DU2PnwZxtIyes6R1wsexp0/Rnjr/ITELsPuC9kpzDK1+7AZMarDXUAHUdDGS2zUNEx2P0g==", + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-1.17.2.tgz", + "integrity": "sha512-Jp3dXk/IzwHKM2Tn3ezdvQSwkPeH4v1s7QjIo7f5NFLIZVpJQ8a34FduZw8E6fT1PVgLXYd/JBIyd+YpgyQddA==", "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.23.2", "@rc-component/portal": "^1.1.0", "classnames": "^2.3.2", - "rc-align": "^4.0.0", "rc-motion": "^2.0.0", "rc-resize-observer": "^1.3.1", - "rc-util": "^5.33.0" + "rc-util": "^5.38.0" }, "engines": { "node": ">=8.x" @@ -1853,9 +1852,9 @@ "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", "dev": true }, "node_modules/@types/node": { @@ -1875,9 +1874,9 @@ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/react": { - "version": "18.2.30", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.30.tgz", - "integrity": "sha512-OfqdJnDsSo4UNw0bqAjFCuBpLYQM7wvZidz0hVxHRjrEkzRlvZL1pJVyOSY55HMiKvRNEo9DUBRuEl7FNlJ/Vg==", + "version": "18.2.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.31.tgz", + "integrity": "sha512-c2UnPv548q+5DFh03y8lEDeMfDwBn9G3dRwfkrxQMo/dOtRHUUO57k6pHvBIfH/VF4Nh+98mZ5aaSe+2echD5g==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1928,9 +1927,9 @@ "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" }, "node_modules/@types/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, "node_modules/@types/stack-utils": { @@ -1972,16 +1971,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.8.0.tgz", - "integrity": "sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz", + "integrity": "sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/type-utils": "6.8.0", - "@typescript-eslint/utils": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", + "@typescript-eslint/scope-manager": "6.9.0", + "@typescript-eslint/type-utils": "6.9.0", + "@typescript-eslint/utils": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2007,15 +2006,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.8.0.tgz", - "integrity": "sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz", + "integrity": "sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/typescript-estree": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", + "@typescript-eslint/scope-manager": "6.9.0", + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/typescript-estree": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", "debug": "^4.3.4" }, "engines": { @@ -2035,13 +2034,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", - "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", + "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0" + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2052,13 +2051,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.8.0.tgz", - "integrity": "sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz", + "integrity": "sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.8.0", - "@typescript-eslint/utils": "6.8.0", + "@typescript-eslint/typescript-estree": "6.9.0", + "@typescript-eslint/utils": "6.9.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2079,9 +2078,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", - "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", + "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2092,13 +2091,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", - "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", + "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/visitor-keys": "6.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2119,17 +2118,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.8.0.tgz", - "integrity": "sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz", + "integrity": "sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/scope-manager": "6.9.0", + "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/typescript-estree": "6.9.0", "semver": "^7.5.4" }, "engines": { @@ -2144,12 +2143,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", - "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", + "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/types": "6.9.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -2160,6 +2159,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@vitejs/plugin-react": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.1.0.tgz", @@ -2452,9 +2457,9 @@ } }, "node_modules/antd": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.10.1.tgz", - "integrity": "sha512-alcBmeH4oAdmEdBs6EORH3onRFRjGYRkWtVjPyJxlTIfLILb/+S5Y+ZqisV3AobC8mlj6T3RV8aKG9ic6PgtzQ==", + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.10.2.tgz", + "integrity": "sha512-0kV6PmlJi7vhPmYH9GCAlU62ZhiuLF+gE3REJ/9MZTo++/3i5q6SALNoRgHLMsa+rX50U3RO3wJVY+fPib594Q==", "dependencies": { "@ant-design/colors": "^7.0.0", "@ant-design/cssinjs": "^1.17.2", @@ -2465,7 +2470,7 @@ "@rc-component/color-picker": "~1.4.1", "@rc-component/mutate-observer": "^1.1.0", "@rc-component/tour": "~1.10.0", - "@rc-component/trigger": "^1.17.0", + "@rc-component/trigger": "^1.17.2", "classnames": "^2.2.6", "copy-to-clipboard": "^3.2.0", "dayjs": "^1.11.1", @@ -2473,7 +2478,7 @@ "rc-cascader": "~3.18.1", "rc-checkbox": "~3.1.0", "rc-collapse": "~3.7.1", - "rc-dialog": "~9.3.3", + "rc-dialog": "~9.3.4", "rc-drawer": "~6.5.2", "rc-dropdown": "~4.1.0", "rc-field-form": "~1.39.0", @@ -2488,10 +2493,10 @@ "rc-picker": "~3.14.5", "rc-progress": "~3.5.1", "rc-rate": "~2.12.0", - "rc-resize-observer": "^1.3.1", + "rc-resize-observer": "^1.4.0", "rc-segmented": "~2.2.2", - "rc-select": "~14.9.1", - "rc-slider": "~10.3.0", + "rc-select": "~14.9.2", + "rc-slider": "~10.3.1", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", "rc-table": "~7.34.4", @@ -3136,11 +3141,6 @@ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true }, - "node_modules/dom-align": { - "version": "1.12.4", - "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz", - "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==" - }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -3282,18 +3282,19 @@ } }, "node_modules/eslint": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", - "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", + "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.51.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/js": "8.52.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -5317,22 +5318,6 @@ } ] }, - "node_modules/rc-align": { - "version": "4.0.15", - "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.15.tgz", - "integrity": "sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==", - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "2.x", - "dom-align": "^1.7.0", - "rc-util": "^5.26.0", - "resize-observer-polyfill": "^1.5.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, "node_modules/rc-cascader": { "version": "3.18.1", "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.18.1.tgz", @@ -5380,9 +5365,9 @@ } }, "node_modules/rc-dialog": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.3.3.tgz", - "integrity": "sha512-OpgzE0wq55ebN8TL/ZPc+MLY6qXswEuZg2/3uX3+lqjxUnVaH78PyntpJwqY+3BJdQkDj28XeXYRVY6gXQ8fNg==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.3.4.tgz", + "integrity": "sha512-975X3018GhR+EjZFbxA2Z57SX5rnu0G0/OxFgMMvZK4/hQWEm3MHaNvP4wXpxYDoJsp+xUvVW+GB9CMMCm81jA==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/portal": "^1.0.0-8", @@ -5654,13 +5639,13 @@ } }, "node_modules/rc-resize-observer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.3.1.tgz", - "integrity": "sha512-iFUdt3NNhflbY3mwySv5CA1TC06zdJ+pfo0oc27xpf4PIOvfZwZGtD9Kz41wGYqC4SLio93RVAirSSpYlV/uYg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz", + "integrity": "sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==", "dependencies": { "@babel/runtime": "^7.20.7", "classnames": "^2.2.1", - "rc-util": "^5.27.0", + "rc-util": "^5.38.0", "resize-observer-polyfill": "^1.5.1" }, "peerDependencies": { @@ -5705,9 +5690,9 @@ } }, "node_modules/rc-slider": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.3.0.tgz", - "integrity": "sha512-kt8ehfvPLoZFYJS3Caaf3l+9OF8JUyexC84qy878vf9rOy9IulO/PEdha8E90i8mnj4mtJMSxojk1fJGkYWjpQ==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.3.1.tgz", + "integrity": "sha512-XszsZLkbjcG9ogQy/zUC0n2kndoKUAnY/Vnk1Go5Gx+JJQBz0Tl15d5IfSiglwBUZPS9vsUJZkfCmkIZSqWbcA==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", @@ -5920,9 +5905,9 @@ } }, "node_modules/react-bootstrap": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.0.tgz", - "integrity": "sha512-dGh6fGjqR9MBzPOp2KbXJznt1Zy6SWepXYUdxMT18Zu/wJ73HCU8JNZe9dfzjmVssZYsJH9N3HHE4wAtQvNz7g==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.1.tgz", + "integrity": "sha512-ezgmh/ARCYp18LbZEqPp0ppvy+ytCmycDORqc8vXSKYV3cer4VH7OReV8uMOoKXmYzivJTxgzGHalGrHamryHA==", "dependencies": { "@babel/runtime": "^7.22.5", "@restart/hooks": "^0.4.9", @@ -6081,9 +6066,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, "node_modules/regexp.prototype.flags": { "version": "1.5.0", diff --git a/vite-app/package.json b/vite-app/package.json index f3eceb8b..0aed2193 100644 --- a/vite-app/package.json +++ b/vite-app/package.json @@ -12,14 +12,14 @@ }, "dependencies": { "@ant-design/icons": "5.2.6", - "antd": "5.10.1", + "antd": "5.10.2", "bootstrap": "5.3.2", "dompurify": "3.0.6", "es-cookie": "1.4.0", "font-awesome": "4.7.0", "marked": "9.1.2", "react": "18.2.0", - "react-bootstrap": "2.9.0", + "react-bootstrap": "2.9.1", "react-bootstrap-icons": "1.10.3", "react-dom": "18.2.0", "react-router-dom": "6.17.0", @@ -33,15 +33,15 @@ "@testing-library/user-event": "14.5.1", "@types/dompurify": "3.0.4", "@types/jest": "29.5.6", - "@types/react": "18.2.30", + "@types/react": "18.2.31", "@types/react-dom": "18.2.14", "@types/react-router-dom": "5.3.3", "@types/uuid": "9.0.6", - "@typescript-eslint/eslint-plugin": "6.8.0", - "@typescript-eslint/parser": "6.8.0", + "@typescript-eslint/eslint-plugin": "6.9.0", + "@typescript-eslint/parser": "6.9.0", "@vitejs/plugin-react": "4.1.0", "@vitest/coverage-v8": "0.34.6", - "eslint": "8.51.0", + "eslint": "8.52.0", "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-react-refresh": "0.4.3", "jsdom": "22.1.0", diff --git a/vite-app/src/applets/about/AboutKBaseUI/AboutKBaseUI.tsx b/vite-app/src/applets/about/AboutKBaseUI/AboutKBaseUI.tsx index 85a6143d..0ac4d8bb 100644 --- a/vite-app/src/applets/about/AboutKBaseUI/AboutKBaseUI.tsx +++ b/vite-app/src/applets/about/AboutKBaseUI/AboutKBaseUI.tsx @@ -38,7 +38,7 @@ export default class AboutKBaseUI extends Component<
  • The{' '} @@ -179,7 +179,7 @@ export default class AboutKBaseUI extends Component< 'http://kbaseincubator.github.io/kbase-ui-docs'; const documentationURL = this.props.config.ui.urls.documentation.url; - const [githubContent, githubUrl,relNotesUrl] = this.renderGitInfo(); + const [githubContent, githubUrl, relNotesUrl] = this.renderGitInfo(); const kbaseGithubOrgURL = 'https://github.com/kbase'; diff --git a/vite-app/src/apps/Navigator/components/NarrativeDetails/NarrativeHeader.tsx b/vite-app/src/apps/Navigator/components/NarrativeDetails/NarrativeHeader.tsx index 90b26651..b6de9dab 100644 --- a/vite-app/src/apps/Navigator/components/NarrativeDetails/NarrativeHeader.tsx +++ b/vite-app/src/apps/Navigator/components/NarrativeDetails/NarrativeHeader.tsx @@ -56,7 +56,7 @@ function countCellTypes(narrative: NarrativeSearchDoc): CellTypesInfo { } const profileLink = (username: string, realname: string) => ( - + {realname} ); diff --git a/vite-app/src/apps/Navigator/components/NarrativeDetails/ToolMenu/LinkOrgItem.tsx b/vite-app/src/apps/Navigator/components/NarrativeDetails/ToolMenu/LinkOrgItem.tsx index ad97cff6..aeada1bb 100644 --- a/vite-app/src/apps/Navigator/components/NarrativeDetails/ToolMenu/LinkOrgItem.tsx +++ b/vite-app/src/apps/Navigator/components/NarrativeDetails/ToolMenu/LinkOrgItem.tsx @@ -326,7 +326,7 @@ const LinkedOrg = (props: LinkedOrgProps) => {
    diff --git a/vite-app/src/apps/Navigator/components/NarrativeDetails/cells/AppCell.tsx b/vite-app/src/apps/Navigator/components/NarrativeDetails/cells/AppCell.tsx index c3fe97dc..cd36ad36 100644 --- a/vite-app/src/apps/Navigator/components/NarrativeDetails/cells/AppCell.tsx +++ b/vite-app/src/apps/Navigator/components/NarrativeDetails/cells/AppCell.tsx @@ -53,7 +53,7 @@ export default class AppCellView extends Component { <>
    diff --git a/vite-app/src/apps/Navigator/components/NarrativeDetails/cells/DataObjectCell.tsx b/vite-app/src/apps/Navigator/components/NarrativeDetails/cells/DataObjectCell.tsx index 2edd55ea..1cab9e71 100644 --- a/vite-app/src/apps/Navigator/components/NarrativeDetails/cells/DataObjectCell.tsx +++ b/vite-app/src/apps/Navigator/components/NarrativeDetails/cells/DataObjectCell.tsx @@ -23,7 +23,7 @@ export default class DataObjectCellView extends Component { return (
    diff --git a/vite-app/src/apps/ORCIDLink/manage/linkingSessions/view.tsx b/vite-app/src/apps/ORCIDLink/manage/linkingSessions/view.tsx index 738737fc..de550ed9 100644 --- a/vite-app/src/apps/ORCIDLink/manage/linkingSessions/view.tsx +++ b/vite-app/src/apps/ORCIDLink/manage/linkingSessions/view.tsx @@ -65,7 +65,7 @@ export default class QueryLinkingSessionsView extends Component { return - {username} + {username} {session_id} @@ -114,7 +114,7 @@ export default class QueryLinkingSessionsView extends Component { return - {username} + {username} {session_id} @@ -172,7 +172,7 @@ export default class QueryLinkingSessionsView extends Component { return - {username} + {username} {session_id} diff --git a/vite-app/src/apps/ORCIDLink/manage/queryLinks/view.tsx b/vite-app/src/apps/ORCIDLink/manage/queryLinks/view.tsx index 3eebf740..f5a67e43 100644 --- a/vite-app/src/apps/ORCIDLink/manage/queryLinks/view.tsx +++ b/vite-app/src/apps/ORCIDLink/manage/queryLinks/view.tsx @@ -21,7 +21,7 @@ interface ORCIDLinkManageState { export default class ORCIDLinkManageView extends Component { viewLink(username: string) { - const url = `/#orcidlink/manage/link/${username}`; + const url = `#orcidlink/manage/link/${username}`; window.open(url, '_blank'); } @@ -52,7 +52,7 @@ export default class ORCIDLinkManageView extends Component { - return {linkRecord.username} + return {linkRecord.username} } }, { diff --git a/vite-app/src/apps/ORCIDLink/manage/viewLink/view.tsx b/vite-app/src/apps/ORCIDLink/manage/viewLink/view.tsx index c1807124..68e1f2e4 100644 --- a/vite-app/src/apps/ORCIDLink/manage/viewLink/view.tsx +++ b/vite-app/src/apps/ORCIDLink/manage/viewLink/view.tsx @@ -85,7 +85,7 @@ export default class ORCIDLinkManageView extends ComponentTools - + @@ -97,7 +97,7 @@ export default class ORCIDLinkManageView extends Component -
  • - Narrative + Narrative
  • - Dashboard + Narratives Navigator
  • @@ -64,7 +64,7 @@ export default class NotFound extends Component - + } } diff --git a/vite-app/src/components/NotFoundChecked/NotFoundChecked.tsx b/vite-app/src/components/NotFoundChecked/NotFoundChecked.tsx index 01a72b58..c4b21195 100644 --- a/vite-app/src/components/NotFoundChecked/NotFoundChecked.tsx +++ b/vite-app/src/components/NotFoundChecked/NotFoundChecked.tsx @@ -145,7 +145,7 @@ export default class NotFound extends Component< 'redirect-to-www' ) ) { - this.redirect('/#login'); + this.redirect('#login'); return; } // this.props.setTitle('Redirecting to h...'); @@ -225,7 +225,7 @@ export default class NotFound extends Component< messages: [ ...this.state.messages.slice(0, -1), this.state.messages[ - this.state.messages.length - 1 + this.state.messages.length - 1 ] + 'nope', ], }, @@ -474,10 +474,10 @@ export default class NotFound extends Component<
  • - Narrative + Narrative
  • - Dashboard + Narratives Navigator
  • diff --git a/vite-app/src/components/Signin/SigninButton.tsx b/vite-app/src/components/Signin/SigninButton.tsx index fac8b5fd..7f68b28f 100644 --- a/vite-app/src/components/Signin/SigninButton.tsx +++ b/vite-app/src/components/Signin/SigninButton.tsx @@ -35,7 +35,7 @@ export default class Signin extends Component { render() { const url = new URL(window.location.href); - url.pathname = ''; + // url.pathname = ''; url.hash = '#login'; const nextRequest = this.props.nextRequest; // || this.makeNextRequstFromHere(); diff --git a/vite-app/src/gtagSupport.ts b/vite-app/src/gtagSupport.ts new file mode 100644 index 00000000..1476713a --- /dev/null +++ b/vite-app/src/gtagSupport.ts @@ -0,0 +1,467 @@ +/** + * Google Analytics (GA) app implementation + * + * The GA mechanism for sending data to the GA collection service + * consists of a very simple, small web app. + * + * Upon loading the primary kbase-ui SPA index.html page, an embedded + * script call to Google loads a GA app which loads necessary support + * files and begins to monitor a global variable "window.dataLayer". + * + * (Why Goggle didn't pick something namespaced to their app like + * GoogleDataLayer, or GoogleAnalyticsDataQueue, I don't know.) + * + * Then, when data is to be sent to GA for a page load (all that we use it for), + * this script below pushes (in the sense of "array push") the appropriate + * data in the appropriate format into the global data queue "dataLayer". + * + * On the next polling call, the GA app pulls the data off the queue and sends it + * to the GA collection service. + * + * Quite straightforward. + * + * Now for our implementation. + * + * First, there is no good reason for the code to be in a standalone file, afaik, + * and it is a bit complicated by the fact that it has to replicate functionality + * in kbase-ui, but here it is. + * + * The script has the general task of sending, for the initial page load and every + * subsequent navigation, the: + * - current url + * - current page path + * - current page title + * - username if there is a valid kbase auth token + * + * There a few complications in this otherwise relatively straightforward task. + * + * Since this script is independent of kbase-ui, it must be configured manually, + * including the auth token name, urls, Google GA ids, and other. + * + * Fetching the username requires a call to the auth service. Since this + * script is independent of kbase-ui, it must perform this logic separately. + * To prevent calling the auth service with every navigation, the token is + * cached for 10 minutes. + * + * The page title is not available until the view code associated with the page load + * or navigation has run and determined and set the title. In other words, it is + * asynchronous, and may take even up to a few seconds. To accommodate this fact, + * the script will monitor the page title and only set the GA data when the title + * has been stable for some period of time (TITLE_STABILIZATION_PERIOD). If navigation + * occurs before the title has stabilized, the GA data is sent anyway + * + * References: + * https://developers.google.com/tag-platform/gtagjs/reference + * https://developers.google.com/analytics/devguides/collection/gtagjs/single-page-applications#measure_virtual_pageviews + */ + +import { Account } from "lib/kb_lib/comm/coreServices/Auth"; + +type GTagStatus = 'WAITING' | 'PENDING' | 'SEND_NOW' | 'SENDING'; + +interface WindowWithGTag extends Window { + dataLayer: Array; +} + +const gtagWindow = window as unknown as WindowWithGTag; + +interface PageView { + page_location: string, + page_path: string, + page_title: string | null, + user_id?: string +}; + +class GTagSupport { + // Configuration + // These should be in a separate configuration, but, to be honest, some of these values have never changed, and others, + // like the Google tags, only every few years. + SESSION_COOKIE_NAME = 'kbase_session'; + PROD_UI_ORIGIN = 'https://narrative.kbase.us'; + PROD_SERVICE_ORIGIN = 'https://kbase.us'; + GOOGLE_GTAG = 'G-KXZCE6YQFZ'; + GOOGLE_AD_TAG = 'AW-753507180'; + + // The sending of the page hit is delayed until the page title stops change for the duration + // set here. + TITLE_STABILIZATION_PERIOD = 3000; + + // Keep the auth token cached for up to 10 minutes. + KBASE_AUTH_TOKEN_TTL = 600000; + KBASE_AUTH_INFO_EXPIRES_AT: number | null = null; + KBASE_AUTH_INFO: Account | null = null; + KBASE_AUTH_TOKEN: string | null = null; + + + + // Stores the current page title, which is really the last one recorded + // in the async loop below. + LAST_PAGE_TITLE: string | null = null; + + /** + * GTag processing states. + * + * Due to the asynchronous nature of loading page titles, and generally the fact that this code + * runs independently of the kbase-ui, which is of course asynchronous in nature, we use a + * little state model to manage this. + * + */ + + GTAG_STATE: GTagStatus = 'WAITING'; + + + + /** + * Sets a new status value, which should be one of WAITING, PENDING, SEND_NOW, or SENDING. + * + * @param {string} newState The new value for the gtag support status + */ + setState(newState: any) { + this.GTAG_STATE = newState; + } + + /** + * Simply compares the provided value to the current status value, returning whether they are the same. + * + * @param {string} state + * @returns {boolean} Whether the provided value is the same as the current status + */ + isState(state: string) { + return this.GTAG_STATE === state; + } + + /** + * Returns a promise that does not resolve until the given status is active. + * + * + * @param {*} status A status value, as defined above: WAITING, PENDING, SEND_NOW, SENDING + * @returns {Promise} A Promise with no important value + */ + // TODO there should be a timeout + async waitUntilStatus(status: GTagStatus, timeout: number) { + const started = Date.now(); + const timeoutAfter = started + timeout; + return new Promise((resolve) => { + const loop = () => { + if (Date.now() >= timeoutAfter) { + throw new Error(`Timed out after ${Date.now() - started}`); + } + setTimeout(() => { + if (this.isState(status)) { + loop(); + } + resolve(); + }, 100); + }; + loop(); + }); + } + + /** + * Returns the KBase service origin. + * + * In all but production, the service origin is the same as the document origin + * for the ui. In production, the ui origin is https://narrative.kbase.us but the + * service origin is https://kbase.us - this adjustment is made. + * + * @returns {string} The KBase service "origin" (protocol and hostname, e.g. https://ci.kbase.us) + */ + getServiceOrigin() { + if (document.location.origin === this.PROD_UI_ORIGIN) { + return this.PROD_SERVICE_ORIGIN; + } + return document.location.origin; + } + + /** + * The canonical function name for queuing messages for the Google gtag app. + * + * Note that the function relies up on the usage of the magic "arguments" variable + * provided to all functions. + * + * @returns {void} - Nothing + */ + pushGTag(_tag: string, _value: any, _options?: any) { + //developers.google.com/tag-platform/tag-manager/datalayer + gtagWindow.dataLayer.push(arguments); + } + + /** + * Get and return the current hash path as a path with a leading + * forward slash (/). + * + * Note that this code is could be a one-liner but for the fact that + * some usages of kbase-ui hash-paths place the search query string + * on the hash itself. + * + * @returns {string} - The current navigation path in kbase-ui + */ + getHashPath() { + const hash = document.location.hash; + let path; + if (hash) { + const m = hash.match(/#[/]?([^?]*)/); + if (m) { + path = m[1]; + } else { + path = ''; + } + } else { + path = ''; + } + return `/${path}`; + } + + /** + * Find KBase auth token from document cookie. + * + * If a token is not found in the cookie, null is returned. + * + * @returns {string|null} A KBase auth token, if any, stored in the browser. + */ + getToken() { + if (!document.cookie) { + return null; + } + const cookies = document.cookie.split(';').map((item) => { + return item.trim(); + }); + + for (const cookie of cookies) { + const [name, value] = cookie.split('='); + if (name === this.SESSION_COOKIE_NAME) { + return value; + } + } + return null; + } + + /** + * Returns the username associated with the given KBase auth token. + * + * If there is no token, or an error is encountered interacting with + * the auth service, null is returned. + * + * @param {string} token - KBase auth token + * @returns {string|null} - A kbase username + */ + async fetchAuth(token: string) { + if ( + this.KBASE_AUTH_INFO !== null && + this.KBASE_AUTH_INFO_EXPIRES_AT !== null && + this.KBASE_AUTH_INFO_EXPIRES_AT > Date.now() && + token === this.KBASE_AUTH_TOKEN + ) { + return this.KBASE_AUTH_INFO; + } + this.KBASE_AUTH_TOKEN = token; + const url = `${this.getServiceOrigin()}/services/auth/api/V2/me`; + try { + const response = await fetch(url, { + method: 'GET', + mode: 'cors', + headers: { + 'Content-Type': 'application/json', + Authorization: token, + }, + }); + if (response.status !== 200) { + console.warn('[gtagSupport] bad auth response, user not available', response); + return null; + } + this.KBASE_AUTH_INFO = await response.json(); + this.KBASE_AUTH_INFO_EXPIRES_AT = Date.now() + this.KBASE_AUTH_TOKEN_TTL; + return this.KBASE_AUTH_INFO; + } catch (error) { + console.error('[gtagSupport] error occurred in call to auth service', error); + return null; + } + } + + /** + * Get the username associated with the current KBase auth token. + * + * If there is no valid KBase auth token available, or an error is + * encountered with the auth service call, null is returned instead. + * + * + * @returns {string|null} username + */ + async getAuth() { + const token = this.getToken(); + if (token) { + try { + const auth = this.fetchAuth(token); + if (auth) { + return auth; + } + } catch (ex) { + console.error('[gtagSupport] Error fetching username', ex); + } + } + this.KBASE_AUTH_INFO = null; + this.KBASE_AUTH_TOKEN = null; + return null; + } + + /** + * + * + * @returns {void} - Nothing + */ + async sendGTag() { + this.setState('SENDING'); + + // The "path" for a view in the ui is determined by + // the url hash. This will change one day. + const path = this.getHashPath(); + + // Simply ensures that the data layer exists. The data layer + // is just an array placed into a "dataLayer" property on the global + // window. Nothing special about the name "dataLayer", other than that + // is where the google scripts expect to see + gtagWindow.dataLayer = gtagWindow.dataLayer || []; + + // See google docs for the api and field definitions. + // E.g. https://developers.google.com/analytics/devguides/collection/gtagjs/pages + // Queue up date for GA + const pageView: PageView = { + page_location: document.location.href, + page_path: path, + page_title: this.LAST_PAGE_TITLE, + }; + + const auth = await this.getAuth(); + if (auth) { + pageView.user_id = auth.anonid; + } + + this.pushGTag('event', 'page_view', pageView); + + this.setState('WAITING'); + } + + /** + * The ever-popular "sleep" function, which returns a promise that resolves with the given period of time elapsed. + * + * @param {number} until The amount of time, in milliseconds, after which the promise should resolve. + * @returns {Promise} + */ + async sleep(until: number) { + return new Promise((resolve) => { + window.setTimeout(() => { + resolve(); + }, until); + }); + } + + /** + * Ensures that if the next page hit is being sent, if the current one has not yet + * been sent, that it send immediately. + * + * Remember, that upon initiating a gtag request, we first wait for the page title + * to stabilize, and then the gtag event is registered. So if a new navigation event + * occurs during the waiting period, this function will be called in order to just + * send the gtag event even if the page title is not yet stabilized. + * + * @returns {Promise} + */ + async sendPendingGTag() { + if (this.isState('PENDING')) { + // Here we set the status to SEND_NOW, which causes the loop monitoring the + // page title to terminate, which returns a promise, and causes the gtag + // event to be pushed. + this.setState('SEND_NOW'); + + // And here we wait until the message is sent and we are back in the WAITING state. + // This should be sent very quickly, so a 2 second timeout should be plenty. + return await this.waitUntilStatus('WAITING', 2000); + } + } + + /** + * When called, will return a Promise that will only resolve when the page title + * has not changed for some amount of time. + * + * This amount of time is set at top of the file as TITLE_STABILIZATION_PERIOD), but + * should be on the order of 2-3 seconds. + * + * @returns {Promise} + */ + + async sendGTagAfterTitleSettles() { + this.setState('PENDING'); + + let lastChanged = Date.now(); + this.LAST_PAGE_TITLE = document.title; + + // This is where we "wait" for the page title to stabilize, + // i.e. stop changing. + const loop = async () => { + if (this.isState('SEND_NOW')) { + return; + } + const now = Date.now(); + if (now >= lastChanged + this.TITLE_STABILIZATION_PERIOD) { + return; + } + if (document.title !== this.LAST_PAGE_TITLE) { + lastChanged = Date.now(); + this.LAST_PAGE_TITLE = document.title; + } + await this.sleep(100); + await loop(); + }; + await loop(); + + // And ... finally we trigger the pushing up data for gtag. + this.sendGTag(); + + // This signals that the status of this little gtag engine + // is waiting for a navigation event. + this.setState('WAITING'); + } + + + + /** + * Sets up gtag support to a known state, and sets up some gtag data that + * will not change over this session. + */ + initialize() { + // Simply ensures that the data layer exists. + gtagWindow.dataLayer = gtagWindow.dataLayer || []; + this.setState('WAITING'); + this.pushGTag('js', new Date()); + this.pushGTag('config', this.GOOGLE_GTAG, { + send_page_view: false, + }); + this.pushGTag('config', this.GOOGLE_AD_TAG, { + send_page_view: false, + }); + + /** + * Send a ping to GA whenever the history state changes, i.e., url navigation + */ + window.onpopstate = async () => { + await this.sendPendingGTag(); + this.sendGTagAfterTitleSettles(); + }; + + this.sendGTagAfterTitleSettles() + } + + +} + +/** + * Initializes the state, and schedules the first page hit to be sent to GA. + * + * After this, navigation triggers the page hit. + */ +window.addEventListener('load', () => { + const gtagSupport = new GTagSupport(); + gtagSupport.initialize(); + // initialize(); + // sendGTagAfterTitleSettles(); +}); diff --git a/vite-app/src/lib/kb_lib/Auth2.ts b/vite-app/src/lib/kb_lib/Auth2.ts index 69b932c9..beb64123 100644 --- a/vite-app/src/lib/kb_lib/Auth2.ts +++ b/vite-app/src/lib/kb_lib/Auth2.ts @@ -132,6 +132,7 @@ export interface Account { local: boolean; roles: Array; user: string; + anonid: string; } export interface LoginCreateResponse { diff --git a/vite-app/src/lib/kb_lib/comm/coreServices/Auth.ts b/vite-app/src/lib/kb_lib/comm/coreServices/Auth.ts index a5af49d1..92ad895a 100644 --- a/vite-app/src/lib/kb_lib/comm/coreServices/Auth.ts +++ b/vite-app/src/lib/kb_lib/comm/coreServices/Auth.ts @@ -85,6 +85,7 @@ export interface Account { local: boolean; roles: Array; user: string; + anonid: string; } export default class AuthClient { url: string; diff --git a/vite-app/vite.config-og.ts b/vite-app/vite.config-og.ts new file mode 100644 index 00000000..a3c5357e --- /dev/null +++ b/vite-app/vite.config-og.ts @@ -0,0 +1,89 @@ +import react from '@vitejs/plugin-react'; +import tsconfigPaths from 'vite-tsconfig-paths'; +import { defineConfig } from 'vitest/config'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react(), tsconfigPaths()], + base: './', + build: { + commonjsOptions: { + include: ['node_modules/**'], + }, + rollupOptions: { + output: { + experimentalMinChunkSize: 500_000, + manualChunks(id) { + if (id.includes('node_modules')) { + return 'vendor'; + } + } + } + } + }, + optimizeDeps: { + disabled: 'build' + }, + server: { + port: 3000, + host: '0.0.0.0', + proxy: { + '/services': { + target: 'https://ci.kbase.us', + changeOrigin: true, + secure: false, + }, + '/dynserv': { + target: 'https://ci.kbase.us', + changeOrigin: true, + secure: false + }, + '/modules/plugins': { + target: 'http://kbase-ui-deploy:80/plugins', + changeOrigin: true, + rewrite: (path: string) => { + return path.replace(/^\/modules\/plugins/, ''); + }, + configure: (proxy, options) => { + proxy.on('error', (error, request, response) => { + console.log('PROXY ERROR', error); + }); + proxy.on('proxyReq', (proxyRequest, request, response) => { + console.log('PROXY Request', request.method, request.url); + }); + proxy.on('proxyRes', (proxyResponse, request, response) => { + console.log('PROXY Response', proxyResponse.statusCode, request.url); + }); + } + }, + '/deploy/plugins': { + target: 'http://kbase-ui-deploy:80/plugins/', + changeOrigin: true, + rewrite: (path: string) => { + return path.replace(/^\/deploy\/plugins/, ''); + } + }, + '/plugins': { + target: 'http://kbase-ui-deploy:80', + changeOrigin: true, + }, + '/deploy': { + target: 'http://kbase-ui-deploy:80/', + changeOrigin: true, + }, + '/build': { + target: 'http://kbase-ui-deploy:80', + changeOrigin: true, + } + } + }, + test: { + globals: true, + environment: 'jsdom', + setupFiles: './tests/setup.js', + coverage: { + provider: 'v8', + all: true + } + }, +}) diff --git a/vite-app/vite.config.ts b/vite-app/vite.config.ts index a3c5357e..4c885bbb 100644 --- a/vite-app/vite.config.ts +++ b/vite-app/vite.config.ts @@ -1,89 +1,173 @@ import react from '@vitejs/plugin-react'; +import { loadEnv } from 'vite'; import tsconfigPaths from 'vite-tsconfig-paths'; import { defineConfig } from 'vitest/config'; // https://vitejs.dev/config/ -export default defineConfig({ - plugins: [react(), tsconfigPaths()], - base: './', - build: { - commonjsOptions: { - include: ['node_modules/**'], +export default defineConfig(({ command, mode }) => { + + const env = loadEnv(mode, process.cwd(), ''); + + // console.log('ENV', basePath); + + // const basePath = env.BASE_PATH;; + // const basePath = '/foo'; + const basePath = "./"; + + const basetPathForProxy = basePath === './' ? '' : basePath; + + const proxy = { + '/services': { + target: 'https://ci.kbase.us', + changeOrigin: true, + secure: false, }, - rollupOptions: { - output: { - experimentalMinChunkSize: 500_000, - manualChunks(id) { - if (id.includes('node_modules')) { - return 'vendor'; - } - } + '/dynserv': { + target: 'https://ci.kbase.us', + changeOrigin: true, + secure: false + }, + '/modules/plugins': { + target: 'http://kbase-ui-deploy:80/plugins', + changeOrigin: true, + rewrite: (path: string) => { + return path.replace(/^\/modules\/plugins/, ''); + }, + configure: (proxy, options) => { + proxy.on('error', (error, request, response) => { + console.log('PROXY ERROR', error); + }); + proxy.on('proxyReq', (proxyRequest, request, response) => { + console.log('PROXY Request', request.method, request.url); + }); + proxy.on('proxyRes', (proxyResponse, request, response) => { + console.log('PROXY Response', proxyResponse.statusCode, request.url); + }); } + }, + '/plugins': { + target: 'http://kbase-ui-deploy:80', + changeOrigin: true, + }, + }; + + // This is for plugins; kbase-ui uses just /plugins + proxy[`^${basePath}/modules/plugins/.*`] = { + target: 'http://kbase-ui-deploy:80/plugins', + changeOrigin: true, + rewrite: (path: string) => { + return path.replace(new RegExp(`^${basePath}/modules/plugins/`), ''); } - }, - optimizeDeps: { - disabled: 'build' - }, - server: { - port: 3000, - host: '0.0.0.0', - proxy: { - '/services': { - target: 'https://ci.kbase.us', - changeOrigin: true, - secure: false, - }, - '/dynserv': { - target: 'https://ci.kbase.us', - changeOrigin: true, - secure: false - }, - '/modules/plugins': { - target: 'http://kbase-ui-deploy:80/plugins', - changeOrigin: true, - rewrite: (path: string) => { - return path.replace(/^\/modules\/plugins/, ''); - }, - configure: (proxy, options) => { - proxy.on('error', (error, request, response) => { - console.log('PROXY ERROR', error); - }); - proxy.on('proxyReq', (proxyRequest, request, response) => { - console.log('PROXY Request', request.method, request.url); - }); - proxy.on('proxyRes', (proxyResponse, request, response) => { - console.log('PROXY Response', proxyResponse.statusCode, request.url); - }); - } + }; + + // This is a stopgap - some (most?) plugins use the hard-coded path + // /modules/plugins. + // proxy[`/modules/plugins/.*`] = { + // target: 'http://kbase-ui-deploy:80/plugins', + // changeOrigin: true, + // // rewrite: (path: string) => { + // // return path.replace(/^\/modules\/plugins/, ''); + // // }, + + // rewrite: (path: string) => { + // return path.replace(new RegExp(`/modules/plugins/`), ''); + // }, + // configure: (proxy, options) => { + // proxy.on('error', (error, request, response) => { + // console.log('PROXY ERROR', error); + // }); + // proxy.on('proxyReq', (proxyRequest, request, response) => { + // console.log('PROXY Request', request.method, request.url); + // }); + // proxy.on('proxyRes', (proxyResponse, request, response) => { + // console.log('PROXY Response', proxyResponse.statusCode, request.url); + // }); + // } + // }; + + + // proxy[`^${basePath}/plugins/.*`] = { + // target: 'http://kbase-ui-deploy:80/plugins/', + // changeOrigin: true, + // // rewrite: (path: string) => { + // // return path.replace(/^\/deploy\/plugins/, ''); + // // } + // rewrite: (path: string) => { + // return path.replace(new RegExp(`^${basePath}`), ''); + // }, + // }; + + proxy[`^${basetPathForProxy}/plugins/.*`] = { + target: 'http://kbase-ui-deploy:80', + changeOrigin: true, + rewrite: (path: string) => { + return path.replace(new RegExp(`^${basePath}`), ''); + }, + }; + + proxy[`^${basetPathForProxy}/deploy/.*`] = { + target: 'http://kbase-ui-deploy:80', + changeOrigin: true, + rewrite: (path: string) => { + return path.replace(new RegExp(`^${basePath}`), ''); + }, + }; + + + proxy[`^${basetPathForProxy}/build/.*`] = { + target: 'http://kbase-ui-deploy:80', + changeOrigin: true, + rewrite: (path: string) => { + return path.replace(new RegExp(`^${basePath}`), ''); + }, + }; + + // What uses this? + proxy[`^${basetPathForProxy}/deploy/plugins/.`] = { + target: 'http://kbase-ui-deploy:80', + changeOrigin: true, + rewrite: (path: string) => { + return path.replace(/^\/deploy\/plugins/, ''); + } + }; + + console.log('PROXY', proxy); + + return { + plugins: [react(), tsconfigPaths()], + // base: '/foo', + base: basePath, + build: { + commonjsOptions: { + include: ['node_modules/**'], }, - '/deploy/plugins': { - target: 'http://kbase-ui-deploy:80/plugins/', - changeOrigin: true, - rewrite: (path: string) => { - return path.replace(/^\/deploy\/plugins/, ''); + rollupOptions: { + output: { + experimentalMinChunkSize: 500_000, + manualChunks(id) { + if (id.includes('node_modules')) { + return 'vendor'; + } + } } - }, - '/plugins': { - target: 'http://kbase-ui-deploy:80', - changeOrigin: true, - }, - '/deploy': { - target: 'http://kbase-ui-deploy:80/', - changeOrigin: true, - }, - '/build': { - target: 'http://kbase-ui-deploy:80', - changeOrigin: true, } - } - }, - test: { - globals: true, - environment: 'jsdom', - setupFiles: './tests/setup.js', - coverage: { - provider: 'v8', - all: true - } - }, -}) + }, + optimizeDeps: { + disabled: 'build' + }, + server: { + port: 3000, + host: '0.0.0.0', + proxy + }, + test: { + globals: true, + environment: 'jsdom', + setupFiles: './tests/setup.js', + coverage: { + provider: 'v8', + all: true + } + }, + } +}); From 0400fe4f6fe1eb8fe66d4511576d004dbae32474 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 25 Oct 2023 19:30:00 +0000 Subject: [PATCH 005/128] minor dep update [CE-315] --- vite-app/package-lock.json | 8 ++++---- vite-app/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vite-app/package-lock.json b/vite-app/package-lock.json index c16f769a..182ba30d 100644 --- a/vite-app/package-lock.json +++ b/vite-app/package-lock.json @@ -30,7 +30,7 @@ "@testing-library/user-event": "14.5.1", "@types/dompurify": "3.0.4", "@types/jest": "29.5.6", - "@types/react": "18.2.31", + "@types/react": "18.2.32", "@types/react-dom": "18.2.14", "@types/react-router-dom": "5.3.3", "@types/uuid": "9.0.6", @@ -1874,9 +1874,9 @@ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/react": { - "version": "18.2.31", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.31.tgz", - "integrity": "sha512-c2UnPv548q+5DFh03y8lEDeMfDwBn9G3dRwfkrxQMo/dOtRHUUO57k6pHvBIfH/VF4Nh+98mZ5aaSe+2echD5g==", + "version": "18.2.32", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.32.tgz", + "integrity": "sha512-F0FVIZQ1x5Gxy/VYJb7XcWvCcHR28Sjwt1dXLspdIatfPq1MVACfnBDwKe6ANLxQ64riIJooXClpUR6oxTiepg==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", diff --git a/vite-app/package.json b/vite-app/package.json index 0aed2193..62783427 100644 --- a/vite-app/package.json +++ b/vite-app/package.json @@ -33,7 +33,7 @@ "@testing-library/user-event": "14.5.1", "@types/dompurify": "3.0.4", "@types/jest": "29.5.6", - "@types/react": "18.2.31", + "@types/react": "18.2.32", "@types/react-dom": "18.2.14", "@types/react-router-dom": "5.3.3", "@types/uuid": "9.0.6", From eceeddfb3825bc303aed5f82f45a7ce056ca05cc Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 25 Oct 2023 19:33:31 +0000 Subject: [PATCH 006/128] local image, disable base path changes for local proxy [CE-315] --- Taskfile | 8 + scripts/host/build-image.sh | 1 + scripts/host/run-image.sh | 5 +- .../conf/nginx.conf-base-path-changes.tmpl | 497 ++++++++++++++++++ tools/proxy/contents/conf/nginx.conf.tmpl | 35 +- tools/proxy/docker-compose.yml | 2 + 6 files changed, 518 insertions(+), 30 deletions(-) mode change 100644 => 100755 scripts/host/build-image.sh mode change 100644 => 100755 scripts/host/run-image.sh create mode 100644 tools/proxy/contents/conf/nginx.conf-base-path-changes.tmpl diff --git a/Taskfile b/Taskfile index 519b6ba8..18767a63 100755 --- a/Taskfile +++ b/Taskfile @@ -125,6 +125,14 @@ function start-local-server { docker compose up } +function build-image { + ./scripts/host/build-image.sh +} + +function run-image { + ./scripts/host/run-image.sh +} + # # TO PORT # diff --git a/scripts/host/build-image.sh b/scripts/host/build-image.sh old mode 100644 new mode 100755 index 96596c06..7df5df53 --- a/scripts/host/build-image.sh +++ b/scripts/host/build-image.sh @@ -1 +1,2 @@ +#!/usr/bin/env bash docker build . -t kbase/kbase-ui:dev \ No newline at end of file diff --git a/scripts/host/run-image.sh b/scripts/host/run-image.sh old mode 100644 new mode 100755 index 61abfb49..fc18df9a --- a/scripts/host/run-image.sh +++ b/scripts/host/run-image.sh @@ -1,9 +1,12 @@ +#!/usr/bin/env bash + docker network create kbase-dev -# -v `pwd`/build/app/modules/plugins/auth2-client:/kb/deployment/services/kbase-ui/dist/modules/plugins/auth2-client \ + export ENV=ci echo echo "Running kbase-ui production image in development, deploy env is '${ENV}'" echo + docker run \ -v `pwd`/dev/gitlab-config:/kb/deployment/config \ --network kbase-dev \ diff --git a/tools/proxy/contents/conf/nginx.conf-base-path-changes.tmpl b/tools/proxy/contents/conf/nginx.conf-base-path-changes.tmpl new file mode 100644 index 00000000..41782c03 --- /dev/null +++ b/tools/proxy/contents/conf/nginx.conf-base-path-changes.tmpl @@ -0,0 +1,497 @@ +# +# A minimal proxying configuration for running kbase-ui through a secure proxy +# against a KBase deploy environment. +# +# Note that lower case environment variables are taken from conf/*.env, where * is the +# deploy environment, taken from DEPLOY_ENV. + +daemon off; +error_log /dev/stdout info; +worker_processes auto; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + types_hash_max_size 2048; + proxy_headers_hash_bucket_size 256; + proxy_ssl_server_name on; + proxy_request_buffering off; + proxy_buffering off; + proxy_http_version 1.1; + + # In addition to the desired file size limit (in bytes), + # we ad smidgen more, as the multipart/form mime structure + # includes the destPath as one part, the file as another, + # and each has a small header section. + # + # In practice, this appears to be about 300 bytes plus + # the value for destPath and the file name. + # And the mime boundary size will vary as well. + # + # So let's call it 1K and then call it a day. + # So, the max body size should be MAX_FILE_SIZE + 1000. + + # For testing, use a 1K file size, 1K extra. + # Or set as you wish to push boundaries. + # client_max_body_size 2000; + + # For production, 5G max file size plus 1KB extra. + # client_max_body_size 5000001000; + + keepalive_requests 0; + # keepalive_timeout 65; + keepalive_timeout 0; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + + # Define upstream servers, for convenience. + upstream kbase_ui { + # Use 80 for image; 3000 for devcontainer + # server {{ .Env.kbase_ui_host }}:80; + server {{ .Env.kbase_ui_host }}:3000; + # allows the proxy to start up even though the + # dev server may not be running yet + server {{ .Env.kbase_ui_host }}:80 backup; + keepalive 16; + } + + # upstream services { + # server {{ .Env.deploy_hostname }}; + # keepalive 16; + # } + + # upstream dynamic_services { + # server {{ .Env.deploy_hostname }}; + # keepalive 16; + # } + + upstream narrative { + {{ if .Env.local_narrative }} + server narrative:8888; + {{ else }} + {{ if .Env.deploy_ui_hostname }} + server {{ .Env.deploy_ui_hostname }}; + {{ else }} + server {{ .Env.deploy_hostname }}; + {{ end }} + {{ end }} + } + + upstream kbase_navigator { + {{ if .Env.local_navigator }} + server navigator:5000; + {{ else }} + {{ if .Env.deploy_ui_hostname }} + server {{ .Env.deploy_ui_hostname }}; + {{ else }} + server {{ .Env.deploy_hostname }}; + {{ end }} + {{ end }} + } + + log_format upstream_log '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request upstream_response_time $upstream_response_time proxy_host $proxy_host upstream_status $upstream_status upstream_response_length $upstream_response_length upstream_http_location $upstream_http_location msec $msec request_time $request_time'; + + + # Logging Settings + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log debug; + + # Route insecure requests to secure. + server { + listen 80 default_server; + listen [::]:80 default_server; + server_name {{ default .Env.deploy_hostname .Env.deploy_ui_hostname }}; + return 301 https://{{ default .Env.deploy_hostname .Env.deploy_ui_hostname }}$request_uri; + } + + + # If there is a separate ui hostname provided in the configuration, + # we need to listen for this separately. + # The only real usage of this is for production, in which kbase-ui and + # the narrative operate at narrative.kbase.us, but services at kbase.us. + {{ if .Env.deploy_ui_hostname }} + + # server { + # server_name {{ .Env.deploy_ui_hostname }}; + # listen 3000 ssl; + # ssl_certificate /kb/deployment/ssl/test.crt; + # ssl_certificate_key /kb/deployment/ssl/test.key; + # ssl_protocols TLSv1.2 TLSv1.1 TLSv1; + # location /ws/ { + # client_max_body_size 300M; + # proxy_connect_timeout 10s; + # proxy_pass http://kbase_ui/ws/; + # proxy_set_header Upgrade $http_upgrade; + # proxy_set_header Connection "Upgrade"; + # proxy_set_header Host {{ .Env.deploy_ui_hostname }}; + # } + # } + + server { + listen 443 ssl; + server_name {{ .Env.deploy_ui_hostname }}; + ssl_certificate /kb/deployment/ssl/test.crt; + ssl_certificate_key /kb/deployment/ssl/test.key; + ssl_protocols TLSv1.2 TLSv1.1 TLSv1; + + location @request_entity_too_large { + default_type text/plain; + return 413 "Request entity is too large (> 5GB)"; + } + + location /__ping__ { + default_type "text/html"; + return 204; + } + + location /data/__perf__ { + gzip off; + gunzip on; + add_header Cache-Control 'no-cache, no-transform'; + proxy_pass http://kbase_ui; + } + + # Needed for running narratives + location /narrative/ { + access_log /var/log/nginx/narrative.log upstream_log; + + include /etc/nginx/cors.conf; + {{ if .Env.local_narrative }} + proxy_pass http://narrative/narrative/; + {{ else }} + {{ if .Env.deploy_ui_hostname }} + proxy_pass https://{{ .Env.deploy_ui_hostname }}/narrative/; + {{ else }} + proxy_pass https://{{ .Env.deploy_hostname }}/narrative/; + {{ end }} + # proxy_pass https://narrative/narrative/; + {{ end }} + + proxy_connect_timeout 10s; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Origin https://{{ .Env.deploy_ui_hostname }}; + proxy_set_header Host {{ .Env.deploy_ui_hostname }}; + } + + location /ui-assets/ { + proxy_pass https://{{ .Env.deploy_ui_hostname }}; + proxy_set_header Connection ""; + } + + location /sn/ { + proxy_pass https://{{ .Env.deploy_ui_hostname }}; + proxy_set_header Connection ""; + } + + location /narratives/ { + # {{ if .Env.local_navigator }} + # proxy_pass http://navigator/narratives/; + # {{ else }} + # proxy_pass https://kbase_navigator/narratives/; + # {{ end }} + + {{ if .Env.deploy_ui_hostname }} + proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; + {{ else }} + proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; + {{ end }} + + access_log /var/log/nginx/navigator.log upstream_log; + + proxy_set_header Connection ""; + proxy_read_timeout 10m; + proxy_set_header Origin https://{{ .Env.deploy_ui_hostname }}; + proxy_set_header Host {{ .Env.deploy_ui_hostname }}; + } + + location /navigator/ { + # {{ if .Env.local_navigator }} + # proxy_pass http://navigator/narratives/; + # {{ else }} + # proxy_pass https://kbase_navigator/narratives/; + # {{ end }} + + {{ if .Env.deploy_ui_hostname }} + proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; + {{ else }} + proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; + {{ end }} + + access_log /var/log/nginx/navigator.log upstream_log; + + proxy_set_header Connection ""; + proxy_read_timeout 10m; + proxy_set_header Origin https://{{ .Env.deploy_ui_hostname }}; + proxy_set_header Host {{ .Env.deploy_ui_hostname }}; + } + + location {{ .Env.base_path }} { + proxy_pass http://kbase_ui; + #proxy_set_header Cache-Control 'no-store'; + #proxy_set_header Cache-Control 'no-cache'; + #expires 0; + # proxy_set_header Connection ""; + # proxy_set_header Upgrade $http_upgrade; + # proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } + } + + {{ end }} + + # server { + # server_name {{ .Env.deploy_hostname }}; + # listen 3000 ssl; + # ssl_certificate /kb/deployment/ssl/test.crt; + # ssl_certificate_key /kb/deployment/ssl/test.key; + # ssl_protocols TLSv1.2 TLSv1.1 TLSv1; + # proxy_http_version 1.1; + # location /ws/ { + # proxy_connect_timeout 10s; + # proxy_pass http://kbase_ui/ws/; + # proxy_set_header Upgrade $http_upgrade; + # proxy_set_header Connection "Upgrade"; + # proxy_set_header Host {{ .Env.deploy_hostname }}; + # } + # } + + server { + server_name {{ .Env.deploy_hostname }}; + listen 443 ssl; + ssl_certificate /kb/deployment/ssl/test.crt; + ssl_certificate_key /kb/deployment/ssl/test.key; + ssl_protocols TLSv1.2 TLSv1.1 TLSv1; + + location @request_entity_too_large { + default_type application/json; + # return 413 "{\"message\": \"Request entity is too large\", \"responseCode\": 413, \"maxBodySize\": \"5GB\", \"contentLength\": ${content_length}}"; + return 413 "{\"message\": \"Request entity is too large\", \"responseCode\": 413, \"maxBodySize\": \"2KB\", \"contentLength\": ${content_length}}"; + } + + keepalive_requests 0; + keepalive_timeout 0; + proxy_socket_keepalive off; + + # Service proxying + # specified as a list of service modules + # note should put the service module name in /etc/hosts and map to localhost + {{ if .Env.service_proxies }} + {{ range splitList " " .Env.service_proxies }} + + {{ if eq . "searchapi2" }} + location /services/searchapi2/legacy { + {{ if $.Env.deploy_ui_hostname }} + include /etc/nginx/cors.conf; + {{ end }} + proxy_pass http://searchapi2:5000/legacy; + proxy_set_header Connection ""; + } + location /services/searchapi2/rpc { + {{ if $.Env.deploy_ui_hostname }} + include /etc/nginx/cors.conf; + {{ end }} + proxy_pass http://searchapi2:5000/rpc; + proxy_set_header Connection ""; + } + {{ else if eq . "staging_service" }} + location /services/{{ . }}/ { + + # For testing, use a 1K file size, 1K extra. + # Or set as you wish to push boundaries. + client_max_body_size 2000; + + # For production, 5G max file size plus 1KB extra. + # client_max_body_size 5000001000; + + error_page 413 @request_entity_too_large; + {{ if $.Env.deploy_ui_hostname }} + include /etc/nginx/cors.conf; + {{ end }} + proxy_pass http://{{ . }}:3000/; + proxy_set_header Connection ""; + proxy_read_timeout 10m; + } + {{ else }} + location /services/{{ . }}/ { + {{ if $.Env.deploy_ui_hostname }} + include /etc/nginx/cors.conf; + {{ end }} + proxy_pass http://{{ . }}:5000/; + proxy_set_header Connection ""; + proxy_read_timeout 10m; + } + location /services/{{ . }} { + {{ if $.Env.deploy_ui_hostname }} + include /etc/nginx/cors.conf; + {{ end }} + proxy_pass http://{{ . }}:5000; + proxy_set_header Connection ""; + proxy_read_timeout 10m; + } + {{ end }} + + {{ end }} + {{ end }} + + + # Proxy all service calls, including auth2, to the real CI + location /services { + access_log /var/log/nginx/services_proxy.log upstream_log; + + # The cookie path rewriting is just for auth2 + {{ if .Env.deploy_ui_hostname }} + include /etc/nginx/cors.conf; + {{ end }} + proxy_cookie_path /login /services/auth/login; + proxy_cookie_path /link /services/auth/link; + proxy_pass https://{{ .Env.deploy_hostname }}/services; + proxy_set_header Connection ""; + proxy_read_timeout 10m; + } + + # Dynamic Service proxying + # If dynamic services are provided in the configuration, we will proxy requests + # to them to local instances. + # This works by trapping calls to /dynserv/XXX.Module + # where /dynserv/ is always the path prefix for dynamic service call urls provided by + # the service wizard + # where XXX is a random-appearing string component provided by the service wizard + # and Module is the dynamic service module name. + + {{ if .Env.dynamic_service_proxies }} + {{ range splitList " " .Env.dynamic_service_proxies }} + + # note that the elements of the list must match the service path used in the ui call, + # and also the hostname assigned to the docker container. + # SO this means that probably service entries which are more complicated than simple strings + # without punctuation will work, but if they contain a / or something, maybe not. + + location ~ ^/dynserv/[^.]+[.]{{ . }}.*$ { + {{ if $.Env.deploy_ui_hostname }} + include /etc/nginx/cors.conf; + {{ end }} + + # This handles plain dynamic service calls, which don't have any path following the module name + rewrite ^/dynserv/[^.]+[.]{{ . }}$ / break; + + # This handles calls into the dynamic service with the path is propagated. + rewrite ^/dynserv/[^.]+[.]{{ . }}(.*)$ $1 break; + proxy_pass http://{{ . }}:5000; + proxy_read_timeout 10m; + } + + {{ end }} + {{ end }} + + # Un-trapped dynamic service calls are routed to the real dynamic service + # endpoints. + location /dynserv { + {{ if .Env.deploy_ui_hostname }} + include /etc/nginx/cors.conf; + {{ end }} + proxy_pass https://{{ .Env.deploy_hostname }}/dynserv; + proxy_set_header Connection ""; + proxy_read_timeout 10m; + } + + # Repeat the ui proxying for the case in which they reside on the same + # host name as services. + {{ if not .Env.deploy_ui_hostname }} + + location /__ping__ { + default_type "text/html"; + return 204; + } + + location /narrative/ { + {{ if .Env.local_narrative }} + proxy_pass http://narrative/narrative/; + {{ else }} + {{ if .Env.deploy_ui_hostname }} + proxy_pass https://{{ .Env.deploy_ui_hostname }}/narrative/; + {{ else }} + proxy_pass https://{{ .Env.deploy_hostname }}/narrative/; + {{ end }} + # proxy_pass https://narrative/narrative/; + {{ end }} + + access_log /var/log/nginx/narrative.log upstream_log; + + proxy_connect_timeout 10s; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Origin https://{{ .Env.deploy_hostname }}; + proxy_set_header Host {{ .Env.deploy_hostname }}; + } + + location /ui-assets/ { + proxy_pass https://{{ .Env.deploy_hostname }}; + proxy_set_header Connection ""; + } + + location /sn/ { + proxy_pass https://{{ .Env.deploy_hostname }}; + proxy_set_header Connection ""; + } + + location /n/ { + proxy_pass https://{{ .Env.deploy_hostname }}; + proxy_set_header Connection ""; + } + + location /narratives/ { + # {{ if .Env.local_navigator }} + # proxy_pass http://navigator/narratives/; + # {{ else }} + # proxy_pass https://kbase_navigator/narratives/; + # {{ end }} + {{ if .Env.deploy_ui_hostname }} + proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; + {{ else }} + proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; + {{ end }} + + access_log /var/log/nginx/navigator.log upstream_log; + + proxy_set_header Connection ""; + proxy_read_timeout 10m; + proxy_set_header Origin https://{{ .Env.deploy_hostname }}; + proxy_set_header Host {{ .Env.deploy_hostname }}; + } + + # location /vite_hms { + # proxy_pass http://{{ .Env.deploy_hostname }}:3001/vite_hms; + # proxy_http_version 1.1; + # proxy_set_header Upgrade $http_upgrade; + # proxy_set_header Connection "Upgrade"; + # proxy_set_header Host {{ .Env.deploy_hostname }}; + # } + + location {{ .Env.base_path }} { + proxy_pass http://kbase_ui; + proxy_set_header Connection ""; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } + + {{ end }} + } +} \ No newline at end of file diff --git a/tools/proxy/contents/conf/nginx.conf.tmpl b/tools/proxy/contents/conf/nginx.conf.tmpl index 1bfe9664..41782c03 100644 --- a/tools/proxy/contents/conf/nginx.conf.tmpl +++ b/tools/proxy/contents/conf/nginx.conf.tmpl @@ -153,12 +153,12 @@ http { return 413 "Request entity is too large (> 5GB)"; } - location {{ .Env.BASE_PATH }}/__ping__ { + location /__ping__ { default_type "text/html"; return 204; } - location {{ .Env.BASE_PATH }}/data/__perf__ { + location /data/__perf__ { gzip off; gunzip on; add_header Cache-Control 'no-cache, no-transform'; @@ -226,7 +226,7 @@ http { # proxy_pass https://kbase_navigator/narratives/; # {{ end }} - {{ if .Env.deploy_ui_hostname }} + {{ if .Env.deploy_ui_hostname }} proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; {{ else }} proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; @@ -240,21 +240,7 @@ http { proxy_set_header Host {{ .Env.deploy_ui_hostname }}; } - location {{ .Env.BASE_PATH }} { - proxy_pass http://kbase_ui; - #proxy_set_header Cache-Control 'no-store'; - #proxy_set_header Cache-Control 'no-cache'; - #expires 0; - # proxy_set_header Connection ""; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - } - - # This one to handle legacy plugin /modules/plugins paths in dev - location / { + location {{ .Env.base_path }} { proxy_pass http://kbase_ui; #proxy_set_header Cache-Control 'no-store'; #proxy_set_header Cache-Control 'no-cache'; @@ -429,7 +415,7 @@ http { # host name as services. {{ if not .Env.deploy_ui_hostname }} - location {{ .Env.BASE_PATH }}/__ping__ { + location /__ping__ { default_type "text/html"; return 204; } @@ -498,16 +484,7 @@ http { # proxy_set_header Host {{ .Env.deploy_hostname }}; # } - location {{ .Env.BASE_PATH }} { - proxy_pass http://kbase_ui; - proxy_set_header Connection ""; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - } - - # legacy plugins - location / { + location {{ .Env.base_path }} { proxy_pass http://kbase_ui; proxy_set_header Connection ""; proxy_http_version 1.1; diff --git a/tools/proxy/docker-compose.yml b/tools/proxy/docker-compose.yml index 0edea586..b302c517 100644 --- a/tools/proxy/docker-compose.yml +++ b/tools/proxy/docker-compose.yml @@ -15,5 +15,7 @@ services: - '80:80' - '443:443' dns: 8.8.8.8 + environment: + - BASE_PATH=${BASE_PATH} # note that this is really a docker env file and is relative to the docker-compose file env_file: ./conf/${DEPLOY_ENV}.env From 587b63447a307fd1dd4ae37e82072e39a9de2bf1 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 25 Oct 2023 19:46:15 +0000 Subject: [PATCH 007/128] set target for to "_top" for the auto-form-post [URO-183] --- vite-app/src/pluginSupport/AutoPostForm.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vite-app/src/pluginSupport/AutoPostForm.tsx b/vite-app/src/pluginSupport/AutoPostForm.tsx index 2bfbbfc7..514ca694 100644 --- a/vite-app/src/pluginSupport/AutoPostForm.tsx +++ b/vite-app/src/pluginSupport/AutoPostForm.tsx @@ -6,7 +6,7 @@ export interface AutoPostFormProps { action: string; } -interface AutoPostFormState {} +interface AutoPostFormState { } export default class AutoPostForm extends Component< AutoPostFormProps, @@ -43,6 +43,7 @@ export default class AutoPostForm extends Component< ref={this.ref} id={formID} action={action} + target="_top" style={{ display: 'hidden' }} > {paramInputs} From 06824c1d5f556e9719bbab4197a962ec842ad228 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Fri, 22 Mar 2024 14:39:01 -0700 Subject: [PATCH 008/128] big big set of changes (wip) [CE-314] the result of refactoring for Europa, fixing plugins, importing a few plugins into kbase-ui, --- .devcontainer/Dockerfile-devcontainer | 4 +- .devcontainer/custom.env | 10 - .devcontainer/devcontainer.env | 1 - .devcontainer/docker-compose.yml | 69 +- .eslintrc | 41 + .eslintrc.yml | 48 - .gitignore | 1 + .prettierignore | 2 + .prettierrc | 9 + .prettierrc.yaml | 5 - .vscode/settings.json | 5 +- LICENSE.md | 2 +- Taskfile | 91 +- config/plugins.yml | 44 +- deployment/config/ci_config.ini | 2 +- deployment/templates/config.json.tmpl | 116 +- deployment/templates/nginx.conf.tmpl | 145 +- docker-compose.yml | 11 +- docs/deployment/configuration.md | 41 +- docs/development/deployment-setup.md | 70 + docs/development/development-setup.md | 211 + docs/environment-variables.md | 203 + scripts/container/generate-proxy-env | 112 + scripts/container/generate-runtime-env | 153 + scripts/host/build.sh | 5 +- scripts/host/clean-build.sh | 2 - scripts/host/extend-docker-compose.sh | 1 - scripts/host/re-build.sh | 2 +- scripts/host/test.sh | 4 +- tools/dockerize/docker-compose.yml | 10 +- .../dockerize/scripts/render-proxy-configs.sh | 26 + tools/dockerize/scripts/render-templates.sh | 54 +- tools/make-dev-cert.sh | 2 +- tools/node/Dockerfile | 4 +- tools/node/docker-compose.yml | 10 +- tools/node/run | 3 + tools/proxy/README.md | 5 +- tools/proxy/conf/README.md | 6 - tools/proxy/conf/appdev.env | 16 - tools/proxy/conf/ci.env | 16 - tools/proxy/conf/dev.env | 16 - tools/proxy/conf/narrative-dev.env | 16 - tools/proxy/conf/narrative2.env | 16 - tools/proxy/conf/next.env | 18 - tools/proxy/conf/prod.env | 17 - tools/proxy/contents/conf/cors.conf.tmpl | 8 +- .../conf/nginx.conf-base-path-changes.tmpl | 497 - tools/proxy/contents/conf/nginx.conf.tmpl | 382 +- tools/proxy/docker-compose.yml | 3 + vite-app/index.html | 10 +- vite-app/package-lock.json | 3889 +++-- vite-app/package.json | 74 +- vite-app/public/data/__perf__/0b.txt | 0 vite-app/public/js/gtagSupport.js | 443 - .../applets/about/AboutBuild/AboutBuild.tsx | 6 +- .../src/applets/about/AboutBuild/index.tsx | 8 +- .../src/applets/about/AboutCoreServices.tsx | 2 +- .../about/AboutKBaseUI/AboutKBaseUI.tsx | 496 +- .../src/applets/about/AboutKBaseUI/index.tsx | 8 +- vite-app/src/applets/about/AboutMenu.tsx | 43 + .../about/AboutPlugins/AboutPlugins.tsx | 16 +- .../src/applets/about/AboutPlugins/index.tsx | 7 +- .../about/AboutService/AboutService.tsx | 5 +- .../about/AboutService/AboutServiceMain.tsx | 11 +- vite-app/src/applets/about/AboutServices.tsx | 232 +- vite-app/src/applets/about/AboutServices2.tsx | 165 - .../applets/about/AboutSession/controller.tsx | 119 + .../ConnectionStatus/ConnectionStatus.tsx | 61 +- .../src/applets/about/ServicePerformance.ts | 40 +- vite-app/src/applets/about/index.module.css | 16 + vite-app/src/applets/about/index.tsx | 43 +- ...nfigEditor.css => ConfigEditor.module.css} | 4 +- .../src/applets/developer/ConfigEditor.tsx | 12 +- .../src/applets/developer/Features.module.css | 2 +- vite-app/src/applets/developer/Features.tsx | 2 +- .../applets/developer/FeaturesController.tsx | 5 +- .../src/applets/developer/Main.module.css | 2 +- vite-app/src/applets/developer/Main.tsx | 2 +- .../developer/{index.css => index.module.css} | 8 +- vite-app/src/applets/developer/index.tsx | 11 +- .../applets/development/DevelopmentAuth.tsx | 88 - .../applets/development/DevelopmentLogin.tsx | 130 - .../development/DevelopmentLoginForm.tsx | 84 - .../applets/development/DevelopmentLogout.tsx | 111 - .../src/applets/narrativeLoader/index.tsx | 135 +- vite-app/src/apps/Auth.tsx | 216 - .../Account/AccountEditor/view.tsx | 100 + .../Account/AccountInfo/view.tsx | 71 + .../AccountManager/Account/controller.tsx | 185 + .../Auth2/AccountManager/Account/view.tsx | 49 + .../Auth2/AccountManager/AddTokenForm.tsx | 49 + .../AccountManager/DevToken/controller.tsx | 207 + .../AccountManager/DevToken/view.module.css | 5 + .../Auth2/AccountManager/DevToken/view.tsx | 246 + .../LinkedIDProviders/controller.tsx | 176 + .../LinkedIDProviders/view.module.css | 29 + .../AccountManager/LinkedIDProviders/view.tsx | 154 + .../AccountManager/LoginTokens/controller.tsx | 198 + .../LoginTokens/view.module.css | 11 + .../Auth2/AccountManager/LoginTokens/view.tsx | 233 + .../AccountManager/ServToken/controller.tsx | 210 + .../AccountManager/ServToken/view.module.css | 5 + .../Auth2/AccountManager/ServToken/view.tsx | 253 + .../TermsAndConditions/controller.tsx | 81 + .../TermsAndConditions/view.tsx | 104 + .../apps/Auth2/AccountManager/TokenCopy.tsx | 71 + .../apps/Auth2/AccountManager/controller.tsx | 28 + .../src/apps/Auth2/AccountManager/view.tsx | 241 + vite-app/src/apps/Auth2/Collapsible.css | 3 + vite-app/src/apps/Auth2/Collapsible.tsx | 48 + .../src/apps/Auth2/CountdownAlarmClock.tsx | 73 + vite-app/src/apps/Auth2/CountdownClock.tsx | 86 + .../Auth2/LinkContinue/ContinueHeader.css | 21 + .../Auth2/LinkContinue/ContinueHeader.tsx | 59 + .../apps/Auth2/LinkContinue/controller.tsx | 270 + vite-app/src/apps/Auth2/LinkContinue/view.css | 5 + vite-app/src/apps/Auth2/LinkContinue/view.tsx | 61 + vite-app/src/apps/Auth2/Providers.ts | 79 + vite-app/src/apps/Auth2/SignIn/SignIn.tsx | 174 + .../src/apps/Auth2/SignIn/SignInButton.css | 25 + .../src/apps/Auth2/SignIn/SignInButton.tsx | 84 + .../src/apps/Auth2/SignIn/SignInControls.css | 67 + .../src/apps/Auth2/SignIn/SignInControls.tsx | 240 + vite-app/src/apps/Auth2/SignIn/SignInView.tsx | 381 + .../SignInContinue/CheckUsernameField.tsx | 61 + .../src/apps/Auth2/SignInContinue/Policy.ts | 83 + .../SignInContinue/PolicyAndAgreement copy.ts | 293 + .../SignInContinue/PolicyAndAgreement.ts | 285 + .../Auth2/SignInContinue/SignInContinue.tsx | 861 + .../SignInContinue/SignInContinueForm.css | 7 + .../SignInContinue/SignInContinueForm.tsx | 258 + .../SignInContinue/SignInContinueView.css | 26 + .../SignInContinue/SignInContinueView.tsx | 183 + .../apps/Auth2/SignInContinue/SignInOops.tsx | 135 + .../Auth2/SignInContinue/SignUpContinue.tsx | 156 + .../apps/Auth2/SignInContinue/SignUpForm.tsx | 459 + .../src/apps/Auth2/SignedOut/controller.tsx | 94 + vite-app/src/apps/Auth2/SignedOut/view.tsx | 45 + .../src/apps/Auth2/Signout/controller.tsx | 0 vite-app/src/apps/Auth2/Signout/view.tsx | 0 vite-app/src/apps/Auth2/TextSpan.tsx | 25 + vite-app/src/apps/Auth2/UseAgreements.css | 9 + vite-app/src/apps/Auth2/UseAgreements.tsx | 175 + .../Auth2/resources/agreements/policies.json | 31 + .../agreements/terms-and-conditions copy.json | 21 + .../agreements/terms-and-conditions.json | 16 + .../apps/Auth2/resources/css/flex-tabs.css | 94 + .../src/apps/Auth2/resources/css/main.css | 105 + .../src/apps/Auth2/resources/data/config.yml | 3 + .../resources/data/globus-providers.json | 1108 ++ .../Auth2/resources/data/institutions.csv | 4666 +++++ .../Auth2/resources/data/institutions.json | 1 + .../Auth2/resources/data/nationalLabs.yaml | 112 + .../Auth2/resources/data/organizations.json | 14068 ++++++++++++++++ .../apps/Auth2/resources/data/providers.json | 26 + .../apps/Auth2/resources/data/providers.yaml | 27 + .../Auth2/resources/data/referralSources.json | 47 + .../resources/dataSources/avatarOptions.json | 10 + .../resources/dataSources/countries.json | 248 + .../resources/dataSources/fundingSources.json | 40 + .../dataSources/gravatarDefaults.json | 16 + .../resources/dataSources/institutions.json | 1 + .../resources/dataSources/jobTitles.json | 17 + .../resources/dataSources/nationalLabs.json | 134 + .../resources/dataSources/nationalLabs.yaml | 112 + .../resources/dataSources/otherLabs.json | 16 + .../resources/dataSources/otherLabs.yaml | 14 + .../dataSources/researchInterests.json | 41 + .../Auth2/resources/dataSources/states.json | 237 + .../src/apps/Auth2/resources/docs/design.md | 73 + vite-app/src/apps/Auth2/resources/doodle.png | Bin 0 -> 6760 bytes .../Auth2/resources/images/kbase-logo-99.png | Bin 0 -> 13616 bytes .../apps/Auth2/resources/images/nouserpic.png | Bin 0 -> 45226 bytes .../Auth2/resources/providers/globus/logo.png | Bin 0 -> 2119 bytes .../globus/signin-button/200px/disabled.png | Bin 0 -> 4736 bytes .../globus/signin-button/200px/hover.png | Bin 0 -> 5237 bytes .../globus/signin-button/200px/normal.png | Bin 0 -> 5223 bytes .../globus/signin-button/200px/pressed.png | Bin 0 -> 5279 bytes .../globus/signin-button/disabled.png | Bin 0 -> 4115 bytes .../providers/globus/signin-button/hover.png | Bin 0 -> 4558 bytes .../signin-button/light/btn-disabled.png | Bin 0 -> 4940 bytes .../globus/signin-button/light/btn-focus.png | Bin 0 -> 5781 bytes .../globus/signin-button/light/btn-normal.png | Bin 0 -> 5778 bytes .../signin-button/light/btn-pressed.png | Bin 0 -> 6545 bytes .../providers/globus/signin-button/normal.png | Bin 0 -> 4527 bytes .../globus/signin-button/pressed.png | Bin 0 -> 4575 bytes .../Auth2/resources/providers/globus_logo.png | Bin 0 -> 2119 bytes .../Auth2/resources/providers/google/logo.png | Bin 0 -> 1323 bytes .../google/signin-button/200px/disabled.png | Bin 0 -> 3953 bytes .../google/signin-button/200px/hover.png | Bin 0 -> 4375 bytes .../google/signin-button/200px/normal.png | Bin 0 -> 4293 bytes .../google/signin-button/200px/pressed.png | Bin 0 -> 4314 bytes .../google/signin-button/disabled.png | Bin 0 -> 3597 bytes .../providers/google/signin-button/hover.png | Bin 0 -> 3961 bytes .../signin-button/light/btn-disabled.png | Bin 0 -> 2308 bytes .../google/signin-button/light/btn-focus.png | Bin 0 -> 4328 bytes .../google/signin-button/light/btn-normal.png | Bin 0 -> 4099 bytes .../signin-button/light/btn-pressed.png | Bin 0 -> 4135 bytes .../providers/google/signin-button/normal.png | Bin 0 -> 3889 bytes .../google/signin-button/pressed.png | Bin 0 -> 3989 bytes .../Auth2/resources/providers/google_logo.png | Bin 0 -> 1323 bytes .../Auth2/resources/providers/orcid/logo.png | Bin 0 -> 1542 bytes .../Auth2/resources/providers/orcid/logox.png | Bin 0 -> 2119 bytes .../orcid/signin-button/200px/disabled.png | Bin 0 -> 3402 bytes .../orcid/signin-button/200px/hover.png | Bin 0 -> 3888 bytes .../orcid/signin-button/200px/normal.png | Bin 0 -> 3746 bytes .../orcid/signin-button/200px/pressed.png | Bin 0 -> 3904 bytes .../orcid/signin-button/darker/disabled.png | Bin 0 -> 3524 bytes .../orcid/signin-button/darker/hover.png | Bin 0 -> 3907 bytes .../orcid/signin-button/darker/normal.png | Bin 0 -> 3833 bytes .../orcid/signin-button/darker/pressed.png | Bin 0 -> 3882 bytes .../orcid/signin-button/disabled.png | Bin 0 -> 3141 bytes .../providers/orcid/signin-button/hover.png | Bin 0 -> 3580 bytes .../signin-button/light/btn-disabled.png | Bin 0 -> 4940 bytes .../orcid/signin-button/light/btn-focus.png | Bin 0 -> 5781 bytes .../orcid/signin-button/light/btn-normal.png | Bin 0 -> 5778 bytes .../orcid/signin-button/light/btn-pressed.png | Bin 0 -> 6545 bytes .../providers/orcid/signin-button/normal.png | Bin 0 -> 3464 bytes .../providers/orcid/signin-button/pressed.png | Bin 0 -> 3613 bytes .../Auth2/resources/providers/orcid_logo.png | Bin 0 -> 2119 bytes vite-app/src/apps/Catalog.tsx | 24 +- vite-app/src/apps/Feeds/api/Feeds.ts | 175 + vite-app/src/apps/Feeds/api/Groups.ts | 32 + vite-app/src/apps/Feeds/api/RestClient.ts | 85 + vite-app/src/apps/Feeds/components/Entity.tsx | 96 + .../src/apps/Feeds/components/controller.tsx | 828 + vite-app/src/apps/Feeds/components/feed.xts | 156 + .../src/apps/Feeds/components/feedTabs.xts | 237 + .../apps/Feeds/components/globalPoster.xts | 174 + .../apps/Feeds/components/notification.xts | 203 + .../src/apps/Feeds/components/view.module.css | 152 + vite-app/src/apps/Feeds/components/view.tsx | 704 + .../notifications/GroupsNotification.tsx | 226 + .../notifications/NarrativeNotification.tsx | 128 + .../Feeds/notifications/NoNotifications.tsx | 125 + .../notifications/Notification.module.css | 39 + .../apps/Feeds/notifications/Notification.tsx | 370 + .../Feeds/notifications/NotificationAlert.tsx | 79 + .../src/apps/Feeds/notifications/base.xts | 103 + .../src/apps/Feeds/notifications/groups.xts | 111 + .../src/apps/Feeds/notifications/icons.xts | 28 + .../apps/Feeds/notifications/narrative.xts | 68 + vite-app/src/apps/Feeds/utils.ts | 45 + .../components/AdminJobs/UserJobsRequest.ts | 75 + .../JobBrowser/components/AdminJobs/index.tsx | 168 + .../JobBrowser/components/AdminJobs/style.css | 148 + .../JobBrowser/components/AdminJobs/view.tsx | 810 + .../apps/JobBrowser/components/DatePicker.tsx | 8 + .../JobBrowser/components/ErrorBoundary.tsx | 37 + .../FilterEditor/AppFunctionSelect/index.tsx | 121 + .../FilterEditor/AppFunctionSelect/view.tsx | 64 + .../FilterEditor/AppModuleSelect/index.tsx | 107 + .../FilterEditor/AppModuleSelect/index.xtsx | 46 + .../FilterEditor/AppModuleSelect/view.tsx | 67 + .../FilterEditor/AppSelect/index.tsx | 117 + .../FilterEditor/AppSelect/view.tsx | 64 + .../FilterEditor/ClientGroupsSelect/index.tsx | 122 + .../FilterEditor/ClientGroupsSelect/view.tsx | 64 + .../FilterEditor/NarrativeSelect/index.tsx | 111 + .../FilterEditor/NarrativeSelect/view.tsx | 58 + .../FilterEditor/UserSelect/index.tsx | 80 + .../FilterEditor/UserSelect/view.tsx | 51 + .../components/FilterEditor/controller.tsx | 42 + .../components/FilterEditor/data.xtsx | 60 + .../components/FilterEditor/index.xtsx | 54 + .../components/FilterEditor/view.tsx | 352 + .../JobBrowser/components/JobDetail/index.tsx | 359 + .../JobBrowser/components/JobDetail/index.xts | 52 + .../JobBrowser/components/JobDetail/style.css | 3 + .../JobBrowser/components/JobDetail/view.tsx | 177 + .../apps/JobBrowser/components/JobInfo.tsx | 195 + .../JobBrowser/components/JobLog/index.tsx | 333 + .../JobBrowser/components/JobLog/style.css | 55 + .../JobBrowser/components/JobLog/view.tsx | 498 + .../JobBrowser/components/JobStatusBadge.tsx | 204 + .../apps/JobBrowser/components/Main/index.tsx | 113 + .../apps/JobBrowser/components/Main/style.css | 48 + .../apps/JobBrowser/components/Main/view.tsx | 128 + .../apps/JobBrowser/components/Monitor.tsx | 182 + .../components/MyJobs/MyJobsRequest.ts | 74 + .../JobBrowser/components/MyJobs/index.tsx | 167 + .../JobBrowser/components/MyJobs/style.css | 375 + .../JobBrowser/components/MyJobs/view.tsx | 840 + .../JobBrowser/components/NarrativeLink.tsx | 16 + .../JobBrowser/components/NiceElapsedTime.tsx | 96 + .../components/NiceRelativeTime.tsx | 123 + .../components/PublicAppStats/index.tsx | 177 + .../components/PublicAppStats/style.css | 7 + .../components/PublicAppStats/view.tsx | 248 + .../JobBrowser/components/Table/Table.css | 121 + .../JobBrowser/components/Table/TableNav.tsx | 138 + .../JobBrowser/components/Table/index.tsx | 573 + .../apps/JobBrowser/components/UILink.xtsx | 26 + .../components/UserJobs/MyJobsRequest.ts | 74 + .../JobBrowser/components/UserJobs/index.tsx | 180 + .../JobBrowser/components/UserJobs/index.xtsx | 61 + .../JobBrowser/components/UserJobs/style.css | 375 + .../JobBrowser/components/UserJobs/view.tsx | 867 + .../components/UserRunSummary/index.tsx | 140 + .../components/UserRunSummary/index.xtsx | 44 + .../components/UserRunSummary/style.css | 7 + .../components/UserRunSummary/view.tsx | 164 + .../src/apps/JobBrowser/lib/AsyncQueue.xts | 67 + .../apps/JobBrowser/lib/CancelableRequest.ts | 46 + .../JobBrowser/lib/JobBrowserBFFClient.ts | 357 + .../JobBrowser/lib/MetricsServiceClient.ts | 95 + vite-app/src/apps/JobBrowser/lib/Poll.ts | 186 + vite-app/src/apps/JobBrowser/lib/Poller.ts | 251 + vite-app/src/apps/JobBrowser/lib/PubSub.ts | 147 + vite-app/src/apps/JobBrowser/lib/PubSub.xts | 217 + .../src/apps/JobBrowser/lib/TableResizer.ts | 110 + vite-app/src/apps/JobBrowser/lib/time.ts | 339 + vite-app/src/apps/JobBrowser/lib/types.ts | 4 + .../apps/JobBrowser/store/PublicAppStats.ts | 76 + .../apps/JobBrowser/store/UserRunSummary.ts | 74 + vite-app/src/apps/JobBrowser/store/base.ts | 57 + vite-app/src/apps/JobBrowser/store/index.ts | 578 + vite-app/src/apps/JobBrowser/types/base.ts | 2 + vite-app/src/apps/JobBrowser/types/error.ts | 12 + .../src/apps/JobBrowser/types/jobState.ts | 83 + vite-app/src/apps/JobBrowser/types/json.ts | 37 + vite-app/src/apps/JobBrowser/utils.ts | 273 + ...oading.css => NarrativeLoading.module.css} | 6 +- .../NarrativeManager/NarrativeLoading.tsx | 5 +- .../apps/NarrativeManager/NarrativeManager.ts | 18 +- vite-app/src/apps/NarrativeManager/New.tsx | 22 +- .../apps/NarrativeManager/OpenNarrative.tsx | 26 +- vite-app/src/apps/NarrativeManager/Start.tsx | 11 +- vite-app/src/apps/NarrativeManager/index.xtsx | 2 +- vite-app/src/apps/Navigator/Navigator.tsx | 24 +- .../src/apps/Navigator/api/IconProvider.ts | 32 +- vite-app/src/apps/Navigator/api/icons.json | 236 +- .../src/apps/Navigator/bootstrapOverrides.css | 4 +- .../src/apps/Navigator/components/Icon.tsx | 75 +- .../src/apps/Navigator/components/Main.tsx | 7 +- .../components/NarrativeDetails/DataView.tsx | 143 +- .../NarrativeDetails/NarrativeDetails.tsx | 255 +- .../NarrativeDetailsWrapper.tsx | 25 +- .../NarrativeDetails/NarrativeHeader.tsx | 626 +- .../components/NarrativeDetails/Preview.tsx | 333 +- .../NarrativeDetails/PreviewCell.tsx | 6 +- .../NarrativeDetails/ToolMenu/CopyItem.tsx | 2 +- .../ToolMenu/DeleteNarrative.tsx | 2 + .../NarrativeDetails/ToolMenu/LinkOrgItem.tsx | 14 +- .../NarrativeDetails/ToolMenu/Model.ts | 4 +- .../NarrativeDetails/ToolMenu/OrgSelect.tsx | 16 +- .../NarrativeDetails/ToolMenu/RenameItem.tsx | 3 +- .../NarrativeDetails/ToolMenu/ToolMenu.tsx | 3 +- .../ToolMenu/ToolMenuWrapper.tsx | 6 +- .../ToolMenu/sharing/PermSearch.tsx | 30 +- .../ToolMenu/sharing/SharingItem.tsx | 4 +- .../NarrativeDetails/cells/AppCell.tsx | 4 +- .../NarrativeDetails/cells/DataObjectCell.tsx | 10 +- .../NarrativeDetails/cells/MarkdownCell.tsx | 2 +- .../cells/ServiceWidgetCell.module.css | 17 + .../cells/ServiceWidgetCell.tsx | 136 + .../NarrativeList/NarrativeList.tsx | 6 +- .../components/NarrativeList/SortControl.tsx | 16 +- .../context/NavigatorContextWrapper.tsx | 2 +- .../src/apps/ORCIDLink/Error/Controller.tsx | 4 +- vite-app/src/apps/ORCIDLink/Error/View.tsx | 4 +- vite-app/src/apps/ORCIDLink/ORCIDLink.tsx | 275 +- .../src/apps/ORCIDLink/continue/Continue.tsx | 24 +- .../ORCIDLink/continue/ContinueController.tsx | 106 +- .../src/apps/ORCIDLink/continue/Error.tsx | 267 +- .../apps/ORCIDLink/home/HomeController.tsx | 41 +- .../ORCIDLink/home/LinkPermissions/View.tsx | 101 +- .../ORCIDLink/home/LinkPermissions/index.tsx | 4 +- vite-app/src/apps/ORCIDLink/home/View.tsx | 469 +- .../ORCIDLink/lib/DynamicServiceClient.ts | 2 - vite-app/src/apps/ORCIDLink/lib/Model.ts | 8 +- .../src/apps/ORCIDLink/lib/ORCIDLinkClient.ts | 43 +- .../src/apps/ORCIDLink/link/CreateLink.tsx | 45 +- .../apps/ORCIDLink/link/LinkController.tsx | 18 +- .../src/apps/ORCIDLink/manage/controller.tsx | 4 +- .../manage/linkingSessions/controller.tsx | 54 +- .../manage/linkingSessions/index.tsx | 19 +- .../ORCIDLink/manage/linkingSessions/view.tsx | 666 +- .../ORCIDLink/manage/overview/controller.tsx | 4 +- .../apps/ORCIDLink/manage/overview/index.tsx | 15 +- .../apps/ORCIDLink/manage/overview/view.tsx | 4 +- .../manage/queryLinks/controller.tsx | 45 +- .../ORCIDLink/manage/queryLinks/index.tsx | 19 +- .../apps/ORCIDLink/manage/queryLinks/view.tsx | 256 +- .../manage/serviceInfo/controller.tsx | 4 +- .../ORCIDLink/manage/serviceInfo/index.tsx | 15 +- .../ORCIDLink/manage/serviceInfo/view.tsx | 44 +- .../ORCIDLink/manage/viewLink/controller.tsx | 4 +- .../apps/ORCIDLink/manage/viewLink/index.tsx | 20 +- .../apps/ORCIDLink/manage/viewLink/view.tsx | 6 +- .../src/apps/ORCIDLink/revoke/Controller.tsx | 6 +- vite-app/src/apps/ORCIDLink/revoke/View.tsx | 8 +- vite-app/src/apps/Organizations.tsx | 22 +- vite-app/src/apps/Typeview/TypeIcon.tsx | 142 + vite-app/src/apps/Typeview/common.tsx | 44 + .../Typeview/module/DataTable7.css} | 54 +- .../src/apps/Typeview/module/DataTable7.tsx | 264 + .../apps/Typeview/module/IncludedModules.tsx | 55 + .../src/apps/Typeview/module/Overview.css | 19 + .../src/apps/Typeview/module/Overview.tsx | 89 + vite-app/src/apps/Typeview/module/Spec.css | 4 + vite-app/src/apps/Typeview/module/Spec.tsx | 21 + vite-app/src/apps/Typeview/module/Types.tsx | 66 + .../src/apps/Typeview/module/Versions.tsx | 70 + .../src/apps/Typeview/module/controller.tsx | 124 + vite-app/src/apps/Typeview/module/view.css | 25 + vite-app/src/apps/Typeview/module/view.tsx | 51 + vite-app/src/apps/Typeview/syntax.ts | 41 + .../src/apps/Typeview/type/DataTable7.css | 111 + .../src/apps/Typeview/type/DataTable7.tsx | 264 + vite-app/src/apps/Typeview/type/Overview.css | 19 + vite-app/src/apps/Typeview/type/Overview.tsx | 87 + vite-app/src/apps/Typeview/type/Spec.css | 4 + vite-app/src/apps/Typeview/type/Spec.tsx | 21 + vite-app/src/apps/Typeview/type/TypesUsed.tsx | 66 + .../src/apps/Typeview/type/TypesUsing.tsx | 66 + vite-app/src/apps/Typeview/type/Versions.tsx | 52 + .../src/apps/Typeview/type/controller.tsx | 142 + vite-app/src/apps/Typeview/type/view.css | 25 + vite-app/src/apps/Typeview/type/view.tsx | 92 + vite-app/src/apps/Typeview/typeIcons.json | 226 + vite-app/src/apps/UserProfile/API.tsx | 2 - .../UserProfile/Narratives/controller.tsx | 4 +- .../src/apps/UserProfile/Narratives/view.tsx | 196 +- .../apps/UserProfile/Profile/Orgs/Orgs.tsx | 67 +- .../src/apps/UserProfile/Profile/Profile.css | 9 + .../UserProfile/Profile/ProfileEditor.tsx | 2633 +-- .../UserProfile/Profile/ProfileViewer.tsx | 197 +- .../apps/UserProfile/Profile/controller.tsx | 11 +- .../Profile/fields/Organization.tsx | 2 + .../UserProfile/SearchUsers/controller.tsx | 2 +- .../src/apps/UserProfile/SearchUsers/view.tsx | 3 +- vite-app/src/apps/UserProfile/constants.ts | 5 - vite-app/src/apps/UserProfile/index.tsx | 17 +- vite-app/src/apps/UserProfile/types.ts | 2 - vite-app/src/apps/UserProfile/utils.ts | 2 +- vite-app/src/apps/gallery/index.tsx | 6 +- vite-app/src/behavior.ts | 10 + vite-app/src/bootstrap-custom.scss | 7 - vite-app/src/components/AlertMessage.tsx | 5 +- vite-app/src/components/App.tsx | 85 +- vite-app/src/components/AsyncUnwrapper.tsx | 26 - vite-app/src/components/AuthProblem/index.tsx | 62 +- vite-app/src/components/Body.tsx | 398 +- vite-app/src/components/Body2.tsx | 517 - vite-app/src/components/CountdownClock.tsx | 10 +- .../src/components/DataBrowser.module.css | 3 +- vite-app/src/components/DataTable.tsx | 275 - vite-app/src/components/Deployment.module.css | 23 - vite-app/src/components/Deployment.tsx | 36 - vite-app/src/components/Empty.module.css | 4 + vite-app/src/components/Empty.tsx | 15 +- .../{ErrorAlert.css => ErrorAlert.module.css} | 6 +- vite-app/src/components/ErrorAlert.test.tsx | 4 +- vite-app/src/components/ErrorAlert.tsx | 13 +- vite-app/src/components/ErrorMessage.tsx | 4 +- vite-app/src/components/ErrorView.module.css | 15 + vite-app/src/components/ErrorView.styles.ts | 19 - vite-app/src/components/ErrorView.tsx | 17 +- vite-app/src/components/ExternalRedirect.tsx | 34 - vite-app/src/components/FlexGrid.module.css | 32 - vite-app/src/components/FlexGrid.tsx | 74 - .../HamburgerMenu-logo.module.css | 23 - .../HamburgerMenu/HamburgerMenu-logo.tsx | 104 - .../HamburgerMenu/HamburgerMenu.module.css | 23 - .../HamburgerMenu/HamburgerMenu.tsx | 106 - .../HamburgerMenuLogo.module.css | 23 - .../HamburgerMenu/HamburgerMenuLogo.tsx | 108 - .../HamburgerMenu/HamburgerMenuMain.tsx | 125 - .../components/HamburgerMenu/kbase_logo.png | Bin 2018 -> 0 bytes vite-app/src/components/HelpLinks.tsx | 10 +- vite-app/src/components/Loading.module.css | 27 + vite-app/src/components/Loading.styles.ts | 34 - vite-app/src/components/Loading.tsx | 12 +- vite-app/src/components/Logo/Logo.tsx | 31 - vite-app/src/components/Logo/kbase_logo.png | Bin 2018 -> 0 bytes vite-app/src/components/MainWindow/index.tsx | 88 - .../components/MainWindow/style.module.css | 2 +- vite-app/src/components/MainWindow/view.tsx | 171 +- .../src/components/MenuSearch/controller.tsx | 13 - .../components/MenuSearch/style.module.css | 13 - vite-app/src/components/MenuSearch/view.tsx | 10 - vite-app/src/components/NiceTimeDuration.tsx | 38 + vite-app/src/components/NotFound/NotFound.tsx | 7 +- .../NotFoundChecked/NotFoundChecked.tsx | 567 - .../components/NotFoundChecked/flapjack.png | Bin 13425 -> 0 bytes .../Notifications/Notifications.css | 174 - .../Notifications/Notifications.tsx | 120 - .../Notifications/NotificationsMain.tsx | 61 - .../src/components/Notifications/readme.md | 32 - vite-app/src/components/Ping.tsx | 158 - .../PluginWrapper/PluginWrapper2.tsx | 40 +- vite-app/src/components/PropTable.module.css | 11 +- .../src/components/RotatedTable.module.css | 96 - vite-app/src/components/RotatedTable.tsx | 141 - vite-app/src/components/Router2.tsx | 104 +- vite-app/src/components/Sidebar/Sidebar.tsx | 110 - .../src/components/SidebarMenu/FeedsBadge.tsx | 63 - .../SidebarMenu/FeedsBadgeWrapper.tsx | 36 - .../components/SidebarMenu/SidebarMenu.css | 3 - .../SidebarMenu/SidebarMenu.module.css | 64 - .../components/SidebarMenu/SidebarMenu.tsx | 200 - .../src/components/Signin/Signin.module.css | 37 - vite-app/src/components/Signin/Signin.tsx | 143 - .../components/Signin/SigninButton.module.css | 47 - .../src/components/Signin/SigninButton.tsx | 81 - vite-app/src/components/Signin/SigninMain.tsx | 47 - ...rView.css => StandardErrorView.module.css} | 10 +- vite-app/src/components/StandardErrorView.tsx | 24 +- vite-app/src/components/Tabs.css | 77 - vite-app/src/components/Tabs.tsx | 96 - vite-app/src/components/Tabs/AutoFlexTabs.tsx | 49 + vite-app/src/components/Tabs/FlexTabs.css | 61 + vite-app/src/components/Tabs/FlexTabs.tsx | 75 + vite-app/src/components/Title.tsx | 4 + .../src/components/ToastNotifications.tsx | 96 + vite-app/src/components/TypeIcon/TypeIcon.tsx | 4 - vite-app/src/components/UILink2.tsx | 75 + vite-app/src/components/UILinkAntdButton.tsx | 77 + vite-app/src/components/UILinkButton.tsx | 70 + vite-app/src/components/Well.module.css | 24 + vite-app/src/components/Well.module.scss | 113 + vite-app/src/components/Well.tsx | 87 +- vite-app/src/components/helpers.tsx | 3 + vite-app/src/components/menus/menu.json | 260 - vite-app/src/components/menus/menu.ts | 30 - vite-app/src/contexts/Auth.tsx | 631 - vite-app/src/contexts/ConfigContext.tsx | 55 +- vite-app/src/contexts/EuropaContext.tsx | 842 + vite-app/src/contexts/FeedsContext.tsx | 80 - vite-app/src/contexts/RouterContext.tsx | 216 +- vite-app/src/contexts/RuntimeContext.tsx | 328 - vite-app/src/css/icons/kbase-icons.eot | Bin 0 -> 2922 bytes vite-app/src/css/icons/kbase-icons.svg | 16 + vite-app/src/css/icons/kbase-icons.ttf | Bin 0 -> 2728 bytes vite-app/src/css/icons/kbase-icons.woff | Bin 0 -> 1944 bytes vite-app/src/css/icons/svg/Compare_icon.svg | 30 + vite-app/src/css/icons/svg/Genome_icon.svg | 46 + .../src/css/icons/svg/Metabolism_icon.svg | 83 + .../src/css/icons/svg/Metagenome_icon.svg | 14 + vite-app/src/css/icons/svg/Tree_icon.svg | 67 + vite-app/src/css/kb-icons.css | 83 + vite-app/src/formSupport/Field.ts | 405 - .../formSupport/editors/StringArrayEditor.tsx | 170 - .../src/formSupport/editors/StringEditor.tsx | 76 - .../editors/StringSelectionEditor.tsx | 123 - .../src/formSupport/editors/TextEditor.tsx | 75 - vite-app/src/gtagSupport.ts | 467 - vite-app/src/lib/AsyncProcessWithHalt.ts | 34 + vite-app/src/lib/ConnectionStatus.ts | 220 - vite-app/src/lib/DataState.ts | 63 - vite-app/src/lib/NextRequest.ts | 84 +- vite-app/src/lib/ReceiveChannel.test.ts | 990 ++ vite-app/src/lib/ReceiveChannel.ts | 321 + vite-app/src/lib/ReceiveChannel.ts.old | 478 + vite-app/src/lib/RepeatableAsyncProcess.ts | 45 + vite-app/src/lib/Route-generic.ts | 182 - vite-app/src/lib/Route.ts | 55 +- vite-app/src/lib/SendChannel.test.ts | 120 + vite-app/src/lib/SendChannel.ts | 123 + vite-app/src/lib/SendChannel.ts.old | 120 + vite-app/src/lib/SimpleError.tsx | 4 + .../Navigator/context => lib}/TaskQueue.ts | 0 vite-app/src/lib/appServiceManager.ts | 170 - vite-app/src/lib/clients/Feeds.ts | 146 +- vite-app/src/lib/clients/NarrativeModel.ts | 37 +- vite-app/src/lib/kb_lib/Auth2.ts | 174 +- vite-app/src/lib/kb_lib/ReceiveChannel.ts | 367 + vite-app/src/lib/kb_lib/SendChannel.ts | 147 + .../lib/kb_lib/comm/JSONRPC11/JSONRPC11.ts | 2 + .../comm/JSONRPC20/DynamicServiceClient.ts | 51 +- .../kb_lib/comm/JSONRPC20/GenericClient.ts | 61 +- .../lib/kb_lib/comm/JSONRPC20/JSONRPC20.ts | 255 +- .../kb_lib/comm/JSONRPC20/ServiceClient.ts | 120 +- .../kb_lib/comm/JSONRPC20/ServiceClient2.ts | 37 - vite-app/src/lib/kb_lib/comm/RestClient.ts | 122 + .../lib/kb_lib/comm/coreServices/Catalog.ts | 55 +- .../comm/coreServices/NarrativeMethodStore.ts | 304 +- .../lib/kb_lib/comm/coreServices/ORCIDLInk.ts | 54 +- .../comm/coreServices/ORCIDLInkManage.ts | 26 +- .../kb_lib/comm/coreServices/UserProfile.ts | 96 + .../lib/kb_lib/comm/coreServices/Workspace.ts | 168 +- vite-app/src/lib/kb_lib/windowMessaging.ts | 542 + vite-app/src/lib/messenger.ts | 38 +- vite-app/src/lib/navigation.ts | 270 +- vite-app/src/lib/reactSelectTypes.ts | 6 + vite-app/src/lib/runtime.ts | 181 - vite-app/src/lib/testUtils.ts | 48 + vite-app/src/lib/time.ts | 31 + vite-app/src/lib/types.ts | 44 - vite-app/src/lib/utils.ts | 90 - vite-app/src/main.css | 57 +- vite-app/src/main.tsx | 14 +- vite-app/src/pluginSupport/AutoPostForm.tsx | 6 +- .../{IFrame.css => IFrame.module.css} | 11 +- vite-app/src/pluginSupport/IFrame.tsx | 19 +- .../pluginSupport/IFrameController.module.css | 6 +- .../src/pluginSupport/IFrameController.tsx | 115 +- .../{Plugin.css => Plugin.module.css} | 2 +- vite-app/src/pluginSupport/Plugin.tsx | 19 +- vite-app/src/scss/bootstrap-custom.scss | 20 + vite-app/src/types/config.ts | 74 +- vite-app/vite.config-og.ts | 89 - vite-app/vite.config.ts | 73 +- 604 files changed, 65425 insertions(+), 16888 deletions(-) delete mode 100644 .devcontainer/custom.env delete mode 100644 .devcontainer/devcontainer.env create mode 100644 .eslintrc delete mode 100644 .eslintrc.yml create mode 100644 .prettierrc delete mode 100644 .prettierrc.yaml create mode 100644 docs/development/deployment-setup.md create mode 100644 docs/development/development-setup.md create mode 100644 docs/environment-variables.md create mode 100755 scripts/container/generate-proxy-env create mode 100755 scripts/container/generate-runtime-env delete mode 100644 scripts/host/clean-build.sh delete mode 100644 scripts/host/extend-docker-compose.sh create mode 100755 tools/dockerize/scripts/render-proxy-configs.sh mode change 100644 => 100755 tools/dockerize/scripts/render-templates.sh create mode 100755 tools/node/run delete mode 100644 tools/proxy/conf/README.md delete mode 100644 tools/proxy/conf/appdev.env delete mode 100644 tools/proxy/conf/ci.env delete mode 100644 tools/proxy/conf/dev.env delete mode 100644 tools/proxy/conf/narrative-dev.env delete mode 100644 tools/proxy/conf/narrative2.env delete mode 100644 tools/proxy/conf/next.env delete mode 100644 tools/proxy/conf/prod.env delete mode 100644 tools/proxy/contents/conf/nginx.conf-base-path-changes.tmpl create mode 100644 vite-app/public/data/__perf__/0b.txt delete mode 100644 vite-app/public/js/gtagSupport.js create mode 100644 vite-app/src/applets/about/AboutMenu.tsx delete mode 100644 vite-app/src/applets/about/AboutServices2.tsx create mode 100644 vite-app/src/applets/about/AboutSession/controller.tsx create mode 100644 vite-app/src/applets/about/index.module.css rename vite-app/src/applets/developer/{ConfigEditor.css => ConfigEditor.module.css} (56%) rename vite-app/src/applets/developer/{index.css => index.module.css} (67%) delete mode 100644 vite-app/src/applets/development/DevelopmentAuth.tsx delete mode 100644 vite-app/src/applets/development/DevelopmentLogin.tsx delete mode 100644 vite-app/src/applets/development/DevelopmentLoginForm.tsx delete mode 100644 vite-app/src/applets/development/DevelopmentLogout.tsx delete mode 100644 vite-app/src/apps/Auth.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/Account/AccountEditor/view.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/Account/AccountInfo/view.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/Account/controller.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/Account/view.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/AddTokenForm.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/DevToken/controller.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/DevToken/view.module.css create mode 100644 vite-app/src/apps/Auth2/AccountManager/DevToken/view.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/controller.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/view.module.css create mode 100644 vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/view.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/LoginTokens/controller.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/LoginTokens/view.module.css create mode 100644 vite-app/src/apps/Auth2/AccountManager/LoginTokens/view.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/ServToken/controller.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/ServToken/view.module.css create mode 100644 vite-app/src/apps/Auth2/AccountManager/ServToken/view.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/TermsAndConditions/controller.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/TermsAndConditions/view.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/TokenCopy.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/controller.tsx create mode 100644 vite-app/src/apps/Auth2/AccountManager/view.tsx create mode 100644 vite-app/src/apps/Auth2/Collapsible.css create mode 100644 vite-app/src/apps/Auth2/Collapsible.tsx create mode 100644 vite-app/src/apps/Auth2/CountdownAlarmClock.tsx create mode 100644 vite-app/src/apps/Auth2/CountdownClock.tsx create mode 100644 vite-app/src/apps/Auth2/LinkContinue/ContinueHeader.css create mode 100644 vite-app/src/apps/Auth2/LinkContinue/ContinueHeader.tsx create mode 100644 vite-app/src/apps/Auth2/LinkContinue/controller.tsx create mode 100644 vite-app/src/apps/Auth2/LinkContinue/view.css create mode 100644 vite-app/src/apps/Auth2/LinkContinue/view.tsx create mode 100644 vite-app/src/apps/Auth2/Providers.ts create mode 100644 vite-app/src/apps/Auth2/SignIn/SignIn.tsx create mode 100644 vite-app/src/apps/Auth2/SignIn/SignInButton.css create mode 100644 vite-app/src/apps/Auth2/SignIn/SignInButton.tsx create mode 100644 vite-app/src/apps/Auth2/SignIn/SignInControls.css create mode 100644 vite-app/src/apps/Auth2/SignIn/SignInControls.tsx create mode 100644 vite-app/src/apps/Auth2/SignIn/SignInView.tsx create mode 100644 vite-app/src/apps/Auth2/SignInContinue/CheckUsernameField.tsx create mode 100644 vite-app/src/apps/Auth2/SignInContinue/Policy.ts create mode 100644 vite-app/src/apps/Auth2/SignInContinue/PolicyAndAgreement copy.ts create mode 100644 vite-app/src/apps/Auth2/SignInContinue/PolicyAndAgreement.ts create mode 100644 vite-app/src/apps/Auth2/SignInContinue/SignInContinue.tsx create mode 100644 vite-app/src/apps/Auth2/SignInContinue/SignInContinueForm.css create mode 100644 vite-app/src/apps/Auth2/SignInContinue/SignInContinueForm.tsx create mode 100644 vite-app/src/apps/Auth2/SignInContinue/SignInContinueView.css create mode 100644 vite-app/src/apps/Auth2/SignInContinue/SignInContinueView.tsx create mode 100644 vite-app/src/apps/Auth2/SignInContinue/SignInOops.tsx create mode 100644 vite-app/src/apps/Auth2/SignInContinue/SignUpContinue.tsx create mode 100644 vite-app/src/apps/Auth2/SignInContinue/SignUpForm.tsx create mode 100644 vite-app/src/apps/Auth2/SignedOut/controller.tsx create mode 100644 vite-app/src/apps/Auth2/SignedOut/view.tsx create mode 100644 vite-app/src/apps/Auth2/Signout/controller.tsx create mode 100644 vite-app/src/apps/Auth2/Signout/view.tsx create mode 100644 vite-app/src/apps/Auth2/TextSpan.tsx create mode 100644 vite-app/src/apps/Auth2/UseAgreements.css create mode 100644 vite-app/src/apps/Auth2/UseAgreements.tsx create mode 100644 vite-app/src/apps/Auth2/resources/agreements/policies.json create mode 100644 vite-app/src/apps/Auth2/resources/agreements/terms-and-conditions copy.json create mode 100644 vite-app/src/apps/Auth2/resources/agreements/terms-and-conditions.json create mode 100644 vite-app/src/apps/Auth2/resources/css/flex-tabs.css create mode 100644 vite-app/src/apps/Auth2/resources/css/main.css create mode 100644 vite-app/src/apps/Auth2/resources/data/config.yml create mode 100644 vite-app/src/apps/Auth2/resources/data/globus-providers.json create mode 100644 vite-app/src/apps/Auth2/resources/data/institutions.csv create mode 100644 vite-app/src/apps/Auth2/resources/data/institutions.json create mode 100644 vite-app/src/apps/Auth2/resources/data/nationalLabs.yaml create mode 100644 vite-app/src/apps/Auth2/resources/data/organizations.json create mode 100644 vite-app/src/apps/Auth2/resources/data/providers.json create mode 100644 vite-app/src/apps/Auth2/resources/data/providers.yaml create mode 100644 vite-app/src/apps/Auth2/resources/data/referralSources.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/avatarOptions.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/countries.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/fundingSources.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/gravatarDefaults.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/institutions.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/jobTitles.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/nationalLabs.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/nationalLabs.yaml create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/otherLabs.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/otherLabs.yaml create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/researchInterests.json create mode 100644 vite-app/src/apps/Auth2/resources/dataSources/states.json create mode 100644 vite-app/src/apps/Auth2/resources/docs/design.md create mode 100755 vite-app/src/apps/Auth2/resources/doodle.png create mode 100644 vite-app/src/apps/Auth2/resources/images/kbase-logo-99.png create mode 100644 vite-app/src/apps/Auth2/resources/images/nouserpic.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/logo.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/200px/disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/200px/hover.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/200px/normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/200px/pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/hover.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/light/btn-disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/light/btn-focus.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/light/btn-normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/light/btn-pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus/signin-button/pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/globus_logo.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/logo.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/200px/disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/200px/hover.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/200px/normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/200px/pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/hover.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/light/btn-disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/light/btn-focus.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/light/btn-normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/light/btn-pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google/signin-button/pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/google_logo.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/logo.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/logox.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/200px/disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/200px/hover.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/200px/normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/200px/pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/hover.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/hover.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/light/btn-disabled.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/light/btn-focus.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/light/btn-normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/light/btn-pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/normal.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/pressed.png create mode 100644 vite-app/src/apps/Auth2/resources/providers/orcid_logo.png create mode 100644 vite-app/src/apps/Feeds/api/Feeds.ts create mode 100644 vite-app/src/apps/Feeds/api/Groups.ts create mode 100644 vite-app/src/apps/Feeds/api/RestClient.ts create mode 100644 vite-app/src/apps/Feeds/components/Entity.tsx create mode 100644 vite-app/src/apps/Feeds/components/controller.tsx create mode 100644 vite-app/src/apps/Feeds/components/feed.xts create mode 100644 vite-app/src/apps/Feeds/components/feedTabs.xts create mode 100644 vite-app/src/apps/Feeds/components/globalPoster.xts create mode 100644 vite-app/src/apps/Feeds/components/notification.xts create mode 100644 vite-app/src/apps/Feeds/components/view.module.css create mode 100644 vite-app/src/apps/Feeds/components/view.tsx create mode 100644 vite-app/src/apps/Feeds/notifications/GroupsNotification.tsx create mode 100644 vite-app/src/apps/Feeds/notifications/NarrativeNotification.tsx create mode 100644 vite-app/src/apps/Feeds/notifications/NoNotifications.tsx create mode 100644 vite-app/src/apps/Feeds/notifications/Notification.module.css create mode 100644 vite-app/src/apps/Feeds/notifications/Notification.tsx create mode 100644 vite-app/src/apps/Feeds/notifications/NotificationAlert.tsx create mode 100644 vite-app/src/apps/Feeds/notifications/base.xts create mode 100644 vite-app/src/apps/Feeds/notifications/groups.xts create mode 100644 vite-app/src/apps/Feeds/notifications/icons.xts create mode 100644 vite-app/src/apps/Feeds/notifications/narrative.xts create mode 100644 vite-app/src/apps/Feeds/utils.ts create mode 100644 vite-app/src/apps/JobBrowser/components/AdminJobs/UserJobsRequest.ts create mode 100644 vite-app/src/apps/JobBrowser/components/AdminJobs/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/AdminJobs/style.css create mode 100644 vite-app/src/apps/JobBrowser/components/AdminJobs/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/DatePicker.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/ErrorBoundary.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/AppFunctionSelect/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/AppFunctionSelect/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/AppModuleSelect/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/AppModuleSelect/index.xtsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/AppModuleSelect/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/AppSelect/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/AppSelect/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/ClientGroupsSelect/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/ClientGroupsSelect/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/NarrativeSelect/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/NarrativeSelect/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/UserSelect/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/UserSelect/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/controller.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/data.xtsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/index.xtsx create mode 100644 vite-app/src/apps/JobBrowser/components/FilterEditor/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/JobDetail/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/JobDetail/index.xts create mode 100644 vite-app/src/apps/JobBrowser/components/JobDetail/style.css create mode 100644 vite-app/src/apps/JobBrowser/components/JobDetail/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/JobInfo.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/JobLog/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/JobLog/style.css create mode 100644 vite-app/src/apps/JobBrowser/components/JobLog/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/JobStatusBadge.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/Main/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/Main/style.css create mode 100644 vite-app/src/apps/JobBrowser/components/Main/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/Monitor.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/MyJobs/MyJobsRequest.ts create mode 100644 vite-app/src/apps/JobBrowser/components/MyJobs/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/MyJobs/style.css create mode 100644 vite-app/src/apps/JobBrowser/components/MyJobs/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/NarrativeLink.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/NiceElapsedTime.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/NiceRelativeTime.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/PublicAppStats/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/PublicAppStats/style.css create mode 100644 vite-app/src/apps/JobBrowser/components/PublicAppStats/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/Table/Table.css create mode 100644 vite-app/src/apps/JobBrowser/components/Table/TableNav.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/Table/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/UILink.xtsx create mode 100644 vite-app/src/apps/JobBrowser/components/UserJobs/MyJobsRequest.ts create mode 100644 vite-app/src/apps/JobBrowser/components/UserJobs/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/UserJobs/index.xtsx create mode 100644 vite-app/src/apps/JobBrowser/components/UserJobs/style.css create mode 100644 vite-app/src/apps/JobBrowser/components/UserJobs/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/UserRunSummary/index.tsx create mode 100644 vite-app/src/apps/JobBrowser/components/UserRunSummary/index.xtsx create mode 100644 vite-app/src/apps/JobBrowser/components/UserRunSummary/style.css create mode 100644 vite-app/src/apps/JobBrowser/components/UserRunSummary/view.tsx create mode 100644 vite-app/src/apps/JobBrowser/lib/AsyncQueue.xts create mode 100644 vite-app/src/apps/JobBrowser/lib/CancelableRequest.ts create mode 100644 vite-app/src/apps/JobBrowser/lib/JobBrowserBFFClient.ts create mode 100644 vite-app/src/apps/JobBrowser/lib/MetricsServiceClient.ts create mode 100644 vite-app/src/apps/JobBrowser/lib/Poll.ts create mode 100644 vite-app/src/apps/JobBrowser/lib/Poller.ts create mode 100644 vite-app/src/apps/JobBrowser/lib/PubSub.ts create mode 100644 vite-app/src/apps/JobBrowser/lib/PubSub.xts create mode 100644 vite-app/src/apps/JobBrowser/lib/TableResizer.ts create mode 100644 vite-app/src/apps/JobBrowser/lib/time.ts create mode 100644 vite-app/src/apps/JobBrowser/lib/types.ts create mode 100644 vite-app/src/apps/JobBrowser/store/PublicAppStats.ts create mode 100644 vite-app/src/apps/JobBrowser/store/UserRunSummary.ts create mode 100644 vite-app/src/apps/JobBrowser/store/base.ts create mode 100644 vite-app/src/apps/JobBrowser/store/index.ts create mode 100644 vite-app/src/apps/JobBrowser/types/base.ts create mode 100644 vite-app/src/apps/JobBrowser/types/error.ts create mode 100644 vite-app/src/apps/JobBrowser/types/jobState.ts create mode 100644 vite-app/src/apps/JobBrowser/types/json.ts create mode 100644 vite-app/src/apps/JobBrowser/utils.ts rename vite-app/src/apps/NarrativeManager/{NarrativeLoading.css => NarrativeLoading.module.css} (54%) create mode 100644 vite-app/src/apps/Navigator/components/NarrativeDetails/cells/ServiceWidgetCell.module.css create mode 100644 vite-app/src/apps/Navigator/components/NarrativeDetails/cells/ServiceWidgetCell.tsx create mode 100644 vite-app/src/apps/Typeview/TypeIcon.tsx create mode 100644 vite-app/src/apps/Typeview/common.tsx rename vite-app/src/{components/DataTable.css => apps/Typeview/module/DataTable7.css} (65%) create mode 100644 vite-app/src/apps/Typeview/module/DataTable7.tsx create mode 100644 vite-app/src/apps/Typeview/module/IncludedModules.tsx create mode 100644 vite-app/src/apps/Typeview/module/Overview.css create mode 100644 vite-app/src/apps/Typeview/module/Overview.tsx create mode 100644 vite-app/src/apps/Typeview/module/Spec.css create mode 100644 vite-app/src/apps/Typeview/module/Spec.tsx create mode 100644 vite-app/src/apps/Typeview/module/Types.tsx create mode 100644 vite-app/src/apps/Typeview/module/Versions.tsx create mode 100644 vite-app/src/apps/Typeview/module/controller.tsx create mode 100644 vite-app/src/apps/Typeview/module/view.css create mode 100644 vite-app/src/apps/Typeview/module/view.tsx create mode 100644 vite-app/src/apps/Typeview/syntax.ts create mode 100644 vite-app/src/apps/Typeview/type/DataTable7.css create mode 100644 vite-app/src/apps/Typeview/type/DataTable7.tsx create mode 100644 vite-app/src/apps/Typeview/type/Overview.css create mode 100644 vite-app/src/apps/Typeview/type/Overview.tsx create mode 100644 vite-app/src/apps/Typeview/type/Spec.css create mode 100644 vite-app/src/apps/Typeview/type/Spec.tsx create mode 100644 vite-app/src/apps/Typeview/type/TypesUsed.tsx create mode 100644 vite-app/src/apps/Typeview/type/TypesUsing.tsx create mode 100644 vite-app/src/apps/Typeview/type/Versions.tsx create mode 100644 vite-app/src/apps/Typeview/type/controller.tsx create mode 100644 vite-app/src/apps/Typeview/type/view.css create mode 100644 vite-app/src/apps/Typeview/type/view.tsx create mode 100644 vite-app/src/apps/Typeview/typeIcons.json create mode 100644 vite-app/src/behavior.ts delete mode 100644 vite-app/src/bootstrap-custom.scss delete mode 100644 vite-app/src/components/AsyncUnwrapper.tsx delete mode 100644 vite-app/src/components/Body2.tsx delete mode 100644 vite-app/src/components/DataTable.tsx delete mode 100644 vite-app/src/components/Deployment.module.css delete mode 100644 vite-app/src/components/Deployment.tsx rename vite-app/src/components/{ErrorAlert.css => ErrorAlert.module.css} (61%) create mode 100644 vite-app/src/components/ErrorView.module.css delete mode 100644 vite-app/src/components/ErrorView.styles.ts delete mode 100644 vite-app/src/components/ExternalRedirect.tsx delete mode 100644 vite-app/src/components/FlexGrid.module.css delete mode 100644 vite-app/src/components/FlexGrid.tsx delete mode 100644 vite-app/src/components/HamburgerMenu/HamburgerMenu-logo.module.css delete mode 100644 vite-app/src/components/HamburgerMenu/HamburgerMenu-logo.tsx delete mode 100644 vite-app/src/components/HamburgerMenu/HamburgerMenu.module.css delete mode 100644 vite-app/src/components/HamburgerMenu/HamburgerMenu.tsx delete mode 100644 vite-app/src/components/HamburgerMenu/HamburgerMenuLogo.module.css delete mode 100644 vite-app/src/components/HamburgerMenu/HamburgerMenuLogo.tsx delete mode 100644 vite-app/src/components/HamburgerMenu/HamburgerMenuMain.tsx delete mode 100644 vite-app/src/components/HamburgerMenu/kbase_logo.png create mode 100644 vite-app/src/components/Loading.module.css delete mode 100644 vite-app/src/components/Loading.styles.ts delete mode 100644 vite-app/src/components/Logo/Logo.tsx delete mode 100644 vite-app/src/components/Logo/kbase_logo.png delete mode 100644 vite-app/src/components/MainWindow/index.tsx delete mode 100644 vite-app/src/components/MenuSearch/controller.tsx delete mode 100644 vite-app/src/components/MenuSearch/style.module.css delete mode 100644 vite-app/src/components/MenuSearch/view.tsx create mode 100644 vite-app/src/components/NiceTimeDuration.tsx delete mode 100644 vite-app/src/components/NotFoundChecked/NotFoundChecked.tsx delete mode 100644 vite-app/src/components/NotFoundChecked/flapjack.png delete mode 100644 vite-app/src/components/Notifications/Notifications.css delete mode 100644 vite-app/src/components/Notifications/Notifications.tsx delete mode 100644 vite-app/src/components/Notifications/NotificationsMain.tsx delete mode 100644 vite-app/src/components/Notifications/readme.md delete mode 100644 vite-app/src/components/Ping.tsx delete mode 100644 vite-app/src/components/RotatedTable.module.css delete mode 100644 vite-app/src/components/RotatedTable.tsx delete mode 100644 vite-app/src/components/Sidebar/Sidebar.tsx delete mode 100644 vite-app/src/components/SidebarMenu/FeedsBadge.tsx delete mode 100644 vite-app/src/components/SidebarMenu/FeedsBadgeWrapper.tsx delete mode 100644 vite-app/src/components/SidebarMenu/SidebarMenu.css delete mode 100644 vite-app/src/components/SidebarMenu/SidebarMenu.module.css delete mode 100644 vite-app/src/components/SidebarMenu/SidebarMenu.tsx delete mode 100644 vite-app/src/components/Signin/Signin.module.css delete mode 100644 vite-app/src/components/Signin/Signin.tsx delete mode 100644 vite-app/src/components/Signin/SigninButton.module.css delete mode 100644 vite-app/src/components/Signin/SigninButton.tsx delete mode 100644 vite-app/src/components/Signin/SigninMain.tsx rename vite-app/src/components/{StandardErrorView.css => StandardErrorView.module.css} (50%) delete mode 100644 vite-app/src/components/Tabs.css delete mode 100644 vite-app/src/components/Tabs.tsx create mode 100644 vite-app/src/components/Tabs/AutoFlexTabs.tsx create mode 100644 vite-app/src/components/Tabs/FlexTabs.css create mode 100644 vite-app/src/components/Tabs/FlexTabs.tsx create mode 100644 vite-app/src/components/ToastNotifications.tsx create mode 100644 vite-app/src/components/UILink2.tsx create mode 100644 vite-app/src/components/UILinkAntdButton.tsx create mode 100644 vite-app/src/components/UILinkButton.tsx create mode 100644 vite-app/src/components/Well.module.scss create mode 100644 vite-app/src/components/helpers.tsx delete mode 100644 vite-app/src/components/menus/menu.json delete mode 100644 vite-app/src/components/menus/menu.ts delete mode 100644 vite-app/src/contexts/Auth.tsx create mode 100644 vite-app/src/contexts/EuropaContext.tsx delete mode 100644 vite-app/src/contexts/FeedsContext.tsx delete mode 100644 vite-app/src/contexts/RuntimeContext.tsx create mode 100644 vite-app/src/css/icons/kbase-icons.eot create mode 100644 vite-app/src/css/icons/kbase-icons.svg create mode 100644 vite-app/src/css/icons/kbase-icons.ttf create mode 100644 vite-app/src/css/icons/kbase-icons.woff create mode 100644 vite-app/src/css/icons/svg/Compare_icon.svg create mode 100644 vite-app/src/css/icons/svg/Genome_icon.svg create mode 100644 vite-app/src/css/icons/svg/Metabolism_icon.svg create mode 100644 vite-app/src/css/icons/svg/Metagenome_icon.svg create mode 100644 vite-app/src/css/icons/svg/Tree_icon.svg create mode 100644 vite-app/src/css/kb-icons.css delete mode 100644 vite-app/src/formSupport/Field.ts delete mode 100644 vite-app/src/formSupport/editors/StringArrayEditor.tsx delete mode 100644 vite-app/src/formSupport/editors/StringEditor.tsx delete mode 100644 vite-app/src/formSupport/editors/StringSelectionEditor.tsx delete mode 100644 vite-app/src/formSupport/editors/TextEditor.tsx delete mode 100644 vite-app/src/gtagSupport.ts create mode 100644 vite-app/src/lib/AsyncProcessWithHalt.ts delete mode 100644 vite-app/src/lib/ConnectionStatus.ts delete mode 100644 vite-app/src/lib/DataState.ts create mode 100644 vite-app/src/lib/ReceiveChannel.test.ts create mode 100644 vite-app/src/lib/ReceiveChannel.ts create mode 100644 vite-app/src/lib/ReceiveChannel.ts.old create mode 100644 vite-app/src/lib/RepeatableAsyncProcess.ts delete mode 100644 vite-app/src/lib/Route-generic.ts create mode 100644 vite-app/src/lib/SendChannel.test.ts create mode 100644 vite-app/src/lib/SendChannel.ts create mode 100644 vite-app/src/lib/SendChannel.ts.old create mode 100644 vite-app/src/lib/SimpleError.tsx rename vite-app/src/{apps/Navigator/context => lib}/TaskQueue.ts (100%) delete mode 100644 vite-app/src/lib/appServiceManager.ts create mode 100644 vite-app/src/lib/kb_lib/ReceiveChannel.ts create mode 100644 vite-app/src/lib/kb_lib/SendChannel.ts delete mode 100644 vite-app/src/lib/kb_lib/comm/JSONRPC20/ServiceClient2.ts create mode 100644 vite-app/src/lib/kb_lib/comm/RestClient.ts create mode 100644 vite-app/src/lib/kb_lib/windowMessaging.ts delete mode 100644 vite-app/src/lib/runtime.ts create mode 100644 vite-app/src/lib/testUtils.ts rename vite-app/src/pluginSupport/{IFrame.css => IFrame.module.css} (52%) rename vite-app/src/pluginSupport/{Plugin.css => Plugin.module.css} (92%) create mode 100644 vite-app/src/scss/bootstrap-custom.scss delete mode 100644 vite-app/vite.config-og.ts diff --git a/.devcontainer/Dockerfile-devcontainer b/.devcontainer/Dockerfile-devcontainer index 7cb8beb2..8b26106a 100644 --- a/.devcontainer/Dockerfile-devcontainer +++ b/.devcontainer/Dockerfile-devcontainer @@ -1,5 +1,5 @@ -FROM node:18 +FROM node:20 RUN apt-get update && \ apt-get install -y npm python3 git make bash && \ - npm install --location=global npm@10.2.0 + npm install --location=global npm@10.5.0 diff --git a/.devcontainer/custom.env b/.devcontainer/custom.env deleted file mode 100644 index 4c847aac..00000000 --- a/.devcontainer/custom.env +++ /dev/null @@ -1,10 +0,0 @@ - -# dynamic_service_proxies=ORCIDLink -# Note that dynamic service proxies use the module name (preserve case), -# whereas core service proxies are typically lower_snake_cased. -# dynamic_service_proxies=NarrativePublisher -# service_proxies="DOIRequest orcidlink" -# service_proxies=orcidlink -# service_proxies=servicewidgetdemo -# service_proxies=staging_service -# local_narrative=t \ No newline at end of file diff --git a/.devcontainer/devcontainer.env b/.devcontainer/devcontainer.env deleted file mode 100644 index f913bec9..00000000 --- a/.devcontainer/devcontainer.env +++ /dev/null @@ -1 +0,0 @@ -DEPLOY_ENV=ci \ No newline at end of file diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 13583fdb..369c7466 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -1,4 +1,5 @@ version: '3.6' +name: kbase-dev networks: kbase-dev: name: kbase-dev @@ -7,73 +8,38 @@ services: build: context: . dockerfile: Dockerfile-devcontainer - # just use dev for the image tag so we can easily clean - # up afterwards. - image: kbase/kbase-ui:dev - container_name: kbase-ui dns: 8.8.8.8 volumes: # Update this to wherever you want VS Code to mount the folder of your project - ..:/workspace:cached - # Uncomment the next line to use Docker from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker-compose for details. - # - /var/run/docker.sock:/var/run/docker.sock - - # Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust. - # cap_add: - # - SYS_PTRACE - # security_opt: - # - seccomp:unconfined - # volumes: - # - ${APP_DIR}:/kb/deployment/app - # Map local source into expected location within container - # - "${PWD}/react-app:/kb/deployment/app" - # # Map local configuration directory into expected location within container - # - "${PWD}/dev/gitlab-config:/kb/deployment/config" - # - ${PWD}/deployment/scripts:/kb/deployment/scripts - # # Map locally installed plugins into the expected location within container - # - ${PWD}/build/dist/deploy/plugins:/kb/deployment/app/public/deploy/plugins - # - ${SCRIPTS_DIR}:/kb/deployment/scripts - - # just use dev for the image tag so we can easily clean - # up afterwards. - # image: kbase/kbase-ui:dev networks: - kbase-dev - environment: - # - PORT=80 - - DEPLOY_ENV=${DEPLOY_ENV:-ci} - - BASE_PATH=${BASE_PATH} + env_file: + - runtime.env # Required for a devcontainer -- keeps the container running. # Don't worry, our main interaction with the container is through the # VSC terminal, which for a devcontainer opens a shell within the # container. command: /bin/sh -c "while sleep 1000; do :; done" kbase-ui-deploy: - image: nginx:1.25.1-alpine + image: nginx:1.25.4-alpine3.18 container_name: kbase-ui-deploy volumes: - ../build:/usr/share/nginx/html - # - /Users/erikpearson/Work/KBase/2023/CE-255/kbase-ui-plugin-react-profile-view/dist/plugin:/usr/share/nginx/html/plugins/react-profile-view - # - /Users/erikpearson/Work/KBase/2023/UFI-60/kbase-ui-plugin-auth2-client/dist/plugin:/usr/share/nginx/html/plugins/auth2-client - # - /Users/erikpearson/Work/KBase/2023/helpdesk/UFI-48/kbase-ui-plugin-dataview/dist/plugin:/usr/share/nginx/html/plugins/dataview - # - /Users/erikpearson/Work/KBase/2023/helpdesk/UFI-48/kbase-ui-plugin-dataview/dist/plugin:/usr/share/nginx/html/plugins/dataview - # - /Users/erikpearson/Work/KBase/2022/fix-app-icons/kbase-ui-plugin-organizations/react-app:/usr/share/nginx/html/plugins/organizations - # - /Users/erikpearson/Work/KBase/2022/UIP-7/kbase-ui-plugin-auth2-client/dist/plugin:/usr/share/nginx/html/plugins/auth2-client - # - /Users/erikpearson/Work/KBase/2022/UIP-7/kbase-ui-plugin-auth2-client/dist/plugin:/usr/share/nginx/html/plugins/auth2-client + # Example of volume mounts for local plugins + # - /Users/erikpearson/Work/KBase/2023/europa-integration/kbase-ui-plugin-auth2-client/dist/plugin:/usr/share/nginx/html/plugins/auth2-client + # - /Users/erikpearson/Work/KBase/2023/europa-integration/kbase-ui-plugin-catalog/dist/plugin:/usr/share/nginx/html/plugins/catalog + # - /Users/erikpearson/Work/KBase/2023/europa-integration/kbase-ui-plugin-dataview/dist/plugin:/usr/share/nginx/html/plugins/dataview + # - /Users/erikpearson/Work/KBase/2023/europa-integration/kbase-ui-plugin-typeview/dist/plugin:/usr/share/nginx/html/plugins/typeview + # - /Users/erikpearson/Work/KBase/2023/europa-integration/kbase-ui-plugin-data-search/dist/plugin:/usr/share/nginx/html/plugins/data-search + # - /Users/erikpearson/Work/KBase/2023/europa-integration/kbase-ui-plugin-organizations/dist/plugin:/usr/share/nginx/html/plugins/organizations + # - /Users/erikpearson/Work/KBase/2023/europa-integration/kbase-ui-plugin-samples/dist/plugin:/usr/share/nginx/html/plugins/samples networks: - kbase-dev ports: - "8081:80" - environment: - # um, does nothing? - # for now, set the proxy port to 80 to match the default - # nginx config. - # TODO: use the templating built into the nginx image. - # or switch to a custom image using dockerize. - - NGINX_HOST=kbase-ui-deploy.ci.kbase.us - - NGINX_PORT=5000 kbase-ui-proxy: build: context: ../tools/proxy @@ -94,14 +60,5 @@ services: - 9.9.9.9 - 1.1.1.1 - 208.67.222.222 - environment: - - BASE_PATH=${BASE_PATH} - - - # note that this is really aq docker env file and is relative to the docker-compose file - # TODO: I think we may need to use an entrypoint which selects the deploy environment - # config (env) file based on the DEPLOY_ENV. - env_file: - - ../tools/proxy/conf/ci.env - - custom.env + - proxy.env diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..35355476 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,41 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:react-hooks/recommended", + "plugin:import/recommended", + "plugin:jsx-a11y/recommended", + "plugin:@typescript-eslint/recommended", + "eslint-config-prettier" + ], + "settings": { + "react": { + "version": "detect" + }, + "import/resolver": { + "node": { + "paths": [ + "src" + ], + "extensions": [ + ".js", + ".jsx", + ".ts", + ".tsx" + ] + } + } + }, + "rules": { + "no-unused-vars": [ + "error", + { + "vars": "all", + "args": "after-used", + "ignoreRestSiblings": true, + "argsIgnorePattern": "^_" + } + ], + "react/react-in-jsx-scope": "off" + } + } \ No newline at end of file diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 61eb4154..00000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,48 +0,0 @@ -env: - amd: true - browser: true - es6: true - node: true -extends: - - 'eslint:recommended' - - prettier - - preact - - 'plugin:@typescript-eslint/recommended' -parserOptions: - ecmaVersion: 2018 -root: true -rules: - strict: - - error - - function - no-console: - - error - - allow: - - warn - - error - require-await: - - error - no-confusing-arrow: - - error - no-const-assign: - - error - no-duplicate-imports: - - error - no-useless-computed-key: - - error - no-useless-rename: - - error - no-var: - - error - prefer-arrow-callback: - - warn - prefer-const: - - error - prefer-rest-params: - - warn - prefer-spread: - - warn - indent: - - error - - 4 - - SwitchCase: 1 diff --git a/.gitignore b/.gitignore index e52b8570..b1210c94 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ yarn.lock # !/react-app/public/data/README.md _working/ _todo/ +.devcontainer/*.env # General purpose temp directory /temp/* diff --git a/.prettierignore b/.prettierignore index 2e1fa2d5..0bebc7db 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,3 @@ +node_modules/ +build/ *.md \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..ec1b7de8 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "printWidth": 120, + "bracketSpacing": true, + "endOfLine": "lf" +} \ No newline at end of file diff --git a/.prettierrc.yaml b/.prettierrc.yaml deleted file mode 100644 index 181366eb..00000000 --- a/.prettierrc.yaml +++ /dev/null @@ -1,5 +0,0 @@ -printWidth: 100 -trailingComma: 'es5' -tabWidth: 4 -# use single quotes instead of double quotes -singleQuote: true diff --git a/.vscode/settings.json b/.vscode/settings.json index e5299838..7a67ca21 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,5 @@ { + "window.title": "kbase-ui/${activeRepositoryBranchName}", "editor.detectIndentation": false, "editor.quickSuggestionsDelay": 1000, "eslint.format.enable": true, @@ -29,5 +30,7 @@ "latex", "plaintext", "typescript" - ] + ], + "typescript.tsserver.log": "verbose", + "peacock.remoteColor": "#42b883" } \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index 7c7facc0..24de0d53 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2015-2023 The KBase Project and its Contributors +Copyright (c) 2015-2024 The KBase Project and its Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/Taskfile b/Taskfile index 18767a63..f6f45525 100755 --- a/Taskfile +++ b/Taskfile @@ -9,13 +9,13 @@ # # Runs docker compose with the given docker compose filename suffix with the given command arguments # -function _run-dc { - docker compose -f "etc/docker-compose-${1}.yml" --project-directory "${PWD}" --project-name orcidlink run --rm orcidlink "${@:2}" -} +# function _run-dc { +# docker compose -f "etc/docker-compose-${1}.yml" --project-directory "${PWD}" --project-name orcidlink run --rm orcidlink "${@:2}" +# } -function _dc-up { - docker compose -f "etc/docker-compose-${1}.yml" --project-directory "${PWD}" --project-name orcidlink up -} +# function _dc-up { +# docker compose -f "etc/docker-compose-${1}.yml" --project-directory "${PWD}" --project-name orcidlink up +# } function _noop { echo "Not implemented yet" @@ -30,7 +30,7 @@ function alias-me { } function install-plugins { - bash tools/deno/scripts/install-plugins.sh "${GH_TOKEN:?GH_TOKEN is required}" + bash tools/deno/scripts/install-plugins.sh "${1}" } function install-plugin { @@ -54,7 +54,7 @@ function create-deploy { } function build { - env DIR="${PWD}/vite-app" bash scripts/host/build.sh + env DIR="${PWD}/vite-app" BASE_PATH="${BASE_PATH}" bash scripts/host/build.sh } function shell { @@ -77,7 +77,6 @@ function setup-for-build-or-dev { git-info build-info install-plugins - render-templates } # @@ -97,6 +96,7 @@ function build-kbase-ui { # function dev-setup { setup-for-build-or-dev + render-templates } # @@ -107,8 +107,67 @@ function format { _noop } -function render-templates { - env DIR="${PWD}" ENV="${ENV:-ci}" DEFAULT_PATH="${DEFAULT_PATH}" BASE_PATH="${BASE_PATH}" bash tools/dockerize/scripts/render-templates.sh + +# Creates environment variables required for the local development proxy. +# See "create-proxy-env-vars.bash", which documents the required and optional input +# environment variables, as well as the generated ones. +# Saves the environment variables into an env file in .devcontainer/proxy-env +function generate-proxy-env { + # ./scripts/host/generate-proxy-env.bash + # DIR="${PWD}" && cd tools/node && docker compose -f run --rm node-tool echo + # "Network Created" + DIR="${PWD}" \ + docker compose \ + -f tools/node/docker-compose.yml \ + -p kbase-dev \ + run \ + -e DIR="${PWD}" \ + -e DEPLOY_ENV \ + -e BASE_PATH \ + -e KBASE_UI_HOSTNAME \ + -e LOCAL_NARRATIVE \ + -e SERVICE_PROXIES \ + -e DYNAMIC_SERVICE_PROXIES \ + -e SERVICES_DOMAIN \ + --rm \ + node-tool ./scripts/container/generate-proxy-env +} + +function generate-runtime-env { + DIR="${PWD}" \ + docker compose \ + -f tools/node/docker-compose.yml \ + -p kbase-dev \ + run \ + -e DEPLOY_ENV \ + -e BASE_PATH \ + -e UI_DOMAIN \ + -e KBASE_UI_HOSTNAME \ + -e FEATURE_SWITCHES_ENABLED \ + -e FEATURE_SWITCHES_DISABLED \ + -e DEFAULT_PATH \ + -e DEFAULT_PATH_TYPE \ + -e KBASE_ENDPOINT \ + --rm \ + node-tool ./scripts/container/generate-runtime-env +} + +function generate-runtime-config { + generate-runtime-env + DIR="${PWD}" tools/dockerize/scripts/render-templates.sh +} + +function remove-proxy-container { + docker rm $(docker ps -a --no-trunc --format="{{.ID}}" --filter name=^/kbase-ui-proxy$) +} + +# Renders the proxy server config file into build/deploy/proxy-nginx.conf +# Depends upon the proxy env variables existing in .devcontainer/proxy.env +# Use ./Taskfile generate-proxy-env. +# This is useful for previwing the development proxy nginx config, especially when +# making changes to it. +function render-proxy-config { + DIR="${PWD}" ENV_FILE="${PWD}/.devcontainer/proxy.env" tools/dockerize/scripts/render-proxy-configs.sh } # Optional dev tooling: @@ -122,7 +181,8 @@ function remove-dev-cert { } function start-local-server { - docker compose up + docker compose up + docker compose rm -f } function build-image { @@ -133,6 +193,13 @@ function run-image { ./scripts/host/run-image.sh } +function create-docker-network { + DIR="${PWD}" && cd tools/node && docker compose -f run --rm node-tool echo "Network Created" + #!/usr/bin/env bash + + # DIR="${PWD}" docker compose -f tools/node/docker-compose.yml run --rm node-tool "$@" +} + # # TO PORT # diff --git a/config/plugins.yml b/config/plugins.yml index 50f65095..6855f6b0 100644 --- a/config/plugins.yml +++ b/config/plugins.yml @@ -1,13 +1,6 @@ ## Plugin Build Configuration --- plugins: - - name: auth2-client - globalName: kbase-ui-plugin-auth2-client - version: 3.2.21 - source: - github: - account: kbase - release: true - name: biochem-search globalName: kbase-ui-plugin-biochem-search version: 2.2.1 @@ -16,10 +9,11 @@ plugins: account: kbase - name: catalog globalName: kbase-ui-plugin-catalog - version: 2.3.4 + version: 3.0.7 source: github: account: kbase + release: true - name: dashboard4 globalName: kbase-ui-plugin-dashboard4 version: 0.4.3 @@ -28,33 +22,28 @@ plugins: account: eapearson - name: data-search globalName: kbase-ui-plugin-data-search - version: 2.5.1 + version: 2.6.2 source: github: account: kbase release: true - name: dataview globalName: kbase-ui-plugin-dataview - version: 4.15.6 + version: 4.16.4 source: github: account: kbase release: true - - name: feeds - globalName: kbase-ui-plugin-feeds - version: 2.1.2 - source: - github: - account: kbase + # in progress - can always revert to this if the new version is problematic + # - name: feeds + # globalName: kbase-ui-plugin-feeds + # version: 2.1.2 + # source: + # github: + # account: kbase - name: jgi-search globalName: kbase-ui-plugin-jgi-search - version: 2.1.5 - source: - github: - account: kbase - - name: job-browser2 - globalName: kbase-ui-plugin-job-browser2 - version: 1.6.3 + version: 2.2.0 source: github: account: kbase @@ -66,7 +55,7 @@ plugins: account: kbase - name: organizations globalName: kbase-ui-plugin-organizations - version: 2.3.2 + version: 3.0.3 source: github: account: kbase @@ -89,10 +78,3 @@ plugins: source: github: account: kbase - - name: typeview - globalName: kbase-ui-plugin-typeview - version: 4.2.1 - source: - github: - account: kbase - release: true diff --git a/deployment/config/ci_config.ini b/deployment/config/ci_config.ini index e5664708..1a727db7 100644 --- a/deployment/config/ci_config.ini +++ b/deployment/config/ci_config.ini @@ -55,4 +55,4 @@ dynamic_service_proxies= ui_coreServices_disabled= -base_path=/kbase-ui \ No newline at end of file +base_path=/kbase-ui diff --git a/deployment/templates/config.json.tmpl b/deployment/templates/config.json.tmpl index ea647346..1e698495 100644 --- a/deployment/templates/config.json.tmpl +++ b/deployment/templates/config.json.tmpl @@ -2,17 +2,9 @@ "deploy": { "id": "kbase-ui", "target": "/kb/deployment/app", - "basePath": "{{ default "" .Env.BASE_PATH }}", - "environment": "{{ .Env.deploy_environment }}", - "displayEnvironment": {{ eq .Env.deploy_environment "prod" | ternary true false }}, - "hostname": "{{ .Env.deploy_hostname }}", - "icon": "{{ .Env.deploy_icon }}", - "name": "{{ .Env.deploy_name }}", + "hostname": "{{ .Env.UI_DOMAIN }}", "ui": { - "origin": "https://{{ default .Env.deploy_hostname .Env.deploy_ui_hostname }}" - }, - "services": { - "urlBase": "{{ .Env.deploy_hostname }}" + "origin": "https://{{ .Env.UI_DOMAIN }}" } }, "ui": { @@ -41,12 +33,7 @@ "name": "Session", "cookie": { "maxAge": 5184000, - "name": "kbase_session", - "backup": { - "name": "kbase_session_backup", - "domain": {{ if .Env.ui_backupCookie_domain }}"{{.Env.ui_backupCookie_domain}}"{{else}}null{{end}}, - "enabled": {{ default "false" .Env.ui_backupCookie_enabled }} - } + "name": "kbase_session" }, "loginWidget": "kb_login_signin", "cookieChangeDetectionInterval": 1000, @@ -62,15 +49,15 @@ }, "urls": { "marketing": { - "url": "www.kbase.us", + "url": "https://www.kbase.us", "title": "Marketing Site" }, "documentation": { - "url": "docs.kbase.us", + "url": "https://docs.kbase.us", "title": "Documentation Site" }, "statusPage": { - "url": "http://kbase.us/internal/status", + "url": "https://kbase.us/internal/status", "title": "KBase Status Page" }, "submitJiraTicket": { @@ -78,7 +65,7 @@ "title": "Submit a Jira Ticket" }, "narrative": { - "url": "https://{{ .Env.deploy_hostname }}.kbase.us/narrative", + "url": "https://{{ .Env.UI_DOMAIN }}/narrative", "title": "Narrative User Interface" }, "loginHelp": { @@ -119,19 +106,14 @@ "beta" ], "featureSwitches": { - "enabled": [{{ range $i, $v := splitList "," (default "" .Env.ui_featureSwitches_enabled) }}{{if $v }}{{ if $i }}, {{end}}"{{ $v }}"{{ end }}{{ end }}], - "disabled": [{{ range $i, $v := splitList "," (default "" .Env.ui_featureSwitches_disabled) }}{{if $v }}{{ if $i }}, {{end}}"{{ $v }}"{{ end }}{{ end }}], + "enabled": [{{ range $i, $v := splitList "," (default "" .Env.FEATURE_SWITCHES_ENABLED) }}{{if $v }}{{ if $i }}, {{end}}"{{ $v }}"{{ end }}{{ end }}], + "disabled": [{{ range $i, $v := splitList "," (default "" .Env.FEATURE_SWITCHES_DISABLED) }}{{if $v }}{{ if $i }}, {{end}}"{{ $v }}"{{ end }}{{ end }}], "available": [ { "id": "orcid_auth_provider", "title": "ORCiD auth provider", "description": "The ORCiD auth provider is" }, - { - "id": "system_alert_notification", - "title": "The New System Alert Notification", - "disabled": true - }, { "id": "search_features", "title": "Search over Genome Features" @@ -140,10 +122,6 @@ "id": "similar_genomes", "title": "Similar Genomes Landing Page Widget" }, - { - "id": "new_provenance_widget", - "title": "New Provenance Widget" - }, { "id": "re-lineage", "title": "Lineage driven by Relation Engine" @@ -173,13 +151,9 @@ }, "defaults": { "path": { - "type": "path", - "value": "{{ default "#about" .Env.DEFAULT_PATH }}" - }, - "hideHeader": {{ default "false" .Env.HIDE_HEADER }}, - "hideNavigation": {{ default "false" .Env.HIDE_NAVIGATION }}, - "integratedHamburgerAndLogo": {{ default "false" - .Env.INTEGRATED_HAMBURGER_AND_LOGO }} + "path": "{{ default "narratives" .Env.DEFAULT_PATH }}", + "type": "{{ default "europaui" .Env.DEFAULT_PATH_TYPE }}" + } } }, "services": { @@ -190,7 +164,7 @@ "auth", "Auth" ], - "url": "https://{{ .Env.deploy_hostname }}/{{ default "services/auth" .Env.deploy_services_auth2_path }}", + "url": "{{ .Env.KBASE_ENDPOINT }}auth", "cookieName": "kbase_session", "extraCookieNames": [], "name": "Authorization Version 2", @@ -199,18 +173,40 @@ "path": "/", "propertyPath": "version" }, - "providers": [ - "Google", - "Globus", - "OrcID" - ] + "supportedProviders": [ + { + "id": "Google", + "label": "Google", + "logoutUrl": "https://accounts.google.com/Logout", + "priority": 1, + "confirmSignin": false, + "description": "Any Google account may be used to access KBase.\n" + }, + { + "id": "OrcID", + "label": "ORCID", + "logoutUrl": "https://www.orcid.org/signout", + "priority": 1, + "confirmSignin": true, + "description": "Use your ORCiD account to access KBase.\n" + }, + { + "id": "Globus", + "label": "Globus", + "logoutUrl": "https://app.globus.org/logout", + "priority": 2, + "confirmSignin": true, + "description": "Use your Globus ID to access KBase.\n" + } + ], + "providers": [{{ range $i, $v := splitList "," (default "Google,Globus,OrcID" .Env.AUTH2_PROVIDERS) }}{{if $v }}{{ if $i }}, {{end}}"{{ $v }}"{{ end }}{{ end }}] }, "Catalog": { "module": "Catalog", "aliases": [ "catalog" ], - "url": "https://{{ .Env.deploy_hostname }}/services/catalog", + "url": "{{ .Env.KBASE_ENDPOINT }}catalog", "name": "Catalog", "type": "jsonrpc", "version": { @@ -223,7 +219,7 @@ "ee2", "ExecutionEngine2" ], - "url": "https://{{ .Env.deploy_hostname }}/services/ee2", + "url": "{{ .Env.KBASE_ENDPOINT }}ee2", "name": "Execution Engine2", "type": "jsonrpc" }, @@ -232,7 +228,7 @@ "aliases": [ "feeds" ], - "url": "https://{{ .Env.deploy_hostname }}/services/feeds", + "url": "{{ .Env.KBASE_ENDPOINT }}feeds", "name": "Feeds", "type": "rest", "version": { @@ -245,7 +241,7 @@ "aliases": [ "groups" ], - "url": "https://{{ .Env.deploy_hostname }}/services/groups", + "url": "{{ .Env.KBASE_ENDPOINT }}groups", "name": "Groups", "type": "rest", "version": { @@ -259,7 +255,7 @@ "narrative_job_service", "njs" ], - "url": "https://{{ .Env.deploy_hostname }}/services/njs_wrapper", + "url": "{{ .Env.KBASE_ENDPOINT }}njs_wrapper", "name": "Narrative Job Service", "type": "jsonrpc", "version": { @@ -271,8 +267,8 @@ "aliases": [ "narrative_method_store" ], - "url": "https://{{ .Env.deploy_hostname }}/services/narrative_method_store/rpc", - "image_url": "https://{{ .Env.deploy_hostname }}/services/narrative_method_store/", + "url": "{{ .Env.KBASE_ENDPOINT }}narrative_method_store/rpc", + "image_url": "{{ .Env.KBASE_ENDPOINT }}narrative_method_store/", "name": "Narrative Method Store", "type": "jsonrpc", "version": { @@ -284,7 +280,7 @@ "aliases": [ "user_profile" ], - "url": "https://{{ .Env.deploy_hostname }}/services/user_profile/rpc", + "url": "{{ .Env.KBASE_ENDPOINT }}user_profile/rpc", "name": "User Profile", "type": "jsonrpc", "version": { @@ -293,7 +289,7 @@ }, "SampleService": { "module": "SampleService", - "url": "https://{{ .Env.deploy_hostname }}/services/sampleservice", + "url": "{{ .Env.KBASE_ENDPOINT }}sampleservice", "name": "Sample Service", "type": "jsonrpc" }, @@ -302,7 +298,7 @@ "aliases": [ "service_wizard" ], - "url": "https://{{ .Env.deploy_hostname }}/services/service_wizard", + "url": "{{ .Env.KBASE_ENDPOINT }}service_wizard", "name": "Service Wizard", "type": "jsonrpc", "version": { @@ -314,7 +310,7 @@ "aliases": [ "workspace" ], - "url": "https://{{ .Env.deploy_hostname }}/services/ws", + "url": "{{ .Env.KBASE_ENDPOINT }}ws", "name": "Workspace", "type": "jsonrpc", "version": { @@ -324,7 +320,7 @@ "RelationEngine": { "module": "RelationEngine", "aliases": [], - "url": "https://{{ .Env.deploy_hostname }}/services/relation_engine_api", + "url": "{{ .Env.KBASE_ENDPOINT }}relation_engine_api", "name": "Relation Engine", "type": "rest", "version": { @@ -335,22 +331,22 @@ "SearchAPI2": { "module": "SearchAPI2", "aliases": [], - "url": "https://{{ .Env.deploy_hostname }}/services/searchapi2/rpc", - "legacyUrl": "https://{{ .Env.deploy_hostname }}/services/searchapi2/legacy", + "url": "{{ .Env.KBASE_ENDPOINT }}searchapi2/rpc", + "legacyUrl": "{{ .Env.KBASE_ENDPOINT }}searchapi2/legacy", "name": "Search Engine", "type": "jsonrpc2" }, "SearchAPI2Legacy": { "aliases": [], "module": "KBaseSearchEngine", - "url": "https://{{ .Env.deploy_hostname }}/services/searchapi2/legacy", + "url": "{{ .Env.KBASE_ENDPOINT }}searchapi2/legacy", "name": "Search Engine", "type": "jsonrpc" }, "ORCIDLink": { "aliases": [], "module": "ORCIDLink", - "url": "https://{{ .Env.deploy_hostname }}/services/orcidlink", + "url": "{{ .Env.KBASE_ENDPOINT }}orcidlink", "name": "KBase ORCID® Link", "type": "rest", "version": { diff --git a/deployment/templates/nginx.conf.tmpl b/deployment/templates/nginx.conf.tmpl index 285f53d8..599aeb92 100644 --- a/deployment/templates/nginx.conf.tmpl +++ b/deployment/templates/nginx.conf.tmpl @@ -4,6 +4,25 @@ worker_processes auto; pid /var/run/nginx.pid; user kbmodule; +# Build Environment Variables: +# UI_DOMAIN = {{ .Env.UI_DOMAIN }} +# KBASE_UI_DOMAIN = {{ .Env.KBASE_UI_DOMAIN }} +# BASE_PATH = {{ .Env.BASE_PATH }} +# NGINX_LOG_SYSLOG = {{ .Env.NGINX_LOG_SYSLOG }} +# NGINX_LOG_STDOUT = {{ .Env.NGINX_LOG_STDOUT }} +# NGINX_LOG_STDERR = {{ .Env.NGINX_LOG_STDERR }} +# NGINX_LOG_LEVEL = {{ .Env.NGINX_LOG_LEVEL }} +# NGINX_LISTEN = {{ .Env.NGINX_LISTEN }} +# NGINX_SERVER_NAME = {{ .Env.NGINX_SERVER_NAME }} + +{{ $subhost := not (eq .Env.UI_DOMAIN .Env.KBASE_UI_DOMAIN) }} + +{{ if $subhost }} +# Configured for SUBHOST {{ .Env.KBASE_UI_DOMAIN }} +{{ else }} +# Configured for SAME HOST +{{ end }} + events { worker_connections 256; # multi_accept on; @@ -27,19 +46,19 @@ http { # as optional # If the template is passed an nginx syslog path via nginx_log_syslog env var, log to there - {{ if .Env.nginx_log_syslog }} - access_log {{ .Env.nginx_log_syslog }} combined; + {{ if (default "" .Env.NGINX_LOG_SYSLOG) }} + access_log {{ .Env.NGINX_LOG_SYSLOG }} combined; {{ end }} # If nginx_log_stdout env var isn't false or empty, log to stdout - {{ if isTrue (default "true" .Env.nginx_log_stdout) }} + {{ if isTrue (default "true" .Env.NGINX_LOG_STDOUT) }} access_log /dev/stdout; {{ end }} access_log /var/log/nginx/access.log; - {{ if isTrue (default "true" .Env.nginx_log_stderr) }} - error_log /dev/stderr {{ default "error" .Env.nginx_loglevel }}; + {{ if isTrue (default "true" .Env.NGINX_LOG_STDERR) }} + error_log /dev/stderr {{ default "error" .Env.NGINX_LOG_LEVEL }}; {{ end }} - error_log /var/log/nginx/error.log {{ default "error" .Env.nginx_loglevel }}; + error_log /var/log/nginx/error.log {{ default "error" .Env.NGINX_LOG_LEVEL }}; ## # Gzip settings @@ -51,19 +70,29 @@ http { gzip_types text/plain text/css text/xml text/javascript application/json application/x-javascript application/xml; gzip_disable "MSIE [1-6]\."; - upstream docs { - server docs.kbase.us:443; - } + server { + listen {{ default "80" .Env.NGINX_LISTEN }} default_server; + server_name {{ default "localhost" .Env.NGINX_SERVER_NAME }}; - upstream marketing { - server www.kbase.us:443; - } + # Matches the root - the index page. + # TODO: this won't work if the base path is empty - fix that. + location = /{{ default "" .Env.BASE_PATH }}/ { + allow all; + # this ensures that a downstream cache service will revalidate. + add_header Cache-Control 'no-cache'; - server { - listen {{ default "80" .Env.nginx_listen }} default_server; - server_name {{ default "localhost" .Env.nginx_server_name }}; + {{ if $subhost }} + add_header Content-Security-Policy "frame-ancestors https://{{ .Env.UI_DOMAIN }} https://{{ .Env.KBASE_UI_DOMAIN }} ;" always; + {{ else }} + add_header Content-Security-Policy "frame-ancestors 'self';" always; + add_header X-Frame-Options "SAMEORIGIN" always; + {{ end }} + + root /kb/deployment/app; + try_files /index.html =404; + } - location {{ default "" .Env.BASE_PATH }}/ { + location ~ /{{ default "" .Env.BASE_PATH }} { # Ensure that index.html is invoked even if a path is # specified and doesn't exist. # try_files $uri /$uri /index.html; @@ -73,95 +102,43 @@ http { add_header Cache-Control 'no-cache'; # add_header Cache-Control 'no-store'; # expires 0; + + {{ if $subhost }} + add_header Content-Security-Policy "frame-ancestors https://{{ .Env.UI_DOMAIN }} https://{{ .Env.KBASE_UI_DOMAIN }} ;" always; + {{ else }} + add_header Content-Security-Policy "frame-ancestors 'self';" always; add_header X-Frame-Options "SAMEORIGIN" always; - add_header Content-Security-Policy "frame-ancestors 'self';" always; + {{ end }} root /kb/deployment/app; + rewrite ^/{{ default "" .Env.BASE_PATH }}(/.*)$ $1 break; } + # Used as a simple endpoint to determine the health of the connection + # to kbase. location {{ default "" .Env.BASE_PATH }}/__ping__ { default_type text/html; return 204; } + # Used by a performance measuring tool, about/connection + # Inside the __perf__ directory are files of specific sizes + # which can be fetched, and their download time measured as a + # rough estimate of network performance. location {{ default "" .Env.BASE_PATH }}/data/__perf__ { gzip off; add_header Cache-Control 'no-cache'; root /kb/deployment/app; } + # Catches references to old "modules/plugins" path; used by + # some plugins to fetch resources from within themselves. + # We just map it to the new canonical location for plugins. location {{ default "" .Env.BASE_PATH }}/modules/plugins/ { ssi_silent_errors off; allow all; add_header Cache-Control 'no-cache'; alias /kb/deployment/app/plugins/; } - - # Format is /__poke/https://www.example.com/some/path - location ~* ^{{ default "" .Env.BASE_PATH }}/__poke/docs/(.*)$ { - proxy_hide_header Content-Security-Policy; - proxy_hide_header X-Content-Security-Policy; - proxy_hide_header X-Webkit-Csp; - proxy_pass https://docs/$1; - proxy_http_version 1.1; - proxy_set_header Connection ""; - client_max_body_size 300M; - proxy_buffer_size 128k; - proxy_buffers 4 256k; - proxy_busy_buffers_size 256k; - proxy_set_header Host docs.kbase.us; - proxy_intercept_errors on; - recursive_error_pages on; - error_page 301 302 307 = @handle_redirect_docs; - } - - location @handle_redirect_docs { - set $saved_redirect_location '$upstream_http_location'; - - # These header fields are massive in gitbook. - proxy_hide_header Content-Security-Policy; - proxy_hide_header X-Content-Security-Policy; - proxy_hide_header X-Webkit-Csp; - proxy_http_version 1.1; - proxy_set_header Connection ""; - client_max_body_size 300M; - proxy_buffer_size 128k; - proxy_buffers 4 256k; - proxy_busy_buffers_size 256k; - proxy_set_header Host docs.kbase.us; - proxy_pass $saved_redirect_location; - proxy_intercept_errors on; - recursive_error_pages on; - error_page 301 302 307 = @handle_redirect_docs; - } - - location ~* ^{{ default "" .Env.BASE_PATH }}/__poke/marketing/(.*)$ { - proxy_pass https://marketing/$1; - proxy_http_version 1.1; - proxy_set_header Connection ""; - client_max_body_size 300M; - proxy_set_header Host www.kbase.us; - proxy_intercept_errors on; - recursive_error_pages on; - error_page 301 302 307 = @handle_redirect_marketing; - } - - location @handle_redirect_marketing { - set $saved_redirect_location '$upstream_http_location'; - set $path $saved_redirect_location; - - if ($saved_redirect_location ~* ^https://www.kbase.us/(.*)$) { - set $path $1; - } - - proxy_http_version 1.1; - proxy_set_header Connection ""; - client_max_body_size 300M; - proxy_set_header Host www.kbase.us; - proxy_pass https://marketing/$path; - proxy_intercept_errors on; - recursive_error_pages on; - error_page 301 302 307 = @handle_redirect_marketing; - } } } diff --git a/docker-compose.yml b/docker-compose.yml index 45e1728c..86aa0022 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,5 @@ -version: '3.6' +version: '3.8' +name: kbase-dev networks: kbase-dev: name: kbase-dev @@ -7,15 +8,11 @@ services: build: context: . dockerfile: Dockerfile - image: local/kbase-ui:dev - container_name: kbase-ui dns: 8.8.8.8 networks: - kbase-dev - environment: - - DEFAULT_PATH=${DEFAULT_PATH} command: - "-template" - "/kb/deployment/templates/nginx.conf.tmpl:/etc/nginx/nginx.conf" @@ -23,7 +20,7 @@ services: - "/kb/deployment/templates/config.json.tmpl:/kb/deployment/app/deploy/config.json" - "bash" - "/kb/deployment/scripts/start-server.bash" - env_file: dev/gitlab-config/${DEPLOY_ENV:-ci}_config.ini + env_file: .devcontainer/runtime.env kbase-ui-proxy: build: context: ./tools/proxy @@ -37,4 +34,4 @@ services: - '80:80' - '443:443' dns: 8.8.8.8 - env_file: tools/proxy/conf/${DEPLOY_ENV:-ci}.env + env_file: .devcontainer/proxy.env diff --git a/docs/deployment/configuration.md b/docs/deployment/configuration.md index 382a2cec..f5ee6304 100644 --- a/docs/deployment/configuration.md +++ b/docs/deployment/configuration.md @@ -192,7 +192,7 @@ dynamicServices_TaxonomyAPI_version=auto ui_services_menu_hamburger_disabled= ui_services_menu_sidebar_disabled= -ui_featureSwitches_enabled=search_features,system_alert_notification,new_provenance_widget,similar_genomes,re-lineage,linked-samples,sampleset-data-links,object-link-to-term +ui_featureSwitches_enabled=search_features,similar_genomes,re-lineage,linked-samples,sampleset-data-links,object-link-to-term ui_featureSwitches_disabled= dynamic_service_proxies= @@ -215,9 +215,6 @@ The environment variables listed below are supported. | Name | Default | Description | |------|---------|-------------| |`DEFAULT_PATH`| `"/narratives"` | A url path or "hash path" to serve as the target internal path if kbase-ui is invoked without a path (root) or the old `#dashboard` path is requested | -| `HIDE_HEADER` | `"false"` | A boolean-like string; setting to `"true"` will cause the page header to be omitted | -| `HIDE_NAVIGATION` | "false"` | A boolean-like string; setting to `"true"` will cause the sidebar navigation to be omitted | -| `INTEGRATED_HAMBURGER_AND_LOGO` | "false"` | A boolean-like string; setting to `"true"` causes the hamburger menu icon to be the KBase logo, and the Kbase logo to be omitted | ### `DEFAULT_PATH` @@ -248,39 +245,3 @@ forward slash. This will cause kbase-ui to navigate to the given path on the sam be redirected to `httpos://ci.kbase.us/narratives`. The configuration defaults to the current behavior, `/narratives`. - -### `HIDE_HEADER` - -This and the following environment variable have been supported in a different form -previously (TODO: documenet that!), but it was not exposed for configuration. - -The value of `HIDE_HEADER` is a "string boolean". Well, since environment variables are -by definition strings, it must be a string representation of a boolean. Since this is a -TypeScript/Javascript application, the Javascript form for boolean is used. In this -case, the value `"true"` indicates that the configuration should be considered `true`, -and any other value should be considered `false`. - -Setting `HIDE_HEADER` to `"true"` causes the entire header area of the site to not be -rendered. It defaults to `"false"` which resolves to `false`. - -This setting, along with the partner "HIDE_NAVIGATION", can be used to make a -"frameless" version of kbase-ui. - -The motivation for this is the same as for "DEFAULT_PATH" - to allow kbase-ui to run -inside a hosted environment which provides the equivalent services (menus, title, -notification, login indicator with avatar). - -### `HIDE_NAVIGATION` - -The value of `HIDE_NAVIGATION` is a string boolean. Setting it to `"true"`causes the -entire sidebar navigation to not be rendered. It defaults to `"false"` and thus resolves -to `false`. - -### `INTEGRATED_HAMBURGER_AND_LOGO` - -The value of `INTEGRATED_HAMBURGER_AND_LOGO` is a string boolean. A `true` value causes -the KBase logo to be integrated into the hamburger menu, replacing the triple-line -hamburger icon. The impact is that the header area is more compact. However, as there -are two other KBase user interfaces (Narrative and Navigator) which share the same -header design, it is not appropriate to default to this unless they are also similarly -updated. Thus this setting defaults to `false`. diff --git a/docs/development/deployment-setup.md b/docs/development/deployment-setup.md new file mode 100644 index 00000000..1990922b --- /dev/null +++ b/docs/development/deployment-setup.md @@ -0,0 +1,70 @@ +# Deployment Setup + +## Local Deployment Setup + +For local deployment, kbase-ui is operated just as in a real deployment - from a built +app, in a container built from the main Dockerfile, using dockerize to process the +kbase-ui and nginx config files using environment variables. + +### Generate configs + +This is the same procedure as for development, as some of the same files are utliized. + +- For local usage of a kbase-ui deployment, we still need to use the proxy in order to + operate on a deployment domain, and to use local services and Narrative. + + ```shell + SERVICE_PROXIES=orcidlink DEPLOY_ENV=ci KBASE_UI_HOSTNAME=legacy ./Taskfile generate-proxy-env + ``` + +- For kbase-ui + + For the deployed kbase-ui, we don't need to use the config.json file, as it is built + "on the fly" by the container via the dockerize entrypoint. However, we do utilize + the env file that is generated along with config.json, so we use the subtask + "generate-runtime-env" to create this env file. + + ```shell + DEPLOY_ENV=ci KBASE_UI_HOSTNAME=legacy ./Taskfile generate-runtime-env + ``` + +### Build kbase-ui + +The kbase-ui build is automated via a Taskfile task `build-kbase-ui`. This task will +generate build and git info files, download and setup plugins, build the web app, and +assemble all of this into a docker image. + +```shell +BASE_PATH="" GH_TOKEN="PAT_HERE" ./Taskfile build-kbase-ui +``` + +The `BASE_PATH` is optional. It is only required if there is a base path. It is utilized +in the `vite` build to construct the root `index.html` file. `kbase-ui` itself doesn't +use this value, rather it will use the value provided in the configuration. So, yes, +this must match the configuration. + +The `GH_TOKEN` is used for a local build, because GitHub rate limits unauthenticated +access to github.com. With a GH_TOKEN set to a Personal Access Token (PAT), rate +limiting is much higher (I've never run into rate limiting when using a PAT). + +Not that the GH_TOKEN is not required in a build through Github Actions. + +### Run kbase-ui + +Once the image is successfully built, starting the local server is as simple as: + +```shell +./Taskfile start-local-server +``` + +Note that this is so simply because an env file is used to supply the runtime +environment variables. This env file is located at `.devcontainer/runtime.env`. + +If you get a message like: + +```shell +Error response from daemon: Conflict. The container name "/kbase-ui" is already in use by container "56b79f26b53079d32e03a45110affe8150a748ac8d63e792274fdf9bdb172fd9". You have to remove (or rename) that container to be able to reuse that name. +``` + +you may already have a development container for kbase-ui. After exiting a VSC +devcontainer, the containers are not removed. diff --git a/docs/development/development-setup.md b/docs/development/development-setup.md new file mode 100644 index 00000000..a0581010 --- /dev/null +++ b/docs/development/development-setup.md @@ -0,0 +1,211 @@ +# `kbase-ui` Development Setup + +`kbase-ui` was designed to run against arbitrary deployment environments, +limited only by available configuration files. Traditionally, `kbase-ui` used +configuration environment files stored in KBase's gitlab. This approach served +well over the years, but suffered a few problems (described elsewhere.) The +current build uses environment variables instead. + +In both cases, kbase-ui configuration is made available to the runtime via a +json config file which is generated from a template, using environment +variables, during service startup. The config file is generated before the +entrypoint is run, with `dockerize`. + +During development, kbase-ui is run inside a devcontainer. Therefore, the +entrypoint configuration process is not run. Instead, before starting the +devcontainer, the developer sets the required environment variables, and builds +the config file with a script (`Taskfile render-templates`). + +So the steps are: + +- Generate env variables: + + - For the proxy: + + ```shell + DEPLOY_ENV=ci KBASE_UI_HOSTNAME=legacy ./Taskfile generate-proxy-env + ``` + + - For kbase-ui + + The kbase-ui development runtime (run via a _vite_ development server) does + not need any environment variables to control its behavior. Rather, all app + parameterization can be found in `config.json`. This file is normally built + by the container's entrypoint, based on environment variables, but for + development this file must be built first: + + ```shell + DEPLOY_ENV=ci KBASE_UI_HOSTNAME=legacy ./Taskfile generate-runtime-config + ``` + +- start the devcontainer + +- launch kbase-ui: + + ```shell + cd vite-app + npm run dev + ``` + +## What Happens + +### Proxy Environment Variables + +The `generate-proxy-env` task creates an "env" file in `.devcontainer/proxy.env`. This +env file is used by the "kbase-ui-proxy" service in the devcontainer's docker-compose +configuration. + +Below is an mexample env file generated from the command using minimal environment +variables. This configuration is suitable for running under Europa, with all services +proxied to the CI environment: + +```shell +DEPLOY_ENV=ci KBASE_UI_HOSTNAME=legacy ./Taskfile generate-proxy-env +``` + +which produces the following env: + +```shell +# An env file for usage by the proxy service in the devcontainer. +KBASE_UI_HOST="kbase-ui" +EUROPA_UI_HOST="europa-ui" +BASE_PATH="" +UI_DOMAIN="ci.kbase.us" +KBASE_UI_DOMAIN="legacy.ci.kbase.us" +SERVICES_HOSTNAME="ci.kbase.us" +LOCAL_NARRATIVE="" +SERVICE_PROXIES="" +DYNAMIC_SERVICE_PROXIES="" +``` + +To support working with a local instance of the Narrative and a local instance of the +orcidlink service we can use this command line + +```shell +LOCAL_NARRATIVE=t SERVICE_PROXIES=orcidlink DEPLOY_ENV=ci KBASE_UI_HOSTNAME=legacy ./Taskfile generate-proxy-env +``` + +which produces the following env: + +```shell +# An env file for usage by the proxy service in the devcontainer. +KBASE_UI_HOST="kbase-ui" +EUROPA_UI_HOST="europa-ui" +BASE_PATH="" +UI_DOMAIN="ci.kbase.us" +KBASE_UI_DOMAIN="legacy.ci.kbase.us" +SERVICES_HOSTNAME="ci.kbase.us" +LOCAL_NARRATIVE="t" +SERVICE_PROXIES="orcidlink" +DYNAMIC_SERVICE_PROXIES="" +``` + +### Runtime Config Environment Variables + +`kbase-ui` traditionally relies upon a pair of configuration files, `deploy/config.json` +and `/etc/nginx/nginx.conf`, to determine configurable runtime behavior. In a deployment, +this file is generated by `dockerize` from environment variables supplied by an env file +served out of a private gitlab. + +The new incarnation of kbase-ui still utilizes this basic framework, but relies upon +environment variables set by the deployment platform rather than an env file out of +gitlab. + +The development support tools allow us to generate these environment variables from a +script. The script is essentialy an environment helper, as it contains logic specific to +different development environments. In a deploy environment, these environment variables +must be specified in the deployment tool (e.g. rancher.) + +To generate the runtine configuration environment variables, we just need to specify the +deploy environment tag and specify how it is to be run under Europa with either +`BASE_PATH` or `KBASE_UI_HOSTNAME`: + +```shell +DEPLOY_ENV=ci KBASE_UI_HOSTNAME=legacy ./Taskfile generate-runtime-env +``` + +> TODO: update to note that we don't need the pre-built config.json for this + +This generates two files, an env file, and the JSON config file built by dockerize with +this env file. + +The env file is located in `.devcontainer/runtime.env` and looks like this: + +```shell +BASE_PATH="" +DEFAULT_PATH="narratives" +DEFAULT_PATH_TYPE="europaui" +UI_DOMAIN="ci.kbase.us" +KBASE_UI_DOMAIN="legacy.ci.kbase.us" +FEATURE_SWITCHES_ENABLED="search_features,similar_genomes,re-lineage,linked-samples,sampleset-data-links,object-link-to-term" +FEATURE_SWITCHES_DISABLED="" +AUTH2_PROVIDERS="Google,Globus,OrcID" +KBASE_ENDPOINT="https://ci.kbase.us/services/" +NGINX_LOG_SYSLOG="" +NGINX_LOG_STDOUT="true" +NGINX_LOG_STDERR="true" +NGINX_LOG_LEVEL="error" +NGINX_LISTEN="80" +NGINX_SERVER_NAME="localhost" +``` + +These are the same environment variables that would be used in a deployment. So, in +fact, the "generate-runtime-config" task can be used to generate environment variables +for a deployment server (e.g. Rancher). + +The runtime config file is placed in `build/deploy/config.json`, and the nginx file in +`build/deploy/nginx.conf`. The nginx file is not used during development, as it is only +used to control the nginx front end to kbase-ui in KBase deployment environments. + +The JSON config file is made available to kbase-ui through the dev server's +proxy and the devcontainer's special "deploy proxy" - a small nginx server whose +job is to proxy assets normally built into the kbase-ui image, or made available +through dockerize-generated files. This includes: + +- `build/build-info.json` +- `build/git-info.json` +- `deploy/config.json` +- `plugins` + +## Running the development server + +To engage in a development session behind the usual kbase-ui development proxies: + +- start the devcontainer: on macOS `Shift`-`Command`-`P`, then search for "Dev + Containers: Reopen in Container", and select it. + +- a terminal should open in the devcontainer. The current directory will be the repo. + +- change into the vite directory `cd vite-app` + +- install npm dependencies `npm ci` + +- run the dev server `npm run dev` + +## environment variables + +Base + +```shell +export NGINX_LOG_STDOUT=true +export NGINX_LOG_STDERR=true +export NGINX_LOG_LEVEL=error +export NGINX_LISTEN=80 +export NGINX_SERVER_NAME=localhost +export DEFAULT_PATH="#about" +export BACKUP_COOKIE_DOMAIN= +export BACKUP_COOKIE_ENABLED=false +export FEATURE_SWITCHES_ENABLED= +export FEATURE_SWITCHES_DISABLED= +export AUTH2_PROVIDERS=Google,Globus,OrcID + +``` + +For CI running locally: + +```shell +export KBASE_ENDPOINT=https://ci.kbase.us/services/ +export UI_HOSTNAME=ci.kbase.us +export FEATURE_SWITCHES_ENABLED=search_features,system_alert_notification,new_provenance_widget,similar_genomes,re-lineage,linked-samples,sampleset-data-links,object-link-to-term +``` + diff --git a/docs/environment-variables.md b/docs/environment-variables.md new file mode 100644 index 00000000..8ef89ef3 --- /dev/null +++ b/docs/environment-variables.md @@ -0,0 +1,203 @@ +# Environment Variables in kbase-ui + +`kbase-ui` relies upon a set of required and optional environment +variables. It depends upon them in a manner quite characteristic of KBase services, that +is, indirectly by using them to create a configuration file. + +This makes sense, as `kbase-ui`, though at its heart a single page web app, +statically compiled, and simply loaded into the browser, is deployed and +operated like any service. + +This is due to the fact that it is deployed with its own nginx server, whose sole job is +to serve up the kbase-ui assets to a browser. This nginx server runs in a +container. This container uses `dockerize` as its entry point + +`kbase-ui` uses `dockerize` to generate two files: `nginx.conf` for the `nginx` +server, and `config.json`, for `kbase-ui`. + +The `nginx` configuration is primarily used to control nginx logging. + +It can also host kbase-ui assets on a path prefix, but this is not utilized at +present. The path for kbase-ui assets within the nginx server is the root path - +`"/"` or `""`. + +The `kbase-ui` configuration is more extensive. It is used to supply: + +- the base path (unused), +- hostnames for the top level user interface (Europa, Narrative) and services. +- special auth behavior for prod (backup cookie) +- feature switches + +## Catalog of Environment Variables + +Environment variables are divided into those supporting the kbase-ui web app, and those +supporting the nginx server. In addition, these are divided into required environment +variables without defaults and those with defaults, which can be considered optional. + +The fulls set of environment variables, therefore, is the intersection. + +The full set of required environment variables is: + +- `KBASE_ENDPOINT` +- `UI_HOSTNAME` + +The full set of optional environment variables is: + +- `BASE_PATH` +- `DEFAULT_PATH` +- `DEFAULT_PATH_TYPE` +- `FEATURE_SWITCHES_ENABLED` +- `FEATURE_SWITCHES_DISABLED` +- `AUTH2_PROVIDERS` +- `NGINX_LOG_SYSLOG` +- `NGINX_LOG_STDOUT` +- `NGINX_LOG_STDERR` +- `NGINX_LOG_LEVEL` +- `NGINX_LISTEN` +- `NGINX_SERVER_NAME` + +### Web App + +These environment variables are applied to `deploy/templates/config.json.tmpl`. + +#### Required (no defaults) + +| Name | Description | +|----------------|-------------------------------------------------------------------------------------------| +| KBASE_ENDPOINT | The traditional KBase services url base; e.g. `https://ci.kbase.us/services/` | +| UI_HOSTNAME | The hostname at which Europa, and most KBase user interfaces, operate in this environment | + +#### Optional (with defaults) + +| Name | Default | Description | +|---------------------------|-----------------------|-------------------------------------------------------------------------------------------| +| BASE_PATH | "/" | The base, or prefix, path kbase-ui should expect; currently unused (but had been planned) | +| DEFAULT_PATH | "narratives" | When kbase-ui is asked to show the dashboard, go here [1] | +| DEFAULT_PATH_TYPE | "europui" | The type of path for the above - either "europaui" or "kbaseui" | +| FEATURE_SWITCHES_ENABLED | "" | | +| FEATURE_SWITCHES_DISABLED | "" | | +| AUTH2_PROVIDERS | "Google,Globus,OrcID" | | + + + +### Nginx Server + +These environment variables are applied to `deploy/templates/nginx.conf.tmpl`. + +#### Required (no defaults) + +| Name | Description | +|----------------|-------------------------------------------------------------------------------| +| KBASE_ENDPOINT | The traditional KBase services url base; e.g. `https://ci.kbase.us/services/` | +| UI_HOSTNAME | The hostname at which Europa and Narrative operate | + + +#### Optional (with defaults) + +| Name | Default | Description | +|-------------------|---------|-----------------------------------------------------------------------------------------------------------------------------| +| NGINX_LOG_SYSLOG | "" | If provided, sets an `access_log NGINX_LOG_SYSLOG combined;` stanza, where the value is a valid syslog configuration string | +| NGINX_LOG_STDOUT | "true" | if "true", `access_log /dev/stdout;` | +| NGINX_LOG_STDERR | "true" | if "true", `access_log /dev/stderr;` | +| NGINX_LOG_LEVEL | "error" | adds given log level to stderr (if enabled) and `/var/log/nginx/error.log` | +| NGINX_LISTEN | "80" | The port on which to listen for requests | +| NGINX_SERVER_NAME | "true" | The host name on which to listen for requests. | + +## Usage in Development + +During development, these environment variables are used to generate the configuration +files manually. This is because local development does not typically use the nginx +server in the deployment container, but rather runs the web app in development mode in a +Visual Studio Code devcontainer. + +To generate the configuration files: + +1. Set the environment variables: + + - for ci: + + ```shell + export KBASE_ENDPOINT=https://ci.kbase.us/services/ + export UI_HOSTNAME=ci.kbase.us + export FEATURE_SWITCHES_ENABLED=search_features,similar_genomes,re-lineage,linked-samples,sampleset-data-links,object-link-to-term + ``` + + For local usage: + + ```shell + NGINX_LOG_SYSLOG= + ``` + + For the real deployment: + + ```shell + NGINX_LOG_SYSLOG=syslog:server=10.58.0.54,facility=local2,tag=ci,severity=info + ``` + + - for appdev: + + ```shell + export KBASE_ENDPOINT=https://appdev.kbase.us/services/ + export UI_HOSTNAME=appdev.kbase.us + export FEATURE_SWITCHES_ENABLED=similar_genomes + ``` + + For local usage: + + ```shell + NGINX_LOG_SYSLOG= + ``` + + For the real deployment: + + ```shell + NGINX_LOG_SYSLOG=syslog:server=10.58.0.54,facility=local2,tag=appdev,severity=info + ``` + + - for next: + + ```shell + export KBASE_ENDPOINT=https://next.kbase.us/services/ + export UI_HOSTNAME=next.kbase.us + export FEATURE_SWITCHES_ENABLED=similar_genomes + ``` + + For local usage: + + ```shell + NGINX_LOG_SYSLOG= + ``` + + For the real deployment: + + ```shell + NGINX_LOG_SYSLOG=syslog:server=10.58.0.54,facility=local2,tag=next,severity=info + ``` + + - for prod: + + ```shell + export KBASE_ENDPOINT=https://kbase.us/services/ + export UI_HOSTNAME=narrative.kbase.us + export FEATURE_SWITCHES_ENABLED=similar_genomes + ``` + + For local usage: + + ```shell + NGINX_LOG_SYSLOG= + ``` + + For the real deployment: + + ```shell + NGINX_LOG_SYSLOG=syslog:server=10.58.0.54,facility=local2,tag=prod,severity=info + ``` + +2. Generate the configs + + ```shell + ./Taskfile render-templates + ``` + +## Usage in Deployments \ No newline at end of file diff --git a/scripts/container/generate-proxy-env b/scripts/container/generate-proxy-env new file mode 100755 index 00000000..a6f41bf9 --- /dev/null +++ b/scripts/container/generate-proxy-env @@ -0,0 +1,112 @@ +#!/usr/bin/env bash + +# Proxy Container +# +# See tools/proxy/contents/conf/nginx.conf.tmpl for usage +# +# Input environment variables: +# +# required: +# +# DEPLOY_ENV +# BASE_PATH +# +# optional: +# +# LOCAL_NARRATIVE +# SERVICE_PROXIES +# DYNAMIC_SERVICE_PROXIES +# KBASE_UI_HOSTNAME +# +# Created environment variables: +# +# KBASE_UI_HOST +# EUROPA_UI_HOST +# BASE_PATH +# LOCAL_NARRATIVE +# SERVICE_PROXIES +# DYNAMIC_SERVICE_PROXIES +# UI_DOMAIN +# KBASE_UI_DOMAIN +# SERVICES_DOMAIN +# KBASE_ENDPOINT + +echo +echo 'Creating proxy env vars...' + +if [ -z "${DEPLOY_ENV}" ] +then + echo 'The "DEPLOY_ENV" environment variable is required to generate config env' + exit 1 +fi + +echo +echo "DEPLOY_ENV is '${DEPLOY_ENV}'" + +if [ -z "${KBASE_UI_BASE_PATH}" ] && [ -z "${KBASE_UI_HOSTNAME}" ] +then + echo 'Either the "KBASE_UI_BASE_PATH" or "KBASE_UI_HOSTNAME" environment variable is required to generate config env' + exit 1 +fi + +echo "KBASE_UI_BASE_PATH is '${KBASE_UI_BASE_PATH}'" +echo "KBASE_UI_HOSTNAME is '${KBASE_UI_HOSTNAME}'" +echo + +# +# These rarely, if ever, change +# + +# The proxy target for kbase-ui; the ip or host of the kbase-ui container. +KBASE_UI_HOST="kbase-ui" +EUROPA_UI_HOST="europa-ui" + +# For all other user intefaces +UI_DOMAIN="${DEPLOY_ENV}.kbase.us" + +# For the time being, the proxy needs to forwared narrative.kbase.us to kbase.us. +# TODO: still necessary? +if [ "${DEPLOY_ENV}" = "narrative" ] +then + SERVICES_DOMAIN="kbase.us" +elif [ "${DEPLOY_ENV}" = "narrative2" ] +then + SERVICES_DOMAIN="kbase.us" +else + SERVICES_DOMAIN="${UI_DOMAIN}" +fi + +# SERVICES_DOMAIN="${UI_DOMAIN}" + +# For running under Europa, this is the server hostname used by kbase-ui. +if [ -z "${KBASE_UI_HOSTNAME}" ] +then + KBASE_UI_DOMAIN="${DEPLOY_ENV}.kbase.us" +else + KBASE_UI_DOMAIN="${KBASE_UI_HOSTNAME}.${DEPLOY_ENV}.kbase.us" +fi + + +BASE_PATH="${KBASE_UI_BASE_PATH}" + +# +# These are controlled directly by the developer +# +LOCAL_NARRATIVE="${LOCAL_NARRATIVE}" +SERVICE_PROXIES="${SERVICE_PROXIES}" +DYNAMIC_SERVICE_PROXIES="${DYNAMIC_SERVICE_PROXIES}" + +# Generates an env file for usage by the proxy service in the devcontainer. + +cat << EOF > ./.devcontainer/proxy.env +# An env file for usage by the proxy service in the devcontainer. +KBASE_UI_HOST="${KBASE_UI_HOST}" +EUROPA_UI_HOST="${EUROPA_UI_HOST}" +BASE_PATH="${BASE_PATH}" +UI_DOMAIN="${UI_DOMAIN}" +KBASE_UI_DOMAIN="${KBASE_UI_DOMAIN}" +SERVICES_DOMAIN="${SERVICES_DOMAIN}" +LOCAL_NARRATIVE="${LOCAL_NARRATIVE}" +SERVICE_PROXIES="${SERVICE_PROXIES}" +DYNAMIC_SERVICE_PROXIES="${DYNAMIC_SERVICE_PROXIES}" +EOF \ No newline at end of file diff --git a/scripts/container/generate-runtime-env b/scripts/container/generate-runtime-env new file mode 100755 index 00000000..55e33e8f --- /dev/null +++ b/scripts/container/generate-runtime-env @@ -0,0 +1,153 @@ +#!/usr/bin/env bash + +# KBase UI Config and Nginx Server Environment Variables +# +# Used to generate config.json and nginx.conf. +# +# Input environment variables: +# +# required: +# +# DEPLOY_ENV +# +# Created env vars for config.json.tmpl: +# +# BASE_PATH +# DEFAULT_PATH +# DEFAULT_PATH_TYPE +# UI_DOMAIN +# KBASE_ENDPOINT +# FEATURE_SWITCHES_ENABLED +# FEATURE_SWITCHES_DISABLED +# AUTH2_PROVIDERS +# + +if [ -z "${DEPLOY_ENV}" ] +then + echo 'The "DEPLOY_ENV" environment variable is required to generate config env' + exit 1 +fi + + +# +# These rarely, if ever, change, so they have defaults. +# +BASE_PATH="${BASE_PATH}" +DEFAULT_PATH="narratives" +DEFAULT_PATH_TYPE="europaui" + +# +# These change per environment, with the special case for prod. +# + +# Domain all other user intefaces +UI_DOMAIN="${DEPLOY_ENV}.kbase.us" + +# Domain for kbase-ui +# TODO: is this used? if it is, we need the subdomain hostname; if not, remove. +if [ -z "${KBASE_UI_HOSTNAME}" ] +then + KBASE_UI_DOMAIN="${DEPLOY_ENV}.kbase.us" +else + KBASE_UI_DOMAIN="${KBASE_UI_HOSTNAME}.${DEPLOY_ENV}.kbase.us" +fi + +# Base URL for services +# KBASE_ENDPOINT="https://${DEPLOY_ENV}.kbase.us/services/" + +# Well, maybe it don't really work like that? (old prod) + +if [ "${DEPLOY_ENV}" = "narrative" ] +then + KBASE_ENDPOINT="https://kbase.us/services/" +elif [ "${DEPLOY_ENV}" = "narrative2" ] +then + KBASE_ENDPOINT="https://kbase.us/services/" +else + KBASE_ENDPOINT="https://${DEPLOY_ENV}.kbase.us/services/" +fi + +# +# Auth providers +# +if [ "$DEPLOY_ENV" = "appdev" ] +then + AUTH2_PROVIDERS="Google,Globus" +else + AUTH2_PROVIDERS="Google,Globus,OrcID" +fi + +# +# Feature switches. +# +# TODO: remove "similar_genomes" feature switch from kbase-ui and landing pages. +# let's do that soon, as we can then get rid of a lot of config below and make +# deployment easier. +# +if [ "$DEPLOY_ENV" = "ci" ] +then + FEATURE_SWITCHES_ENABLED=search_features,similar_genomes,re-lineage,linked-samples,sampleset-data-links,object-link-to-term +elif [ "$DEPLOY_ENV" = "ci-europa" ] +then + FEATURE_SWITCHES_ENABLED=search_features,similar_genomes,re-lineage,linked-samples,sampleset-data-links,object-link-to-term +elif [ "$DEPLOY_ENV" = "narrative-dev" ] +then + FEATURE_SWITCHES_ENABLED=similar_genomes +elif [ "$DEPLOY_ENV" = "next" ] +then + FEATURE_SWITCHES_ENABLED=similar_genomes +elif [ "$DEPLOY_ENV" = "appdev" ] +then + FEATURE_SWITCHES_ENABLED=similar_genomes +elif [ "$DEPLOY_ENV" = "narrative2" ] +then + FEATURE_SWITCHES_ENABLED=similar_genomes +elif [ "$DEPLOY_ENV" = "narrative" ] +then + FEATURE_SWITCHES_ENABLED=similar_genomes +fi + + +# +# Created env vars for nginx.json.tmpl: +# Note that these may not be used, but we generate them anyway. +# +# BASE_PATH +# NGINX_LOG_SYSLOG +# NGINX_LOG_STDOUT +# NGINX_LOG_STDERR +# NGINX_LOG_LEVEL +# NGINX_LISTEN +# NGINX_SERVER_NAME + + +# Note that nginx env vars, NGINX_*, are not used for development, but we generate the +# nginx config file anyway. +NGINX_LOG_SYSLOG= +NGINX_LOG_STDOUT=true +NGINX_LOG_STDERR=true +NGINX_LOG_LEVEL=error +NGINX_LISTEN=80 +NGINX_SERVER_NAME=localhost + + +# Generates a temporary env file for usage in generating the runtime template +# config.json and nginx.conf + +cat << EOF > ./.devcontainer/runtime.env +BASE_PATH="${BASE_PATH}" +DEFAULT_PATH="${DEFAULT_PATH}" +DEFAULT_PATH_TYPE="${DEFAULT_PATH_TYPE}" +UI_DOMAIN="${UI_DOMAIN}" +KBASE_UI_DOMAIN="${KBASE_UI_DOMAIN}" +FEATURE_SWITCHES_ENABLED="${FEATURE_SWITCHES_ENABLED}" +FEATURE_SWITCHES_DISABLED="${FEATURE_SWITCHES_DISABLED}" +AUTH2_PROVIDERS="${AUTH2_PROVIDERS}" +KBASE_ENDPOINT="${KBASE_ENDPOINT}" +NGINX_LOG_SYSLOG="${NGINX_LOG_SYSLOG}" +NGINX_LOG_STDOUT="${NGINX_LOG_STDOUT}" +NGINX_LOG_STDERR="${NGINX_LOG_STDERR}" +NGINX_LOG_LEVEL="${NGINX_LOG_LEVEL}" +NGINX_LISTEN="${NGINX_LISTEN}" +NGINX_SERVER_NAME="${NGINX_SERVER_NAME}" +EOF \ No newline at end of file diff --git a/scripts/host/build.sh b/scripts/host/build.sh index 91450c68..8ec3e93e 100644 --- a/scripts/host/build.sh +++ b/scripts/host/build.sh @@ -1,4 +1,3 @@ cd tools/node -docker compose run --rm node npm uninstall * -docker compose run --rm node npm install -docker compose run --rm node npm run build \ No newline at end of file +docker compose run --rm node-tool npm ci +docker compose run -e BASE_PATH --rm node-tool npm run build \ No newline at end of file diff --git a/scripts/host/clean-build.sh b/scripts/host/clean-build.sh deleted file mode 100644 index 8107c7a0..00000000 --- a/scripts/host/clean-build.sh +++ /dev/null @@ -1,2 +0,0 @@ -# ensure the target directory is empty (mostly for dev usage) -rm -rf build/dist diff --git a/scripts/host/extend-docker-compose.sh b/scripts/host/extend-docker-compose.sh deleted file mode 100644 index 3ed8abbf..00000000 --- a/scripts/host/extend-docker-compose.sh +++ /dev/null @@ -1 +0,0 @@ -bash scripts/deno/docker-compose-override.sh \ No newline at end of file diff --git a/scripts/host/re-build.sh b/scripts/host/re-build.sh index 17cadba9..caf747c3 100644 --- a/scripts/host/re-build.sh +++ b/scripts/host/re-build.sh @@ -1,2 +1,2 @@ cd tools/deno -DIR=`pwd`/../../react-app docker compose run node npm run build \ No newline at end of file +DIR=`pwd`/../../react-app docker compose run node-tool npm run build \ No newline at end of file diff --git a/scripts/host/test.sh b/scripts/host/test.sh index 0a0f85d3..5cb4af60 100644 --- a/scripts/host/test.sh +++ b/scripts/host/test.sh @@ -2,5 +2,5 @@ echo "[test.sh] starting in ${PWD}, DIR=${DIR}" echo "" cd tools/node ls -docker compose run --rm node npm install -docker compose run --rm node npm run test \ No newline at end of file +docker compose run --rm node-tool npm install +docker compose run --rm node-tool npm run test \ No newline at end of file diff --git a/tools/dockerize/docker-compose.yml b/tools/dockerize/docker-compose.yml index 783f710e..e9fcb17a 100644 --- a/tools/dockerize/docker-compose.yml +++ b/tools/dockerize/docker-compose.yml @@ -5,12 +5,8 @@ services: image: powerman/dockerize container_name: dockerize dns: 8.8.8.8 - environment: - - BASE_PATH - - DEFAULT_PATH - - HIDE_HEADER - - HIDE_NAVIGATION - - INTEGRATED_HAMBURGER_AND_LOGO - - deploy_name + env_file: + - $ENV_FILE + # - ../../dev/templates-context.env volumes: - $DIR:/app \ No newline at end of file diff --git a/tools/dockerize/scripts/render-proxy-configs.sh b/tools/dockerize/scripts/render-proxy-configs.sh new file mode 100755 index 00000000..0f9cd20c --- /dev/null +++ b/tools/dockerize/scripts/render-proxy-configs.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# source "${DIR}/scripts/host/create-dev-proxy-env-vars.bash" +source "${DIR}/.devcontainer/proxy.env" + +set -e +echo "Render development proxy config files" +echo "Parameters (Environment Variables):" +echo "" +echo "UI_DOMAIN = ${UI_DOMAIN}" +echo "KBASE_UI_DOMAIN = ${KBASE_UI_DOMAIN}" +echo "" + + + +# Generate the deployment configs that are normally generated by the entrypoint in the +# Dockerfile. Note that for development we don't actually use nginx.conf, but we +# generate it here so we can inspect it. + # --env-file ${DIR}/.devcontainer/proxy.env \ +docker compose \ + -f ${DIR}/tools/dockerize/docker-compose.yml \ + run \ + --rm \ + dockerize \ + -template /app/tools/proxy/contents/conf/nginx.conf.tmpl:/app/build/deploy/proxy-nginx.conf + diff --git a/tools/dockerize/scripts/render-templates.sh b/tools/dockerize/scripts/render-templates.sh old mode 100644 new mode 100755 index 192cef29..f10490b4 --- a/tools/dockerize/scripts/render-templates.sh +++ b/tools/dockerize/scripts/render-templates.sh @@ -1,18 +1,48 @@ -set -e -echo "Rendering kbase-ui config file from template for environment '${ENV}' using base app dir '${DIR}'" -echo "Parameters (Environment Variables):" -echo " ENV=${ENV}" -echo " DIR=${DIR}" -echo " BASE_PATH=${BASE_PATH}" -echo " DEFAULT_PATH=${DEFAULT_PATH}" -echo " HIDE_HEADER=${HIDE_HEADER}" -echo " HIDE_NAVIGATION=${HIDE_NAVIGATION}" -echo " INTEGRATED_HAMBURGER_AND_LOGO=${INTEGRATED_HAMBURGER_AND_LOGO}" -echo "" +#!/usr/bin/env bash + +# source "${DIR}/scripts/host/development-env-vars.bash" + +# set -e +# echo "Rendering kbase-ui config file from template for environment '${DEPLOY_ENV}' using base app dir '${DIR}'" +# echo "Parameters (Environment Variables):" +# echo "" +# echo "Just for development" +# echo "--------------------" +# echo " DIR=${DIR}" +# echo "" +# echo "Required" +# echo "--------" +# echo "" +# echo "URL Bases" +# echo " UI_DOMAIN=${UI_DOMAIN}" +# echo "" +# echo "Feature Switches" +# echo " FEATURE_SWITCHES_ENABLED=${FEATURE_SWITCHES_ENABLED}" +# echo " FEATURE_SWITCHES_DISABLED=${FEATURE_SWITCHES_DISABLED}" +# echo "" + +if [ -z "$DIR" ] +then + echo "The environment variable 'DIR' must be set first" + exit 1 +fi + +export ENV_FILE="${DIR}/.devcontainer/runtime.env" + +if [ ! -f "$ENV_FILE" ] +then + echo "The env file '${ENV_FILE}' must be generated first" + exit 1 +fi + + +# Generate the deployment configs that are normally generated by the entrypoint in the +# Dockerfile. Note that for development we don't actually use nginx.conf, but we +# generate it here so we can inspect it. docker compose \ -f ${DIR}/tools/dockerize/docker-compose.yml \ run \ --rm \ dockerize \ -template /app/deployment/templates/config.json.tmpl:/app/build/deploy/config.json \ - -env /app/dev/gitlab-config/${ENV}_config.ini + -template /app/deployment/templates/nginx.conf.tmpl:/app/build/deploy/nginx.conf diff --git a/tools/make-dev-cert.sh b/tools/make-dev-cert.sh index cb5d03e9..e7a0c52f 100644 --- a/tools/make-dev-cert.sh +++ b/tools/make-dev-cert.sh @@ -1,4 +1,4 @@ cd temp -mkcert -cert-file test.crt --key-file test.key kbase.us "*.kbase.us" +mkcert -cert-file test.crt --key-file test.key kbase.us "*.kbase.us" "*.ci.kbase.us" "*.next.kbase.us" "*.appdev.kbase.us" "*.narrative2.kbase.us" "*.narrative.kbase.us" "*.narrative-dev.kbase.us" "*.ci-europa.kbase.us" mv test.* ../tools/proxy/contents/ssl \ No newline at end of file diff --git a/tools/node/Dockerfile b/tools/node/Dockerfile index ad67de5e..3340bbd2 100644 --- a/tools/node/Dockerfile +++ b/tools/node/Dockerfile @@ -1,5 +1,5 @@ -FROM node:18-slim +FROM node:20-slim RUN apt-get update && \ apt-get install -y npm python3 git make bash && \ - npm install --location=global npm@10.2.0 + npm install --location=global npm@10.5.0 diff --git a/tools/node/docker-compose.yml b/tools/node/docker-compose.yml index 9a8023a1..1b9658e6 100644 --- a/tools/node/docker-compose.yml +++ b/tools/node/docker-compose.yml @@ -1,11 +1,17 @@ -version: '3.6' +version: '3.8' +name: kbase-dev +networks: + kbase-dev: + name: kbase-dev services: - node: + node-tool: working_dir: /app build: context: . dockerfile: Dockerfile container_name: node-builder dns: 8.8.8.8 + networks: + - kbase-dev volumes: - $DIR:/app \ No newline at end of file diff --git a/tools/node/run b/tools/node/run new file mode 100755 index 00000000..5b5c48a2 --- /dev/null +++ b/tools/node/run @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +DIR="${PWD}" docker compose -f tools/node/docker-compose.yml run --rm node-tool "$@" \ No newline at end of file diff --git a/tools/proxy/README.md b/tools/proxy/README.md index 8c88a3e3..f4178007 100644 --- a/tools/proxy/README.md +++ b/tools/proxy/README.md @@ -23,4 +23,7 @@ optional: local_navigator local_narrative service_proxies -dynamic_service_proxies \ No newline at end of file +dynamic_service_proxies + +> NOTE: the standalone docker-compose.yml has not been used for a while; just the +> devcontainer one. It will need some work to ... work. \ No newline at end of file diff --git a/tools/proxy/conf/README.md b/tools/proxy/conf/README.md deleted file mode 100644 index eb195192..00000000 --- a/tools/proxy/conf/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Configuration files - -Configuration files for the Proxy development image. - - - diff --git a/tools/proxy/conf/appdev.env b/tools/proxy/conf/appdev.env deleted file mode 100644 index 2432bb96..00000000 --- a/tools/proxy/conf/appdev.env +++ /dev/null @@ -1,16 +0,0 @@ -# Proxy Container - -deploy_hostname=appdev.kbase.us - -# disabled -#deploy_ui_hostname= - -# the ip or host of the kbase-ui container. This is required -# may need to override in the run command -kbase_ui_host=kbase-ui - -# true if actually deployed -# probably best to just override in the run command -deployed=true - -base_path=/ diff --git a/tools/proxy/conf/ci.env b/tools/proxy/conf/ci.env deleted file mode 100644 index e78792bf..00000000 --- a/tools/proxy/conf/ci.env +++ /dev/null @@ -1,16 +0,0 @@ -# Proxy Container - -deploy_hostname=ci.kbase.us - -# disabled -#deploy_ui_hostname= - -# the ip or host of the kbase-ui container. This is required -# may need to override in the run command -kbase_ui_host=kbase-ui - -# true if actually deployed -# probably best to just override in the run command -deployed=true - -base_path=/ diff --git a/tools/proxy/conf/dev.env b/tools/proxy/conf/dev.env deleted file mode 100644 index 764f7d2f..00000000 --- a/tools/proxy/conf/dev.env +++ /dev/null @@ -1,16 +0,0 @@ -# Proxy Container - -deploy_hostname=ci.kbase.us - -# disabled -#deploy_ui_hostname= - -# the ip or host of the kbase-ui container. This is required -# may need to override in the run command -kbase_ui_host=kbase-ui - -# true if actually deployed -# probably best to just override in the run command -deployed=false - -base_path=/ diff --git a/tools/proxy/conf/narrative-dev.env b/tools/proxy/conf/narrative-dev.env deleted file mode 100644 index 1e87cffe..00000000 --- a/tools/proxy/conf/narrative-dev.env +++ /dev/null @@ -1,16 +0,0 @@ -# Proxy Container -deploy_hostname=narrative-dev.kbase.us - -# disabled -# deploy_ui_hostname=narrative-dev.kbase.us - -# the ip or host of the kbase-ui container. This is required -# may need to override in the run command -kbase_ui_host=kbase-ui - -# true if actually deployed -# probably best to just override in the run command -deployed=true - -base_path=/ - diff --git a/tools/proxy/conf/narrative2.env b/tools/proxy/conf/narrative2.env deleted file mode 100644 index 3671fbc3..00000000 --- a/tools/proxy/conf/narrative2.env +++ /dev/null @@ -1,16 +0,0 @@ -# Proxy Container -deploy_hostname=narrative2.kbase.us - -# disabled -# deploy_ui_hostname=narrative-dev.kbase.us - -# the ip or host of the kbase-ui container. This is required -# may need to override in the run command -kbase_ui_host=kbase-ui - -# true if actually deployed -# probably best to just override in the run command -deployed=true - -base_path=/ - diff --git a/tools/proxy/conf/next.env b/tools/proxy/conf/next.env deleted file mode 100644 index 1116431f..00000000 --- a/tools/proxy/conf/next.env +++ /dev/null @@ -1,18 +0,0 @@ -# Proxy Container - -deploy_hostname=next.kbase.us - -# disabled -#deploy_ui_hostname= - -# the ip or host of the kbase-ui container. This is required -# may need to override in the run command -kbase_ui_host=kbase-ui - -# true if actually deployed -# probably best to just override in the run command -deployed=true - -base_path=/ - - diff --git a/tools/proxy/conf/prod.env b/tools/proxy/conf/prod.env deleted file mode 100644 index 86e1e6cb..00000000 --- a/tools/proxy/conf/prod.env +++ /dev/null @@ -1,17 +0,0 @@ -# Proxy Container - -deploy_hostname=kbase.us - -# for proxying to the narrative in this env. -deploy_ui_hostname=narrative.kbase.us - -# the ip or host of the kbase-ui container. This is required -# may need to override in the run command -kbase_ui_host=kbase-ui - -# true if actually deployed -# probably best to just override in the run command -deployed=true - -base_path=/ - diff --git a/tools/proxy/contents/conf/cors.conf.tmpl b/tools/proxy/contents/conf/cors.conf.tmpl index 0f33d757..256ed827 100644 --- a/tools/proxy/contents/conf/cors.conf.tmpl +++ b/tools/proxy/contents/conf/cors.conf.tmpl @@ -1,4 +1,3 @@ -{{ if .Env.deploy_ui_hostname }} proxy_hide_header 'Access-Control-Max-Age,'; proxy_hide_header 'Access-Control-Allow-Headers'; @@ -10,20 +9,17 @@ add_header 'Access-Control-Max-Age' 1728000; add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type'; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; - add_header 'Access-Control-Allow-Origin' 'https://{{ .Env.deploy_ui_hostname }}'; - # add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Origin' $http_origin; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0 always; return 204; } - add_header 'Access-Control-Allow-Origin' 'https://{{ .Env.deploy_ui_hostname }}' always; - # add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Origin' $http_origin always; add_header 'Access-Control-Allow-Credentials' 'true' always; add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Cookie' always; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; -{{ end }} \ No newline at end of file diff --git a/tools/proxy/contents/conf/nginx.conf-base-path-changes.tmpl b/tools/proxy/contents/conf/nginx.conf-base-path-changes.tmpl deleted file mode 100644 index 41782c03..00000000 --- a/tools/proxy/contents/conf/nginx.conf-base-path-changes.tmpl +++ /dev/null @@ -1,497 +0,0 @@ -# -# A minimal proxying configuration for running kbase-ui through a secure proxy -# against a KBase deploy environment. -# -# Note that lower case environment variables are taken from conf/*.env, where * is the -# deploy environment, taken from DEPLOY_ENV. - -daemon off; -error_log /dev/stdout info; -worker_processes auto; -pid /var/run/nginx.pid; - -events { - worker_connections 1024; -} - - -http { - sendfile on; - tcp_nopush on; - tcp_nodelay on; - types_hash_max_size 2048; - proxy_headers_hash_bucket_size 256; - proxy_ssl_server_name on; - proxy_request_buffering off; - proxy_buffering off; - proxy_http_version 1.1; - - # In addition to the desired file size limit (in bytes), - # we ad smidgen more, as the multipart/form mime structure - # includes the destPath as one part, the file as another, - # and each has a small header section. - # - # In practice, this appears to be about 300 bytes plus - # the value for destPath and the file name. - # And the mime boundary size will vary as well. - # - # So let's call it 1K and then call it a day. - # So, the max body size should be MAX_FILE_SIZE + 1000. - - # For testing, use a 1K file size, 1K extra. - # Or set as you wish to push boundaries. - # client_max_body_size 2000; - - # For production, 5G max file size plus 1KB extra. - # client_max_body_size 5000001000; - - keepalive_requests 0; - # keepalive_timeout 65; - keepalive_timeout 0; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - map $http_upgrade $connection_upgrade { - default upgrade; - '' close; - } - - - # Define upstream servers, for convenience. - upstream kbase_ui { - # Use 80 for image; 3000 for devcontainer - # server {{ .Env.kbase_ui_host }}:80; - server {{ .Env.kbase_ui_host }}:3000; - # allows the proxy to start up even though the - # dev server may not be running yet - server {{ .Env.kbase_ui_host }}:80 backup; - keepalive 16; - } - - # upstream services { - # server {{ .Env.deploy_hostname }}; - # keepalive 16; - # } - - # upstream dynamic_services { - # server {{ .Env.deploy_hostname }}; - # keepalive 16; - # } - - upstream narrative { - {{ if .Env.local_narrative }} - server narrative:8888; - {{ else }} - {{ if .Env.deploy_ui_hostname }} - server {{ .Env.deploy_ui_hostname }}; - {{ else }} - server {{ .Env.deploy_hostname }}; - {{ end }} - {{ end }} - } - - upstream kbase_navigator { - {{ if .Env.local_navigator }} - server navigator:5000; - {{ else }} - {{ if .Env.deploy_ui_hostname }} - server {{ .Env.deploy_ui_hostname }}; - {{ else }} - server {{ .Env.deploy_hostname }}; - {{ end }} - {{ end }} - } - - log_format upstream_log '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request upstream_response_time $upstream_response_time proxy_host $proxy_host upstream_status $upstream_status upstream_response_length $upstream_response_length upstream_http_location $upstream_http_location msec $msec request_time $request_time'; - - - # Logging Settings - access_log /var/log/nginx/access.log; - error_log /var/log/nginx/error.log debug; - - # Route insecure requests to secure. - server { - listen 80 default_server; - listen [::]:80 default_server; - server_name {{ default .Env.deploy_hostname .Env.deploy_ui_hostname }}; - return 301 https://{{ default .Env.deploy_hostname .Env.deploy_ui_hostname }}$request_uri; - } - - - # If there is a separate ui hostname provided in the configuration, - # we need to listen for this separately. - # The only real usage of this is for production, in which kbase-ui and - # the narrative operate at narrative.kbase.us, but services at kbase.us. - {{ if .Env.deploy_ui_hostname }} - - # server { - # server_name {{ .Env.deploy_ui_hostname }}; - # listen 3000 ssl; - # ssl_certificate /kb/deployment/ssl/test.crt; - # ssl_certificate_key /kb/deployment/ssl/test.key; - # ssl_protocols TLSv1.2 TLSv1.1 TLSv1; - # location /ws/ { - # client_max_body_size 300M; - # proxy_connect_timeout 10s; - # proxy_pass http://kbase_ui/ws/; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "Upgrade"; - # proxy_set_header Host {{ .Env.deploy_ui_hostname }}; - # } - # } - - server { - listen 443 ssl; - server_name {{ .Env.deploy_ui_hostname }}; - ssl_certificate /kb/deployment/ssl/test.crt; - ssl_certificate_key /kb/deployment/ssl/test.key; - ssl_protocols TLSv1.2 TLSv1.1 TLSv1; - - location @request_entity_too_large { - default_type text/plain; - return 413 "Request entity is too large (> 5GB)"; - } - - location /__ping__ { - default_type "text/html"; - return 204; - } - - location /data/__perf__ { - gzip off; - gunzip on; - add_header Cache-Control 'no-cache, no-transform'; - proxy_pass http://kbase_ui; - } - - # Needed for running narratives - location /narrative/ { - access_log /var/log/nginx/narrative.log upstream_log; - - include /etc/nginx/cors.conf; - {{ if .Env.local_narrative }} - proxy_pass http://narrative/narrative/; - {{ else }} - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narrative/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narrative/; - {{ end }} - # proxy_pass https://narrative/narrative/; - {{ end }} - - proxy_connect_timeout 10s; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Origin https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Host {{ .Env.deploy_ui_hostname }}; - } - - location /ui-assets/ { - proxy_pass https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Connection ""; - } - - location /sn/ { - proxy_pass https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Connection ""; - } - - location /narratives/ { - # {{ if .Env.local_navigator }} - # proxy_pass http://navigator/narratives/; - # {{ else }} - # proxy_pass https://kbase_navigator/narratives/; - # {{ end }} - - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; - {{ end }} - - access_log /var/log/nginx/navigator.log upstream_log; - - proxy_set_header Connection ""; - proxy_read_timeout 10m; - proxy_set_header Origin https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Host {{ .Env.deploy_ui_hostname }}; - } - - location /navigator/ { - # {{ if .Env.local_navigator }} - # proxy_pass http://navigator/narratives/; - # {{ else }} - # proxy_pass https://kbase_navigator/narratives/; - # {{ end }} - - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; - {{ end }} - - access_log /var/log/nginx/navigator.log upstream_log; - - proxy_set_header Connection ""; - proxy_read_timeout 10m; - proxy_set_header Origin https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Host {{ .Env.deploy_ui_hostname }}; - } - - location {{ .Env.base_path }} { - proxy_pass http://kbase_ui; - #proxy_set_header Cache-Control 'no-store'; - #proxy_set_header Cache-Control 'no-cache'; - #expires 0; - # proxy_set_header Connection ""; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - } - } - - {{ end }} - - # server { - # server_name {{ .Env.deploy_hostname }}; - # listen 3000 ssl; - # ssl_certificate /kb/deployment/ssl/test.crt; - # ssl_certificate_key /kb/deployment/ssl/test.key; - # ssl_protocols TLSv1.2 TLSv1.1 TLSv1; - # proxy_http_version 1.1; - # location /ws/ { - # proxy_connect_timeout 10s; - # proxy_pass http://kbase_ui/ws/; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "Upgrade"; - # proxy_set_header Host {{ .Env.deploy_hostname }}; - # } - # } - - server { - server_name {{ .Env.deploy_hostname }}; - listen 443 ssl; - ssl_certificate /kb/deployment/ssl/test.crt; - ssl_certificate_key /kb/deployment/ssl/test.key; - ssl_protocols TLSv1.2 TLSv1.1 TLSv1; - - location @request_entity_too_large { - default_type application/json; - # return 413 "{\"message\": \"Request entity is too large\", \"responseCode\": 413, \"maxBodySize\": \"5GB\", \"contentLength\": ${content_length}}"; - return 413 "{\"message\": \"Request entity is too large\", \"responseCode\": 413, \"maxBodySize\": \"2KB\", \"contentLength\": ${content_length}}"; - } - - keepalive_requests 0; - keepalive_timeout 0; - proxy_socket_keepalive off; - - # Service proxying - # specified as a list of service modules - # note should put the service module name in /etc/hosts and map to localhost - {{ if .Env.service_proxies }} - {{ range splitList " " .Env.service_proxies }} - - {{ if eq . "searchapi2" }} - location /services/searchapi2/legacy { - {{ if $.Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; - {{ end }} - proxy_pass http://searchapi2:5000/legacy; - proxy_set_header Connection ""; - } - location /services/searchapi2/rpc { - {{ if $.Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; - {{ end }} - proxy_pass http://searchapi2:5000/rpc; - proxy_set_header Connection ""; - } - {{ else if eq . "staging_service" }} - location /services/{{ . }}/ { - - # For testing, use a 1K file size, 1K extra. - # Or set as you wish to push boundaries. - client_max_body_size 2000; - - # For production, 5G max file size plus 1KB extra. - # client_max_body_size 5000001000; - - error_page 413 @request_entity_too_large; - {{ if $.Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; - {{ end }} - proxy_pass http://{{ . }}:3000/; - proxy_set_header Connection ""; - proxy_read_timeout 10m; - } - {{ else }} - location /services/{{ . }}/ { - {{ if $.Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; - {{ end }} - proxy_pass http://{{ . }}:5000/; - proxy_set_header Connection ""; - proxy_read_timeout 10m; - } - location /services/{{ . }} { - {{ if $.Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; - {{ end }} - proxy_pass http://{{ . }}:5000; - proxy_set_header Connection ""; - proxy_read_timeout 10m; - } - {{ end }} - - {{ end }} - {{ end }} - - - # Proxy all service calls, including auth2, to the real CI - location /services { - access_log /var/log/nginx/services_proxy.log upstream_log; - - # The cookie path rewriting is just for auth2 - {{ if .Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; - {{ end }} - proxy_cookie_path /login /services/auth/login; - proxy_cookie_path /link /services/auth/link; - proxy_pass https://{{ .Env.deploy_hostname }}/services; - proxy_set_header Connection ""; - proxy_read_timeout 10m; - } - - # Dynamic Service proxying - # If dynamic services are provided in the configuration, we will proxy requests - # to them to local instances. - # This works by trapping calls to /dynserv/XXX.Module - # where /dynserv/ is always the path prefix for dynamic service call urls provided by - # the service wizard - # where XXX is a random-appearing string component provided by the service wizard - # and Module is the dynamic service module name. - - {{ if .Env.dynamic_service_proxies }} - {{ range splitList " " .Env.dynamic_service_proxies }} - - # note that the elements of the list must match the service path used in the ui call, - # and also the hostname assigned to the docker container. - # SO this means that probably service entries which are more complicated than simple strings - # without punctuation will work, but if they contain a / or something, maybe not. - - location ~ ^/dynserv/[^.]+[.]{{ . }}.*$ { - {{ if $.Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; - {{ end }} - - # This handles plain dynamic service calls, which don't have any path following the module name - rewrite ^/dynserv/[^.]+[.]{{ . }}$ / break; - - # This handles calls into the dynamic service with the path is propagated. - rewrite ^/dynserv/[^.]+[.]{{ . }}(.*)$ $1 break; - proxy_pass http://{{ . }}:5000; - proxy_read_timeout 10m; - } - - {{ end }} - {{ end }} - - # Un-trapped dynamic service calls are routed to the real dynamic service - # endpoints. - location /dynserv { - {{ if .Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; - {{ end }} - proxy_pass https://{{ .Env.deploy_hostname }}/dynserv; - proxy_set_header Connection ""; - proxy_read_timeout 10m; - } - - # Repeat the ui proxying for the case in which they reside on the same - # host name as services. - {{ if not .Env.deploy_ui_hostname }} - - location /__ping__ { - default_type "text/html"; - return 204; - } - - location /narrative/ { - {{ if .Env.local_narrative }} - proxy_pass http://narrative/narrative/; - {{ else }} - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narrative/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narrative/; - {{ end }} - # proxy_pass https://narrative/narrative/; - {{ end }} - - access_log /var/log/nginx/narrative.log upstream_log; - - proxy_connect_timeout 10s; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Origin https://{{ .Env.deploy_hostname }}; - proxy_set_header Host {{ .Env.deploy_hostname }}; - } - - location /ui-assets/ { - proxy_pass https://{{ .Env.deploy_hostname }}; - proxy_set_header Connection ""; - } - - location /sn/ { - proxy_pass https://{{ .Env.deploy_hostname }}; - proxy_set_header Connection ""; - } - - location /n/ { - proxy_pass https://{{ .Env.deploy_hostname }}; - proxy_set_header Connection ""; - } - - location /narratives/ { - # {{ if .Env.local_navigator }} - # proxy_pass http://navigator/narratives/; - # {{ else }} - # proxy_pass https://kbase_navigator/narratives/; - # {{ end }} - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; - {{ end }} - - access_log /var/log/nginx/navigator.log upstream_log; - - proxy_set_header Connection ""; - proxy_read_timeout 10m; - proxy_set_header Origin https://{{ .Env.deploy_hostname }}; - proxy_set_header Host {{ .Env.deploy_hostname }}; - } - - # location /vite_hms { - # proxy_pass http://{{ .Env.deploy_hostname }}:3001/vite_hms; - # proxy_http_version 1.1; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "Upgrade"; - # proxy_set_header Host {{ .Env.deploy_hostname }}; - # } - - location {{ .Env.base_path }} { - proxy_pass http://kbase_ui; - proxy_set_header Connection ""; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - } - - {{ end }} - } -} \ No newline at end of file diff --git a/tools/proxy/contents/conf/nginx.conf.tmpl b/tools/proxy/contents/conf/nginx.conf.tmpl index 41782c03..46029320 100644 --- a/tools/proxy/contents/conf/nginx.conf.tmpl +++ b/tools/proxy/contents/conf/nginx.conf.tmpl @@ -5,6 +5,27 @@ # Note that lower case environment variables are taken from conf/*.env, where * is the # deploy environment, taken from DEPLOY_ENV. +# Environment Variables: +# BASE_PATH = {{ .Env.BASE_PATH }} +# UI_DOMAIN = {{ .Env.UI_DOMAIN }} +# KBASE_UI_DOMAIN = {{ .Env.KBASE_UI_DOMAIN }} +# KBASE_UI_HOST = {{ .Env.KBASE_UI_HOST }} +# EUROPA_UI_HOST = {{ .Env.EUROPA_UI_HOST }} +# LOCAL_NARRATIVE = {{ .Env.LOCAL_NARRATIVE }} +# SERVICE_PROXIES = {{ .Env.SERVICE_PROXIES }} +# DYNAMIC_SERVICE_PROXIES = {{ .Env.DYNAMIC_SERVICE_PROXIES }} +# SERVICES_DOMAIN = {{ .Env.SERVICES_DOMAIN }} + + + +{{ $subhost := not (eq .Env.UI_DOMAIN .Env.KBASE_UI_DOMAIN) }} + +{{ if $subhost }} +# Configured for SUBHOST {{ .Env.KBASE_UI_DOMAIN }} +{{ else }} +# Configured for SAME HOST +{{ end }} + daemon off; error_log /dev/stdout info; worker_processes auto; @@ -14,7 +35,6 @@ events { worker_connections 1024; } - http { sendfile on; tcp_nopush on; @@ -57,54 +77,31 @@ http { '' close; } - - # Define upstream servers, for convenience. upstream kbase_ui { - # Use 80 for image; 3000 for devcontainer - # server {{ .Env.kbase_ui_host }}:80; - server {{ .Env.kbase_ui_host }}:3000; + server {{ .Env.KBASE_UI_HOST }}:3000; # allows the proxy to start up even though the - # dev server may not be running yet - server {{ .Env.kbase_ui_host }}:80 backup; + # target may not be running yet + server {{ .Env.KBASE_UI_HOST }}:80 backup; keepalive 16; } - # upstream services { - # server {{ .Env.deploy_hostname }}; - # keepalive 16; - # } - - # upstream dynamic_services { - # server {{ .Env.deploy_hostname }}; - # keepalive 16; - # } + upstream europa_ui { + server {{ .Env.EUROPA_UI_HOST }}:8080; + # allows the proxy to start up even though the + # target may not be running yet + server {{ .Env.EUROPA_UI_HOST }}:80 backup; + keepalive 16; + } upstream narrative { - {{ if .Env.local_narrative }} + {{ if eq .Env.LOCAL_NARRATIVE "t" }} server narrative:8888; {{ else }} - {{ if .Env.deploy_ui_hostname }} - server {{ .Env.deploy_ui_hostname }}; - {{ else }} - server {{ .Env.deploy_hostname }}; - {{ end }} - {{ end }} - } - - upstream kbase_navigator { - {{ if .Env.local_navigator }} - server navigator:5000; - {{ else }} - {{ if .Env.deploy_ui_hostname }} - server {{ .Env.deploy_ui_hostname }}; - {{ else }} - server {{ .Env.deploy_hostname }}; - {{ end }} + server {{ .Env.UI_DOMAIN }}; {{ end }} } - log_format upstream_log '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request upstream_response_time $upstream_response_time proxy_host $proxy_host upstream_status $upstream_status upstream_response_length $upstream_response_length upstream_http_location $upstream_http_location msec $msec request_time $request_time'; - + log_format upstream_log '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request upstream_response_time $upstream_response_time proxy_host $proxy_host upstream_status $upstream_status upstream_response_length $upstream_response_length upstream_http_location $upstream_http_location msec $msec request_time $request_time http_origin $http_origin'; # Logging Settings access_log /var/log/nginx/access.log; @@ -114,166 +111,12 @@ http { server { listen 80 default_server; listen [::]:80 default_server; - server_name {{ default .Env.deploy_hostname .Env.deploy_ui_hostname }}; - return 301 https://{{ default .Env.deploy_hostname .Env.deploy_ui_hostname }}$request_uri; + server_name {{ .Env.UI_DOMAIN }}; + return 301 https://{{ .Env.UI_DOMAIN }}$request_uri; } - - - # If there is a separate ui hostname provided in the configuration, - # we need to listen for this separately. - # The only real usage of this is for production, in which kbase-ui and - # the narrative operate at narrative.kbase.us, but services at kbase.us. - {{ if .Env.deploy_ui_hostname }} - - # server { - # server_name {{ .Env.deploy_ui_hostname }}; - # listen 3000 ssl; - # ssl_certificate /kb/deployment/ssl/test.crt; - # ssl_certificate_key /kb/deployment/ssl/test.key; - # ssl_protocols TLSv1.2 TLSv1.1 TLSv1; - # location /ws/ { - # client_max_body_size 300M; - # proxy_connect_timeout 10s; - # proxy_pass http://kbase_ui/ws/; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "Upgrade"; - # proxy_set_header Host {{ .Env.deploy_ui_hostname }}; - # } - # } - server { - listen 443 ssl; - server_name {{ .Env.deploy_ui_hostname }}; - ssl_certificate /kb/deployment/ssl/test.crt; - ssl_certificate_key /kb/deployment/ssl/test.key; - ssl_protocols TLSv1.2 TLSv1.1 TLSv1; - - location @request_entity_too_large { - default_type text/plain; - return 413 "Request entity is too large (> 5GB)"; - } - - location /__ping__ { - default_type "text/html"; - return 204; - } - - location /data/__perf__ { - gzip off; - gunzip on; - add_header Cache-Control 'no-cache, no-transform'; - proxy_pass http://kbase_ui; - } - - # Needed for running narratives - location /narrative/ { - access_log /var/log/nginx/narrative.log upstream_log; - - include /etc/nginx/cors.conf; - {{ if .Env.local_narrative }} - proxy_pass http://narrative/narrative/; - {{ else }} - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narrative/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narrative/; - {{ end }} - # proxy_pass https://narrative/narrative/; - {{ end }} - - proxy_connect_timeout 10s; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Origin https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Host {{ .Env.deploy_ui_hostname }}; - } - - location /ui-assets/ { - proxy_pass https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Connection ""; - } - - location /sn/ { - proxy_pass https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Connection ""; - } - - location /narratives/ { - # {{ if .Env.local_navigator }} - # proxy_pass http://navigator/narratives/; - # {{ else }} - # proxy_pass https://kbase_navigator/narratives/; - # {{ end }} - - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; - {{ end }} - - access_log /var/log/nginx/navigator.log upstream_log; - - proxy_set_header Connection ""; - proxy_read_timeout 10m; - proxy_set_header Origin https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Host {{ .Env.deploy_ui_hostname }}; - } - - location /navigator/ { - # {{ if .Env.local_navigator }} - # proxy_pass http://navigator/narratives/; - # {{ else }} - # proxy_pass https://kbase_navigator/narratives/; - # {{ end }} - - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; - {{ end }} - - access_log /var/log/nginx/navigator.log upstream_log; - - proxy_set_header Connection ""; - proxy_read_timeout 10m; - proxy_set_header Origin https://{{ .Env.deploy_ui_hostname }}; - proxy_set_header Host {{ .Env.deploy_ui_hostname }}; - } - - location {{ .Env.base_path }} { - proxy_pass http://kbase_ui; - #proxy_set_header Cache-Control 'no-store'; - #proxy_set_header Cache-Control 'no-cache'; - #expires 0; - # proxy_set_header Connection ""; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - } - } - - {{ end }} - - # server { - # server_name {{ .Env.deploy_hostname }}; - # listen 3000 ssl; - # ssl_certificate /kb/deployment/ssl/test.crt; - # ssl_certificate_key /kb/deployment/ssl/test.key; - # ssl_protocols TLSv1.2 TLSv1.1 TLSv1; - # proxy_http_version 1.1; - # location /ws/ { - # proxy_connect_timeout 10s; - # proxy_pass http://kbase_ui/ws/; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "Upgrade"; - # proxy_set_header Host {{ .Env.deploy_hostname }}; - # } - # } - - server { - server_name {{ .Env.deploy_hostname }}; + server { + server_name {{ .Env.UI_DOMAIN }}; listen 443 ssl; ssl_certificate /kb/deployment/ssl/test.crt; ssl_certificate_key /kb/deployment/ssl/test.key; @@ -289,22 +132,25 @@ http { keepalive_timeout 0; proxy_socket_keepalive off; + # Include service and dynamic service proxying here if the ui host + # is the same as the service host. + # Service proxying # specified as a list of service modules # note should put the service module name in /etc/hosts and map to localhost - {{ if .Env.service_proxies }} - {{ range splitList " " .Env.service_proxies }} + {{ if .Env.SERVICE_PROXIES }} + {{ range splitList " " .Env.SERVICE_PROXIES }} {{ if eq . "searchapi2" }} location /services/searchapi2/legacy { - {{ if $.Env.deploy_ui_hostname }} + {{ if $subhost }} include /etc/nginx/cors.conf; {{ end }} proxy_pass http://searchapi2:5000/legacy; proxy_set_header Connection ""; } location /services/searchapi2/rpc { - {{ if $.Env.deploy_ui_hostname }} + {{ if $subhost }} include /etc/nginx/cors.conf; {{ end }} proxy_pass http://searchapi2:5000/rpc; @@ -321,16 +167,16 @@ http { # client_max_body_size 5000001000; error_page 413 @request_entity_too_large; - {{ if $.Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; - {{ end }} + + # include /etc/nginx/cors.conf; + proxy_pass http://{{ . }}:3000/; proxy_set_header Connection ""; proxy_read_timeout 10m; } {{ else }} location /services/{{ . }}/ { - {{ if $.Env.deploy_ui_hostname }} + {{ if $subhost }} include /etc/nginx/cors.conf; {{ end }} proxy_pass http://{{ . }}:5000/; @@ -338,7 +184,7 @@ http { proxy_read_timeout 10m; } location /services/{{ . }} { - {{ if $.Env.deploy_ui_hostname }} + {{ if $subhost }} include /etc/nginx/cors.conf; {{ end }} proxy_pass http://{{ . }}:5000; @@ -350,18 +196,20 @@ http { {{ end }} {{ end }} - # Proxy all service calls, including auth2, to the real CI location /services { access_log /var/log/nginx/services_proxy.log upstream_log; - # The cookie path rewriting is just for auth2 - {{ if .Env.deploy_ui_hostname }} + # need cors because kbase-ui will be on a different host. + + {{ if $subhost }} include /etc/nginx/cors.conf; {{ end }} + + # The cookie path rewriting is just for auth2 proxy_cookie_path /login /services/auth/login; proxy_cookie_path /link /services/auth/link; - proxy_pass https://{{ .Env.deploy_hostname }}/services; + proxy_pass https://{{ .Env.SERVICES_DOMAIN }}/services; proxy_set_header Connection ""; proxy_read_timeout 10m; } @@ -375,8 +223,8 @@ http { # where XXX is a random-appearing string component provided by the service wizard # and Module is the dynamic service module name. - {{ if .Env.dynamic_service_proxies }} - {{ range splitList " " .Env.dynamic_service_proxies }} + {{ if .Env.DYNAMIC_SERVICE_PROXIES }} + {{ range splitList " " .Env.DYNAMIC_SERVICE_PROXIES }} # note that the elements of the list must match the service path used in the ui call, # and also the hostname assigned to the docker container. @@ -384,9 +232,10 @@ http { # without punctuation will work, but if they contain a / or something, maybe not. location ~ ^/dynserv/[^.]+[.]{{ . }}.*$ { - {{ if $.Env.deploy_ui_hostname }} + + {{ if $subhost }} include /etc/nginx/cors.conf; - {{ end }} + {{ end }} # This handles plain dynamic service calls, which don't have any path following the module name rewrite ^/dynserv/[^.]+[.]{{ . }}$ / break; @@ -403,33 +252,25 @@ http { # Un-trapped dynamic service calls are routed to the real dynamic service # endpoints. location /dynserv { - {{ if .Env.deploy_ui_hostname }} - include /etc/nginx/cors.conf; + # need cors because kbase-ui will be on a different host. + + {{ if $subhost }} + include /etc/nginx/cors.conf; {{ end }} - proxy_pass https://{{ .Env.deploy_hostname }}/dynserv; + proxy_pass https://{{ .Env.SERVICES_DOMAIN }}/dynserv; proxy_set_header Connection ""; proxy_read_timeout 10m; } - # Repeat the ui proxying for the case in which they reside on the same - # host name as services. - {{ if not .Env.deploy_ui_hostname }} - - location /__ping__ { - default_type "text/html"; - return 204; - } - location /narrative/ { - {{ if .Env.local_narrative }} + {{ if eq .Env.LOCAL_NARRATIVE "t" }} proxy_pass http://narrative/narrative/; {{ else }} - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narrative/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narrative/; - {{ end }} - # proxy_pass https://narrative/narrative/; + proxy_pass https://{{ .Env.UI_DOMAIN }}/narrative/; + {{ end }} + + {{ if $subhost }} + include /etc/nginx/cors.conf; {{ end }} access_log /var/log/nginx/narrative.log upstream_log; @@ -437,61 +278,78 @@ http { proxy_connect_timeout 10s; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; - proxy_set_header Origin https://{{ .Env.deploy_hostname }}; - proxy_set_header Host {{ .Env.deploy_hostname }}; + proxy_set_header Origin https://{{ .Env.UI_DOMAIN }}; + proxy_set_header Host {{ .Env.UI_DOMAIN }}; } location /ui-assets/ { - proxy_pass https://{{ .Env.deploy_hostname }}; + proxy_pass https://{{ .Env.UI_DOMAIN }}; proxy_set_header Connection ""; } location /sn/ { - proxy_pass https://{{ .Env.deploy_hostname }}; + proxy_pass https://{{ .Env.UI_DOMAIN }}; proxy_set_header Connection ""; } location /n/ { - proxy_pass https://{{ .Env.deploy_hostname }}; + proxy_pass https://{{ .Env.UI_DOMAIN }}; proxy_set_header Connection ""; } - location /narratives/ { - # {{ if .Env.local_navigator }} - # proxy_pass http://navigator/narratives/; - # {{ else }} - # proxy_pass https://kbase_navigator/narratives/; - # {{ end }} - {{ if .Env.deploy_ui_hostname }} - proxy_pass https://{{ .Env.deploy_ui_hostname }}/narratives/; - {{ else }} - proxy_pass https://{{ .Env.deploy_hostname }}/narratives/; - {{ end }} + # kbase-ui will be located on a path + # disable this if the subdomain is used instead. + # in this case, BASE_PATH had better not be empty or /. + {{ if eq .Env.UI_DOMAIN .Env.KBASE_UI_DOMAIN }} - access_log /var/log/nginx/navigator.log upstream_log; + {{ if .Env.BASE_PATH }} + location /{{ .Env.BASE_PATH }}/ { + proxy_pass http://kbase_ui; + proxy_set_header Connection ""; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } + {{ else }} + location / { + proxy_pass http://kbase_ui; + proxy_set_header Connection ""; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } + {{ end }} + {{ end }} + + # Europa is always at the root. + location / { + proxy_pass http://europa_ui; proxy_set_header Connection ""; - proxy_read_timeout 10m; - proxy_set_header Origin https://{{ .Env.deploy_hostname }}; - proxy_set_header Host {{ .Env.deploy_hostname }}; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; } + } - # location /vite_hms { - # proxy_pass http://{{ .Env.deploy_hostname }}:3001/vite_hms; - # proxy_http_version 1.1; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "Upgrade"; - # proxy_set_header Host {{ .Env.deploy_hostname }}; - # } + # This is invoked to run kbase-ui on a subdomain if specified + # This is de-facto always the case in the current Europa implementation. + {{ if $subhost }} + server { + server_name {{ .Env.KBASE_UI_DOMAIN }}; + listen 443 ssl; + ssl_certificate /kb/deployment/ssl/test.crt; + ssl_certificate_key /kb/deployment/ssl/test.key; + ssl_protocols TLSv1.2 TLSv1.1 TLSv1; - location {{ .Env.base_path }} { + location {{ .Env.BASE_PATH }}/ { + include /etc/nginx/cors.conf; proxy_pass http://kbase_ui; proxy_set_header Connection ""; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } - - {{ end }} } -} \ No newline at end of file + {{ end }} +} diff --git a/tools/proxy/docker-compose.yml b/tools/proxy/docker-compose.yml index b302c517..b693465a 100644 --- a/tools/proxy/docker-compose.yml +++ b/tools/proxy/docker-compose.yml @@ -1,4 +1,5 @@ version: '3.6' +name: kbase-dev networks: kbase-dev: name: kbase-dev @@ -10,6 +11,8 @@ services: image: kbase/kbase-ui-proxy:dev networks: - kbase-dev + # volumes: + container_name: kbase-ui-proxy ports: - '80:80' diff --git a/vite-app/index.html b/vite-app/index.html index b8abf8c5..593ab0a3 100644 --- a/vite-app/index.html +++ b/vite-app/index.html @@ -8,25 +8,21 @@ - - - - KBase
    -
    -
    Loading KBase UI ...
    +
    KBase animated logo
    -
    +
    -->
    diff --git a/vite-app/package-lock.json b/vite-app/package-lock.json index 182ba30d..7312942b 100644 --- a/vite-app/package-lock.json +++ b/vite-app/package-lock.json @@ -1,53 +1,65 @@ { - "name": "vite-app", + "name": "kbase-ui", "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "vite-app", + "name": "kbase-ui", "version": "0.0.0", "dependencies": { - "@ant-design/icons": "5.2.6", - "antd": "5.10.2", - "bootstrap": "5.3.2", - "dompurify": "3.0.6", + "@ant-design/icons": "5.3.4", + "@fortawesome/fontawesome-svg-core": "6.5.1", + "@fortawesome/free-regular-svg-icons": "6.5.1", + "@fortawesome/free-solid-svg-icons": "6.5.1", + "@fortawesome/react-fontawesome": "0.2.0", + "antd": "5.15.3", + "bootstrap": "5.3.3", + "dompurify": "3.0.11", "es-cookie": "1.4.0", "font-awesome": "4.7.0", - "marked": "9.1.2", + "formik": "2.4.5", + "highlight.js": "11.9.0", + "marked": "12.0.1", "react": "18.2.0", - "react-bootstrap": "2.9.1", - "react-bootstrap-icons": "1.10.3", + "react-bootstrap": "2.10.2", + "react-bootstrap-icons": "1.11.3", "react-dom": "18.2.0", - "react-router-dom": "6.17.0", - "react-select": "5.7.7", - "uuid": "9.0.1" + "react-router-dom": "6.22.3", + "react-select": "5.8.0", + "ts-md5": "1.3.1", + "uuid": "9.0.1", + "yup": "1.4.0" }, "devDependencies": { "@kbase/ui-lib": "0.7.1", - "@testing-library/jest-dom": "6.1.4", - "@testing-library/react": "14.0.0", - "@testing-library/user-event": "14.5.1", - "@types/dompurify": "3.0.4", - "@types/jest": "29.5.6", - "@types/react": "18.2.32", - "@types/react-dom": "18.2.14", + "@testing-library/jest-dom": "6.4.2", + "@testing-library/react": "14.2.2", + "@testing-library/user-event": "14.5.2", + "@types/dompurify": "3.0.5", + "@types/jest": "29.5.12", + "@types/react": "18.2.69", + "@types/react-dom": "18.2.22", "@types/react-router-dom": "5.3.3", - "@types/uuid": "9.0.6", - "@typescript-eslint/eslint-plugin": "6.9.0", - "@typescript-eslint/parser": "6.9.0", - "@vitejs/plugin-react": "4.1.0", - "@vitest/coverage-v8": "0.34.6", - "eslint": "8.52.0", + "@types/uuid": "9.0.8", + "@typescript-eslint/eslint-plugin": "7.3.1", + "@typescript-eslint/parser": "7.3.1", + "@vitejs/plugin-react": "4.2.1", + "@vitest/coverage-v8": "1.4.0", + "eslint": "8.57.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-import": "2.29.1", + "eslint-plugin-jsx-a11y": "6.8.0", + "eslint-plugin-react": "7.34.1", "eslint-plugin-react-hooks": "4.6.0", - "eslint-plugin-react-refresh": "0.4.3", - "jsdom": "22.1.0", - "prettier": "3.0.3", + "eslint-plugin-react-refresh": "0.4.6", + "jsdom": "24.0.0", + "prettier": "3.2.5", "sass": "1.64.", - "typescript": "5.2.2", - "vite": "4.5.0", - "vite-tsconfig-paths": "4.2.1", - "vitest": "0.34.6" + "typescript": "5.4.3", + "vite": "5.2.3", + "vite-tsconfig-paths": "4.3.2", + "vitest": "1.4.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -60,9 +72,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz", - "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.2.tgz", + "integrity": "sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==", "dev": true }, "node_modules/@ampproject/remapping": { @@ -79,23 +91,23 @@ } }, "node_modules/@ant-design/colors": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.0.0.tgz", - "integrity": "sha512-iVm/9PfGCbC0dSMBrz7oiEXZaaGH7ceU40OJEfKmyuzR9R5CRimJYPlRiFtMQGQcbNMea/ePcoIebi4ASGYXtg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.0.2.tgz", + "integrity": "sha512-7KJkhTiPiLHSu+LmMJnehfJ6242OCxSlR3xHVBecYxnMW8MS/878NXct1GqYARyL59fyeFdKRxXTfvR9SnDgJg==", "dependencies": { - "@ctrl/tinycolor": "^3.4.0" + "@ctrl/tinycolor": "^3.6.1" } }, "node_modules/@ant-design/cssinjs": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.17.2.tgz", - "integrity": "sha512-vu7lnfEx4Mf8MPzZxn506Zen3Nt4fRr2uutwvdCuTCN5IiU0lDdQ0tiJ24/rmB8+pefwjluYsbyzbQSbgfJy+A==", + "version": "1.18.4", + "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.18.4.tgz", + "integrity": "sha512-IrUAOj5TYuMG556C9gdbFuOrigyhzhU5ZYpWb3gYTxAwymVqRbvLzFCZg6OsjLBR6GhzcxYF3AhxKmjB+rA2xA==", "dependencies": { "@babel/runtime": "^7.11.1", "@emotion/hash": "^0.8.0", "@emotion/unitless": "^0.7.5", "classnames": "^2.3.1", - "csstype": "^3.0.10", + "csstype": "^3.1.3", "rc-util": "^5.35.0", "stylis": "^4.0.13" }, @@ -115,12 +127,12 @@ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, "node_modules/@ant-design/icons": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.2.6.tgz", - "integrity": "sha512-4wn0WShF43TrggskBJPRqCD0fcHbzTYjnaoskdiJrVHg86yxoZ8ZUqsXvyn4WUqehRiFKnaclOhqk9w4Ui2KVw==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.3.4.tgz", + "integrity": "sha512-U5eTSeSFr2V9SeJzYOo5mybAZfsoNuiIA8bvFoZUe+h9LBLs8UwrVaVwcMQC4AhBuojXkLMlmtnIlvUczXXHaQ==", "dependencies": { "@ant-design/colors": "^7.0.0", - "@ant-design/icons-svg": "^4.3.0", + "@ant-design/icons-svg": "^4.4.0", "@babel/runtime": "^7.11.2", "classnames": "^2.2.6", "rc-util": "^5.31.1" @@ -134,9 +146,9 @@ } }, "node_modules/@ant-design/icons-svg": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.3.0.tgz", - "integrity": "sha512-WOgvdH/1Wl8Z7VXigRbCa5djO14zxrNTzvrAQzhWiBQtEKT0uTc8K1ltjKZ8U1gPn/wXhMA8/jE39SJl0WNxSg==" + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.0.tgz", + "integrity": "sha512-71rcNssTaRL1ytvPLebKuc/8Bjqxs5V1YkTbqlSCvNa0Se+HmYJwWHhRTpsSHBh+sWFtc7xpGCTRW2Ta04XyHw==" }, "node_modules/@ant-design/react-slick": { "version": "1.0.2", @@ -154,11 +166,11 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -230,30 +242,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz", - "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz", - "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.0", - "@babel/helpers": "^7.23.0", - "@babel/parser": "^7.23.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.0", - "@babel/types": "^7.23.0", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -284,12 +296,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.23.0", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -299,14 +311,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -384,9 +396,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", - "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", @@ -436,9 +448,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "engines": { "node": ">=6.9.0" } @@ -452,32 +464,32 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", - "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz", - "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.0", - "@babel/types": "^7.23.0" + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -552,9 +564,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -564,9 +576,9 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz", - "integrity": "sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz", + "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -579,9 +591,9 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz", - "integrity": "sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz", + "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -594,9 +606,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -619,20 +631,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -649,11 +661,11 @@ } }, "node_modules/@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, @@ -778,10 +790,26 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.11.tgz", - "integrity": "sha512-q4qlUf5ucwbUJZXF5tEQ8LF7y0Nk4P58hOsGk3ucY0oCwgQqAnqXVbUuahCddVHfrxmpyewRpiTHwVHIETYu7Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "cpu": [ "arm" ], @@ -795,9 +823,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.11.tgz", - "integrity": "sha512-snieiq75Z1z5LJX9cduSAjUr7vEI1OdlzFPMw0HH5YI7qQHDd3qs+WZoMrWYDsfRJSq36lIA6mfZBkvL46KoIw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "cpu": [ "arm64" ], @@ -811,9 +839,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.11.tgz", - "integrity": "sha512-iPuoxQEV34+hTF6FT7om+Qwziv1U519lEOvekXO9zaMMlT9+XneAhKL32DW3H7okrCOBQ44BMihE8dclbZtTuw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "cpu": [ "x64" ], @@ -827,9 +855,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.11.tgz", - "integrity": "sha512-Gm0QkI3k402OpfMKyQEEMG0RuW2LQsSmI6OeO4El2ojJMoF5NLYb3qMIjvbG/lbMeLOGiW6ooU8xqc+S0fgz2w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "cpu": [ "arm64" ], @@ -843,9 +871,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.11.tgz", - "integrity": "sha512-N15Vzy0YNHu6cfyDOjiyfJlRJCB/ngKOAvoBf1qybG3eOq0SL2Lutzz9N7DYUbb7Q23XtHPn6lMDF6uWbGv9Fw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "cpu": [ "x64" ], @@ -859,9 +887,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.11.tgz", - "integrity": "sha512-atEyuq6a3omEY5qAh5jIORWk8MzFnCpSTUruBgeyN9jZq1K/QI9uke0ATi3MHu4L8c59CnIi4+1jDKMuqmR71A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "cpu": [ "arm64" ], @@ -875,9 +903,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.11.tgz", - "integrity": "sha512-XtuPrEfBj/YYYnAAB7KcorzzpGTvOr/dTtXPGesRfmflqhA4LMF0Gh/n5+a9JBzPuJ+CGk17CA++Hmr1F/gI0Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "cpu": [ "x64" ], @@ -891,9 +919,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.11.tgz", - "integrity": "sha512-Idipz+Taso/toi2ETugShXjQ3S59b6m62KmLHkJlSq/cBejixmIydqrtM2XTvNCywFl3VC7SreSf6NV0i6sRyg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "cpu": [ "arm" ], @@ -907,9 +935,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.11.tgz", - "integrity": "sha512-c6Vh2WS9VFKxKZ2TvJdA7gdy0n6eSy+yunBvv4aqNCEhSWVor1TU43wNRp2YLO9Vng2G+W94aRz+ILDSwAiYog==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "cpu": [ "arm64" ], @@ -923,9 +951,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.11.tgz", - "integrity": "sha512-S3hkIF6KUqRh9n1Q0dSyYcWmcVa9Cg+mSoZEfFuzoYXXsk6196qndrM+ZiHNwpZKi3XOXpShZZ+9dfN5ykqjjw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "cpu": [ "ia32" ], @@ -939,9 +967,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.11.tgz", - "integrity": "sha512-MRESANOoObQINBA+RMZW+Z0TJWpibtE7cPFnahzyQHDCA9X9LOmGh68MVimZlM9J8n5Ia8lU773te6O3ILW8kw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "cpu": [ "loong64" ], @@ -955,9 +983,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.11.tgz", - "integrity": "sha512-qVyPIZrXNMOLYegtD1u8EBccCrBVshxMrn5MkuFc3mEVsw7CCQHaqZ4jm9hbn4gWY95XFnb7i4SsT3eflxZsUg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "cpu": [ "mips64el" ], @@ -971,9 +999,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.11.tgz", - "integrity": "sha512-T3yd8vJXfPirZaUOoA9D2ZjxZX4Gr3QuC3GztBJA6PklLotc/7sXTOuuRkhE9W/5JvJP/K9b99ayPNAD+R+4qQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "cpu": [ "ppc64" ], @@ -987,9 +1015,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.11.tgz", - "integrity": "sha512-evUoRPWiwuFk++snjH9e2cAjF5VVSTj+Dnf+rkO/Q20tRqv+644279TZlPK8nUGunjPAtQRCj1jQkDAvL6rm2w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "cpu": [ "riscv64" ], @@ -1003,9 +1031,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.11.tgz", - "integrity": "sha512-/SlRJ15XR6i93gRWquRxYCfhTeC5PdqEapKoLbX63PLCmAkXZHY2uQm2l9bN0oPHBsOw2IswRZctMYS0MijFcg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "cpu": [ "s390x" ], @@ -1019,9 +1047,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.11.tgz", - "integrity": "sha512-xcncej+wF16WEmIwPtCHi0qmx1FweBqgsRtEL1mSHLFR6/mb3GEZfLQnx+pUDfRDEM4DQF8dpXIW7eDOZl1IbA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "cpu": [ "x64" ], @@ -1035,9 +1063,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.11.tgz", - "integrity": "sha512-aSjMHj/F7BuS1CptSXNg6S3M4F3bLp5wfFPIJM+Km2NfIVfFKhdmfHF9frhiCLIGVzDziggqWll0B+9AUbud/Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "cpu": [ "x64" ], @@ -1051,9 +1079,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.11.tgz", - "integrity": "sha512-tNBq+6XIBZtht0xJGv7IBB5XaSyvYPCm1PxJ33zLQONdZoLVM0bgGqUrXnJyiEguD9LU4AHiu+GCXy/Hm9LsdQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "cpu": [ "x64" ], @@ -1067,9 +1095,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.11.tgz", - "integrity": "sha512-kxfbDOrH4dHuAAOhr7D7EqaYf+W45LsAOOhAet99EyuxxQmjbk8M9N4ezHcEiCYPaiW8Dj3K26Z2V17Gt6p3ng==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "cpu": [ "x64" ], @@ -1083,9 +1111,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.11.tgz", - "integrity": "sha512-Sh0dDRyk1Xi348idbal7lZyfSkjhJsdFeuC13zqdipsvMetlGiFQNdO+Yfp6f6B4FbyQm7qsk16yaZk25LChzg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "cpu": [ "arm64" ], @@ -1099,9 +1127,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.11.tgz", - "integrity": "sha512-o9JUIKF1j0rqJTFbIoF4bXj6rvrTZYOrfRcGyL0Vm5uJ/j5CkBD/51tpdxe9lXEDouhRgdr/BYzUrDOvrWwJpg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "cpu": [ "ia32" ], @@ -1115,9 +1143,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.11.tgz", - "integrity": "sha512-rQI4cjLHd2hGsM1LqgDI7oOCYbQ6IBOVsX9ejuRMSze0GqXUG2ekwiKkiBU1pRGSeCqFFHxTrcEydB2Hyoz9CA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "cpu": [ "x64" ], @@ -1155,9 +1183,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -1178,9 +1206,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", - "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1199,14 +1227,71 @@ "@floating-ui/core": "^1.3.1" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz", + "integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz", + "integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-regular-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz", + "integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz", + "integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -1227,9 +1312,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "node_modules/@istanbuljs/schema": { @@ -1321,21 +1406,15 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, "node_modules/@kbase/ui-lib": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@kbase/ui-lib/-/ui-lib-0.7.1.tgz", @@ -1395,14 +1474,14 @@ } }, "node_modules/@rc-component/color-picker": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.4.1.tgz", - "integrity": "sha512-vh5EWqnsayZa/JwUznqDaPJz39jznx/YDbyBuVJntv735tKXKwEUZZb2jYEldOg+NKWZwtALjGMrNeGBmqFoEw==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.3.tgz", + "integrity": "sha512-+tGGH3nLmYXTalVe0L8hSZNs73VTP5ueSHwUlDC77KKRaN7G4DS4wcpG5DTDzdcV/Yas+rzA6UGgIyzd8fS4cw==", "dependencies": { - "@babel/runtime": "^7.10.1", - "@ctrl/tinycolor": "^3.6.0", + "@babel/runtime": "^7.23.6", + "@ctrl/tinycolor": "^3.6.1", "classnames": "^2.2.6", - "rc-util": "^5.30.0" + "rc-util": "^5.38.1" }, "peerDependencies": { "react": ">=16.9.0", @@ -1468,13 +1547,13 @@ } }, "node_modules/@rc-component/tour": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.10.0.tgz", - "integrity": "sha512-voV0BKaTJbewB9LLgAHQ7tAGG7rgDkKQkZo82xw2gIk542hY+o7zwoqdN16oHhIKk7eG/xi+mdXrONT62Dt57A==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.14.2.tgz", + "integrity": "sha512-A75DZ8LVvahBIvxooj3Gvf2sxe+CGOkmzPNX7ek0i0AJHyKZ1HXe5ieIGo3m0FMdZfVOlbCJ952Duq8VKAHk6g==", "dependencies": { "@babel/runtime": "^7.18.0", "@rc-component/portal": "^1.0.0-9", - "@rc-component/trigger": "^1.3.6", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.3.2", "rc-util": "^5.24.4" }, @@ -1487,9 +1566,9 @@ } }, "node_modules/@rc-component/trigger": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-1.17.2.tgz", - "integrity": "sha512-Jp3dXk/IzwHKM2Tn3ezdvQSwkPeH4v1s7QjIo7f5NFLIZVpJQ8a34FduZw8E6fT1PVgLXYd/JBIyd+YpgyQddA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.0.0.tgz", + "integrity": "sha512-niwKADPdY5dhdIblV6uwSayVivwo2uUISfJqri+/ovYQcH/omxDYBJKo755QKeoIIsWptxnRpgr7reEnNEZGFg==", "dependencies": { "@babel/runtime": "^7.23.2", "@rc-component/portal": "^1.1.0", @@ -1507,52 +1586,42 @@ } }, "node_modules/@react-aria/ssr": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.6.0.tgz", - "integrity": "sha512-OFiYQdv+Yk7AO7IsQu/fAEPijbeTwrrEYvdNoJ3sblBBedD5j5fBTNWrUPNVlwC4XWWnWTCMaRIVsJujsFiWXg==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.2.tgz", + "integrity": "sha512-0gKkgDYdnq1w+ey8KzG9l+H5Z821qh9vVjztk55rUg71vTk/Eaebeir+WtzcLLwTjw3m/asIjx8Y59y1lJZhBw==", "dependencies": { - "@swc/helpers": "^0.4.14" + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, - "node_modules/@react-aria/ssr/node_modules/@swc/helpers": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", - "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@react-aria/ssr/node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" - }, "node_modules/@remix-run/router": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.10.0.tgz", - "integrity": "sha512-Lm+fYpMfZoEucJ7cMxgt4dYt8jLfbpwRCzAjm9UgSLOkmlqo9gupxt6YX3DY0Fk155NT9l17d/ydi+964uS9Lw==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", + "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==", "engines": { "node": ">=14.0.0" } }, "node_modules/@restart/hooks": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.9.tgz", - "integrity": "sha512-3BekqcwB6Umeya+16XPooARn4qEPW6vNvwYnlofIYe6h9qG1/VeD7UvShCWx11eFz5ELYmwIEshz+MkPX3wjcQ==", + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", + "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", "dependencies": { - "dequal": "^2.0.2" + "dequal": "^2.0.3" }, "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@restart/ui": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", - "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.8.tgz", + "integrity": "sha512-6ndCv3oZ7r9vuP1Ok9KH55TM1/UkdBnP/fSraW0DFDMbPMzWKhVKeFAIEUCRCSdzayjZDcFYK6xbMlipN9dmMA==", "dependencies": { "@babel/runtime": "^7.21.0", "@popperjs/core": "^2.11.6", @@ -1570,19 +1639,196 @@ } }, "node_modules/@restart/ui/node_modules/uncontrollable": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.2.tgz", - "integrity": "sha512-/GDx+K1STGtpgTsj5Dj3J51YaKxZDblbCQHTH1zHLuoBEWodj6MjtRVv3TUijj1JYLRLSFsFzN8NV4M3QV4d9w==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", "peerDependencies": { "react": ">=16.14.0" } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", + "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", + "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", + "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", + "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", + "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", + "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", + "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", + "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", + "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", + "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", + "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", + "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, + "node_modules/@swc/helpers": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.7.tgz", + "integrity": "sha512-BVvNZhx362+l2tSwSuyEUV4h7+jk9raNdoTSdLfwTshXJSaGmYKluGRJznziCI3KX02Z19DdsQrdfrpXAU3Hfg==", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@testing-library/dom": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", @@ -1603,17 +1849,17 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.4.tgz", - "integrity": "sha512-wpoYrCYwSZ5/AxcrjLxJmCU6I5QAJXslEeSiMQqaWmP2Kzpd1LvF/qxmAIW2qposULGWq2gw30GgVNFLSc2Jnw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz", + "integrity": "sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==", "dev": true, "dependencies": { - "@adobe/css-tools": "^4.3.1", + "@adobe/css-tools": "^4.3.2", "@babel/runtime": "^7.9.2", "aria-query": "^5.0.0", "chalk": "^3.0.0", "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", + "dom-accessibility-api": "^0.6.3", "lodash": "^4.17.15", "redent": "^3.0.0" }, @@ -1624,6 +1870,7 @@ }, "peerDependencies": { "@jest/globals": ">= 28", + "@types/bun": "latest", "@types/jest": ">= 28", "jest": ">= 28", "vitest": ">= 0.32" @@ -1632,6 +1879,9 @@ "@jest/globals": { "optional": true }, + "@types/bun": { + "optional": true + }, "@types/jest": { "optional": true }, @@ -1656,10 +1906,16 @@ "node": ">=8" } }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, "node_modules/@testing-library/react": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.0.0.tgz", - "integrity": "sha512-S04gSNJbYE30TlIMLTzv6QCTzt9AqIF5y6s6SzVFILNcNvbV/jU96GeiTPillGQo+Ny64M/5PV7klNYYgv5Dfg==", + "version": "14.2.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.2.2.tgz", + "integrity": "sha512-SOUuM2ysCvjUWBXTNfQ/ztmnKDmqaiPV3SvoIuyxMUca45rbSWWAT/qB8CUs/JQ/ux/8JFs9DNdFQ3f6jH3crA==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", @@ -1675,9 +1931,9 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.5.1", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.1.tgz", - "integrity": "sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==", + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", "dev": true, "engines": { "node": ">=12", @@ -1687,15 +1943,6 @@ "@testing-library/dom": ">=7.21.4" } }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, "node_modules/@types/aria-query": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", @@ -1703,9 +1950,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz", - "integrity": "sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "dependencies": { "@babel/parser": "^7.20.7", @@ -1716,18 +1963,18 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.5", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.5.tgz", - "integrity": "sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==", + "version": "7.6.7", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", + "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.2.tgz", - "integrity": "sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -1735,9 +1982,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.2.tgz", - "integrity": "sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==", + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" @@ -1749,36 +1996,36 @@ "integrity": "sha512-yR/Kxc0dd4FfwtEoLZMoqJbM/VE/W7hXn/MIjb+axcwag0iFmSPK7OBUZq1YWLynJUoWQkfUrI7T0HDqGApNSg==", "dev": true }, - "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", - "dev": true - }, - "node_modules/@types/chai-subset": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", - "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", - "dev": true, - "dependencies": { - "@types/chai": "*" - } - }, "node_modules/@types/dompurify": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.4.tgz", - "integrity": "sha512-1Jk8S/IRzNSbwQRbuGuLFHviwxQ8pX81ZEW3INY9432Cwb4VedkBYan8gSIXVLOLHBtimOmUTEYphjRVmo+30g==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", + "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", "dev": true, "dependencies": { "@types/trusted-types": "*" } }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/history": { "version": "4.7.11", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", "dev": true }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -1804,9 +2051,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.6", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.6.tgz", - "integrity": "sha512-/t9NnzkOpXb4Nfvg17ieHE6EeSjDS2SGSpNYfoLbUAeL/EOueU/RSdOWFpfQTXBEM7BguYW1XQ0EbM+6RlIh6w==", + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -1852,9 +2099,15 @@ "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", - "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "node_modules/@types/node": { @@ -1874,9 +2127,9 @@ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/react": { - "version": "18.2.32", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.32.tgz", - "integrity": "sha512-F0FVIZQ1x5Gxy/VYJb7XcWvCcHR28Sjwt1dXLspdIatfPq1MVACfnBDwKe6ANLxQ64riIJooXClpUR6oxTiepg==", + "version": "18.2.69", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.69.tgz", + "integrity": "sha512-W1HOMUWY/1Yyw0ba5TkCV+oqynRjG7BnteBB+B7JmAK7iw3l2SW+VGOxL+akPweix6jk2NNJtyJKpn4TkpfK3Q==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1884,9 +2137,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.2.14", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.14.tgz", - "integrity": "sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==", + "version": "18.2.22", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.22.tgz", + "integrity": "sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==", "dev": true, "dependencies": { "@types/react": "*" @@ -1927,9 +2180,9 @@ "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" }, "node_modules/@types/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/stack-utils": { @@ -1945,15 +2198,15 @@ "dev": true }, "node_modules/@types/uuid": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz", - "integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==", + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", "dev": true }, "node_modules/@types/warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" }, "node_modules/@types/yargs": { "version": "17.0.24", @@ -1971,16 +2224,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz", - "integrity": "sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.3.1.tgz", + "integrity": "sha512-STEDMVQGww5lhCuNXVSQfbfuNII5E08QWkvAw5Qwf+bj2WT+JkG1uc+5/vXA3AOYMDHVOSpL+9rcbEUiHIm2dw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/type-utils": "6.9.0", - "@typescript-eslint/utils": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/scope-manager": "7.3.1", + "@typescript-eslint/type-utils": "7.3.1", + "@typescript-eslint/utils": "7.3.1", + "@typescript-eslint/visitor-keys": "7.3.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1989,15 +2242,15 @@ "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2006,26 +2259,26 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz", - "integrity": "sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.3.1.tgz", + "integrity": "sha512-Rq49+pq7viTRCH48XAbTA+wdLRrB/3sRq4Lpk0oGDm0VmnjBrAOVXH/Laalmwsv2VpekiEfVFwJYVk6/e8uvQw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/scope-manager": "7.3.1", + "@typescript-eslint/types": "7.3.1", + "@typescript-eslint/typescript-estree": "7.3.1", + "@typescript-eslint/visitor-keys": "7.3.1", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2034,16 +2287,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz", - "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.3.1.tgz", + "integrity": "sha512-fVS6fPxldsKY2nFvyT7IP78UO1/I2huG+AYu5AMjCT9wtl6JFiDnsv4uad4jQ0GTFzcUV5HShVeN96/17bTBag==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0" + "@typescript-eslint/types": "7.3.1", + "@typescript-eslint/visitor-keys": "7.3.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2051,25 +2304,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz", - "integrity": "sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.3.1.tgz", + "integrity": "sha512-iFhaysxFsMDQlzJn+vr3OrxN8NmdQkHks4WaqD4QBnt5hsq234wcYdyQ9uquzJJIDAj5W4wQne3yEsYA6OmXGw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.9.0", - "@typescript-eslint/utils": "6.9.0", + "@typescript-eslint/typescript-estree": "7.3.1", + "@typescript-eslint/utils": "7.3.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2078,12 +2331,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz", - "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.3.1.tgz", + "integrity": "sha512-2tUf3uWggBDl4S4183nivWQ2HqceOZh1U4hhu4p1tPiIJoRRXrab7Y+Y0p+dozYwZVvLPRI6r5wKe9kToF9FIw==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2091,21 +2344,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz", - "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.3.1.tgz", + "integrity": "sha512-tLpuqM46LVkduWP7JO7yVoWshpJuJzxDOPYIVWUUZbW+4dBpgGeUdl/fQkhuV0A8eGnphYw3pp8d2EnvPOfxmQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/visitor-keys": "6.9.0", + "@typescript-eslint/types": "7.3.1", + "@typescript-eslint/visitor-keys": "7.3.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2117,42 +2371,66 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz", - "integrity": "sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.3.1.tgz", + "integrity": "sha512-jIERm/6bYQ9HkynYlNZvXpzmXWZGhMbrOvq3jJzOSOlKXsVjrrolzWBjDW6/TvT5Q3WqaN4EkmcfdQwi9tDjBQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.0", - "@typescript-eslint/types": "6.9.0", - "@typescript-eslint/typescript-estree": "6.9.0", + "@typescript-eslint/scope-manager": "7.3.1", + "@typescript-eslint/types": "7.3.1", + "@typescript-eslint/typescript-estree": "7.3.1", "semver": "^7.5.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz", - "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.3.1.tgz", + "integrity": "sha512-9RMXwQF8knsZvfv9tdi+4D/j7dMG28X/wMJ8Jj6eOHyHWwDW4ngQJcqEczSsqIKKjFiLFr40Mnr7a5ulDD3vmw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.0", + "@typescript-eslint/types": "7.3.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2166,57 +2444,60 @@ "dev": true }, "node_modules/@vitejs/plugin-react": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.1.0.tgz", - "integrity": "sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz", + "integrity": "sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==", "dev": true, "dependencies": { - "@babel/core": "^7.22.20", - "@babel/plugin-transform-react-jsx-self": "^7.22.5", - "@babel/plugin-transform-react-jsx-source": "^7.22.5", - "@types/babel__core": "^7.20.2", + "@babel/core": "^7.23.5", + "@babel/plugin-transform-react-jsx-self": "^7.23.3", + "@babel/plugin-transform-react-jsx-source": "^7.23.3", + "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.0" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0" + "vite": "^4.2.0 || ^5.0.0" } }, "node_modules/@vitest/coverage-v8": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-0.34.6.tgz", - "integrity": "sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.4.0.tgz", + "integrity": "sha512-4hDGyH1SvKpgZnIByr9LhGgCEuF9DKM34IBLCC/fVfy24Z3+PZ+Ii9hsVBsHvY1umM1aGPEjceRkzxCfcQ10wg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", "@bcoe/v8-coverage": "^0.2.3", - "istanbul-lib-coverage": "^3.2.0", + "debug": "^4.3.4", + "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", - "istanbul-lib-source-maps": "^4.0.1", - "istanbul-reports": "^3.1.5", - "magic-string": "^0.30.1", + "istanbul-lib-source-maps": "^5.0.4", + "istanbul-reports": "^3.1.6", + "magic-string": "^0.30.5", + "magicast": "^0.3.3", "picocolors": "^1.0.0", - "std-env": "^3.3.3", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", "test-exclude": "^6.0.0", - "v8-to-istanbul": "^9.1.0" + "v8-to-istanbul": "^9.2.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": ">=0.32.0 <1" + "vitest": "1.4.0" } }, "node_modules/@vitest/expect": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz", - "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz", + "integrity": "sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==", "dev": true, "dependencies": { - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", + "@vitest/spy": "1.4.0", + "@vitest/utils": "1.4.0", "chai": "^4.3.10" }, "funding": { @@ -2224,13 +2505,13 @@ } }, "node_modules/@vitest/runner": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz", - "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.4.0.tgz", + "integrity": "sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==", "dev": true, "dependencies": { - "@vitest/utils": "0.34.6", - "p-limit": "^4.0.0", + "@vitest/utils": "1.4.0", + "p-limit": "^5.0.0", "pathe": "^1.1.1" }, "funding": { @@ -2238,15 +2519,15 @@ } }, "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", "dev": true, "dependencies": { "yocto-queue": "^1.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2265,14 +2546,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz", - "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.4.0.tgz", + "integrity": "sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==", "dev": true, "dependencies": { - "magic-string": "^0.30.1", + "magic-string": "^0.30.5", "pathe": "^1.1.1", - "pretty-format": "^29.5.0" + "pretty-format": "^29.7.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -2311,26 +2592,27 @@ "dev": true }, "node_modules/@vitest/spy": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz", - "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz", + "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==", "dev": true, "dependencies": { - "tinyspy": "^2.1.1" + "tinyspy": "^2.2.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz", - "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==", "dev": true, "dependencies": { - "diff-sequences": "^29.4.3", - "loupe": "^2.3.6", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -2368,12 +2650,6 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true - }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -2396,24 +2672,24 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", "dev": true, "dependencies": { - "debug": "4" + "debug": "^4.3.4" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { @@ -2457,57 +2733,57 @@ } }, "node_modules/antd": { - "version": "5.10.2", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.10.2.tgz", - "integrity": "sha512-0kV6PmlJi7vhPmYH9GCAlU62ZhiuLF+gE3REJ/9MZTo++/3i5q6SALNoRgHLMsa+rX50U3RO3wJVY+fPib594Q==", + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.15.3.tgz", + "integrity": "sha512-53dpdGbfwipHVbqITmppp8N16i+BscMzz8NUNwaJgxwSvO9VQh/NfC/90lqGq3I2oBmxQ8TzRIxzFVKD/9OhlQ==", "dependencies": { - "@ant-design/colors": "^7.0.0", - "@ant-design/cssinjs": "^1.17.2", - "@ant-design/icons": "^5.2.6", + "@ant-design/colors": "^7.0.2", + "@ant-design/cssinjs": "^1.18.4", + "@ant-design/icons": "^5.3.3", "@ant-design/react-slick": "~1.0.2", - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.24.0", "@ctrl/tinycolor": "^3.6.1", - "@rc-component/color-picker": "~1.4.1", + "@rc-component/color-picker": "~1.5.3", "@rc-component/mutate-observer": "^1.1.0", - "@rc-component/tour": "~1.10.0", - "@rc-component/trigger": "^1.17.2", - "classnames": "^2.2.6", - "copy-to-clipboard": "^3.2.0", - "dayjs": "^1.11.1", + "@rc-component/tour": "~1.14.2", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.5.1", + "copy-to-clipboard": "^3.3.3", + "dayjs": "^1.11.10", "qrcode.react": "^3.1.0", - "rc-cascader": "~3.18.1", - "rc-checkbox": "~3.1.0", - "rc-collapse": "~3.7.1", - "rc-dialog": "~9.3.4", - "rc-drawer": "~6.5.2", - "rc-dropdown": "~4.1.0", - "rc-field-form": "~1.39.0", - "rc-image": "~7.3.1", - "rc-input": "~1.2.1", - "rc-input-number": "~8.1.0", - "rc-mentions": "~2.8.0", - "rc-menu": "~9.12.2", + "rc-cascader": "~3.24.0", + "rc-checkbox": "~3.2.0", + "rc-collapse": "~3.7.2", + "rc-dialog": "~9.4.0", + "rc-drawer": "~7.1.0", + "rc-dropdown": "~4.2.0", + "rc-field-form": "~1.42.1", + "rc-image": "~7.6.0", + "rc-input": "~1.4.5", + "rc-input-number": "~9.0.0", + "rc-mentions": "~2.11.1", + "rc-menu": "~9.13.0", "rc-motion": "^2.9.0", - "rc-notification": "~5.2.0", - "rc-pagination": "~3.6.1", - "rc-picker": "~3.14.5", + "rc-notification": "~5.3.0", + "rc-pagination": "~4.0.4", + "rc-picker": "~4.3.0", "rc-progress": "~3.5.1", "rc-rate": "~2.12.0", "rc-resize-observer": "^1.4.0", - "rc-segmented": "~2.2.2", - "rc-select": "~14.9.2", - "rc-slider": "~10.3.1", + "rc-segmented": "~2.3.0", + "rc-select": "~14.13.0", + "rc-slider": "~10.5.0", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", - "rc-table": "~7.34.4", - "rc-tabs": "~12.12.1", - "rc-textarea": "~1.4.0", - "rc-tooltip": "~6.1.1", - "rc-tree": "~5.7.12", - "rc-tree-select": "~5.13.0", - "rc-upload": "~4.3.5", - "rc-util": "^5.38.0", - "scroll-into-view-if-needed": "^3.0.3", + "rc-table": "~7.42.0", + "rc-tabs": "~14.1.1", + "rc-textarea": "~1.6.3", + "rc-tooltip": "~6.2.0", + "rc-tree": "~5.8.5", + "rc-tree-select": "~5.19.0", + "rc-upload": "~4.5.2", + "rc-util": "^5.39.1", + "scroll-into-view-if-needed": "^3.1.0", "throttle-debounce": "^5.0.0" }, "funding": { @@ -2548,13 +2824,36 @@ } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2574,6 +2873,129 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -2583,6 +3005,12 @@ "node": "*" } }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, "node_modules/async-validator": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", @@ -2595,10 +3023,13 @@ "dev": true }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -2606,6 +3037,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", @@ -2642,9 +3091,9 @@ "dev": true }, "node_modules/bootstrap": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", - "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz", + "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==", "funding": [ { "type": "github", @@ -2682,9 +3131,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.0.tgz", - "integrity": "sha512-v+Jcv64L2LbfTC6OnRcaxtqJNJuQAVhZKSJfR/6hn7lhnChUXl4amwVviqN1k411BB+3rRoKMitELRn1CojeRA==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, "funding": [ { @@ -2701,9 +3150,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001539", - "electron-to-chromium": "^1.4.530", - "node-releases": "^2.0.13", + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, "bin": { @@ -2723,13 +3172,19 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2744,9 +3199,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001539", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001539.tgz", - "integrity": "sha512-hfS5tE8bnNiNvEOEkm8HElUHroYwlqMMENEzELymy77+tJ6m+gA2krtHl5hxJaj71OlpC2cHZbdSMX1/YEqEkA==", + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", "dev": true, "funding": [ { @@ -2764,9 +3219,9 @@ ] }, "node_modules/chai": { - "version": "4.3.10", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", - "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", @@ -2864,9 +3319,9 @@ } }, "node_modules/classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, "node_modules/color-convert": { "version": "2.0.1", @@ -2899,9 +3354,9 @@ } }, "node_modules/compute-scroll-into-view": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.0.3.tgz", - "integrity": "sha512-nadqwNxghAGTamwIqQSG433W6OADZx2vCo3UXHNrzTRHK/htu+7+L0zhjEoaeaQVNAi3YgqWDv8+tzf0hRfR+A==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz", + "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==" }, "node_modules/concat-map": { "version": "0.0.1", @@ -2958,34 +3413,90 @@ "dev": true }, "node_modules/cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", + "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", "dev": true, "dependencies": { "rrweb-cssom": "^0.6.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true }, "node_modules/data-urls": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", - "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dev": true, "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/dayjs": { @@ -3057,24 +3568,44 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/deep-equal/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -3103,9 +3634,9 @@ } }, "node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -3150,27 +3681,21 @@ "csstype": "^3.0.2" } }, - "node_modules/domexception": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", - "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", - "dev": true, - "dependencies": { - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/dompurify": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz", - "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w==" + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.11.tgz", + "integrity": "sha512-Fan4uMuyB26gFV3ovPoEoQbxRRPfTu3CvImyZnhGq5fsIEO+gEFLp45ISFt+kQBWsK5ulDdT0oV28jS1UrwQLg==" }, "node_modules/electron-to-chromium": { - "version": "1.4.530", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.530.tgz", - "integrity": "sha512-rsJ9O8SCI4etS8TBsXuRfHa2eZReJhnGf5MHZd3Vo05PukWHKXhk3VQGbHHnDLa8nZz9woPCpLCMQpLGgkGNRA==", + "version": "1.4.612", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.612.tgz", + "integrity": "sha512-dM8BMtXtlH237ecSMnYdYuCkib2QHq0kpWfUnavjdYsyr/6OsAwg5ZGUfnQ9KD1Ga4QgB2sqXlB2NT8zy2GnVg==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, "node_modules/entities": { @@ -3193,12 +3718,93 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-abstract": { + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", + "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-cookie": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/es-cookie/-/es-cookie-1.4.0.tgz", "integrity": "sha512-V4bHxyGBmwwiV+CKTLUPLmwhcutTxGEC5n4HWaUDSnTvkNvfIjkMw8qIVTVgPeNCWojgR5IUzFnGenNvCoKQ5A==" }, - "node_modules/es-get-iterator": { + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", @@ -3218,16 +3824,87 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-get-iterator/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "node_modules/es-iterator-helpers": { + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", + "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/esbuild": { - "version": "0.18.11", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.11.tgz", - "integrity": "sha512-i8u6mQF0JKJUlGR3OdFLKldJQMMs8OqM9Cc3UCi9XXziJ9WERM5bfkHaEAy0YAvPRMgqSW55W7xYn84XtEFTtA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "hasInstallScript": true, "bin": { @@ -3237,28 +3914,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.11", - "@esbuild/android-arm64": "0.18.11", - "@esbuild/android-x64": "0.18.11", - "@esbuild/darwin-arm64": "0.18.11", - "@esbuild/darwin-x64": "0.18.11", - "@esbuild/freebsd-arm64": "0.18.11", - "@esbuild/freebsd-x64": "0.18.11", - "@esbuild/linux-arm": "0.18.11", - "@esbuild/linux-arm64": "0.18.11", - "@esbuild/linux-ia32": "0.18.11", - "@esbuild/linux-loong64": "0.18.11", - "@esbuild/linux-mips64el": "0.18.11", - "@esbuild/linux-ppc64": "0.18.11", - "@esbuild/linux-riscv64": "0.18.11", - "@esbuild/linux-s390x": "0.18.11", - "@esbuild/linux-x64": "0.18.11", - "@esbuild/netbsd-x64": "0.18.11", - "@esbuild/openbsd-x64": "0.18.11", - "@esbuild/sunos-x64": "0.18.11", - "@esbuild/win32-arm64": "0.18.11", - "@esbuild/win32-ia32": "0.18.11", - "@esbuild/win32-x64": "0.18.11" + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "node_modules/escalade": { @@ -3282,16 +3960,16 @@ } }, "node_modules/eslint": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", - "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.52.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -3336,6 +4014,213 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.34.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", + "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlast": "^1.2.4", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.17", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7", + "object.hasown": "^1.1.3", + "object.values": "^1.1.7", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.10" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", @@ -3349,14 +4234,52 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz", - "integrity": "sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==", + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.6.tgz", + "integrity": "sha512-NjGXdm7zgcKRkKMua34qVO9doI7VOxZ6ancSvBELJSSoX97jyndXcSoa8XBh69JoB31dNz3EEzlMcizZl7LaMA==", "dev": true, "peerDependencies": { "eslint": ">=7" } }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -3435,6 +4358,15 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -3444,6 +4376,29 @@ "node": ">=0.10.0" } }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/expect": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", @@ -3467,9 +4422,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3610,6 +4565,30 @@ "node": ">= 6" } }, + "node_modules/formik": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.5.tgz", + "integrity": "sha512-Gxlht0TD3vVdzMDHwkiNZqJ7Mvg77xQNfmBRrNtvzcHZs72TJppSTDKHpImCMJZwcWPBJ8jSQQ95GJzXFf1nAQ==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3617,9 +4596,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -3631,9 +4610,30 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/functions-have-names": { "version": "1.2.3", @@ -3663,15 +4663,48 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3710,9 +4743,9 @@ } }, "node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3724,6 +4757,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -3774,17 +4822,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -3804,21 +4841,21 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -3840,12 +4877,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -3854,6 +4891,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/highlight.js": { + "version": "11.9.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", + "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -3863,15 +4919,15 @@ } }, "node_modules/html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, "dependencies": { - "whatwg-encoding": "^2.0.0" + "whatwg-encoding": "^3.1.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/html-escaper": { @@ -3881,30 +4937,38 @@ "dev": true }, "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", "dev": true, "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", "dev": true, "dependencies": { - "agent-base": "6", + "agent-base": "^7.0.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" } }, "node_modules/iconv-lite": { @@ -3984,13 +5048,13 @@ "dev": true }, "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -4022,14 +5086,16 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4040,6 +5106,21 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -4093,11 +5174,26 @@ } }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4127,6 +5223,33 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -4148,6 +5271,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4213,17 +5348,32 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -4255,16 +5405,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -4282,6 +5428,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakset": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", @@ -4295,6 +5453,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4302,9 +5466,9 @@ "dev": true }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "engines": { "node": ">=8" @@ -4325,32 +5489,23 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.4.tgz", + "integrity": "sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "istanbul-lib-coverage": "^3.0.0" }, "engines": { "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -4360,6 +5515,19 @@ "node": ">=8" } }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, "node_modules/jest-diff": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", @@ -4559,40 +5727,38 @@ } }, "node_modules/jsdom": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", - "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.0.0.tgz", + "integrity": "sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==", "dev": true, "dependencies": { - "abab": "^2.0.6", - "cssstyle": "^3.0.0", - "data-urls": "^4.0.0", + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", "decimal.js": "^10.4.3", - "domexception": "^4.0.0", "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.4", + "nwsapi": "^2.2.7", "parse5": "^7.1.2", "rrweb-cssom": "^0.6.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^4.0.0", + "tough-cookie": "^4.1.3", + "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.1", - "ws": "^8.13.0", - "xml-name-validator": "^4.0.0" + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.16.0", + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { - "canvas": "^2.5.0" + "canvas": "^2.11.2" }, "peerDependenciesMeta": { "canvas": { @@ -4655,6 +5821,39 @@ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4674,10 +5873,14 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/local-pkg": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", - "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, "engines": { "node": ">=14" }, @@ -4703,8 +5906,12 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -4724,12 +5931,12 @@ } }, "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "dependencies": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "node_modules/lru-cache": { @@ -4754,9 +5961,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", - "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -4765,6 +5972,17 @@ "node": ">=12" } }, + "node_modules/magicast": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.3.tgz", + "integrity": "sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "source-map-js": "^1.0.2" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -4781,14 +5999,14 @@ } }, "node_modules/marked": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.2.tgz", - "integrity": "sha512-qoKMJqK0w6vkLk8+KnKZAH6neUZSNaQqVZ/h2yZ9S7CbLuFHyS2viB0jnqcWF9UKjwsAbMrQtnQhdmdvOVOw9w==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.1.tgz", + "integrity": "sha512-Y1/V2yafOcOdWQCX0XpAKXzDakPOpn6U0YLxTJs3cww6VxOzZV1BTOOYWLvH3gX38cq+iLwljHHTnMtlDfg01Q==", "bin": { "marked": "bin/marked.js" }, "engines": { - "node": ">= 16" + "node": ">= 18" } }, "node_modules/memoize-one": { @@ -4796,6 +6014,12 @@ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -4839,6 +6063,18 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -4860,6 +6096,15 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/mlly": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.2.tgz", @@ -4879,9 +6124,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -4903,9 +6148,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/normalize-path": { @@ -4917,6 +6162,33 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/nwsapi": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", @@ -4932,9 +6204,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4966,13 +6238,13 @@ } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -4983,6 +6255,82 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4992,6 +6340,21 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -5163,10 +6526,19 @@ "pathe": "^1.1.0" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.4.37", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.37.tgz", + "integrity": "sha512-7iB/v/r7Woof0glKLH8b1SPHrsX7uhdO+Geb41QpF/+mWZHU3uxxSlN+UXGVit1PawOYDToO+AbZzhBzWRDwbQ==", "dev": true, "funding": [ { @@ -5183,9 +6555,9 @@ } ], "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -5201,9 +6573,9 @@ } }, "node_modules/prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -5269,6 +6641,11 @@ "react": ">=0.14.0" } }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -5276,9 +6653,9 @@ "dev": true }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -5319,16 +6696,16 @@ ] }, "node_modules/rc-cascader": { - "version": "3.18.1", - "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.18.1.tgz", - "integrity": "sha512-M7Xr5Fs/E87ZGustfObtBYQjsvBCET0UX2JYXB2GmOP+2fsZgjaRGXK+CJBmmWXQ6o4OFinpBQBXG4wJOQ5MEg==", + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.24.0.tgz", + "integrity": "sha512-NwkYsVULA61S085jbOYbq8Z7leyIxVmLwf+71mWLjA3kCfUf/rAKC0WfjQbqBDaLGlU9d4z1EzyPaHBKLYWv6A==", "dependencies": { "@babel/runtime": "^7.12.5", "array-tree-filter": "^2.1.0", "classnames": "^2.3.1", - "rc-select": "~14.9.0", - "rc-tree": "~5.7.0", - "rc-util": "^5.35.0" + "rc-select": "~14.13.0", + "rc-tree": "~5.8.1", + "rc-util": "^5.37.0" }, "peerDependencies": { "react": ">=16.9.0", @@ -5336,9 +6713,9 @@ } }, "node_modules/rc-checkbox": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.1.0.tgz", - "integrity": "sha512-PAwpJFnBa3Ei+5pyqMMXdcKYKNBMS+TvSDiLdDnARnMJHC8ESxwPfm4Ao1gJiKtWLdmGfigascnCpwrHFgoOBQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.2.0.tgz", + "integrity": "sha512-8inzw4y9dAhZmv/Ydl59Qdy5tdp9CKg4oPVcRigi+ga/yKPZS5m5SyyQPtYSgbcqHRYOdUhiPSeKfktc76du1A==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.3.2", @@ -5350,9 +6727,9 @@ } }, "node_modules/rc-collapse": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.1.tgz", - "integrity": "sha512-N/7ejyiTf3XElNJBBpxqnZBUuMsQWEOPjB2QkfNvZ/Ca54eAvJXuOD1EGbCWCk2m7v/MSxku7mRpdeaLOCd4Gg==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.2.tgz", + "integrity": "sha512-ZRw6ipDyOnfLFySxAiCMdbHtb5ePAsB9mT17PA6y1mRD/W6KHRaZeb5qK/X9xDV1CqgyxMpzw0VdS74PCcUk4A==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", @@ -5365,9 +6742,9 @@ } }, "node_modules/rc-dialog": { - "version": "9.3.4", - "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.3.4.tgz", - "integrity": "sha512-975X3018GhR+EjZFbxA2Z57SX5rnu0G0/OxFgMMvZK4/hQWEm3MHaNvP4wXpxYDoJsp+xUvVW+GB9CMMCm81jA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.4.0.tgz", + "integrity": "sha512-AScCexaLACvf8KZRqCPz12BJ8olszXOS4lKlkMyzDQHS1m0zj1KZMYgmMCh39ee0Dcv8kyrj8mTqxuLyhH+QuQ==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/portal": "^1.0.0-8", @@ -5381,15 +6758,15 @@ } }, "node_modules/rc-drawer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-6.5.2.tgz", - "integrity": "sha512-QckxAnQNdhh4vtmKN0ZwDf3iakO83W9eZcSKWYYTDv4qcD2fHhRAZJJ/OE6v2ZlQ2kSqCJX5gYssF4HJFvsEPQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.1.0.tgz", + "integrity": "sha512-nBE1rF5iZvpavoyqhSSz2mk/yANltA7g3aF0U45xkx381n3we/RKs9cJfNKp9mSWCedOKWt9FLEwZDaAaOGn2w==", "dependencies": { - "@babel/runtime": "^7.10.1", + "@babel/runtime": "^7.23.9", "@rc-component/portal": "^1.1.1", "classnames": "^2.2.6", "rc-motion": "^2.6.1", - "rc-util": "^5.36.0" + "rc-util": "^5.38.1" }, "peerDependencies": { "react": ">=16.9.0", @@ -5397,12 +6774,12 @@ } }, "node_modules/rc-dropdown": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.1.0.tgz", - "integrity": "sha512-VZjMunpBdlVzYpEdJSaV7WM7O0jf8uyDjirxXLZRNZ+tAC+NzD3PXPEtliFwGzVwBBdCmGuSqiS9DWcOLxQ9tw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.2.0.tgz", + "integrity": "sha512-odM8Ove+gSh0zU27DUj5cG1gNKg7mLWBYzB5E4nNLrLwBmYEgYP43vHKDGOVZcJSVElQBI0+jTQgjnq0NfLjng==", "dependencies": { "@babel/runtime": "^7.18.3", - "@rc-component/trigger": "^1.7.0", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.2.6", "rc-util": "^5.17.0" }, @@ -5412,9 +6789,9 @@ } }, "node_modules/rc-field-form": { - "version": "1.39.0", - "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.39.0.tgz", - "integrity": "sha512-V7Wk7uji1jBsUGGgP788H9rpFy55HLiD4lywTlktUGjK7EgW5dt+mq1MPbtCpPRMzs83vZBW4SOChOmCACz4WA==", + "version": "1.42.1", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.42.1.tgz", + "integrity": "sha512-SqiEmWNP+I61Lt80+ofPvT+3l8Ij6vb35IS+x14gheVnCJN0SRnOwEgsqCEB5FslT7xqjUqDnU845hRZ1jzlAA==", "dependencies": { "@babel/runtime": "^7.18.0", "async-validator": "^4.1.0", @@ -5429,14 +6806,14 @@ } }, "node_modules/rc-image": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.3.1.tgz", - "integrity": "sha512-Tu3vcUyMHa6zxTiQRzHt1glbGwuNWzeQBG9O6qIdy/+1ue0Qb70it+jUct1YPVNkJa/QfaTfUhmsNsqrw7mgsg==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.6.0.tgz", + "integrity": "sha512-tL3Rvd1sS+frZQ01i+tkeUPaOeFz2iG9/scAt/Cfs0hyCRVA/w0Pu1J/JxIX8blalvmHE0bZQRYdOmRAzWu4Hg==", "dependencies": { "@babel/runtime": "^7.11.2", "@rc-component/portal": "^1.0.2", "classnames": "^2.2.6", - "rc-dialog": "~9.3.0", + "rc-dialog": "~9.4.0", "rc-motion": "^2.6.2", "rc-util": "^5.34.1" }, @@ -5446,9 +6823,9 @@ } }, "node_modules/rc-input": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.2.1.tgz", - "integrity": "sha512-nQRmBvEFoGi+SNRDavccZ8ueyhFgmxkWqIt4aDyuNJgUZF12HJKIwDhAafUM7N+g7PyuW9FH3pf3zPHzdiCWbA==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.4.5.tgz", + "integrity": "sha512-AjzykhwnwYTRSwwgCu70CGKBIAv6bP2nqnFptnNTprph/TF1BAs0Qxl91mie/BR6n827WIJB6ZjaRf9iiMwAfw==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -5460,14 +6837,14 @@ } }, "node_modules/rc-input-number": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-8.1.0.tgz", - "integrity": "sha512-bdHgduOxuN0lrhzgPmoKbhRD4GLIzVcddVz972/JHPHr7oLwPX5xDb9w4bXhuMzyT2VzQy7nggRCfH3yAl09oA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.0.0.tgz", + "integrity": "sha512-RfcDBDdWFFetouWFXBA+WPEC8LzBXyngr9b+yTLVIygfFu7HiLRGn/s/v9wwno94X7KFvnb28FNynMGj9XJlDQ==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/mini-decimal": "^1.0.1", "classnames": "^2.2.5", - "rc-input": "~1.2.1", + "rc-input": "~1.4.0", "rc-util": "^5.28.0" }, "peerDependencies": { @@ -5476,16 +6853,16 @@ } }, "node_modules/rc-mentions": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.8.0.tgz", - "integrity": "sha512-LBMkO6bSGhEvS1CvMK978qGN82tI+mzk7l/uTiQJH+UDiwpvq+pxK4DxU5b6Q1T5LW6bn2pSua9RaZKZrDoBOw==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.11.1.tgz", + "integrity": "sha512-upb4AK1SRFql7qGnbLEvJqLMugVVIyjmwBJW9L0eLoN9po4JmJZaBzmKA4089fNtsU8k6l/tdZiVafyooeKnLw==", "dependencies": { "@babel/runtime": "^7.22.5", - "@rc-component/trigger": "^1.5.0", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.2.6", - "rc-input": "~1.2.1", - "rc-menu": "~9.12.0", - "rc-textarea": "~1.4.0", + "rc-input": "~1.4.0", + "rc-menu": "~9.13.0", + "rc-textarea": "~1.6.1", "rc-util": "^5.34.1" }, "peerDependencies": { @@ -5494,12 +6871,12 @@ } }, "node_modules/rc-menu": { - "version": "9.12.2", - "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.12.2.tgz", - "integrity": "sha512-NzloFH2pRUYmQ3S/YbJAvRkgCZaLvq0sRa5rgJtuIHLfPPprNHNyepeSlT64+dbVqI4qRWL44VN0lUCldCbbfg==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.13.0.tgz", + "integrity": "sha512-1l8ooCB3HcYJKCltC/s7OxRKRjgymdl9htrCeGZcXNaMct0RxZRK6OPV3lPhVksIvAGMgzPd54ClpZ5J4b8cZA==", "dependencies": { "@babel/runtime": "^7.10.1", - "@rc-component/trigger": "^1.17.0", + "@rc-component/trigger": "^2.0.0", "classnames": "2.x", "rc-motion": "^2.4.3", "rc-overflow": "^1.3.1", @@ -5525,9 +6902,9 @@ } }, "node_modules/rc-notification": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.2.0.tgz", - "integrity": "sha512-HwUSypEW4mfOpiakJ7dm6TAKf+3zuSR2xm0I0XMes493rtA3n4EVMvQyldrp23hUwCE3RFj8oncyU1E8iNC4ag==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.3.0.tgz", + "integrity": "sha512-WCf0uCOkZ3HGfF0p1H4Sgt7aWfipxORWTPp7o6prA3vxwtWhtug3GfpYls1pnBp4WA+j8vGIi5c2/hQRpGzPcQ==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", @@ -5558,13 +6935,13 @@ } }, "node_modules/rc-pagination": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-3.6.1.tgz", - "integrity": "sha512-R/sUnKKXx1Nm4kZfUKS3YKa7yEPF1ZkVB/AynQaHt+nMER7h9wPTfliDJFdYo+RM/nk2JD4Yc5QpUq8fIQHeug==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-4.0.4.tgz", + "integrity": "sha512-GGrLT4NgG6wgJpT/hHIpL9nELv27A1XbSZzECIuQBQTVSf4xGKxWr6I/jhpRPauYEWEbWVw22ObG6tJQqwJqWQ==", "dependencies": { "@babel/runtime": "^7.10.1", - "classnames": "^2.2.1", - "rc-util": "^5.32.2" + "classnames": "^2.3.2", + "rc-util": "^5.38.0" }, "peerDependencies": { "react": ">=16.9.0", @@ -5572,14 +6949,16 @@ } }, "node_modules/rc-picker": { - "version": "3.14.5", - "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-3.14.5.tgz", - "integrity": "sha512-h0O8b5AYfWwHSRUUH/9F2oBXB5gZerHIyGG6z2r5rn/kfSQodyCXEO4GNqrG30iUC1qkvLFIOn/JqI4XaO0+2A==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.3.0.tgz", + "integrity": "sha512-bQNB/+NdW55jlQ5lPnNqF5J90Tq4SihLbAF7tzPBvGDJyoYmDgwLm4FN0ZB3Ot9i1v6vJY/1mgqZZTT9jbYc5w==", "dependencies": { "@babel/runtime": "^7.10.1", - "@rc-component/trigger": "^1.5.0", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.2.1", - "rc-util": "^5.30.0" + "rc-overflow": "^1.3.2", + "rc-resize-observer": "^1.4.0", + "rc-util": "^5.38.1" }, "engines": { "node": ">=8.x" @@ -5654,9 +7033,9 @@ } }, "node_modules/rc-segmented": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.2.2.tgz", - "integrity": "sha512-Mq52M96QdHMsNdE/042ibT5vkcGcD5jxKp7HgPC2SRofpia99P5fkfHy1pEaajLMF/kj0+2Lkq1UZRvqzo9mSA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.3.0.tgz", + "integrity": "sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==", "dependencies": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -5669,12 +7048,12 @@ } }, "node_modules/rc-select": { - "version": "14.9.2", - "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.9.2.tgz", - "integrity": "sha512-VQ15sRFgPURHb8ZcZNSDtb2rAw3+C9xlL0nDziwNHTEW1KvEpZ8y+0v5w24X/Bpl9b3cW1BOyW1F5UqSAq+7Dg==", + "version": "14.13.0", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.13.0.tgz", + "integrity": "sha512-ew34FsaqHokK4dxVrcIxSYrgWJ2XJYlkk32eiOIiEo3GkHUExdCzmozMYaUc2P67c5QJRUvvY0uqCs3QG67h5A==", "dependencies": { "@babel/runtime": "^7.10.1", - "@rc-component/trigger": "^1.5.0", + "@rc-component/trigger": "^2.0.0", "classnames": "2.x", "rc-motion": "^2.0.1", "rc-overflow": "^1.3.1", @@ -5690,9 +7069,9 @@ } }, "node_modules/rc-slider": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.3.1.tgz", - "integrity": "sha512-XszsZLkbjcG9ogQy/zUC0n2kndoKUAnY/Vnk1Go5Gx+JJQBz0Tl15d5IfSiglwBUZPS9vsUJZkfCmkIZSqWbcA==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.5.0.tgz", + "integrity": "sha512-xiYght50cvoODZYI43v3Ylsqiw14+D7ELsgzR40boDZaya1HFa1Etnv9MDkQE8X/UrXAffwv2AcNAhslgYuDTw==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", @@ -5738,15 +7117,15 @@ } }, "node_modules/rc-table": { - "version": "7.34.4", - "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.34.4.tgz", - "integrity": "sha512-os+i88Y2AO/6dNkOgJkKSHgXYaZZGnuOEEe+nyaq5IRgvAQNhLysUjXt2objtBeFDEZR8TqXrajwBNRUwunmdw==", + "version": "7.42.0", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.42.0.tgz", + "integrity": "sha512-GwHV9Zs3HvWxBkoXatO/IeKoElzy3Ojf3dcyw1Rj3cyQVb+ZHtexslKdyzsrKRPJ0mUa62BoX+ZAg3zgTEql8w==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/context": "^1.4.0", "classnames": "^2.2.5", "rc-resize-observer": "^1.1.0", - "rc-util": "^5.36.0", + "rc-util": "^5.37.0", "rc-virtual-list": "^3.11.1" }, "engines": { @@ -5758,14 +7137,14 @@ } }, "node_modules/rc-tabs": { - "version": "12.12.1", - "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-12.12.1.tgz", - "integrity": "sha512-e10VBjEkECdPl4XZSs9to81SE+mgclBTM7J8/LMsFqmJoi05Tci91bRnmeeDtrcOCx2PuZdJv57XUlC4d8PEIw==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-14.1.1.tgz", + "integrity": "sha512-5nOr9PVpJy2SWHTLgv1+kESDOb0tFzl0cYU9r9d8LfL0Wg9i/n1B558rmkxdQHgBwMqxmwoyPSAbQROxMQe8nw==", "dependencies": { "@babel/runtime": "^7.11.2", "classnames": "2.x", - "rc-dropdown": "~4.1.0", - "rc-menu": "~9.12.0", + "rc-dropdown": "~4.2.0", + "rc-menu": "~9.13.0", "rc-motion": "^2.6.2", "rc-resize-observer": "^1.0.0", "rc-util": "^5.34.1" @@ -5779,13 +7158,13 @@ } }, "node_modules/rc-textarea": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.4.0.tgz", - "integrity": "sha512-CiqK+uyoJlnfufbC0kwfHJpfElhQacuDSNyNQ/xGnA/QMaJLDbgmqRT8QmX0T0KD/ws/hy6qqRaGJSsrRR5uiQ==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.6.3.tgz", + "integrity": "sha512-8k7+8Y2GJ/cQLiClFMg8kUXOOdvcFQrnGeSchOvI2ZMIVvX5a3zQpLxoODL0HTrvU63fPkRmMuqaEcOF9dQemA==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.1", - "rc-input": "~1.2.1", + "rc-input": "~1.4.0", "rc-resize-observer": "^1.0.0", "rc-util": "^5.27.0" }, @@ -5795,12 +7174,12 @@ } }, "node_modules/rc-tooltip": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.1.1.tgz", - "integrity": "sha512-YoxL0Ev4htsX37qgN23eKr0L5PIRpZaLVL9GX6aJ4x6UEnwgXZYUNCAEHfKlKT3eD1felDq3ob4+Cn9lprLDBw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.2.0.tgz", + "integrity": "sha512-iS/3iOAvtDh9GIx1ulY7EFUXUtktFccNLsARo3NPgLf0QW9oT0w3dA9cYWlhqAKmD+uriEwdWz1kH0Qs4zk2Aw==", "dependencies": { "@babel/runtime": "^7.11.2", - "@rc-component/trigger": "^1.17.0", + "@rc-component/trigger": "^2.0.0", "classnames": "^2.3.1" }, "peerDependencies": { @@ -5809,9 +7188,9 @@ } }, "node_modules/rc-tree": { - "version": "5.7.12", - "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.7.12.tgz", - "integrity": "sha512-LXA5nY2hG5koIAlHW5sgXgLpOMz+bFRbnZZ+cCg0tQs4Wv1AmY7EDi1SK7iFXhslYockbqUerQan82jljoaItg==", + "version": "5.8.5", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.8.5.tgz", + "integrity": "sha512-PRfcZtVDNkR7oh26RuNe1hpw11c1wfgzwmPFL0lnxGnYefe9lDAO6cg5wJKIAwyXFVt5zHgpjYmaz0CPy1ZtKg==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", @@ -5828,14 +7207,14 @@ } }, "node_modules/rc-tree-select": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.13.0.tgz", - "integrity": "sha512-g01JU9EdE7j/9KfDKtmvFqJ7ZDNIYDzkpmAXllbTBFoRNhWJBjW1x/dCZLVG+IdZeIz8SKJkgZzCf1CUZrzV/Q==", + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.19.0.tgz", + "integrity": "sha512-f4l5EsmSGF3ggj76YTzKNPY9SnXfFaer7ZccTSGb3urUf54L+cCqyT+UsPr+S5TAr8mZSxJ7g3CgkCe+cVQ6sw==", "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "2.x", - "rc-select": "~14.9.0", - "rc-tree": "~5.7.0", + "rc-select": "~14.13.0", + "rc-tree": "~5.8.1", "rc-util": "^5.16.1" }, "peerDependencies": { @@ -5844,9 +7223,9 @@ } }, "node_modules/rc-upload": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.3.5.tgz", - "integrity": "sha512-EHlKJbhkgFSQHliTj9v/2K5aEuFwfUQgZARzD7AmAPOneZEPiCNF3n6PEWIuqz9h7oq6FuXgdR67sC5BWFxJbA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.5.2.tgz", + "integrity": "sha512-QO3ne77DwnAPKFn0bA5qJM81QBjQi0e0NHdkvpFyY73Bea2NfITiotqJqVjHgeYPOJu5lLVR32TNGP084aSoXA==", "dependencies": { "@babel/runtime": "^7.18.3", "classnames": "^2.2.5", @@ -5858,9 +7237,9 @@ } }, "node_modules/rc-util": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.38.0.tgz", - "integrity": "sha512-yV/YBNdFn+edyBpBdCqkPE29Su0jWcHNgwx2dJbRqMrMfrUcMJUjCRV+ZPhcvWyKFJ63GzEerPrz9JIVo0zXmA==", + "version": "5.39.1", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.39.1.tgz", + "integrity": "sha512-OW/ERynNDgNr4y0oiFmtes3rbEamXw7GHGbkbNd9iRr7kgT03T6fT0b9WpJ3mbxKhyOcAHnGcIoh5u/cjrC2OQ==", "dependencies": { "@babel/runtime": "^7.18.3", "react-is": "^18.2.0" @@ -5876,9 +7255,9 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/rc-virtual-list": { - "version": "3.11.2", - "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.11.2.tgz", - "integrity": "sha512-MTFLL2LOHr3+/+r+WjTIs6j8XmJE6EqdOsJvCH8SWig7qyik3aljCEImUtw5tdWR0tQhXUfbv7P7nZaLY91XPg==", + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.11.4.tgz", + "integrity": "sha512-NbBi0fvyIu26gP69nQBiWgUMTPX3mr4FcuBQiVqagU0BnuX8WQkiivnMs105JROeuUIFczLrlgUhLQwTWV1XDA==", "dependencies": { "@babel/runtime": "^7.20.0", "classnames": "^2.2.6", @@ -5889,8 +7268,8 @@ "node": ">=8.x" }, "peerDependencies": { - "react": "*", - "react-dom": "*" + "react": ">=16.9.0", + "react-dom": ">=16.9.0" } }, "node_modules/react": { @@ -5905,13 +7284,13 @@ } }, "node_modules/react-bootstrap": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.9.1.tgz", - "integrity": "sha512-ezgmh/ARCYp18LbZEqPp0ppvy+ytCmycDORqc8vXSKYV3cer4VH7OReV8uMOoKXmYzivJTxgzGHalGrHamryHA==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.2.tgz", + "integrity": "sha512-UvB7mRqQjivdZNxJNEA2yOQRB7L9N43nBnKc33K47+cH90/ujmnMwatTCwQLu83gLhrzAl8fsa6Lqig/KLghaA==", "dependencies": { "@babel/runtime": "^7.22.5", "@restart/hooks": "^0.4.9", - "@restart/ui": "^1.6.6", + "@restart/ui": "^1.6.8", "@types/react-transition-group": "^4.4.6", "classnames": "^2.3.2", "dom-helpers": "^5.2.1", @@ -5934,9 +7313,9 @@ } }, "node_modules/react-bootstrap-icons": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/react-bootstrap-icons/-/react-bootstrap-icons-1.10.3.tgz", - "integrity": "sha512-j4hSby6gT9/enhl3ybB1tfr1slZNAYXDVntcRrmVjxB3//2WwqrzpESVqKhyayYVaWpEtnwf9wgUQ03cuziwrw==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/react-bootstrap-icons/-/react-bootstrap-icons-1.11.3.tgz", + "integrity": "sha512-f/DAy4UXnjdbaZyUcZKR2I3xim56uCznb9t+u3ojwzDG1p2RUrua/d8R4xplAQ8Bj/LVZwHVSrvO+npvp3l3pw==", "dependencies": { "prop-types": "^15.7.2" }, @@ -5956,6 +7335,11 @@ "react": "^18.2.0" } }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -5976,11 +7360,11 @@ } }, "node_modules/react-router": { - "version": "6.17.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.17.0.tgz", - "integrity": "sha512-YJR3OTJzi3zhqeJYADHANCGPUu9J+6fT5GLv82UWRGSxu6oJYCKVmxUcaBQuGm9udpWmPsvpme/CdHumqgsoaA==", + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz", + "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==", "dependencies": { - "@remix-run/router": "1.10.0" + "@remix-run/router": "1.15.3" }, "engines": { "node": ">=14.0.0" @@ -5990,12 +7374,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.17.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.17.0.tgz", - "integrity": "sha512-qWHkkbXQX+6li0COUUPKAUkxjNNqPJuiBd27dVwQGDNsuFBdMbrS6UZ0CLYc4CsbdLYTckn4oB4tGDuPZpPhaQ==", + "version": "6.22.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz", + "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==", "dependencies": { - "@remix-run/router": "1.10.0", - "react-router": "6.17.0" + "@remix-run/router": "1.15.3", + "react-router": "6.22.3" }, "engines": { "node": ">=14.0.0" @@ -6006,9 +7390,9 @@ } }, "node_modules/react-select": { - "version": "5.7.7", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.7.tgz", - "integrity": "sha512-HhashZZJDRlfF/AKj0a0Lnfs3sRdw/46VJIRd8IbB9/Ovr74+ZIwkAdSBjSPXsFMG+u72c5xShqwLSKIJllzqw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz", + "integrity": "sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==", "dependencies": { "@babel/runtime": "^7.12.0", "@emotion/cache": "^11.4.0", @@ -6065,20 +7449,42 @@ "node": ">=8" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -6148,18 +7554,34 @@ } }, "node_modules/rollup": { - "version": "3.27.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.27.2.tgz", - "integrity": "sha512-YGwmHf7h2oUHkVBT248x0yt6vZkYQ3/rvE5iQuVBh3WO8GcJ6BNeOkpoX1yMHIiBm18EMLjBPIoUDkhgnyxGOQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.13.0", + "@rollup/rollup-android-arm64": "4.13.0", + "@rollup/rollup-darwin-arm64": "4.13.0", + "@rollup/rollup-darwin-x64": "4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", + "@rollup/rollup-linux-arm64-gnu": "4.13.0", + "@rollup/rollup-linux-arm64-musl": "4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-musl": "4.13.0", + "@rollup/rollup-win32-arm64-msvc": "4.13.0", + "@rollup/rollup-win32-ia32-msvc": "4.13.0", + "@rollup/rollup-win32-x64-msvc": "4.13.0", "fsevents": "~2.3.2" } }, @@ -6192,6 +7614,41 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -6236,26 +7693,58 @@ } }, "node_modules/scroll-into-view-if-needed": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.0.10.tgz", - "integrity": "sha512-t44QCeDKAPf1mtQH3fYpWz8IM/DyvHLjs8wUvvwMYxk5moOqCzrMSxK6HQVD0QVmVjXFavoFIPRVrMuJPKAvtg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", + "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==", "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": ">=10" + "node": ">= 0.4" } }, "node_modules/shebang-command": { @@ -6280,14 +7769,18 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6299,6 +7792,18 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6317,9 +7822,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -6353,9 +7858,9 @@ "dev": true }, "node_modules/std-env": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz", - "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.6.0.tgz", + "integrity": "sha512-aFZ19IgVmhdB2uX599ve2kE6BIE3YMnQ6Gp6BURhW/oIzpXGKr878TQfAQZn1+i0Flcc/UKUy1gOlcfaUBCryg==", "dev": true }, "node_modules/stop-iteration-iterator": { @@ -6375,6 +7880,81 @@ "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -6387,6 +7967,27 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -6412,17 +8013,23 @@ } }, "node_modules/strip-literal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.0.1.tgz", - "integrity": "sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz", + "integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==", "dev": true, "dependencies": { - "acorn": "^8.8.2" + "js-tokens": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", + "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "dev": true + }, "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", @@ -6485,25 +8092,35 @@ "node": ">=12.22" } }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/tinybench": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", - "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", + "integrity": "sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==", "dev": true }, "node_modules/tinypool": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", - "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", + "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", "dev": true, "engines": { "node": ">=14.0.0" } }, "node_modules/tinyspy": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.0.tgz", - "integrity": "sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", "dev": true, "engines": { "node": ">=14.0.0" @@ -6534,6 +8151,11 @@ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, "node_modules/tough-cookie": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", @@ -6550,42 +8172,50 @@ } }, "node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", "dev": true, "dependencies": { - "punycode": "^2.3.0" + "punycode": "^2.3.1" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", + "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" } }, + "node_modules/ts-md5": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/ts-md5/-/ts-md5-1.3.1.tgz", + "integrity": "sha512-DiwiXfwvcTeZ5wCE0z+2A9EseZsztaiZtGrtSaY5JOD7ekPnR/GoIVD5gXZAlK9Na9Kvpo9Waz5rW64WKAWApg==", + "engines": { + "node": ">=12" + } + }, "node_modules/tsconfck": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-2.1.1.tgz", - "integrity": "sha512-ZPCkJBKASZBmBUNqGHmRhdhM8pJYDdOXp4nRgj/O0JwUwsMq50lCDRQP/M5GBNAA0elPrq4gAeu4dkaVCuKWww==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.3.tgz", + "integrity": "sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==", "dev": true, "bin": { "tsconfck": "bin/tsconfck.js" }, "engines": { - "node": "^14.13.1 || ^16 || >=18" + "node": "^18 || >=20" }, "peerDependencies": { - "typescript": "^4.3.5 || ^5.0.0" + "typescript": "^5.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -6593,6 +8223,35 @@ } } }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6626,10 +8285,83 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6640,11 +8372,26 @@ } }, "node_modules/ufo": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.1.tgz", - "integrity": "sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz", + "integrity": "sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==", "dev": true }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/uncontrollable": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", @@ -6743,43 +8490,49 @@ } }, "node_modules/v8-to-istanbul": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", - "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" + "convert-source-map": "^2.0.0" }, "engines": { "node": ">=10.12.0" } }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/vite": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", - "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.3.tgz", + "integrity": "sha512-+i1oagbvkVIhEy9TnEV+fgXsng13nZM90JQbrcPrf6DvW2mXARlz+DK7DLiDP+qeKoD1FCVx/1SpFL1CLq9Mhw==", "dev": true, "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "esbuild": "^0.20.1", + "postcss": "^8.4.36", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", @@ -6812,37 +8565,36 @@ } }, "node_modules/vite-node": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz", - "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz", + "integrity": "sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==", "dev": true, "dependencies": { "cac": "^6.7.14", "debug": "^4.3.4", - "mlly": "^1.4.0", "pathe": "^1.1.1", "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0" + "vite": "^5.0.0" }, "bin": { "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=v14.18.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/vite-tsconfig-paths": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.2.1.tgz", - "integrity": "sha512-GNUI6ZgPqT3oervkvzU+qtys83+75N/OuDaQl7HmOqFTb0pjZsuARrRipsyJhJ3enqV8beI1xhGbToR4o78nSQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz", + "integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==", "dev": true, "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", - "tsconfck": "^2.1.0" + "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" @@ -6854,59 +8606,56 @@ } }, "node_modules/vitest": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz", - "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz", + "integrity": "sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==", "dev": true, "dependencies": { - "@types/chai": "^4.3.5", - "@types/chai-subset": "^1.3.3", - "@types/node": "*", - "@vitest/expect": "0.34.6", - "@vitest/runner": "0.34.6", - "@vitest/snapshot": "0.34.6", - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", - "acorn": "^8.9.0", - "acorn-walk": "^8.2.0", - "cac": "^6.7.14", + "@vitest/expect": "1.4.0", + "@vitest/runner": "1.4.0", + "@vitest/snapshot": "1.4.0", + "@vitest/spy": "1.4.0", + "@vitest/utils": "1.4.0", + "acorn-walk": "^8.3.2", "chai": "^4.3.10", "debug": "^4.3.4", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.1", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", "pathe": "^1.1.1", "picocolors": "^1.0.0", - "std-env": "^3.3.3", - "strip-literal": "^1.0.1", - "tinybench": "^2.5.0", - "tinypool": "^0.7.0", - "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", - "vite-node": "0.34.6", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.2", + "vite": "^5.0.0", + "vite-node": "1.4.0", "why-is-node-running": "^2.2.2" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": ">=v14.18.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@vitest/browser": "*", - "@vitest/ui": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.4.0", + "@vitest/ui": "1.4.0", "happy-dom": "*", - "jsdom": "*", - "playwright": "*", - "safaridriver": "*", - "webdriverio": "*" + "jsdom": "*" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, + "@types/node": { + "optional": true + }, "@vitest/browser": { "optional": true }, @@ -6918,28 +8667,19 @@ }, "jsdom": { "optional": true - }, - "playwright": { - "optional": true - }, - "safaridriver": { - "optional": true - }, - "webdriverio": { - "optional": true } } }, "node_modules/w3c-xmlserializer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", - "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, "dependencies": { - "xml-name-validator": "^4.0.0" + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/warning": { @@ -6960,37 +8700,37 @@ } }, "node_modules/whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dev": true, "dependencies": { "iconv-lite": "0.6.3" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/whatwg-url": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", - "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", "dev": true, "dependencies": { - "tr46": "^4.1.1", + "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/which": { @@ -7024,6 +8764,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/which-collection": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", @@ -7040,17 +8806,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7082,9 +8847,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -7103,12 +8868,12 @@ } }, "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "dev": true, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/xmlchars": { @@ -7142,6 +8907,28 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yup": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.4.0.tgz", + "integrity": "sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/yup/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/vite-app/package.json b/vite-app/package.json index 62783427..9e576f96 100644 --- a/vite-app/package.json +++ b/vite-app/package.json @@ -1,5 +1,5 @@ { - "name": "vite-app", + "name": "kbase-ui", "private": true, "version": "0.0.0", "type": "module", @@ -11,45 +11,57 @@ "test": "vitest run --coverage " }, "dependencies": { - "@ant-design/icons": "5.2.6", - "antd": "5.10.2", - "bootstrap": "5.3.2", - "dompurify": "3.0.6", + "@ant-design/icons": "5.3.4", + "@fortawesome/fontawesome-svg-core": "6.5.1", + "@fortawesome/free-regular-svg-icons": "6.5.1", + "@fortawesome/free-solid-svg-icons": "6.5.1", + "@fortawesome/react-fontawesome": "0.2.0", + "antd": "5.15.3", + "bootstrap": "5.3.3", + "dompurify": "3.0.11", "es-cookie": "1.4.0", "font-awesome": "4.7.0", - "marked": "9.1.2", + "formik": "2.4.5", + "highlight.js": "11.9.0", + "marked": "12.0.1", "react": "18.2.0", - "react-bootstrap": "2.9.1", - "react-bootstrap-icons": "1.10.3", + "react-bootstrap": "2.10.2", + "react-bootstrap-icons": "1.11.3", "react-dom": "18.2.0", - "react-router-dom": "6.17.0", - "react-select": "5.7.7", - "uuid": "9.0.1" + "react-router-dom": "6.22.3", + "react-select": "5.8.0", + "ts-md5": "1.3.1", + "uuid": "9.0.1", + "yup": "1.4.0" }, "devDependencies": { "@kbase/ui-lib": "0.7.1", - "@testing-library/jest-dom": "6.1.4", - "@testing-library/react": "14.0.0", - "@testing-library/user-event": "14.5.1", - "@types/dompurify": "3.0.4", - "@types/jest": "29.5.6", - "@types/react": "18.2.32", - "@types/react-dom": "18.2.14", + "@testing-library/jest-dom": "6.4.2", + "@testing-library/react": "14.2.2", + "@testing-library/user-event": "14.5.2", + "@types/dompurify": "3.0.5", + "@types/jest": "29.5.12", + "@types/react": "18.2.69", + "@types/react-dom": "18.2.22", "@types/react-router-dom": "5.3.3", - "@types/uuid": "9.0.6", - "@typescript-eslint/eslint-plugin": "6.9.0", - "@typescript-eslint/parser": "6.9.0", - "@vitejs/plugin-react": "4.1.0", - "@vitest/coverage-v8": "0.34.6", - "eslint": "8.52.0", + "@types/uuid": "9.0.8", + "@typescript-eslint/eslint-plugin": "7.3.1", + "@typescript-eslint/parser": "7.3.1", + "@vitejs/plugin-react": "4.2.1", + "@vitest/coverage-v8": "1.4.0", + "eslint": "8.57.0", + "eslint-plugin-jsx-a11y": "6.8.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-react": "7.34.1", "eslint-plugin-react-hooks": "4.6.0", - "eslint-plugin-react-refresh": "0.4.3", - "jsdom": "22.1.0", - "prettier": "3.0.3", + "eslint-plugin-import": "2.29.1", + "eslint-plugin-react-refresh": "0.4.6", + "jsdom": "24.0.0", + "prettier": "3.2.5", "sass": "1.64.", - "typescript": "5.2.2", - "vite": "4.5.0", - "vite-tsconfig-paths": "4.2.1", - "vitest": "0.34.6" + "typescript": "5.4.3", + "vite": "5.2.3", + "vite-tsconfig-paths": "4.3.2", + "vitest": "1.4.0" } } \ No newline at end of file diff --git a/vite-app/public/data/__perf__/0b.txt b/vite-app/public/data/__perf__/0b.txt new file mode 100644 index 00000000..e69de29b diff --git a/vite-app/public/js/gtagSupport.js b/vite-app/public/js/gtagSupport.js deleted file mode 100644 index 9e78f0bb..00000000 --- a/vite-app/public/js/gtagSupport.js +++ /dev/null @@ -1,443 +0,0 @@ -/** - * Google Analytics (GA) app implementation - * - * The GA mechanism for sending data to the GA collection service - * consists of a very simple, small web app. - * - * Upon loading the primary kbase-ui SPA index.html page, an embedded - * script call to Google loads a GA app which loads necessary support - * files and begins to monitor a global variable "window.dataLayer". - * - * (Why Goggle didn't pick something namespaced to their app like - * GoogleDataLayer, or GoogleAnalyticsDataQueue, I don't know.) - * - * Then, when data is to be sent to GA for a page load (all that we use it for), - * this script below pushes (in the sense of "array push") the appropriate - * data in the appropriate format into the global data queue "dataLayer". - * - * On the next polling call, the GA app pulls the data off the queue and sends it - * to the GA collection service. - * - * Quite straightforward. - * - * Now for our implementation. - * - * First, there is no good reason for the code to be in a standalone file, afaik, - * and it is a bit complicated by the fact that it has to replicate functionality - * in kbase-ui, but here it is. - * - * The script has the general task of sending, for the initial page load and every - * subsequent navigation, the: - * - current url - * - current page path - * - current page title - * - username if there is a valid kbase auth token - * - * There a few complications in this otherwise relatively straightforward task. - * - * Since this script is independent of kbase-ui, it must be configured manually, - * including the auth token name, urls, Google GA ids, and other. - * - * Fetching the username requires a call to the auth service. Since this - * script is independent of kbase-ui, it must perform this logic separately. - * To prevent calling the auth service with every navigation, the token is - * cached for 10 minutes. - * - * The page title is not available until the view code associated with the page load - * or navigation has run and determined and set the title. In other words, it is - * asynchronous, and may take even up to a few seconds. To accommodate this fact, - * the script will monitor the page title and only set the GA data when the title - * has been stable for some period of time (TITLE_STABILIZATION_PERIOD). If navigation - * occurs before the title has stabilized, the GA data is sent anyway - * - * References: - * https://developers.google.com/tag-platform/gtagjs/reference - * https://developers.google.com/analytics/devguides/collection/gtagjs/single-page-applications#measure_virtual_pageviews - */ - -function main() { - // Configuration - // These should be in a separate configuration, but, to be honest, some of these values have never changed, and others, - // like the Google tags, only every few years. - const SESSION_COOKIE_NAME = 'kbase_session'; - const PROD_UI_ORIGIN = 'https://narrative.kbase.us'; - const PROD_SERVICE_ORIGIN = 'https://kbase.us'; - const GOOGLE_GTAG = 'G-KXZCE6YQFZ'; - const GOOGLE_AD_TAG = 'AW-753507180'; - - // The sending of the page hit is delayed until the page title stops change for the duration - // set here. - const TITLE_STABILIZATION_PERIOD = 3000; - - // Keep the auth token cached for up to 10 minutes. - const KBASE_AUTH_TOKEN_TTL = 600000; - let KBASE_AUTH_INFO_EXPIRES_AT = null; - let KBASE_AUTH_INFO = null; - let KBASE_AUTH_TOKEN = null; - - /** - * GTag processing states. - * - * Due to the asynchronous nature of loading page titles, and generally the fact that this code - * runs independently of the kbase-ui, which is of course asynchronous in nature, we use a - * little state model to manage this. - * - */ - const WAITING = 'WAITING'; - const PENDING = 'PENDING'; - const SEND_NOW = 'SEND_NOW'; - const SENDING = 'SENDING'; - let GTAG_STATE = WAITING; - - // Simply ensures that the data layer exists. - window.dataLayer = window.dataLayer || []; - - /** - * Sets a new status value, which should be one of WAITING, PENDING, SEND_NOW, or SENDING. - * - * @param {string} newState The new value for the gtag support status - */ - function setState(newState) { - GTAG_STATE = newState; - } - - /** - * Simply compares the provided value to the current status value, returning whether they are the same. - * - * @param {string} state - * @returns {boolean} Whether the provided value is the same as the current status - */ - function isState(state) { - return GTAG_STATE === state; - } - - /** - * Returns a promise that does not resolve until the given status is active. - * - * - * @param {*} status A status value, as defined above: WAITING, PENDING, SEND_NOW, SENDING - * @returns {Promise} A Promise with no important value - */ - // TODO there should be a timeout - async function waitUntilStatus(status, timeout) { - const started = Date.now(); - const timeoutAfter = started + timeout; - return new Promise((resolve) => { - const loop = () => { - if (Date.now() >= timeoutAfter) { - throw new Error(`Timed out after ${Date.now() - started}`); - } - window.setTimeout(() => { - if (isState(status)) { - loop(); - } - resolve(); - }, 100); - }; - loop(); - }); - } - - /** - * Returns the KBase service origin. - * - * In all but production, the service origin is the same as the document origin - * for the ui. In production, the ui origin is https://narrative.kbase.us but the - * service origin is https://kbase.us - this adjustment is made. - * - * @returns {string} The KBase service "origin" (protocol and hostname, e.g. https://ci.kbase.us) - */ - function getServiceOrigin() { - if (document.location.origin === PROD_UI_ORIGIN) { - return PROD_SERVICE_ORIGIN; - } - return document.location.origin; - } - - /** - * The canonical function name for queuing messages for the Google gtag app. - * - * Note that the function relies up on the usage of the magic "arguments" variable - * provided to all functions. - * - * @returns {void} - Nothing - */ - function pushGTag() { - //developers.google.com/tag-platform/tag-manager/datalayer - window.dataLayer.push(arguments); - } - - /** - * Get and return the current hash path as a path with a leading - * forward slash (/). - * - * Note that this code is could be a one-liner but for the fact that - * some usages of kbase-ui hash-paths place the search query string - * on the hash itself. - * - * @returns {string} - The current navigation path in kbase-ui - */ - function getHashPath() { - const hash = document.location.hash; - let path; - if (hash) { - const m = hash.match(/#[/]?([^?]*)/); - if (m) { - path = m[1]; - } else { - path = ''; - } - } else { - path = ''; - } - return `/${path}`; - } - - /** - * Find KBase auth token from document cookie. - * - * If a token is not found in the cookie, null is returned. - * - * @returns {string|null} A KBase auth token, if any, stored in the browser. - */ - function getToken() { - if (!document.cookie) { - return null; - } - const cookies = document.cookie.split(';').map((item) => { - return item.trim(); - }); - - for (const cookie of cookies) { - const [name, value] = cookie.split('='); - if (name === SESSION_COOKIE_NAME) { - return value; - } - } - return null; - } - - /** - * Returns the username associated with the given KBase auth token. - * - * If there is no token, or an error is encountered interacting with - * the auth service, null is returned. - * - * @param {string} token - KBase auth token - * @returns {string|null} - A kbase username - */ - async function fetchAuth(token) { - if ( - KBASE_AUTH_INFO !== null && - KBASE_AUTH_INFO_EXPIRES_AT > Date.now() && - token === KBASE_AUTH_TOKEN - ) { - return KBASE_AUTH_INFO.user; - } - KBASE_AUTH_TOKEN = token; - const url = `${getServiceOrigin()}/services/auth/api/V2/me`; - try { - const response = await fetch(url, { - method: 'GET', - mode: 'cors', - headers: { - 'Content-Type': 'application/json', - Authorization: token, - }, - }); - if (response.status !== 200) { - console.warn('[gtagSupport] bad auth response, user not available', response); - return null; - } - KBASE_AUTH_INFO = await response.json(); - KBASE_AUTH_INFO_EXPIRES_AT = Date.now() + KBASE_AUTH_TOKEN_TTL; - return KBASE_AUTH_INFO; - } catch (error) { - console.error('[gtagSupport] error occurred in call to auth service', error); - return null; - } - } - - /** - * Get the username associated with the current KBase auth token. - * - * If there is no valid KBase auth token available, or an error is - * encountered with the auth service call, null is returned instead. - * - * - * @returns {string|null} username - */ - async function getAuth() { - const token = getToken(); - if (token) { - try { - const auth = fetchAuth(token); - if (auth) { - return auth; - } - } catch (ex) { - console.error('[gtagSupport] Error fetching username', ex); - } - } - KBASE_AUTH_INFO = null; - KBASE_AUTH_TOKEN = null; - return null; - } - - /** - * - * - * @returns {void} - Nothing - */ - async function sendGTag() { - setState(SENDING); - - // The "path" for a view in the ui is determined by - // the url hash. This will change one day. - const path = getHashPath(); - - // Simply ensures that the data layer exists. The data layer - // is just an array placed into a "dataLayer" property on the global - // window. Nothing special about the name "dataLayer", other than that - // is where the google scripts expect to see - window.dataLayer = window.dataLayer || []; - - // See google docs for the api and field definitions. - // E.g. https://developers.google.com/analytics/devguides/collection/gtagjs/pages - // Queue up date for GA - const pageView = { - page_location: document.location.href, - page_path: path, - page_title: LAST_PAGE_TITLE, - }; - - const auth = await getAuth(); - if (auth) { - pageView.user_id = auth.anonid; - } - - pushGTag('event', 'page_view', pageView); - - setState(WAITING); - } - - /** - * The ever-popular "sleep" function, which returns a promise that resolves with the given period of time elapsed. - * - * @param {number} until The amount of time, in milliseconds, after which the promise should resolve. - * @returns {Promise} - */ - async function sleep(until) { - return new Promise((resolve) => { - window.setTimeout(() => { - resolve(); - }, until); - }); - } - - /** - * Ensures that if the next page hit is being sent, if the current one has not yet - * been sent, that it send immediately. - * - * Remember, that upon initiating a gtag request, we first wait for the page title - * to stabilize, and then the gtag event is registered. So if a new navigation event - * occurs during the waiting period, this function will be called in order to just - * send the gtag event even if the page title is not yet stabilized. - * - * @returns {Promise} - */ - async function sendPendingGTag() { - if (isState(PENDING)) { - // Here we set the status to SEND_NOW, which causes the loop monitoring the - // page title to terminate, which returns a promise, and causes the gtag - // event to be pushed. - setState(SEND_NOW); - - // And here we wait until the message is sent and we are back in the WAITING state. - // This should be sent very quickly, so a 2 second timeout should be plenty. - return await waitUntilStatus(WAITING, 2000); - } - } - - // Stores the current page title, which is really the last one recorded - // in the async loop below. - let LAST_PAGE_TITLE = null; - - /** - * When called, will return a Promise that will only resolve when the page title - * has not changed for some amount of time. - * - * This amount of time is set at top of the file as TITLE_STABILIZATION_PERIOD), but - * should be on the order of 2-3 seconds. - * - * @returns {Promise} - */ - - async function sendGTagAfterTitleSettles() { - setState(PENDING); - - let lastChanged = Date.now(); - LAST_PAGE_TITLE = document.title; - - // This is where we "wait" for the page title to stabilize, - // i.e. stop changing. - const loop = async () => { - if (isState(SEND_NOW)) { - return; - } - const now = Date.now(); - if (now >= lastChanged + TITLE_STABILIZATION_PERIOD) { - return; - } - if (document.title !== LAST_PAGE_TITLE) { - lastChanged = Date.now(); - LAST_PAGE_TITLE = document.title; - } - await sleep(100); - await loop(); - }; - await loop(); - - // And ... finally we trigger the pushing up data for gtag. - sendGTag(); - - // This signals that the status of this little gtag engine - // is waiting for a navigation event. - setState(WAITING); - } - - /** - * Send a ping to GA whenever the history state changes, i.e., url navigation - */ - window.onpopstate = async () => { - await sendPendingGTag(); - sendGTagAfterTitleSettles(); - }; - - /** - * Sets up gtag support to a known state, and sets up some gtag data that - * will not change over this session. - */ - function initialize() { - setState(WAITING); - pushGTag('js', new Date()); - pushGTag('config', GOOGLE_GTAG, { - send_page_view: false, - }); - pushGTag('config', GOOGLE_AD_TAG, { - send_page_view: false, - }); - } - - /** - * Initializes the state, and schedules the first page hit to be sent to GA. - * - * After this, navigation triggers the page hit. - */ - window.addEventListener('load', () => { - initialize(); - sendGTagAfterTitleSettles(); - }); -} - -main(); diff --git a/vite-app/src/applets/about/AboutBuild/AboutBuild.tsx b/vite-app/src/applets/about/AboutBuild/AboutBuild.tsx index 9dbd5653..e5e017d9 100644 --- a/vite-app/src/applets/about/AboutBuild/AboutBuild.tsx +++ b/vite-app/src/applets/about/AboutBuild/AboutBuild.tsx @@ -6,13 +6,9 @@ export interface AboutBuildProps { buildInfo: BuildInfo; } -interface AboutBuildState { } - export default class AboutBuild extends Component< - AboutBuildProps, - AboutBuildState + AboutBuildProps > { - renderCommit() { return ( diff --git a/vite-app/src/applets/about/AboutBuild/index.tsx b/vite-app/src/applets/about/AboutBuild/index.tsx index afb883f5..e07a992d 100644 --- a/vite-app/src/applets/about/AboutBuild/index.tsx +++ b/vite-app/src/applets/about/AboutBuild/index.tsx @@ -1,6 +1,6 @@ import { Component } from 'react'; import Loading from '../../../components/Loading'; -import { ConfigState, ConfigContext } from '../../../contexts/ConfigContext'; +import { ConfigContext, ConfigState } from '../../../contexts/ConfigContext'; import { AsyncProcessStatus } from '../../../lib/AsyncProcess2'; import AboutBuild from './AboutBuild'; @@ -32,9 +32,9 @@ export default class AboutBuildWrapper extends Component< case AsyncProcessStatus.SUCCESS: this.props.setTitle('About the kbase-ui build'); return + buildInfo={configValue.value.buildInfo} + gitInfo={configValue.value.gitInfo} + /> } }} diff --git a/vite-app/src/applets/about/AboutCoreServices.tsx b/vite-app/src/applets/about/AboutCoreServices.tsx index 675f85fc..e4e049e1 100644 --- a/vite-app/src/applets/about/AboutCoreServices.tsx +++ b/vite-app/src/applets/about/AboutCoreServices.tsx @@ -1,5 +1,5 @@ import { Component } from 'react'; -import { AuthenticationState } from '../../contexts/Auth'; +import { AuthenticationState } from '../../contexts/EuropaContext'; import { Config } from '../../types/config'; import AboutService from './AboutService/AboutServiceMain'; import { SERVICES } from './ServiceDescription'; diff --git a/vite-app/src/applets/about/AboutKBaseUI/AboutKBaseUI.tsx b/vite-app/src/applets/about/AboutKBaseUI/AboutKBaseUI.tsx index 0ac4d8bb..f8d750b4 100644 --- a/vite-app/src/applets/about/AboutKBaseUI/AboutKBaseUI.tsx +++ b/vite-app/src/applets/about/AboutKBaseUI/AboutKBaseUI.tsx @@ -1,296 +1,222 @@ +import UILink from 'components/UILink2'; import { Component } from 'react'; import { Config } from '../../../types/config'; import { BuildInfo, GitInfo } from '../../../types/info'; export interface AboutKBaseUIProps { - config: Config; - gitInfo: GitInfo; - buildInfo: BuildInfo; + config: Config; + gitInfo: GitInfo; + buildInfo: BuildInfo; + uiURL: (path: string, params?: Record) => URL; } -interface AboutKBaseUIState { } - -export default class AboutKBaseUI extends Component< - AboutKBaseUIProps, - AboutKBaseUIState -> { - renderHub() { - return ( - - KBase UI - - ); - } - - renderWelcome() { - // const docSiteUrl = this.props.config.ui.urls. - return ( -
    -

    - You are currently using the KBase User Interface (UI), a - collection of tools for KBase Users and Developers. -

    -

    - The UI is one of three primary web-based tools which - comprise KBase: -

    -
      -
    • - The{' '} - - Narrative Interface - - , a tool for creating, editing, running and publishing - active scientific documents called Narratives. New to - the Narrative? Perhaps you would like to check out the{' '} - - Narrative Interface User Guide - - . -
    • -
    • - The{' '} - - Documentation Site - - , which provides tutorials and developer documentation, - communications and publications, links to social media - outlets, developer documentation, and background on - KBase. -
    • -
    • - The UI, which provides login, account management, - dashboard, catalog, data object viewing, and search - services. -
    • -
    -
    - ); - } - - renderGitInfo(): [JSX.Element, string, string] { - const gitInfo = this.props.gitInfo; - - let repoUrl = gitInfo.originURL; // 'https://github.com/kbase/kbase-ui'; - const hash = gitInfo.hash.full; - if (/^ssh:/.test(repoUrl)) { - const m = /^ssh:\/\/git@(.*?)\/(.*?)$/.exec(repoUrl); - if (m) { - repoUrl = 'https://' + m[1] + '/' + m[2]; - } - } - - const commitHash = gitInfo.hash.full - - let relNotesUrl; - let githubUrl; - if (gitInfo.tag) { - relNotesUrl = [ - repoUrl, - 'blob', - hash, - 'release-notes', - 'RELEASE_NOTES_' + gitInfo.version + '.md', - ].join('/'); - githubUrl = [repoUrl, 'tree', gitInfo.tag].join('/'); - - return [ -

    - You are currently using version{' '} - - {gitInfo.version} - {' '} - of {this.renderHub()}. -

    , - githubUrl, - relNotesUrl, - ]; - } else { - relNotesUrl = [ - repoUrl, - 'blob', - hash, - 'release-notes', - 'index.md', - ].join('/'); - githubUrl = [repoUrl, 'tree', hash].join('/'); - return [ -

    - This build is not located at a tagged commit. The current - commit is{' '} - - {commitHash} - - . -

    , - githubUrl, - relNotesUrl, - ]; - } - } - - - renderVersionInfo() { - const buildInfo = this.props.buildInfo; - - const buildDate = new Date(buildInfo.builtAt); - - const buildDateString = Intl.DateTimeFormat('en-US', { - year: 'numeric', - month: 'long', - day: 'numeric', - }).format(buildDate); - - const buildTimeString = Intl.DateTimeFormat('en-US', { - hour: 'numeric', - minute: 'numeric', - second: 'numeric', - timeZoneName: 'short', - }).format(buildDate); - - const contactUrl = this.props.config.ui.urls.contact.url; - - const aboutKBase = this.props.config.ui.urls.aboutKBase.url; - - const uiDocumentationUrl = - 'http://kbaseincubator.github.io/kbase-ui-docs'; - const documentationURL = this.props.config.ui.urls.documentation.url; - - const [githubContent, githubUrl, relNotesUrl] = this.renderGitInfo(); - - const kbaseGithubOrgURL = 'https://github.com/kbase'; - - return ( -
    - {githubContent} -

    - It was built on {buildDateString} at {buildTimeString}. -

    -

    You may also be interested in:

    - -
    - ); +export default class AboutKBaseUI extends Component { + renderHub() { + return ( + + KBase UI + + ); + } + + renderWelcome() { + return ( +
    +

    + You are currently using the KBase User Interface (UI), a collection of tools for KBase Users and Developers. +

    +

    The UI is one of three primary web-based tools which comprise KBase:

    +
      +
    • + The{' '} + + NarrativeInterface + + , a tool for creating, editing, running and publishing active scientific documents called Narratives. New to + the Narrative? Perhaps you would like to check out the{' '} + + Narrative Interface User Guide + + . +
    • +
    • + The{' '} + + Documentation Site + + , which provides tutorials and developer documentation, communications and publications, links to social + media outlets, developer documentation, and background on KBase. +
    • +
    • + The UI, which provides login, account management, dashboard, catalog, data object viewing, and search + services. +
    • +
    +
    + ); + } + + renderGitInfo(): [JSX.Element, string, string] { + const gitInfo = this.props.gitInfo; + + let repoUrl = gitInfo.originURL; + const hash = gitInfo.hash.full; + if (/^ssh:/.test(repoUrl)) { + const m = /^ssh:\/\/git@(.*?)\/(.*?)$/.exec(repoUrl); + if (m) { + repoUrl = 'https://' + m[1] + '/' + m[2]; + } } - render() { - return ( -
    -
    -
    -

    The KBase User Interface

    - {this.renderWelcome()} -
    -
    -

    This Version

    - {this.renderVersionInfo()} -
    -
    -
    - ); + const commitHash = gitInfo.hash.full; + + let relNotesUrl; + let githubUrl; + if (gitInfo.tag) { + relNotesUrl = [repoUrl, 'blob', hash, 'release-notes', 'RELEASE_NOTES_' + gitInfo.version + '.md'].join('/'); + githubUrl = [repoUrl, 'tree', gitInfo.tag].join('/'); + + return [ +

    + You are currently using version{' '} + + {gitInfo.version} + {' '} + of {this.renderHub()}. +

    , + githubUrl, + relNotesUrl, + ]; + } else { + relNotesUrl = [repoUrl, 'blob', hash, 'release-notes', 'index.md'].join('/'); + githubUrl = [repoUrl, 'tree', hash].join('/'); + return [ +

    + This build is not located at a tagged commit. The current commit is{' '} + + {commitHash} + + . +

    , + githubUrl, + relNotesUrl, + ]; } + } + + renderVersionInfo() { + const buildInfo = this.props.buildInfo; + + const buildDate = new Date(buildInfo.builtAt); + + const buildDateString = Intl.DateTimeFormat('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + }).format(buildDate); + + const buildTimeString = Intl.DateTimeFormat('en-US', { + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + timeZoneName: 'short', + }).format(buildDate); + + const contactUrl = this.props.config.ui.urls.contact.url; + + const aboutKBase = this.props.config.ui.urls.aboutKBase.url; + + const uiDocumentationUrl = 'http://kbaseincubator.github.io/kbase-ui-docs'; + const documentationURL = this.props.config.ui.urls.documentation.url; + + const [githubContent, githubUrl, relNotesUrl] = this.renderGitInfo(); + + const kbaseGithubOrgURL = 'https://github.com/kbase'; + + return ( +
    + {githubContent} +

    + It was built on {buildDateString} at {buildTimeString}. +

    +

    You may also be interested in:

    + +
    + ); + } + + render() { + return ( +
    +
    +
    +

    The KBase User Interface

    + {this.renderWelcome()} +
    +
    +

    This Version

    + {this.renderVersionInfo()} +
    +
    +
    + ); + } } diff --git a/vite-app/src/applets/about/AboutKBaseUI/index.tsx b/vite-app/src/applets/about/AboutKBaseUI/index.tsx index 3710c3ee..b3282e9c 100644 --- a/vite-app/src/applets/about/AboutKBaseUI/index.tsx +++ b/vite-app/src/applets/about/AboutKBaseUI/index.tsx @@ -1,6 +1,6 @@ import { Component } from 'react'; import Loading from '../../../components/Loading'; -import { ConfigState, ConfigContext } from '../../../contexts/ConfigContext'; +import { ConfigContext, ConfigState } from '../../../contexts/ConfigContext'; import { AsyncProcessStatus } from '../../../lib/AsyncProcess2'; import AboutKBaseUI from './AboutKBaseUI'; @@ -8,11 +8,8 @@ export interface AboutBuildWrapperProps { setTitle: (title: string) => void; } -interface AboutBuildWrapperState { } - export default class AboutBuildWrapper extends Component< - AboutBuildWrapperProps, - AboutBuildWrapperState + AboutBuildWrapperProps > { componentDidMount() { this.props.setTitle('About the KBase User Interface'); @@ -37,6 +34,7 @@ export default class AboutBuildWrapper extends Component< config={configValue.value.config} gitInfo={configValue.value.gitInfo} buildInfo={configValue.value.buildInfo} + uiURL={configValue.value.uiURL} /> } }} diff --git a/vite-app/src/applets/about/AboutMenu.tsx b/vite-app/src/applets/about/AboutMenu.tsx new file mode 100644 index 00000000..19848639 --- /dev/null +++ b/vite-app/src/applets/about/AboutMenu.tsx @@ -0,0 +1,43 @@ +import { navigate2 } from "lib/navigation"; +import { Component } from "react"; +import { Nav } from "react-bootstrap"; + +export interface AboutMenuProps { + tab: string; +} + +export default class AboutMenu extends Component { + onSelect(eventKey: string | null) { + navigate2({type: 'kbaseui', path: `about/${eventKey || 'kbase-ui'}`}); + } + + render() { + return
    +
    About
    + +
    + } +} diff --git a/vite-app/src/applets/about/AboutPlugins/AboutPlugins.tsx b/vite-app/src/applets/about/AboutPlugins/AboutPlugins.tsx index 29a2a7d8..89324891 100644 --- a/vite-app/src/applets/about/AboutPlugins/AboutPlugins.tsx +++ b/vite-app/src/applets/about/AboutPlugins/AboutPlugins.tsx @@ -1,18 +1,16 @@ +import Well from 'components/Well'; import { Component } from 'react'; import DataBrowser, { ColumnDef } from '../../../components/DataBrowser'; -import { PluginsInfo, PluginInfo } from '../../../types/info'; +import { PluginInfo, PluginsInfo } from '../../../types/info'; export interface AboutPluginsProps { pluginsInfo: PluginsInfo; } -interface AboutPluginsState { } - export default class AboutPlugins extends Component< - AboutPluginsProps, - AboutPluginsState + AboutPluginsProps > { renderPlugins() { const columns: Array> = [ @@ -102,10 +100,10 @@ export default class AboutPlugins extends Component< } render() { - return
    -
    + return + {this.renderPlugins()} -
    -
    ; + + ; } } diff --git a/vite-app/src/applets/about/AboutPlugins/index.tsx b/vite-app/src/applets/about/AboutPlugins/index.tsx index ab2574f6..ab0f1b0b 100644 --- a/vite-app/src/applets/about/AboutPlugins/index.tsx +++ b/vite-app/src/applets/about/AboutPlugins/index.tsx @@ -1,6 +1,6 @@ import { Component } from 'react'; import Loading from '../../../components/Loading'; -import { ConfigState, ConfigContext } from '../../../contexts/ConfigContext'; +import { ConfigContext, ConfigState } from '../../../contexts/ConfigContext'; import { AsyncProcessStatus } from '../../../lib/AsyncProcess2'; import AboutPlugins from './AboutPlugins'; @@ -8,11 +8,8 @@ export interface AboutBuildWrapperProps { setTitle: (title: string) => void; } -interface AboutBuildWrapperState { } - export default class AboutBuildWrapper extends Component< - AboutBuildWrapperProps, - AboutBuildWrapperState + AboutBuildWrapperProps > { componentDidMount() { this.props.setTitle('About kbase-ui Plugins'); diff --git a/vite-app/src/applets/about/AboutService/AboutService.tsx b/vite-app/src/applets/about/AboutService/AboutService.tsx index 808acb62..27d208ed 100644 --- a/vite-app/src/applets/about/AboutService/AboutService.tsx +++ b/vite-app/src/applets/about/AboutService/AboutService.tsx @@ -6,11 +6,8 @@ export interface AboutServiceProps { average: number; } -interface AboutServiceState {} - export default class AboutService extends Component< - AboutServiceProps, - AboutServiceState + AboutServiceProps > { render() { return ( diff --git a/vite-app/src/applets/about/AboutService/AboutServiceMain.tsx b/vite-app/src/applets/about/AboutService/AboutServiceMain.tsx index 496abb4b..38712e56 100644 --- a/vite-app/src/applets/about/AboutService/AboutServiceMain.tsx +++ b/vite-app/src/applets/about/AboutService/AboutServiceMain.tsx @@ -1,4 +1,5 @@ import { isJSONObject, traverse } from 'lib/json'; +import { resultOrThrow } from 'lib/kb_lib/comm/JSONRPC20/JSONRPC20'; import { Component } from 'react'; import ErrorAlert from '../../../components/ErrorAlert'; import Loading from '../../../components/Loading'; @@ -45,14 +46,8 @@ export default class AboutServiceMain extends Component< AboutServiceMainProps, AboutServiceMainState > { - // method : string; constructor(props: AboutServiceMainProps) { super(props); - // const method = props.service.statusMethod || props.service.versionMethod; - // if (typeof method === 'undefined') { - // throw new Error('Neither status nor version method provided') - // } - // this.method = method; this.state = { load: { status: AsyncProcessStatus.NONE, @@ -152,7 +147,9 @@ export default class AboutServiceMain extends Component< prefix: false, }); return async () => { - const result = await client.callFunc(service.method); + const response = await client.callFunc(service.method); + const result = resultOrThrow(response); + console.log('WEll, weLL', result); if (service.versionKey) { if (isJSONObject(result)) { const result2 = traverse(result, service.versionKey); diff --git a/vite-app/src/applets/about/AboutServices.tsx b/vite-app/src/applets/about/AboutServices.tsx index 00801522..76228af9 100644 --- a/vite-app/src/applets/about/AboutServices.tsx +++ b/vite-app/src/applets/about/AboutServices.tsx @@ -1,25 +1,241 @@ +import Well from 'components/Well'; +import { NA } from 'components/helpers'; +import { SimpleError } from 'lib/SimpleError'; import { Component } from 'react'; -import { AuthenticationState } from '../../contexts/Auth'; +import DataBrowser, { ColumnDef } from '../../components/DataBrowser'; +import ErrorAlert from '../../components/ErrorAlert'; +import Loading from '../../components/Loading'; +import { AuthenticationState } from '../../contexts/EuropaContext'; +import { AsyncProcess, AsyncProcessStatus } from '../../lib/AsyncProcess'; import { Config } from '../../types/config'; -import AboutCoreServices from './AboutCoreServices'; +import { SERVICES, ServiceDescription } from './ServiceDescription'; +import ServicePerformance, { PerformanceMeasurementsStatus } from './ServicePerformance'; -export interface AboutKBaseUIProps { +const ITERATIONS = 5; + +export interface AboutServicesProps { config: Config; setTitle: (title: string) => void; authState: AuthenticationState; } -interface AboutKBaseUIState { } +export enum ServiceMeasurementSummaryStatus { + OK = 'OK', + ERROR = 'ERROR' +} + +export interface ServiceMeasurementSummaryBase { + status: ServiceMeasurementSummaryStatus + description: ServiceDescription; +} -export default class AboutKBaseUI extends Component< - AboutKBaseUIProps, - AboutKBaseUIState +export interface ServiceMeasurementSummaryOK extends ServiceMeasurementSummaryBase { + status: ServiceMeasurementSummaryStatus.OK, + version: string; + average: number; + measures: Array; +} + +export interface ServiceMeasurementSummaryError extends ServiceMeasurementSummaryBase { + status: ServiceMeasurementSummaryStatus.ERROR + message: string; +} + +export type ServiceMeasurementSummary = ServiceMeasurementSummaryOK | ServiceMeasurementSummaryError; + +interface AboutServicesState { + loadState: AsyncProcess, SimpleError> +} + +export default class AboutServices extends Component< + AboutServicesProps, + AboutServicesState > { + constructor(props: AboutServicesProps) { + super(props); + this.state = { + loadState: { + status: AsyncProcessStatus.NONE + } + } + } + componentDidMount() { this.props.setTitle('About KBase Core Services'); + + this.performMeasurements(); + } + + async performMeasurements() { + try { + const measurements: Array = await Promise.all(SERVICES.map(async (service) => { + const measurer = new ServicePerformance({ + config: this.props.config, + service, + iterations: ITERATIONS + }); + const result = await measurer.measure(); + switch (result.status) { + case PerformanceMeasurementsStatus.SUCCESS: { + const {version, measurements } = result; + return { + status: ServiceMeasurementSummaryStatus.OK, + description: service, + version, + ...measurements + } + } + case PerformanceMeasurementsStatus.ERROR: + return { + status: ServiceMeasurementSummaryStatus.ERROR, + description: service, + message: result.message + } + } + })); + this.setState({ + loadState: { + status: AsyncProcessStatus.SUCCESS, + value: measurements + } + }) + + } catch (ex) { + this.setState({ + loadState: { + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown error' + } + } + }); + } + } + + renderServices(services: Array) { + const columns: Array> = [ + { + id: 'module', + label: 'Module', + style: {}, + render: (service: ServiceMeasurementSummary) => { + // TODO: should manage to get the service's git url + return {service.description.module}; + }, + sorter: (a: ServiceMeasurementSummary, b: ServiceMeasurementSummary) => { + return a.description.module.localeCompare(b.description.module); + }, + }, + { + id: 'version', + label: 'Version', + style: {}, + render: (service: ServiceMeasurementSummary) => { + if (service.status === ServiceMeasurementSummaryStatus.ERROR) { + return
    {service.message}
    ; + } + return {service.version}; + }, + sorter: (a: ServiceMeasurementSummary, b: ServiceMeasurementSummary) => { + if (a.status === ServiceMeasurementSummaryStatus.ERROR) { + if (b.status === ServiceMeasurementSummaryStatus.ERROR) { + return 0; + } else { + return -1; + } + } else { + if (b.status === ServiceMeasurementSummaryStatus.ERROR) { + return 1; + } else { + return a.version.localeCompare(b.version); + } + } + }, + }, + { + id: 'type', + label: 'Type', + style: {}, + render: (service: ServiceMeasurementSummary) => { + return {service.description.type}; + }, + sorter: (a: ServiceMeasurementSummary, b: ServiceMeasurementSummary) => { + return a.description.type.localeCompare(b.description.type); + }, + }, + { + id: 'perf', + label: 'Perf (ms/call)', + style: {}, + render: (service: ServiceMeasurementSummary) => { + if (service.status === ServiceMeasurementSummaryStatus.ERROR) { + return NA(); + } + return {Intl.NumberFormat('en-US', { + useGrouping: true, + minimumFractionDigits: 1, + maximumFractionDigits: 1, + }).format(service.average)}; + }, + sorter: (a: ServiceMeasurementSummary, b: ServiceMeasurementSummary) => { + if (a.status === ServiceMeasurementSummaryStatus.ERROR) { + if (b.status === ServiceMeasurementSummaryStatus.ERROR) { + return 0; + } else { + return -1; + } + } else { + if (b.status === ServiceMeasurementSummaryStatus.ERROR) { + return 1; + } else { + return a.average - b.average; + } + } + }, + } + ]; + + return ( + + ); + } + + renderLoading() { + return ( + + ); + } + + renderError({message}: SimpleError) { + return ; + } + + renderState() { + switch (this.state.loadState.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return this.renderLoading(); + case AsyncProcessStatus.ERROR: + return this.renderError(this.state.loadState.error); + case AsyncProcessStatus.SUCCESS: + return this.renderServices(this.state.loadState.value); + } } render() { - return ; + const stretch = this.state.loadState.status === AsyncProcessStatus.SUCCESS; + return + + {this.renderState()} + + } } diff --git a/vite-app/src/applets/about/AboutServices2.tsx b/vite-app/src/applets/about/AboutServices2.tsx deleted file mode 100644 index b21858a2..00000000 --- a/vite-app/src/applets/about/AboutServices2.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { Component } from 'react'; -import DataBrowser, { ColumnDef } from '../../components/DataBrowser'; -import ErrorAlert from '../../components/ErrorAlert'; -import Loading from '../../components/Loading'; -import { AuthenticationState } from '../../contexts/Auth'; -import { AsyncProcess, AsyncProcessError, AsyncProcessStatus } from '../../lib/AsyncProcess'; -import { Config } from '../../types/config'; -import { SERVICES, ServiceDescription } from './ServiceDescription'; -import ServicePerformance from './ServicePerformance'; - -const ITERATIONS = 5; - -export interface AboutServicesProps { - config: Config; - setTitle: (title: string) => void; - authState: AuthenticationState; -} - -export interface ServiceDescriptionWithPerformance { - description: ServiceDescription; - version: string; - average: number; - measures: Array; -} - -interface AboutServicesState { - loadState: AsyncProcess, string> -} - -export default class AboutServices extends Component< - AboutServicesProps, - AboutServicesState -> { - - constructor(props: AboutServicesProps) { - super(props); - this.state = { - loadState: { - status: AsyncProcessStatus.NONE - } - } - } - componentDidMount() { - this.props.setTitle('About KBase Core Services'); - this.performMeasurements(); - } - - async performMeasurements() { - const measurements = await Promise.all(SERVICES.map(async (service) => { - const measurer = new ServicePerformance({ - config: this.props.config, - service, - iterations: ITERATIONS - }); - const [version, measurement] = await measurer.measure(); - return { - description: service, - version, - ...measurement - } - })); - this.setState({ - loadState: { - status: AsyncProcessStatus.SUCCESS, - value: measurements - } - }); - } - - renderServices(services: Array) { - const columns: Array> = [ - { - id: 'module', - label: 'Module', - style: {}, - render: (service: ServiceDescriptionWithPerformance) => { - // TODO: should manage to get the service's git url - return {service.description.module}; - }, - sorter: (a: ServiceDescriptionWithPerformance, b: ServiceDescriptionWithPerformance) => { - return a.description.module.localeCompare(b.description.module); - }, - }, - { - id: 'version', - label: 'Version', - style: {}, - render: (service: ServiceDescriptionWithPerformance) => { - return {service.version}; - }, - sorter: (a: ServiceDescriptionWithPerformance, b: ServiceDescriptionWithPerformance) => { - return a.version.localeCompare(b.version); - }, - }, - { - id: 'type', - label: 'Type', - style: {}, - render: (service: ServiceDescriptionWithPerformance) => { - return {service.description.type}; - }, - sorter: (a: ServiceDescriptionWithPerformance, b: ServiceDescriptionWithPerformance) => { - return a.description.type.localeCompare(b.description.type); - }, - }, - { - id: 'perf', - label: 'Perf (ms/call)', - style: {}, - render: (service: ServiceDescriptionWithPerformance) => { - return {Intl.NumberFormat('en-US', { - useGrouping: true, - minimumFractionDigits: 1, - maximumFractionDigits: 1, - }).format(service.average)}; - }, - sorter: (a: ServiceDescriptionWithPerformance, b: ServiceDescriptionWithPerformance) => { - return a.average - b.average; - }, - } - ]; - - return ( - - ); - } - - renderLoading() { - return ( - - ); - } - - renderError(state: AsyncProcessError) { - return ; - } - - renderState() { - switch (this.state.loadState.status) { - case AsyncProcessStatus.NONE: - case AsyncProcessStatus.PENDING: - return this.renderLoading(); - case AsyncProcessStatus.ERROR: - return this.renderError(this.state.loadState); - case AsyncProcessStatus.SUCCESS: - return this.renderServices(this.state.loadState.value); - } - } - - render() { - return
    -
    - {this.renderState()} -
    -
    - } -} diff --git a/vite-app/src/applets/about/AboutSession/controller.tsx b/vite-app/src/applets/about/AboutSession/controller.tsx new file mode 100644 index 00000000..5167359f --- /dev/null +++ b/vite-app/src/applets/about/AboutSession/controller.tsx @@ -0,0 +1,119 @@ +import Empty from 'components/Empty'; +import Well, { Variant } from 'components/Well'; +import { AuthenticationState, AuthenticationStateAuthenticated, AuthenticationStateUnauthenticated, AuthenticationStatus } from 'contexts/EuropaContext'; +import { Role } from 'lib/kb_lib/Auth2'; +import { Component } from 'react'; +import { Table } from 'react-bootstrap'; + +export interface AboutSessionControllerProps { + authState: AuthenticationState + setTitle: (title: string) => void; +} + +export default class AboutSessionController extends Component< + AboutSessionControllerProps +> { + componentDidMount() { + this.props.setTitle('About Your Session'); + } + + renderRoles(roles: Array) { + if (roles.length === 0) { + return + } + const rows = roles.map(({ id, desc }) => { + return
    + + + + }) + + return
    {id}{desc}
    + + + + + + + + {rows} + +
    Role IdDescription
    + } + + renderCustomRoles(roles: Array) { + if (roles.length === 0) { + return + } + return roles.map((roleId) => { + return
    + {roleId} +
    + }) + } + + renderAuthenticated(authState: AuthenticationStateAuthenticated) { + const { authInfo: { token, tokenInfo: { user, expires }, account: { roles, customroles } } } = authState; + + return + + + + + + + + + + + + + + + + + + + + + + +
    Token{token}
    Expires{Intl.DateTimeFormat('en-US', { dateStyle: 'medium', timeStyle: 'medium' }).format(expires)}
    Username{user}
    Roles{this.renderRoles(roles)}
    Custom Roles{this.renderCustomRoles(customroles)}
    + } + + renderUnauthenticated(_authState: AuthenticationStateUnauthenticated) { + return + You are not signed in, and therefore do not have a KBase Session. + + } + + renderState() { + switch (this.props.authState.status) { + case AuthenticationStatus.NONE: + return + case AuthenticationStatus.UNAUTHENTICATED: + return this.renderUnauthenticated(this.props.authState); + case AuthenticationStatus.AUTHENTICATED: + return this.renderAuthenticated(this.props.authState) + } + } + + renderVariant(): Variant { + switch (this.props.authState.status) { + case AuthenticationStatus.NONE: + return 'secondary'; + case AuthenticationStatus.UNAUTHENTICATED: + return 'warning'; + case AuthenticationStatus.AUTHENTICATED: + return 'secondary'; + } + } + + render() { + return + + {this.renderState()} + + + } +} diff --git a/vite-app/src/applets/about/ConnectionStatus/ConnectionStatus.tsx b/vite-app/src/applets/about/ConnectionStatus/ConnectionStatus.tsx index be77e543..9f74ac9f 100644 --- a/vite-app/src/applets/about/ConnectionStatus/ConnectionStatus.tsx +++ b/vite-app/src/applets/about/ConnectionStatus/ConnectionStatus.tsx @@ -1,4 +1,6 @@ +import ErrorAlert from 'components/ErrorAlert'; import { Component } from 'react'; +import { Table } from 'react-bootstrap'; import { AsyncProcess, AsyncProcessStatus } from '../../../lib/AsyncProcess'; import ConnectionMonitor from '../../../lib/ConnectionMonitor'; import styles from './ConnectionStatus.module.css'; @@ -264,28 +266,57 @@ export class ConnectionStatus extends Component { + return + + {this.renderSize(size)} + + + {this.renderPing2(ping + overhead, size, measure)} + + ; + }); + return + + + + + + + + + + {rows} + + {/* [{this.pingCount}] P {this.niceNumber(ping)}ms: */} + {/* OH {this.niceNumber(overhead)}ms: */} + {/* {content} */} +
    + Pings + + {this.pingCount} +
    + Overhead + + {this.niceNumber(overhead)}ms +
    + } + renderState() { switch (this.state.connectionStats.status) { case AsyncProcessStatus.NONE: case AsyncProcessStatus.PENDING: return; case AsyncProcessStatus.ERROR: - return
    {this.state.connectionStats.error}
    + return case AsyncProcessStatus.SUCCESS: - const stats = this.state.connectionStats.value.stats; - const ping = stats[0].measure.totalMeasure / this.pingCount; - const overhead = stats[1].measure.totalMeasure / this.pingCount - ping; - - const content = stats.slice(2).map(({ size, measure }, index) => { - return - {this.renderSize(size)} = {this.renderPing2(ping + overhead, size, measure)} - ; - }); - return
    - [{this.pingCount}] P {this.niceNumber(ping)}ms: - OH {this.niceNumber(overhead)}ms: - {content} -
    + return this.renderSuccess(this.state.connectionStats.value); } } diff --git a/vite-app/src/applets/about/ServicePerformance.ts b/vite-app/src/applets/about/ServicePerformance.ts index 552ac444..cf4bbc97 100644 --- a/vite-app/src/applets/about/ServicePerformance.ts +++ b/vite-app/src/applets/about/ServicePerformance.ts @@ -1,4 +1,5 @@ import { isJSONObject, traverse } from '@kbase/ui-lib/lib/json'; +import { resultOrThrow } from 'lib/kb_lib/comm/JSONRPC20/JSONRPC20'; import GenericClient11 from '../../lib/kb_lib/comm/JSONRPC11/GenericClient'; import GenericClient20 from '../../lib/kb_lib/comm/JSONRPC20/GenericClient'; import { Config } from '../../types/config'; @@ -27,6 +28,29 @@ export interface PerformanceMetrics { average: number; } +export enum PerformanceMeasurementsStatus { + SUCCESS = 'SUCCESS', + ERROR = 'ERROR', +} + +export interface PerformanceMeasurementsBase { + status: PerformanceMeasurementsStatus +} + +export interface PerformanceMeasurementsSuccess extends PerformanceMeasurementsBase{ + status: PerformanceMeasurementsStatus.SUCCESS, + version: string; + measurements: PerformanceMetrics; +} + +export interface PerformanceMeasurementsError extends PerformanceMeasurementsBase { + status: PerformanceMeasurementsStatus.ERROR, + message: string; +} + +export type PerformanceMeasurements = PerformanceMeasurementsSuccess | PerformanceMeasurementsError; + + export default class ServicePerformance { params: ServicePerformanceParams constructor(params: ServicePerformanceParams) { @@ -63,7 +87,7 @@ export default class ServicePerformance { return await next(itersLeft - 1); // return null; } catch (ex) { - console.error('ERROR', expect); + console.error('ERROR', ex); return await next(itersLeft - 1); } }; @@ -121,7 +145,8 @@ export default class ServicePerformance { prefix: false, }); return async () => { - const result = await client.callFunc(service.method); + const response = await client.callFunc(service.method); + const result = resultOrThrow(response); if (service.versionKey) { if (isJSONObject(result)) { const result2 = traverse(result, service.versionKey); @@ -184,8 +209,15 @@ export default class ServicePerformance { } } - async measure() { + async measure(): Promise { const ver = this.getAPICall(); - return await Promise.all([ver(), this.measurePerformance(ver)]); + try { + const [version, measurements] = await Promise.all([ver(), this.measurePerformance(ver)]); + return {status: PerformanceMeasurementsStatus.SUCCESS, version, measurements} + } catch (ex) { + return {status: PerformanceMeasurementsStatus.ERROR, + message: ex instanceof Error ? ex.message : 'Unknown error' + } + } } } diff --git a/vite-app/src/applets/about/index.module.css b/vite-app/src/applets/about/index.module.css new file mode 100644 index 00000000..2fd29a4c --- /dev/null +++ b/vite-app/src/applets/about/index.module.css @@ -0,0 +1,16 @@ +.main { + flex: 1 1 0; + display: flex; + flex-direction: column; +} + +.menu { + flex: 0 0 auto; +} + +.body { + flex: 1 1 0; + display: flex; + flex-direction: column; + overflow-y: hidden; +} \ No newline at end of file diff --git a/vite-app/src/applets/about/index.tsx b/vite-app/src/applets/about/index.tsx index ec132924..104b5f94 100644 --- a/vite-app/src/applets/about/index.tsx +++ b/vite-app/src/applets/about/index.tsx @@ -1,14 +1,18 @@ +import { SignIn } from 'apps/Auth2/SignIn/SignIn'; import { Component } from 'react'; import NotFound from '../../components/NotFound/NotFound'; import { RouteProps, Router } from '../../components/Router2'; -import { AuthenticationState } from '../../contexts/Auth'; +import { AuthenticationState } from '../../contexts/EuropaContext'; import { Route } from '../../lib/Route'; import { Config } from '../../types/config'; import AboutBuild from './AboutBuild'; import AboutKBaseUI from './AboutKBaseUI'; +import AboutMenu from './AboutMenu'; import AboutPlugins from './AboutPlugins'; -import AboutServices from './AboutServices2'; +import AboutServices from './AboutServices'; +import AboutSessionController from './AboutSession/controller'; import { ConnectionStatus } from './ConnectionStatus/ConnectionStatus'; +import styles from './index.module.css'; export interface AboutProps extends RouteProps { config: Config; @@ -21,13 +25,17 @@ interface AboutState { export default class About extends Component { render() { - const routes: Array = [ new Route('about', { authenticationRequired: false }, () => { return ( ); }), + new Route('about/kbase-ui', { authenticationRequired: false }, () => { + return ( + + ); + }), new Route('about/services', { authenticationRequired: false }, () => { return ( @@ -47,6 +55,11 @@ export default class About extends Component { return ( ); + }), + new Route('about/session', { authenticationRequired: false }, () => { + return ( + + ); }), new Route('about/*', { authenticationRequired: false }, (props: RouteProps) => { return ( @@ -58,7 +71,29 @@ export default class About extends Component { }), ]; - return + const authRoute = new Route( + '^login|signin|signup$', + {authenticationRequired: false}, + (props: RouteProps) => { + return + } + ) + + return
    +
    + +
    +
    + +
    +
    ; // return ( // diff --git a/vite-app/src/applets/developer/ConfigEditor.css b/vite-app/src/applets/developer/ConfigEditor.module.css similarity index 56% rename from vite-app/src/applets/developer/ConfigEditor.css rename to vite-app/src/applets/developer/ConfigEditor.module.css index bf903e06..e540ac4c 100644 --- a/vite-app/src/applets/developer/ConfigEditor.css +++ b/vite-app/src/applets/developer/ConfigEditor.module.css @@ -1,7 +1,7 @@ -.ConfigEditor { +.main { overflow-y: auto; } -.ConfigEditor .path { +.main .path { font-style: italic; } \ No newline at end of file diff --git a/vite-app/src/applets/developer/ConfigEditor.tsx b/vite-app/src/applets/developer/ConfigEditor.tsx index ac2d170f..9dab97e0 100644 --- a/vite-app/src/applets/developer/ConfigEditor.tsx +++ b/vite-app/src/applets/developer/ConfigEditor.tsx @@ -7,7 +7,7 @@ import { JSONValue, } from '../../lib/json'; import { Config } from '../../types/config'; -import './ConfigEditor.css'; +import styles from './ConfigEditor.module.css'; type Path = Array; @@ -40,7 +40,7 @@ export default class ConfigEditor extends Component< /> -
    {path.join('.')}
    +
    {path.join('.')}
    ); } @@ -50,7 +50,7 @@ export default class ConfigEditor extends Component<
    -
    {path.join('.')}
    +
    {path.join('.')}
    ); } @@ -67,7 +67,7 @@ export default class ConfigEditor extends Component< -
    {path.join('.')}
    +
    {path.join('.')}
    ); } @@ -77,7 +77,7 @@ export default class ConfigEditor extends Component<
    -
    {path.join('.')}
    +
    {path.join('.')}
    ); } @@ -141,7 +141,7 @@ export default class ConfigEditor extends Component< } render() { return ( -
    +
    {this.renderEditor()}
    ); diff --git a/vite-app/src/applets/developer/Features.module.css b/vite-app/src/applets/developer/Features.module.css index 97182421..1f797c29 100644 --- a/vite-app/src/applets/developer/Features.module.css +++ b/vite-app/src/applets/developer/Features.module.css @@ -1,3 +1,3 @@ -.Main { +.main { padding: 10px; } \ No newline at end of file diff --git a/vite-app/src/applets/developer/Features.tsx b/vite-app/src/applets/developer/Features.tsx index 85962ff0..077cde19 100644 --- a/vite-app/src/applets/developer/Features.tsx +++ b/vite-app/src/applets/developer/Features.tsx @@ -69,7 +69,7 @@ export default class Features extends Component { render() { return ( -
    +

    Welcome to the Features Editor

    {this.renderFeatures()} diff --git a/vite-app/src/applets/developer/FeaturesController.tsx b/vite-app/src/applets/developer/FeaturesController.tsx index 870a6331..e88177cf 100644 --- a/vite-app/src/applets/developer/FeaturesController.tsx +++ b/vite-app/src/applets/developer/FeaturesController.tsx @@ -1,6 +1,6 @@ +import * as Cookie from 'es-cookie'; import { Component } from 'react'; import Features from './Features'; -import * as Cookie from 'es-cookie'; // Just for now; // TODO: move into config. @@ -27,7 +27,6 @@ export interface FeatureState extends Feature { interface FeaturesControllerState { features: Array - } const FEATURE_COOKIE_SEPARATOR = /s*,s*/; @@ -58,7 +57,6 @@ export default class FeaturesController extends Component { render() { return ( -
    +

    Welcome to the Developer Tools.

    Currently this tool just lets you edit the runtime config. diff --git a/vite-app/src/applets/developer/index.css b/vite-app/src/applets/developer/index.module.css similarity index 67% rename from vite-app/src/applets/developer/index.css rename to vite-app/src/applets/developer/index.module.css index 5d653a70..2cc15e0c 100644 --- a/vite-app/src/applets/developer/index.css +++ b/vite-app/src/applets/developer/index.module.css @@ -1,19 +1,19 @@ -.Developer { +.main { flex: 1 1 0; display: flex; flex-direction: column; min-height: 0; - margin: 0 10px; + margin: 0 1rem 1rem 1rem; } -.Developer .tab-content { +.main :global .tab-content { flex: 1 1 0; display: flex; flex-direction: column; min-height: 0; } -.Developer .tab-content .tab-pane.active { +.main :global .tab-content :global .tab-pane.active { flex: 1 1 0; display: flex; flex-direction: column; diff --git a/vite-app/src/applets/developer/index.tsx b/vite-app/src/applets/developer/index.tsx index e053be1d..2f059967 100644 --- a/vite-app/src/applets/developer/index.tsx +++ b/vite-app/src/applets/developer/index.tsx @@ -2,9 +2,9 @@ import { Component } from 'react'; import { Tab, Tabs } from 'react-bootstrap'; import { Config } from '../../types/config'; import ConfigEditor from './ConfigEditor'; -import Main from './Main'; -import './index.css'; import Features from './FeaturesController'; +import Main from './Main'; +import styles from './index.module.css'; export interface DeveloperProps { tab?: string; @@ -12,11 +12,8 @@ export interface DeveloperProps { setTitle: (title: string) => void; } -interface DeveloperState { } - export default class Developer extends Component< - DeveloperProps, - DeveloperState + DeveloperProps > { componentDidMount() { this.props.setTitle('Developer Tools ;)'); @@ -45,7 +42,7 @@ export default class Developer extends Component< render() { return ( -

    +
    {this.renderTabs()}
    ); diff --git a/vite-app/src/applets/development/DevelopmentAuth.tsx b/vite-app/src/applets/development/DevelopmentAuth.tsx deleted file mode 100644 index c113b820..00000000 --- a/vite-app/src/applets/development/DevelopmentAuth.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { Component } from 'react'; -import Loading from '../../components/Loading'; -import { - AuthenticationState, - AuthenticationStateAuthenticated, - AuthenticationStateUnauthenticated, - AuthenticationStatus, -} from '../../contexts/Auth'; -import { Config } from '../../types/config'; -import DevelopmentLogin from './DevelopmentLogin'; -import DevelopmentLogout from './DevelopmentLogout'; - -export interface DevelopmentAuthProps { - config: Config; - authState: AuthenticationState; -} - -interface DevelopmentAuthState {} - -export default class DevelopmentAuth extends Component< - DevelopmentAuthProps, - DevelopmentAuthState -> { - renderLoading() { - return ( - - ); - } - - renderUnauthenticated(authState: AuthenticationStateUnauthenticated) { - return ( - - ); - } - - renderAuthenticated(authState: AuthenticationStateAuthenticated) { - return ( - - ); - } - renderState() { - switch (this.props.authState.status) { - case AuthenticationStatus.NONE: - return this.renderLoading(); - case AuthenticationStatus.UNAUTHENTICATED: - return this.renderUnauthenticated(this.props.authState); - case AuthenticationStatus.AUTHENTICATED: - return this.renderAuthenticated(this.props.authState); - } - } - - render() { - return ( -
    -

    - DEVELOPMENT MODE -

    -
    - {this.renderState()} -
    -
    - ); - } -} diff --git a/vite-app/src/applets/development/DevelopmentLogin.tsx b/vite-app/src/applets/development/DevelopmentLogin.tsx deleted file mode 100644 index e51e82f9..00000000 --- a/vite-app/src/applets/development/DevelopmentLogin.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import { Component } from 'react'; -import AlertMessage from '../../components/AlertMessage'; -import ErrorAlert from '../../components/ErrorAlert'; -import Loading from '../../components/Loading'; -import { AuthenticationStateUnauthenticated } from '../../contexts/Auth'; -import { AsyncProcess, AsyncProcessStatus } from '../../lib/AsyncProcess'; -import { Auth2 } from '../../lib/kb_lib/Auth2'; -import { Config } from '../../types/config'; -import DevelopmentLoginForm from './DevelopmentLoginForm'; - -export interface DevelopmentLoginProps { - config: Config; - authState: AuthenticationStateUnauthenticated; -} - -interface DevelopmentLoginState { - loginState: AsyncProcess< - { - token: string; - username: string; - realname: string; - }, - string - >; -} - -export default class DevelopmentLogin extends Component< - DevelopmentLoginProps, - DevelopmentLoginState -> { - constructor(props: DevelopmentLoginProps) { - super(props); - this.state = { - loginState: { - status: AsyncProcessStatus.NONE, - }, - }; - } - renderLoading() { - return ( - - ); - } - - async doSetToken(token: string) { - // check token; - const auth = new Auth2({ - baseUrl: this.props.config.services.Auth2.url, - }); - try { - // const tokenInfo = await auth.getTokenInfo(token); - const meInfo = await auth.getMe(token); - this.setState({ - loginState: { - status: AsyncProcessStatus.SUCCESS, - value: { - token, - username: meInfo.user, - realname: meInfo.display, - }, - }, - }); - } catch (ex) { - this.setState({ - loginState: { - status: AsyncProcessStatus.ERROR, - error: ex instanceof Error ? ex.message : 'Unknown error', - }, - }); - } - } - - setToken(token: string) { - this.props.authState.login(token, 0); - } - - renderLoginStatus() { - const loginState = this.state.loginState; - switch (loginState.status) { - case AsyncProcessStatus.NONE: - return ( - - ); - case AsyncProcessStatus.PENDING: - return ( - - ); - case AsyncProcessStatus.ERROR: - return ; - case AsyncProcessStatus.SUCCESS: - return ( -
    - -
    - -
    -
    - ); - } - } - - render() { - return ( -
    - -
    - {this.renderLoginStatus()} -
    -
    - ); - } -} diff --git a/vite-app/src/applets/development/DevelopmentLoginForm.tsx b/vite-app/src/applets/development/DevelopmentLoginForm.tsx deleted file mode 100644 index 657b947c..00000000 --- a/vite-app/src/applets/development/DevelopmentLoginForm.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { Component, FormEvent } from 'react'; - -export interface DevelopmentLoginFormProps { - onLogin: (token: string) => void; -} - -interface DevelopmentLoginFormState { - token: string | null; -} - -export default class DevelopmentLoginForm extends Component< - DevelopmentLoginFormProps, - DevelopmentLoginFormState -> { - constructor(props: DevelopmentLoginFormProps) { - super(props); - this.state = { - token: null, - }; - } - doLoginSubmit(ev: FormEvent) { - ev.preventDefault(); - if (this.state.token) { - this.props.onLogin(this.state.token); - } - return false; - } - - onTokenInput(ev: FormEvent) { - this.setState({ - token: ev.currentTarget.value, - }); - } - - isValidToken() { - const token = this.state.token; - if (!token) { - return false; - } - if (token.length !== 32) { - return false; - } - return true; - } - - render() { - return ( -
    -

    Development Mode Login

    -

    Please Enter a KBase Login Token Below:

    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    - ); - } -} diff --git a/vite-app/src/applets/development/DevelopmentLogout.tsx b/vite-app/src/applets/development/DevelopmentLogout.tsx deleted file mode 100644 index b734e4c8..00000000 --- a/vite-app/src/applets/development/DevelopmentLogout.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { Component } from 'react'; -import AlertMessage from '../../components/AlertMessage'; -import ErrorAlert from '../../components/ErrorAlert'; -import Loading from '../../components/Loading'; -import { AuthenticationStateAuthenticated } from '../../contexts/Auth'; -import { AsyncProcess, AsyncProcessStatus } from '../../lib/AsyncProcess'; -import { Config } from '../../types/config'; - -export interface DevelopmentLogoutProps { - config: Config; - authState: AuthenticationStateAuthenticated; -} - -interface DevelopmentLogoutState { - logoutState: AsyncProcess; -} - -export default class DevelopmentLogout extends Component< - DevelopmentLogoutProps, - DevelopmentLogoutState -> { - constructor(props: DevelopmentLogoutProps) { - super(props); - this.state = { - logoutState: { - status: AsyncProcessStatus.NONE, - }, - }; - } - - async doLogout(authState: AuthenticationStateAuthenticated) { - this.setState({ - logoutState: { - status: AsyncProcessStatus.PENDING, - }, - }); - try { - await authState.logout(); - this.setState({ - logoutState: { - status: AsyncProcessStatus.SUCCESS, - value: null, - }, - }); - } catch (ex) { - this.setState({ - logoutState: { - status: AsyncProcessStatus.ERROR, - error: ex instanceof Error ? ex.message : 'Unknown error', - }, - }); - } - } - - renderLogoutForm() { - return ( -
    -

    Please use the button below to log out of KBase:

    -
    - -
    -
    - ); - } - - renderLoginStatus() { - const logoutState = this.state.logoutState; - switch (logoutState.status) { - case AsyncProcessStatus.NONE: - return ( -
    - -
    - ); - case AsyncProcessStatus.PENDING: - return ( - - ); - case AsyncProcessStatus.ERROR: - return ; - case AsyncProcessStatus.SUCCESS: - return ( -
    - -
    - ); - } - } - - render() { - return ( -
    - {this.renderLogoutForm()} - {this.renderLoginStatus()} -
    - ); - } -} diff --git a/vite-app/src/applets/narrativeLoader/index.tsx b/vite-app/src/applets/narrativeLoader/index.tsx index 92bd9a8d..c320a005 100644 --- a/vite-app/src/applets/narrativeLoader/index.tsx +++ b/vite-app/src/applets/narrativeLoader/index.tsx @@ -1,12 +1,12 @@ +import { navigationPathToURL } from 'contexts/RouterContext'; import { Component } from 'react'; -import { AuthenticationState } from '../../contexts/Auth'; -import { Config } from '../../types/config'; -// import { RouteComponentProps } from 'react-router'; import { Alert, ProgressBar } from 'react-bootstrap'; import AlertMessage from '../../components/AlertMessage'; import ErrorMessage from '../../components/ErrorMessage'; import Loading from '../../components/Loading'; import { RouteProps } from '../../components/Router2'; +import { AuthenticationState } from '../../contexts/EuropaContext'; +import { Config } from '../../types/config'; const MAX_TRIES = 20; const TIMEOUT = 60000; @@ -57,7 +57,8 @@ export enum LoadStatus { NONE = 'NONE', POKING = 'POKING', OK = 'OK', - ERROR = 'ERROR', + INIT_ERROR = 'INIT_ERROR', + CHECK_ERROR = 'CHECK_ERROR', TIMED_OUT = 'TIMED_OUT', STRUCK_OUT = 'STRUCK_OUT', } @@ -72,43 +73,55 @@ export interface LoadStateNone extends LoadStateBase { export interface LoadStatePoking extends LoadStateBase { status: LoadStatus.POKING; - url: string; + narrativeId: number; + url: URL; tries: number; } export interface LoadStateOk extends LoadStateBase { status: LoadStatus.OK; - url: string; narrativeId: number; + url: URL; } -export interface LoadStateError extends LoadStateBase { - status: LoadStatus.ERROR; +export interface LoadStateInitError extends LoadStateBase { + status: LoadStatus.INIT_ERROR; // url: string; title: string; message: string; } +export interface LoadStateCheckError extends LoadStateBase { + status: LoadStatus.CHECK_ERROR; + title: string; + message: string; + narrativeId: number; + url: URL; +} + export interface LoadStateTimedOut extends LoadStateBase { status: LoadStatus.TIMED_OUT; tries: number; timeout: number; elapsed: number; - url: string; + narrativeId: number; + url: URL; } export interface LoadStateStruckOut extends LoadStateBase { status: LoadStatus.STRUCK_OUT; tries: number; elapsed: number; - url: string; + narrativeId: number; + url: URL; } export type LoadState = | LoadStateNone | LoadStatePoking | LoadStateOk - | LoadStateError + | LoadStateInitError + | LoadStateCheckError | LoadStateStruckOut | LoadStateTimedOut; @@ -129,21 +142,32 @@ export default class NarrativeLoader extends Component< state: NarrativeLoaderState = { loadState: { status: LoadStatus.NONE, - }, + } }; urlToCheck() { - return `${document.location.origin}/narrative/static/kbase/config/config.json?check=true`; + return navigationPathToURL({ + path: `narrative/static/kbase/config/config.json`, + type: 'europaui' + }); + } + + narrativeURL(narrativeId: number) { + return navigationPathToURL({ + path: `/narrative/${narrativeId}`, + type: 'europaui' + }); } componentDidMount() { + console.log('HERE'); this.props.setTitle('Narrative Loader'); - const searchParams = this.props.hashPath.query; - const narrativeIdRaw = searchParams.get('n'); + const searchParams = this.props.hashPath.params || {}; + const narrativeIdRaw = searchParams['n']; if (!narrativeIdRaw) { this.setState({ loadState: { - status: LoadStatus.ERROR, + status: LoadStatus.INIT_ERROR, title: "Missing Parameter", message: "The Narrative Loader requires the 'n' search parameter, which was not provided in the URL.", @@ -155,7 +179,7 @@ export default class NarrativeLoader extends Component< if (!/^[1-9][0-9]*$/.test(narrativeIdRaw)) { this.setState({ loadState: { - status: LoadStatus.ERROR, + status: LoadStatus.INIT_ERROR, title: "Invalid Parameter", message: `The "n" search parameter in the URL is not an integer > 0: It is "${narrativeIdRaw}".`, }, @@ -165,11 +189,14 @@ export default class NarrativeLoader extends Component< const narrativeId = parseInt(narrativeIdRaw); + console.log('CHECKING', this.urlToCheck()); + this.setState( { loadState: { status: LoadStatus.POKING, tries: 0, + narrativeId, url: this.urlToCheck() }, }, @@ -186,9 +213,6 @@ export default class NarrativeLoader extends Component< renderProgress() { } async tryLoading(narrativeId: number) { - const narrativeURL = - document.location.origin + '/narrative/' + narrativeId; - if (this.state.loadState.status !== LoadStatus.POKING) { return; } @@ -199,20 +223,22 @@ export default class NarrativeLoader extends Component< this.state.loadState.url ); if (retry) { - await waitFor(RETRY_PAUSE); this.setState({ loadState: { status: LoadStatus.POKING, tries, + narrativeId, url: this.urlToCheck(), }, }); + + await waitFor(RETRY_PAUSE); } else { this.setState({ loadState: { status: LoadStatus.OK, - url: narrativeURL, - narrativeId + narrativeId, + url: this.urlToCheck() }, }); @@ -226,50 +252,61 @@ export default class NarrativeLoader extends Component< status: LoadStatus.STRUCK_OUT, tries: MAX_TRIES, elapsed: Date.now() - start, - url: narrativeURL + narrativeId, + url: this.urlToCheck() } }) resolve(); }, RETRY_PAUSE); }); } catch (ex) { + console.error('ERROR', ex); if (ex) if (ex instanceof LoadingError) { this.setState({ loadState: { - status: LoadStatus.ERROR, + status: LoadStatus.CHECK_ERROR, title: "Error waiting for Narrative to start", - message: ex.message + message: ex.message, + narrativeId, + url: this.urlToCheck() } }); } else if (ex instanceof TimeoutError) { this.setState({ loadState: { - status: LoadStatus.ERROR, + status: LoadStatus.CHECK_ERROR, title: "Error waiting for Narrative to start", - message: ex.message + message: ex.message, + narrativeId, + url: this.urlToCheck() } }); } else if (ex instanceof Error) { this.setState({ loadState: { - status: LoadStatus.ERROR, + status: LoadStatus.CHECK_ERROR, title: "Error waiting for Narrative to start", - message: ex.message + message: ex.message, + narrativeId, + url: this.urlToCheck() } }); } else { this.setState({ loadState: { - status: LoadStatus.ERROR, + status: LoadStatus.CHECK_ERROR, title: 'Unknown Error', - message: 'An unknown error occurred waiting for the Narrative to start' + message: 'An unknown error occurred waiting for the Narrative to start', + narrativeId, + url: this.urlToCheck() }, }); } } } - checkNarrative(url: string) { + + checkNarrative(url: URL) { const startTime = new Date().getTime(); return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); @@ -349,7 +386,7 @@ export default class NarrativeLoader extends Component< } try { - xhr.withCredentials = false; + xhr.withCredentials = true; xhr.send(); } catch (ex) { reject( @@ -360,15 +397,19 @@ export default class NarrativeLoader extends Component< } renderOK(loadingState: LoadStateOk) { - const url: URL = new URL(window.location.href); - // Nuke the hash and search - for (const key of Array.from(url.searchParams.keys())) { - url.searchParams.delete(key); - } - url.hash = ''; - url.pathname = `/narrative/${loadingState.narrativeId}`; + // const url: URL = new URL(window.location.href); + // // Nuke the hash and search + // for (const key of Array.from(url.searchParams.keys())) { + // url.searchParams.delete(key); + // } + // url.hash = ''; + const url = navigationPathToURL({ + path: `narrative/${loadingState.narrativeId}`, + type: 'europaui' + }); + window.setTimeout(() => { - document.location.href = url.toString(); + window.open(url, '_top'); }, SLIGHT_DELAY_BEFORE_REDIRECT) return } - - renderState() { + render() { switch (this.state.loadState.status) { case LoadStatus.NONE: return ; @@ -394,7 +434,9 @@ export default class NarrativeLoader extends Component< ); case LoadStatus.OK: return this.renderOK(this.state.loadState); - case LoadStatus.ERROR: + case LoadStatus.INIT_ERROR: + return ; + case LoadStatus.CHECK_ERROR: return ; case LoadStatus.STRUCK_OUT: return ; @@ -402,7 +444,4 @@ export default class NarrativeLoader extends Component< return ; } } - render() { - return this.renderState(); - } } diff --git a/vite-app/src/apps/Auth.tsx b/vite-app/src/apps/Auth.tsx deleted file mode 100644 index a044c124..00000000 --- a/vite-app/src/apps/Auth.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import { Component } from 'react'; -import ErrorMessage from '../components/ErrorMessage'; -import PluginWrapper2 from '../components/PluginWrapper/PluginWrapper2'; -import { RouteProps, Router } from '../components/Router2'; -import { AuthenticationState } from '../contexts/Auth'; -import { RouterContext } from '../contexts/RouterContext'; -import { AsyncProcessStatus } from '../lib/AsyncProcess2'; -import { Route, SimplePluginRouteSpec } from '../lib/Route'; -import { Config } from '../types/config'; - -export interface AuthProps extends RouteProps { - config: Config; - authState: AuthenticationState; - setTitle: (title: string) => void; -} - -interface AuthState { -} - -export default class Catalog extends Component { - makePath(extraPath?: string) { - if (extraPath) { - return `${this.props.hashPath.path}/${extraPath}`; - } else { - return this.props.hashPath.path; - } - } - - render() { - const common = { - name: "auth2-client", - setTitle: this.props.setTitle, - authState: this.props.authState, - config: this.props.config - }; - - const routeSpecs: Array = [ - { - path: 'account', - auth: true, - view: 'account' - }, - { - path: 'auth2/account', - auth: true, - view: 'account' - }, - { - path: 'login', - auth: false, - view: 'login' - }, - { - path: 'signup', - auth: false, - view: 'signup' - }, - { - path: 'auth2/signedout', - auth: false, - view: 'signedout' - }, - { - path: 'auth2/login/continue', - auth: false, - view: 'loginContinue' - }, - { - path: 'auth2/link/continue', - auth: true, - view: 'linkContinue' - }, - ] - - const routes = routeSpecs.map(({path, view, auth}) => { - return new Route(path, {authenticationRequired: auth}, (props: RouteProps) => { - return - }); - }); - - return ( - - {(value) => { - switch (value.status) { - case AsyncProcessStatus.NONE: - return
    ; - case AsyncProcessStatus.PENDING: - return
    ; - case AsyncProcessStatus.ERROR: - return ; - case AsyncProcessStatus.SUCCESS: - return ; - } - }} - - ); - // return ; - // 1 - // return ( - // - // { - // return ( - // - // ); - // }} - // /> - // { - // return ( - // - // ); - // }} - // /> - // { - // return ( - // - // ); - // }} - // /> - // { - // return ( - // - // ); - // }} - // /> - - // { - // return ( - // - // ); - // }} - // /> - - // { - // return ( - // - // ); - // }} - // /> - // { - // return ( - // - // ); - // }} - // /> - // - // ); - } -} diff --git a/vite-app/src/apps/Auth2/AccountManager/Account/AccountEditor/view.tsx b/vite-app/src/apps/Auth2/AccountManager/Account/AccountEditor/view.tsx new file mode 100644 index 00000000..a4778a48 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/Account/AccountEditor/view.tsx @@ -0,0 +1,100 @@ +import { notifySuccess } from 'contexts/EuropaContext'; +import * as formik from 'formik'; +import { FormikHelpers } from 'formik'; +import { Component } from "react"; +import { Button, Col, Container, Form, InputGroup, Row } from "react-bootstrap"; +import * as yup from 'yup'; +import { AccountEditorFields } from '../controller'; + +export interface AccountEditorViewProps { + fields: AccountEditorFields + save: (fields: AccountEditorFields) => Promise; +} + +interface AccountEditorViewState { +} + +export default class AccountEditorView extends Component { + async onSubmit(fields: AccountEditorFields, {resetForm}: FormikHelpers) { + await this.props.save(fields); + + // Okay, this "resets" the form, but keeping the data changed and saved above, + // thus it doesn't "reset" to the previous state, it just effectively clears the + // dirty and possibly other flags. + resetForm({values: fields}); + + notifySuccess('Successfully saved changes to your account and profile'); + } + + render() { + const { Formik } = formik; + + const schema = yup.object().shape({ + realname: yup.string().required().min(2).max(100), + email: yup.string().required().email() + }) + + return + {({ handleSubmit, handleChange, values, errors, dirty, isValid }) => { + return
    { handleSubmit(e); }} > + + + + Your Name + + + + {errors.realname} + + + + + Your real name, displayed to other KBase users + + + + + E-Mail Address + + + + {errors.email} + + + + + Your email address; may be used by KBase staff to contact you. + + + + + + + + +
    + }} +
    + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/Account/AccountInfo/view.tsx b/vite-app/src/apps/Auth2/AccountManager/Account/AccountInfo/view.tsx new file mode 100644 index 00000000..fac8cb28 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/Account/AccountInfo/view.tsx @@ -0,0 +1,71 @@ +import { Account } from "lib/kb_lib/Auth2"; +import { niceRelativeTime, niceTime } from "lib/time"; +import { Component } from "react"; +import { Col, Container, Form, Row } from "react-bootstrap"; + +export interface AccountInfoViewProps { + account: Account +} + +export default class AccountInfoView extends Component { + render() { + const {user, created, lastlogin} = this.props.account; + return + + + Username +
    {user}
    + + + + Your permanent identifier within KBase + + +
    + {/* + + Name +
    {display}
    + + k + + The name you provided at signup to show to other users. + + +
    */} + {/* + + E-Mail +
    {email}
    + + + + The email address you provided at signup. + + +
    */} + + + Account Created +
    {niceTime(new Date(created))}
    + + + + When you signed up for KBase + + +
    + + + Last Sign In +
    {niceRelativeTime(new Date(lastlogin))} ({niceTime(new Date(lastlogin))})
    + + + + When you last signed in to KBase + + +
    +
    + } +} diff --git a/vite-app/src/apps/Auth2/AccountManager/Account/controller.tsx b/vite-app/src/apps/Auth2/AccountManager/Account/controller.tsx new file mode 100644 index 00000000..c57a2534 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/Account/controller.tsx @@ -0,0 +1,185 @@ +import { AuthenticationStateAuthenticated } from "contexts/EuropaContext"; +import { Component } from "react"; +import { Config } from "types/config"; +import AccountEditorView from "./view"; + +export interface AccountEditorControllerProps { + authState: AuthenticationStateAuthenticated, + config: Config, + setTitle: (title: string) => void; +} + +import ErrorAlert from "components/ErrorAlert"; +import Loading from "components/Loading"; +// import { AsyncProcess, AsyncProcessStatus } from "lib/AsyncProcess"; +import { SimpleError } from 'lib/SimpleError'; +import { Account, Auth2 } from "lib/kb_lib/Auth2"; +import UserProfile from "lib/kb_lib/comm/coreServices/UserProfile"; + + +import { RepeatAsyncProcess, RepeatAsyncProcessStatus } from "lib/RepeatableAsyncProcess"; +import { Md5 } from 'ts-md5'; + +export interface AccountEditorFields { + realname: string; + email: string; +} + +export interface AccountEditor { + fields: AccountEditorFields; + account: Account +} + +type AccountEditorControllerState = RepeatAsyncProcess; + +export default class AccountEditorController extends Component { + constructor(props: AccountEditorControllerProps) { + super(props); + this.state = { + status: RepeatAsyncProcessStatus.NONE + }; + } + + componentDidMount() { + this.props.setTitle('Account Manager - Update Your Account'); + this.loadData(); + } + + async save({email, realname}: AccountEditorFields) { + const {authInfo: {token, account: {user: username}}} = this.props.authState; + const {services: {Auth2: {url: authURL}, UserProfile: {url: userProfileURL}}} = this.props.config; + const userProfileClient = new UserProfile({ + url: userProfileURL, + token, + timeout: 1000 // TODO: get from config + }); + const authClient = new Auth2({ + baseUrl: authURL + }); + + const profile = (await userProfileClient.get_user_profile([username]))[0]; + + // Extract field values from form + + const hashedEmail = Md5.hashStr(email.trim().toLowerCase()); + profile.profile.synced.gravatarHash = hashedEmail; + profile.user.realname = realname; + + // Auth2 params + const meData = { + email, display: realname + }; + + await Promise.all([ + authClient.putMe(token, meData), + userProfileClient.set_user_profile({ + profile + }) + ]); + + await this.reloadData(); + + // return {email: account?.email, realname: account?.display}; + + // TODO: is this still implemented? + // this.props.runtime.send('profile', 'reload'); + + // this.props.runtime.notifySuccess( + // 'Successfully updated your account and user profile', + // 3000 + // ); + } + + async fetchData() { + const {authInfo: {token}} = this.props.authState; + const {services: {Auth2: {url: authURL}}} = this.props.config; + const auth2 = new Auth2({ + baseUrl: authURL + }); + const account = await auth2.getMe(token); + return account; + } + + async loadData() { + this.setState({ + status: RepeatAsyncProcessStatus.PENDING + }); + + + try { + const account = await this.fetchData(); + const {display, email} = await this.fetchData(); + this.setState({ + status: RepeatAsyncProcessStatus.SUCCESS, + value: { + fields: { + realname: display, + email + }, + account + } + }); + + } catch (ex) { + this.setState({ + status: RepeatAsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }); + } + } + + + + async reloadData() { + this.setState({ + status: RepeatAsyncProcessStatus.SUCCESS_PENDING + }); + + + try { + const account = await this.fetchData(); + const {display, email} = await this.fetchData(); + this.setState({ + status: RepeatAsyncProcessStatus.SUCCESS, + value: { + fields: { + realname: display, + email + }, + account + } + }); + // return account; + } catch (ex) { + this.setState({ + status: RepeatAsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }); + } + } + + renderSuccess(value: AccountEditor) { + return ; + } + + render() { + switch (this.state.status) { + case RepeatAsyncProcessStatus.NONE: + case RepeatAsyncProcessStatus.PENDING: + return + case RepeatAsyncProcessStatus.SUCCESS: + case RepeatAsyncProcessStatus.SUCCESS_PENDING: + return this.renderSuccess(this.state.value); + case RepeatAsyncProcessStatus.ERROR: + return + } + } +} diff --git a/vite-app/src/apps/Auth2/AccountManager/Account/view.tsx b/vite-app/src/apps/Auth2/AccountManager/Account/view.tsx new file mode 100644 index 00000000..6d20ca0d --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/Account/view.tsx @@ -0,0 +1,49 @@ +import Well from "components/Well"; +import { Account } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import AccountEditor from "./AccountEditor/view"; +import AccountInfo from "./AccountInfo/view"; +import { AccountEditorFields } from "./controller"; + +export interface AccountEditorViewProps { + account: Account; + fields: AccountEditorFields; + save: (fields: AccountEditorFields) => Promise; +} + +interface AccountEditorViewState { +} + +export default class AccountEditorView extends Component { + renderAccountEditor() { + return + } + + renderAccountInfo() { + return + } + + render() { + return
    + + + Edit Account + + + {this.renderAccountEditor()} + + + + + Account Info + + + {this.renderAccountInfo()} + + +
    + } +} diff --git a/vite-app/src/apps/Auth2/AccountManager/AddTokenForm.tsx b/vite-app/src/apps/Auth2/AccountManager/AddTokenForm.tsx new file mode 100644 index 00000000..fc8b3e7c --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/AddTokenForm.tsx @@ -0,0 +1,49 @@ +import { Component } from "react"; +import { Button, Col, Form, Row } from "react-bootstrap"; + +export interface AddTokenFormProps { + createToken: (tokenName: string) => void; +} + +interface AddTokenFormState { + tokenName: string | null; +} + +export default class AddTokenForm extends Component { + constructor(props: AddTokenFormProps) { + super(props); + // this.ref = createRef(); + this.state = { + tokenName: null + }; + } + onSubmit() { + // e.preventDefault(); + if (this.state.tokenName === null) { + return; + } + this.props.createToken(this.state.tokenName); + this.setState({ + tokenName: null + }); + } + render() { + return
    { e.preventDefault(); this.onSubmit() }}> + + Token Name + + { + this.setState({ tokenName: e.target.value }); + }}> + + + + +
    + } +} diff --git a/vite-app/src/apps/Auth2/AccountManager/DevToken/controller.tsx b/vite-app/src/apps/Auth2/AccountManager/DevToken/controller.tsx new file mode 100644 index 00000000..d90096cf --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/DevToken/controller.tsx @@ -0,0 +1,207 @@ +import ErrorAlert from "components/ErrorAlert"; +import Loading from "components/Loading"; +import { notifySuccess } from "contexts/EuropaContext"; +import { AsyncProcess, AsyncProcessStatus } from "lib/AsyncProcess"; +import { SimpleError } from 'lib/SimpleError'; +import { Auth2, Role, TokenInfoFull } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import ActiveTokensView from "./view"; + +export interface DevTokensControllerProps { + token: string; + roles: Array + authURL: string; + setTitle: (title: string) => void; +} + +export interface DevTokens { + tokens: Array; + newToken: TokenInfoFull | null; + serverTimeBias: number; +} + +type DevTokensControllerState = AsyncProcess; + + +export default class DevTokensController extends Component { + constructor(props: DevTokensControllerProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + } + } + componentDidMount() { + this.props.setTitle('Account Manager - Developer Tokens'); + this.loadData(); + } + + async revokeToken(tokenToRevoke: string, name: string) { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + try { + await auth2.revokeToken(this.props.token, tokenToRevoke); + const { tokens } = await auth2.getTokens(this.props.token); + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + ...this.state.value, + tokens: tokens.filter((token) => { + return token.type === 'Developer'; + }), + } + }); + notifySuccess(`Dev token "${name}" as been revoked`); + } catch (ex) { + console.error(ex); + // TODO: what now? probably send an alert + } + } + + async revokeAllTokens() { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + const authToken = this.props.token; + try { + const {tokens: currentTokens} = await auth2.getTokens(authToken); + + // All others + await Promise.all(currentTokens + .filter(({type}) => { + return type=== 'Developer'; + }) + .map(({id}) => { + return auth2.revokeToken(authToken, id); + })); + + const {tokens} = await auth2.getTokens(authToken); + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + ...this.state.value, + tokens: tokens.filter((token) => { + return token.type === 'Developer'; + }) + } + }); + } catch (ex) { + console.error(ex); + // TODO: what now? probably send an alert + } + } + + async getServerTimeBias() { + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + const { servertime } = await auth2.root(); + return servertime - Date.now(); + } + + async loadData() { + this.setState({ + status: AsyncProcessStatus.PENDING + }); + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + + try { + const { tokens } = await auth2.getTokens(this.props.token); + + const serverTimeBias = await this.getServerTimeBias(); + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + tokens: tokens.filter((token) => { + return token.type === 'Developer'; + }), + newToken: null, + serverTimeBias + } + }); + } catch (ex) { + console.error(ex); + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }); + } + } + + async createDeveloperToken(name: string) { + const state = this.state; + if (state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + const authToken = this.props.token + try { + const newToken = await auth2.createToken(authToken, { + name, + type: 'developer' + }); + + this.setState({ + ...state, + value: { + ...state.value, + newToken, + tokens: state.value.tokens.concat([newToken]) + } + }); + + notifySuccess(`New dev token named "${name}" has been created`); + } catch (ex) { + console.error(ex); + // what to do - notification? + } + } + + clearNewToken() { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + this.setState({ + ...this.state, + value: { + ...this.state.value, + newToken: null + } + }); + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return + case AsyncProcessStatus.SUCCESS: + const { tokens, newToken, serverTimeBias } = this.state.value; + return + case AsyncProcessStatus.ERROR: + return + } + } +} diff --git a/vite-app/src/apps/Auth2/AccountManager/DevToken/view.module.css b/vite-app/src/apps/Auth2/AccountManager/DevToken/view.module.css new file mode 100644 index 00000000..4501cf94 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/DevToken/view.module.css @@ -0,0 +1,5 @@ +.main { + flex: 1 1 0; + display: flex; + flex-direction: column; +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/DevToken/view.tsx b/vite-app/src/apps/Auth2/AccountManager/DevToken/view.tsx new file mode 100644 index 00000000..d4114eaf --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/DevToken/view.tsx @@ -0,0 +1,246 @@ +import Empty from "components/Empty"; +import Well from "components/Well"; +import { notifySuccess } from "contexts/EuropaContext"; +import { TokenInfoFull } from "lib/kb_lib/Auth2"; +import { niceDuration, niceTime } from "lib/time"; +import { Component } from "react"; +import { Button, ButtonGroup, ButtonToolbar } from "react-bootstrap"; +import AddTokenForm from '../AddTokenForm'; +import TokenCopy from "../TokenCopy"; +import styles from './view.module.css'; + +const TOKEN_VIEWER_EXPIRES_IN = 300000; + +export interface DevTokensViewProps { + tokens: Array; + newToken: TokenInfoFull | null; + serverTimeBias: number; + revokeToken: (token: string, name: string) => void; + revokeAllTokens: () => void; + createDeveloperToken: (name: string) => void; + clearNewToken: () => void; +} + +interface DevTokensViewState { + newTokenCopied?: boolean; +} + +export default class DevTokensView extends Component { + doRevokeToken(tokenId: string, name: string) { + this.props.revokeToken(tokenId, name); + } + + doRevokeAllTokens() { + this.props.revokeAllTokens(); + } + + renderTokenBrowser(tokens: Array, removeVerb: string) { + const revokeAllButton = (() => { + if (tokens.length > 1) { + return + } + })(); + const rows = tokens.map(({ name, id, created, expires, os, osver, agent, agentver, ip }) => { + const renderBrowser = () => { + if (agent === null) { // } || agent.agent === 0) { // TODO: what is this actual type??? + return + n/a + + } + return + {agent} + + {agentver} + + + }; + const renderOS = () => { + if (os === null) { // } || os.agent === 0) { // TODO: is that supposed to be "length"? + return + n/a + + } + return + {os} + + {osver} + + + }; + + return + + {name} + + + {niceTime(new Date(created))} + + + {niceDuration(expires - (Date.now() - this.props.serverTimeBias))} + + + {renderBrowser()} + + + {renderOS()} + + + {ip} + + + + + + }); + return + + + + + + + + + + + + + {rows} + +
    + Name + + Created + + Expires + + Browser + + Operating System + + IP Address + + {revokeAllButton} +
    + } + + renderDevTokens() { + if (this.props.tokens.length > 0) { + return this.renderTokenBrowser(this.props.tokens, 'Remove'); + } + return + } + + renderRemoveAll() { + return + + + + + } + + renderTokens() { + return + + Dev Tokens + + + {this.renderDevTokens()} + + + {this.renderRemoveAll()} + + + } + + renderHelp() { + return
    +

    + a sign-in session is created when you + sign in to KBase. A sign-in session is removed when you logout. + However, if you do not logout, your sign-in session will remain active for two weeks. + At the end of two weeks, the sign-in session will become invalid, and you will need to sign-in again. +

    +
    + } + + renderNewToken() { + if (!this.props.newToken) { + return; + } + + const onCopied = () => { + notifySuccess('Token copied to clipboard', 3000); + }; + + const onCopyError = (message: string) => { + // TODO: implement notification + console.warn('message ignored', message); + // this.props.runtime.notifyError( + // `Error copying token to clipboard: ${message}` + // ); + }; + + const onDone = () => { + this.props.clearNewToken(); + }; + + return + } + + renderNewTokenForm() { + return + + Create Dev Token + + + + {this.renderNewToken()} + + + } + + render() { + return
    + {this.renderNewTokenForm()} + {this.renderTokens()} +
    + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/controller.tsx b/vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/controller.tsx new file mode 100644 index 00000000..5e159c4c --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/controller.tsx @@ -0,0 +1,176 @@ +import ErrorAlert from "components/ErrorAlert"; +import Loading from "components/Loading"; +import { AsyncProcess, AsyncProcessStatus } from "lib/AsyncProcess"; +import { SimpleError } from 'lib/SimpleError'; +import { Auth2, Identity } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import LinkedIdProvidersView from "./view"; + +import { Providers } from "apps/Auth2/Providers"; +import AutoPostForm from "pluginSupport/AutoPostForm"; +import ReactDOM from 'react-dom/client'; +import { Config, IDProvider } from "types/config"; + +export interface LinkedIdProvidersControllerProps { + config: Config; + token: string; + authURL: string; + // params: Record; + setTitle: (title: string) => void; +} + +export interface LinkedIdProviders { + identities: Array; + providers: Array; +} + + +type LinkedIdProvidersControllerState = AsyncProcess; + + +export default class LinkedIdProvidersController extends Component { + constructor(props: LinkedIdProvidersControllerProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + } + } + + componentDidMount() { + this.props.setTitle('Account Manager - Linked Sign-In Accounts'); + this.loadData(); + } + + + async unlinkIdentity(identityId: string) { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + try { + await auth2.removeLink(this.props.token, { + identityId + }); + // this.props.runtime.notifySuccess( + // 'Successfully unlinked identity', + // 3000 + // ); + const identities = await this.fetchIdentities(); + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + ...this.state.value, + identities + } + }); + } catch (ex) { + console.error(ex); + // this.props.runtime.notifyError( + // `Error unlinking: ${ex.message}` + // ); + } + } + + formPost({ + action, + params, + }: { + action: string; + params: Record; + }) { + const donorNode = document.createElement('div'); + document.body.appendChild(donorNode); + const props = { + action, + params, + }; + const root = ReactDOM.createRoot(donorNode); + root.render(); + } + + linkIdentity(providerId: string) { + try { + // TODO: routing back into here. + const params: Record = { + provider: providerId, + token: this.props.token + }; + const action = `${this.props.authURL}/link/start`; + + // this.props.runtime.send('app', 'post-form', { + // action, + // params + // }); + + this.formPost({ action, params }); + + // this.auth2.linkStart(this.currentUserToken, { + // provider: providerId, + // node: this.container + // }); + } catch (ex) { + console.error(ex); + // this.props.runtime.notifyError( + // `Error starting the linking process: ${ex.message}` + // ); + } + } + + async fetchIdentities() { + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + const authToken = this.props.token; + + const { idents } = await auth2.getMe(authToken); + return idents; + } + + async loadData() { + this.setState({ + status: AsyncProcessStatus.PENDING + }); + + try { + const identities = await this.fetchIdentities(); + const providers = new Providers({ + supportedProviders: this.props.config.services.Auth2.supportedProviders, + providers: this.props.config.services.Auth2.providers + }).get(); + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + identities, providers + } + }); + } catch (ex) { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }); + } + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return + case AsyncProcessStatus.SUCCESS: + return + case AsyncProcessStatus.ERROR: + return + } + } + +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/view.module.css b/vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/view.module.css new file mode 100644 index 00000000..2177af3f --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/view.module.css @@ -0,0 +1,29 @@ +.main { + flex: 1 1 0; + display: flex; + flex-direction: column; +} + +.providerLabel { + display: flex; + flex-direction: row +} + +.logo { + flex: 0 0 3em; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; +} + + +.label { + flex: 1 1 0; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start +} + + diff --git a/vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/view.tsx b/vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/view.tsx new file mode 100644 index 00000000..6e3d46c0 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/LinkedIDProviders/view.tsx @@ -0,0 +1,154 @@ +import { providerLabel, providerLogoSrc } from "apps/Auth2/Providers"; +import TextSpan from "apps/Auth2/TextSpan"; +import Well from "components/Well"; +import { Identity } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import { Button, Dropdown, Form } from "react-bootstrap"; +import { IDProvider } from "types/config"; +import styles from './view.module.css'; + +export interface LinkedIdProvidersViewProps { + providers: Array; + identities: Array; + linkIdentity: (id: string) => void; + unlinkIdentity: (id: string) => void; +} + +interface LinkedIdProvidersViewState { + canUnlink: boolean; + selectedProvider: IDProvider | null +} + +export default class LinkedIdProvidersView extends Component { + constructor(props: LinkedIdProvidersViewProps) { + super(props); + this.state = { + canUnlink: this.props.identities.length > 1, + selectedProvider: null + } + } + + renderProviderLabel(providerId: string) { + return
    +
    + +
    +
    + {providerLabel(providerId)} +
    +
    + } + + renderLinkedAccounts() { + const rows = this.props.identities.map((identity) => { + const tooltip = (() => { + if (this.state.canUnlink) { + return `Unlink this ${identity.provider} account from your KBase account`; + } + return 'Since this is the only external sign-in account linked to your KBase account, you cannot unlink it'; + + })(); + return + + {this.renderProviderLabel(identity.provider)} + + + {identity.provusername} + + + + + + }); + return + + + + + + + + + {rows} + +
    ProviderUsernameAction
    ; + } + + doSubmitLinkRequest() { + if (this.state.selectedProvider === null) { + return; + } + this.props.linkIdentity(this.state.selectedProvider.id); + } + + selectProvider(provider: IDProvider) { + this.setState({ + selectedProvider: provider + }); + } + + renderAccountLinker() { + return
    {e.preventDefault(); this.doSubmitLinkRequest();}}> +
    + + an account from the identity provider +
    + + + Select a Provider + + + { + this.props.providers.map((provider) => { + return {this.selectProvider(provider)}}> + {this.renderProviderLabel(provider.id)} + + }) + } + + +
    +
    +
    ; + } + + render() { + return
    + + + Currently Linked Accounts + + + {this.renderLinkedAccounts()} + + + + + + Link an additional sign-in account to this KBase Account + + + {this.renderAccountLinker()} + + +
    + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/LoginTokens/controller.tsx b/vite-app/src/apps/Auth2/AccountManager/LoginTokens/controller.tsx new file mode 100644 index 00000000..44797861 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/LoginTokens/controller.tsx @@ -0,0 +1,198 @@ +import ErrorAlert from "components/ErrorAlert"; +import Loading from "components/Loading"; +import { $GlobalMessenger, notifySuccess } from "contexts/EuropaContext"; +import { AsyncProcess, AsyncProcessStatus } from "lib/AsyncProcess"; +import { SimpleError } from 'lib/SimpleError'; +import { Auth2, Role, TokenInfoFull } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import ActiveTokensView from "./view"; + +export interface LoginTokensControllerProps { + token: string; + roles: Array + authURL: string; + setTitle: (title: string) => void; +} + +export interface LoginTokens { + tokens: Array; + current: TokenInfoFull + serverTimeBias: number; +} + +type LoginTokensControllerState = AsyncProcess; + + +export default class LoginTokensController extends Component { + constructor(props: LoginTokensControllerProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + } + } + componentDidMount() { + this.props.setTitle('Account Manager - Active Sign-In Sessions'); + this.loadData(); + } + + logout() { + $GlobalMessenger.send('session', 'logout', null); + } + + async revokeToken(tokenToRevoke: string) { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + try { + await auth2.revokeToken(this.props.token, tokenToRevoke); + const { tokens } = await auth2.getTokens(this.props.token); + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + ...this.state.value, + tokens: tokens.filter((token) => { + return token.type === 'Login'; + }), + } + }); + + notifySuccess('Login token successfully removed'); + } catch (ex) { + console.error(ex); + // TODO: what now? probably send an alert + } + } + + async revokeAllTokens() { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + const authToken = this.props.token; + try { + const {tokens: currentTokens} = await auth2.getTokens(authToken); + + // All others + await Promise.all(currentTokens + .filter(({type}) => { + return type=== 'Login'; + }) + .map(({id}) => { + return auth2.revokeToken(authToken, id); + })); + + const {tokens} = await auth2.getTokens(authToken); + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + ...this.state.value, + tokens: tokens.filter((token) => { + return token.type === 'Login'; + }) + } + }); + + notifySuccess('All Login tokens removed'); + } catch (ex) { + console.error(ex); + // TODO: what now? probably send an alert + } + } + + async revokeAllTokensAndLogout() { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + await this.revokeAllTokens(); + + await this.revokeCurrentTokenAndLogout(); + } + + async revokeCurrentTokenAndLogout() { + // const authToken = this.props.token + // const auth2Client = new Auth2({ baseUrl: this.props.authURL }) + try { + + // TODO: compatibility with Europa! + // If this signs out here, it will leave Europa hanging, as it does not + // appear to monitor the cookie very frequently. + // await auth2Client.logout(authToken); + this.logout(); + + // notifySuccess('Successfully removed current Login token'); + + // navigate('auth2/signedout'); + } catch (ex) { + console.error(ex); + // TODO: what now? probably send an alertpruntim e + } + } + + async getServerTimeBias() { + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + const { servertime } = await auth2.root(); + return servertime - Date.now(); + } + + async loadData() { + this.setState({ + status: AsyncProcessStatus.PENDING + }); + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + + try { + const { tokens, current } = await auth2.getTokens(this.props.token); + + const serverTimeBias = await this.getServerTimeBias(); + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + tokens: tokens.filter((token) => { + return token.type === 'Login'; + }), + current, + serverTimeBias + } + }); + } catch (ex) { + console.error(ex); + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }); + } + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return + case AsyncProcessStatus.SUCCESS: + const { tokens, current, serverTimeBias } = this.state.value; + return + case AsyncProcessStatus.ERROR: + return + } + } +} diff --git a/vite-app/src/apps/Auth2/AccountManager/LoginTokens/view.module.css b/vite-app/src/apps/Auth2/AccountManager/LoginTokens/view.module.css new file mode 100644 index 00000000..a3d77729 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/LoginTokens/view.module.css @@ -0,0 +1,11 @@ +.main { + flex: 1 1 0; + display: flex; + flex-direction: column; + +} + +/* Middle vertical align table cells in this module. */ +.main :global .table td { + vertical-align: middle; +} diff --git a/vite-app/src/apps/Auth2/AccountManager/LoginTokens/view.tsx b/vite-app/src/apps/Auth2/AccountManager/LoginTokens/view.tsx new file mode 100644 index 00000000..2671cb50 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/LoginTokens/view.tsx @@ -0,0 +1,233 @@ +import Empty from "components/Empty"; +import Well from "components/Well"; +import { TokenInfoFull } from "lib/kb_lib/Auth2"; +import { niceDuration, niceTime } from "lib/time"; +import { Component } from "react"; +import { Button, ButtonGroup, ButtonToolbar, Table } from "react-bootstrap"; +import styles from './view.module.css'; + +export interface LoginTokensViewProps { + tokens: Array; + currentToken: TokenInfoFull; + serverTimeBias: number; + revokeCurrentTokenAndLogout: () => void; + revokeAllTokensAndLogout: () => void; + revokeToken: (token: string) => void; + revokeAllTokens: () => void; +} + +interface LoginTokensViewState { +} + +export default class LoginTokensView extends Component { + doRevokeToken(tokenId: string) { + if (tokenId === this.props.currentToken.id) { + this.props.revokeCurrentTokenAndLogout(); + } else { + this.props.revokeToken(tokenId); + } + } + + doRevokeAllTokens() { + this.props.revokeAllTokens(); + } + + doRevokeAllTokensAndLogout() { + this.props.revokeAllTokensAndLogout(); + } + + renderTokenBrowser(tokens: Array, removeVerb: string) { + const revokeAllButton = (() => { + if (tokens.length > 1) { + return + } + })(); + const rows = tokens.map(({ id, created, expires, os, osver, agent, agentver, ip }) => { + const renderBrowser = () => { + if (agent === null) { // } || agent.agent === 0) { // TODO: what is this actual type??? + return + n/a + + } + return + {agent} + + {agentver} + + + }; + const renderOS = () => { + if (os === null) { // } || os.agent === 0) { // TODO: is that supposed to be "length"? + return + n/a + + } + return + {os} + + {osver} + + + }; + + return + + {niceTime(new Date(created))} + + + {niceDuration(expires - (Date.now() - this.props.serverTimeBias))} + + + {renderBrowser()} + + + {renderOS()} + + + {ip} + + + + + + }); + return + + + + + + + + + + + + {rows} + +
    + Created + + Expires + + Browser + + Operating System + + IP Address + + {revokeAllButton} +
    + } + + renderCurrentToken() { + return this.renderTokenBrowser([this.props.currentToken], 'Logout'); + } + + renderOtherTokens() { + if (this.props.tokens.length > 0) { + return this.renderTokenBrowser(this.props.tokens, 'Remove'); + } + return + You do not have any additional active sign-in sessions. + + } + + renderRemoveAll() { + return + + + + + } + + renderRemoveAllAndLogout() { + return + + + + + } + + renderCurrentSession() { + return + + Your Current Login Session + + + {this.renderCurrentToken()} + + + } + + renderOtherSessions() { + return + + Other Login Sessions + + + {this.renderOtherTokens()} + + + {this.renderRemoveAll()} + + + } + + renderHelp() { + return
    +

    + a sign-in session is created when you + sign in to KBase. A sign-in session is removed when you logout. + However, if you do not logout, your sign-in session will remain active for two weeks. + At the end of two weeks, the sign-in session will become invalid, and you will need to sign-in again. +

    +
    + } + + render() { + return
    + {this.renderRemoveAllAndLogout()} + {this.renderCurrentSession()} + {this.renderOtherSessions()} +
    + } +} diff --git a/vite-app/src/apps/Auth2/AccountManager/ServToken/controller.tsx b/vite-app/src/apps/Auth2/AccountManager/ServToken/controller.tsx new file mode 100644 index 00000000..798d547f --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/ServToken/controller.tsx @@ -0,0 +1,210 @@ +import ErrorAlert from "components/ErrorAlert"; +import Loading from "components/Loading"; +import { notifySuccess } from "contexts/EuropaContext"; +import { AsyncProcess, AsyncProcessStatus } from "lib/AsyncProcess"; +import { SimpleError } from 'lib/SimpleError'; +import { Auth2, Role, TokenInfoFull } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import ActiveTokensView from "./view"; + +export interface ServTokensControllerProps { + token: string; + roles: Array + authURL: string; + setTitle: (title: string) => void; +} + +export interface ServTokens { + tokens: Array; + newToken: TokenInfoFull | null; + serverTimeBias: number; +} + +type ServTokensControllerState = AsyncProcess; + + +export default class ServTokensController extends Component { + constructor(props: ServTokensControllerProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + } + } + componentDidMount() { + this.props.setTitle('Account Manager - Service Tokens'); + this.loadData(); + } + + async revokeToken(tokenToRevoke: string, name: string) { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + try { + await auth2.revokeToken(this.props.token, tokenToRevoke); + const { tokens } = await auth2.getTokens(this.props.token); + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + ...this.state.value, + tokens: tokens.filter((token) => { + return token.type === 'Service'; + }), + } + }); + + notifySuccess(`Service token "${name}" as been revoked`); + } catch (ex) { + console.error(ex); + // TODO: what now? probably send an alert + } + } + + async revokeAllTokens() { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + const authToken = this.props.token; + try { + const {tokens: currentTokens} = await auth2.getTokens(authToken); + + // All others + await Promise.all(currentTokens + .filter(({type}) => { + return type=== 'Service'; + }) + .map(({id}) => { + return auth2.revokeToken(authToken, id); + })); + + const {tokens} = await auth2.getTokens(authToken); + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + ...this.state.value, + tokens: tokens.filter((token) => { + return token.type === 'Service'; + }) + } + }); + + notifySuccess(`All service tokens have been revoked`); + } catch (ex) { + console.error(ex); + // TODO: what now? probably send an alert + } + } + + async getServerTimeBias() { + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + const { servertime } = await auth2.root(); + return servertime - Date.now(); + } + + async loadData() { + this.setState({ + status: AsyncProcessStatus.PENDING + }); + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + + try { + const { tokens } = await auth2.getTokens(this.props.token); + + const serverTimeBias = await this.getServerTimeBias(); + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + tokens: tokens.filter((token) => { + return token.type === 'Service'; + }), + newToken: null, + serverTimeBias + } + }); + } catch (ex) { + console.error(ex); + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }); + } + } + + async createServiceToken(name: string) { + const state = this.state; + if (state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + + const auth2 = new Auth2({ + baseUrl: this.props.authURL + }); + const authToken = this.props.token + try { + const newToken = await auth2.createToken(authToken, { + name, + type: 'service' + }); + + this.setState({ + ...state, + value: { + ...state.value, + newToken, + tokens: state.value.tokens.concat([newToken]) + } + }); + + notifySuccess(`New service token named "${name}" has been created`); + } catch (ex) { + console.error(ex); + // what to do - notification? + } + } + + clearNewToken() { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + this.setState({ + ...this.state, + value: { + ...this.state.value, + newToken: null + } + }); + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return + case AsyncProcessStatus.SUCCESS: + const { tokens, newToken, serverTimeBias } = this.state.value; + return + case AsyncProcessStatus.ERROR: + return + } + } +} diff --git a/vite-app/src/apps/Auth2/AccountManager/ServToken/view.module.css b/vite-app/src/apps/Auth2/AccountManager/ServToken/view.module.css new file mode 100644 index 00000000..4501cf94 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/ServToken/view.module.css @@ -0,0 +1,5 @@ +.main { + flex: 1 1 0; + display: flex; + flex-direction: column; +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/ServToken/view.tsx b/vite-app/src/apps/Auth2/AccountManager/ServToken/view.tsx new file mode 100644 index 00000000..fcfc6668 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/ServToken/view.tsx @@ -0,0 +1,253 @@ +import Empty from "components/Empty"; +import Well from "components/Well"; +import { notifySuccess } from "contexts/EuropaContext"; +import { TokenInfoFull } from "lib/kb_lib/Auth2"; +import { niceDuration, niceTime } from "lib/time"; +import { Component } from "react"; +import { Button, ButtonGroup, ButtonToolbar } from "react-bootstrap"; +import AddTokenForm from '../AddTokenForm'; +import TokenCopy from "../TokenCopy"; +import styles from './view.module.css'; + +const TOKEN_VIEWER_EXPIRES_IN = 300000; + +export interface ServTokensViewProps { + tokens: Array; + newToken: TokenInfoFull | null; + serverTimeBias: number; + revokeToken: (token: string, name: string) => void; + revokeAllTokens: () => void; + createServiceToken: (name: string) => void; + clearNewToken: () => void; +} + +interface ServTokensViewState { +} + +export default class ServTokensView extends Component { + doRevokeToken(tokenId: string, name: string) { + this.props.revokeToken(tokenId, name); + } + + doRevokeAllTokens() { + this.props.revokeAllTokens(); + } + + renderTokenBrowser(tokens: Array, removeVerb: string) { + const revokeAllButton = (() => { + if (tokens.length > 1) { + return + } + })(); + const rows = tokens.map(({ name, id, created, expires, os, osver, agent, agentver, ip }) => { + const renderBrowser = () => { + if (agent === null) { // } || agent.agent === 0) { // TODO: what is this actual type??? + return + n/a + + } + return + {agent} + + {agentver} + + + }; + const renderOS = () => { + if (os === null) { // } || os.agent === 0) { // TODO: is that supposed to be "length"? + return + n/a + + } + return + {os} + + {osver} + + + }; + + return + + {name} + + + {niceTime(new Date(created))} + + + {niceDuration(expires - (Date.now() - this.props.serverTimeBias))} + + + {renderBrowser()} + + + {renderOS()} + + + {ip} + + + + + + }); + return + + + + + + + + + + + + + {rows} + +
    + Name + + Created + + Expires + + Browser + + Operating System + + IP Address + + {revokeAllButton} +
    + } + + renderServTokens() { + if (this.props.tokens.length > 0) { + return this.renderTokenBrowser(this.props.tokens, 'Remove'); + } + return + } + + renderRemoveAll() { + return + + + + + } + + renderTokens() { + return + + Service Tokens + + + {this.renderServTokens()} + + + {this.renderRemoveAll()} + + + } + + renderHelp() { + return
    +

    + a sign-in session is created when you + sign in to KBase. A sign-in session is removed when you logout. + However, if you do not logout, your sign-in session will remain active for two weeks. + At the end of two weeks, the sign-in session will become invalid, and you will need to sign-in again. +

    +
    + } + + renderNewToken() { + if (!this.props.newToken) { + return; + } + + const onCopied = () => { + notifySuccess('Token copied to clipboard', 3000); + }; + + const onCopyError = (message: string) => { + console.log('message', message) + // this.props.runtime.notifyError( + // `Error copying token to clipboard: ${message}` + // ); + }; + + const onDone = () => { + this.props.clearNewToken(); + + // this.props.runtime.send('notification', 'notify', { + // type: 'warning', + // id: 'devtoken', + // icon: 'ban', + // message: 'The Developer Token session has been canceled', + // description: 'The Developer Token session has been canceled', + // autodismiss: 10000 + // }); + }; + + return + } + + renderNewTokenForm() { + return + + Create Service Token + + + + {this.renderNewToken()} + + + } + + render() { + return
    + {this.renderNewTokenForm()} + {this.renderTokens()} +
    + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/TermsAndConditions/controller.tsx b/vite-app/src/apps/Auth2/AccountManager/TermsAndConditions/controller.tsx new file mode 100644 index 00000000..abcb4ccd --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/TermsAndConditions/controller.tsx @@ -0,0 +1,81 @@ +import PolicyAndAgreement, { PolicyAgreement } from "apps/Auth2/SignInContinue/PolicyAndAgreement"; +import ErrorMessage from "components/ErrorMessage"; +import Loading from "components/Loading"; +import { AsyncProcess, AsyncProcessStatus } from "lib/AsyncProcess"; +import { SimpleError } from 'lib/SimpleError'; +import { Auth2 } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import TermsAndConditionsView from "./view"; + +export interface TermsAndConditionsControllerProps { + authURL: string; + token: string; + // authState: AuthenticationState, + // config: Config, + setTitle: (title: string) => void; +} + +export interface TermsAndConditions { + agreement: PolicyAgreement +} + +type TermsAndConditionsControllerState = AsyncProcess; + + +export default class TermsAndConditionsController extends Component { + constructor(props: TermsAndConditionsControllerProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + } + } + + componentDidMount() { + this.props.setTitle('Account Manager - Terms and Conditions'); + this.loadData(); + } + + async loadData() { + const auth2 = new Auth2({ baseUrl: this.props.authURL }) + + this.setState({ + status: AsyncProcessStatus.PENDING + }); + + try { + const { policyids } = await auth2.getMe(this.props.token); + + const policies = new PolicyAndAgreement({ + policyids + }); + + const policyAgreement = policies.getPolicyAgreement(); + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + agreement: policyAgreement + } + }); + } catch (ex) { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }); + } + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return + case AsyncProcessStatus.ERROR: + return + case AsyncProcessStatus.SUCCESS: + return + } + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/TermsAndConditions/view.tsx b/vite-app/src/apps/Auth2/AccountManager/TermsAndConditions/view.tsx new file mode 100644 index 00000000..4ca32b63 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/TermsAndConditions/view.tsx @@ -0,0 +1,104 @@ +import { PolicyAgreement } from "apps/Auth2/SignInContinue/PolicyAndAgreement"; +import Well from "components/Well"; +import { niceTime } from "lib/time"; +import { Component } from "react"; +import { Button, Col, Container, Form, Row } from "react-bootstrap"; + +export interface TermsAndConditionsViewProps { + agreement: PolicyAgreement; +} + +interface TermsAndConditionsViewState { + +} + +export default class TermsAndConditionsView extends Component { + renderInfo() { + return + + + + View the Terms and Conditions + +
    + +
    + + + + View the current Terms and Conditions on the KBase website. + + +
    + + + + Version + +
    {this.props.agreement.currentPolicy.version}
    + + + + The KBase Terms and Conditions is updated from time to time; each updated + has a new version. + + +
    + + + + Published At + +
    {niceTime(this.props.agreement.currentPolicy.publishedAt)}
    + + + + The KBase Terms and Conditions is updated from time to time; each updated + has a new publication date. + + +
    + + + + Agreed At + +
    {niceTime(this.props.agreement.agreement!.agreedAt)}
    + + + + When you sign up for KBase, and the first time you sign in after a new + Terms and Conditions has been published, you will need to agree to the + new T&C. We record this agreement date and time in your KBase account. + + +
    + {/* + +
    + +
    +
    {niceRelativeTime(new Date(lastlogin))} ({niceTime(new Date(lastlogin))})
    + + + + When you last signed in to KBase + + +
    */} +
    + } + render() { + return
    + + + Terms and Conditions + + + {this.renderInfo()} + + + +
    + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/TokenCopy.tsx b/vite-app/src/apps/Auth2/AccountManager/TokenCopy.tsx new file mode 100644 index 00000000..143c2e5f --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/TokenCopy.tsx @@ -0,0 +1,71 @@ +import Well from "components/Well"; +import { TokenInfoFull } from "lib/kb_lib/Auth2"; +import { niceDuration } from "lib/time"; +import { Component } from "react"; +import { Button, ButtonToolbar } from "react-bootstrap"; +import CountdownAlarmClock from "../CountdownAlarmClock"; + +const DEFAULT_EXPIRES_IN = 300000; + +export interface TokenCopyProps { + newToken: TokenInfoFull; + expiresIn: number; + onCopied: () => void; + onDone: () => void; + onCopyError: (message: string) => void; +} + +export default class TokenCopy extends Component { + render() { + let clipboardButton = null; + if (navigator && navigator.clipboard) { + const copyNewToken = async () => { + try { + await navigator.clipboard.writeText(this.props.newToken.token); + this.props.onCopied(); + } catch (ex) { + console.error(ex); + this.props.onCopyError(ex instanceof Error ? ex.message : 'Unknown Error'); + } + }; + clipboardButton = + } + return + +

    + New {this.props.newToken.type} token named {this.props.newToken.name} successfully created +

    +

    + Please copy it to a secure location and remove this message. +

    +

    + This message will self-destruct in {' '} + { return {niceDuration(timeLeft)}; }} />. +

    +

    + New Token {this.props.newToken.token} +

    + + {clipboardButton} + + +
    +
    + } +} diff --git a/vite-app/src/apps/Auth2/AccountManager/controller.tsx b/vite-app/src/apps/Auth2/AccountManager/controller.tsx new file mode 100644 index 00000000..64d6e609 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/controller.tsx @@ -0,0 +1,28 @@ +import { RouteProps } from "components/Router2"; +import { AuthenticationStateAuthenticated } from "contexts/EuropaContext"; +import { Component } from "react"; +import { Config } from "types/config"; +import AccountManagerView from "./view"; + +export interface AccountManagerControllerProps extends RouteProps { + authState: AuthenticationStateAuthenticated, + config: Config, + setTitle: (title: string) => void; + // logout: () => void; +} + +interface AccountManagerControllerState { + +} + +export default class AccountManagerController extends Component { + render() { + return ; + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/AccountManager/view.tsx b/vite-app/src/apps/Auth2/AccountManager/view.tsx new file mode 100644 index 00000000..8ec6dbc7 --- /dev/null +++ b/vite-app/src/apps/Auth2/AccountManager/view.tsx @@ -0,0 +1,241 @@ +import { AuthenticationStateAuthenticated } from "contexts/EuropaContext"; +import { navigate2 } from "lib/navigation"; +import { Component } from "react"; +import { Nav, Tab, TabContainer } from "react-bootstrap"; +import { Config } from "types/config"; +import AccountEditorController from "./Account/controller"; +import DevTokensController from "./DevToken/controller"; +import LinkedIdProvidersController from "./LinkedIDProviders/controller"; +import LoginTokensController from "./LoginTokens/controller"; +import ServTokensController from "./ServToken/controller"; +import TermsAndConditionsController from "./TermsAndConditions/controller"; + +export interface AccountManagerViewProps { + config: Config; + authState: AuthenticationStateAuthenticated, + tab?: string; + setTitle: (title: string) => void; + // logout: () => void; +} + +export default class AccountManagerView extends Component { + renderDevTokenTab() { + if (!this.props.authState.authInfo.account.roles.find(({ id }) => { + return id === 'DevToken' + })) { + return; + } + return +
    + +
    +
    + } + + renderServerTokenTab() { + if (!this.props.authState.authInfo.account.roles.find(({ id }) => { + return id === 'ServToken' + })) { + return; + } + return +
    + +
    +
    + } + + // renderx() { + // return { + // if (eventKey === null) { + // eventKey = 'account'; + // } + // // navigate(`account/${eventKey}`, {params: {tab: eventKey}}); + // navigate(`account&tab=${eventKey}`); + // }} + // unmountOnExit> + // + //
    + // + //
    + //
    + // + //
    + // + //
    + //
    + // + //
    + // + //
    + //
    + // {this.renderDevTokenTab()} + // {this.renderServerTokenTab()} + // + //
    + // + //
    + //
    + //
    + // } + + render() { + const hasServToken = this.props.authState.authInfo.account.roles.find(({ id }) => { + return id === 'ServToken' + }) + const hasDevToken = this.props.authState.authInfo.account.roles.find(({ id }) => { + return id === 'DevToken' + }) + return { + if (eventKey === null) { + eventKey = 'account'; + } + navigate2({path: `account`, params: {tab: eventKey}, type: "kbaseui"}) + // navigate(`account&tab=${eventKey}`); + }} + unmountOnExit> +
    +
    + +
    +
    + + + + + + + + + + + + { + (() => { + if (!hasServToken) { + return; + } + return + + + })() + } + + { + (() => { + if (!hasDevToken) { + return; + } + return + + ; + })() + } + + + + + +
    +
    +
    + } +} diff --git a/vite-app/src/apps/Auth2/Collapsible.css b/vite-app/src/apps/Auth2/Collapsible.css new file mode 100644 index 00000000..e36a7491 --- /dev/null +++ b/vite-app/src/apps/Auth2/Collapsible.css @@ -0,0 +1,3 @@ +.Collapsible { + +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/Collapsible.tsx b/vite-app/src/apps/Auth2/Collapsible.tsx new file mode 100644 index 00000000..1841f065 --- /dev/null +++ b/vite-app/src/apps/Auth2/Collapsible.tsx @@ -0,0 +1,48 @@ +import Well, { Variant } from "components/Well"; +import { CSSProperties, Component, PropsWithChildren, ReactNode } from "react"; +import { Button, Collapse } from "react-bootstrap"; +import './Collapsible.css'; + +export interface CollapsibleProps extends PropsWithChildren { + title: ReactNode; + variant: Variant; + style?: CSSProperties; + // Annoying to need a render prop; but the Collapse component does not take the + // standard react children prop. + render: () => JSX.Element; +} + +interface CollapsibleState { + open: boolean; +} + +export default class Collapsible extends Component { + constructor(props: CollapsibleProps) { + super(props); + this.state = { + open: false + } + } + + render() { + return
    + + + + + {this.props.render()} + + + +
    + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/CountdownAlarmClock.tsx b/vite-app/src/apps/Auth2/CountdownAlarmClock.tsx new file mode 100644 index 00000000..e19df1d2 --- /dev/null +++ b/vite-app/src/apps/Auth2/CountdownAlarmClock.tsx @@ -0,0 +1,73 @@ +import { Component } from "react"; +import CountdownClock from "./CountdownClock"; + +export interface CountdownAlarmClockProps { + expiresIn?: number; + expiresAt?: number; + onExpired: () => void; + render: (remaining: number) => JSX.Element +} + +enum CountdownAlarmClockStatus { + NONE = 'NONE', + RUNNING = 'RUNNING', + DONE = 'DONE' +} + +interface CountdownAlarmClockState { + status: CountdownAlarmClockStatus; + remaining: number +} + +export default class CountdownAlarmClock extends Component { + clock: CountdownClock; + constructor(props: CountdownAlarmClockProps) { + super(props); + this.clock = new CountdownClock({ + // tick: 1000, + expiresIn: this.props.expiresIn, + expiresAt: this.props.expiresAt, + onTick: this.onTick.bind(this), + onExpired: this.onExpired.bind(this) + }); + this.state = { + status: CountdownAlarmClockStatus.NONE, + remaining: this.clock.remaining() + }; + } + + componentDidMount() { + this.clock.start(); + } + + componentWillUnmount() { + if (this.clock === null) { + return; + } + this.clock.stop(); + } + + onTick(remaining: number) { + this.setState({ + status: CountdownAlarmClockStatus.RUNNING, + remaining + }); + } + + onExpired() { + this.props.onExpired(); + this.setState({ + status: CountdownAlarmClockStatus.DONE + }); + } + + render() { + switch (this.state.status) { + case 'NONE': + case 'RUNNING': + return this.props.render(this.state.remaining); + case 'DONE': + return this.props.render(0); + } + } +} diff --git a/vite-app/src/apps/Auth2/CountdownClock.tsx b/vite-app/src/apps/Auth2/CountdownClock.tsx new file mode 100644 index 00000000..68033980 --- /dev/null +++ b/vite-app/src/apps/Auth2/CountdownClock.tsx @@ -0,0 +1,86 @@ +const DEFAULT_TICK_INTERVAL = 250; + +export interface CountdownClockParams { + expiresAt?: number; + expiresIn?: number; + tick?: number; + onTick: (remaining: number) => void; + onExpired: () => void; +} + +enum CountdownClockStatus { + NONE = 'NONE', + RUNNING = 'RUNNING', + STOPPED = 'STOPPED' +} + +export default class CountdownClock { + params: CountdownClockParams; + targetTime: number; + tickInterval: number; + timer: number | null; + status: CountdownClockStatus + constructor(params: CountdownClockParams) { + this.params = params; + const { expiresAt, expiresIn, tick } = params; + // Either countdown until a specific time ... + if (expiresAt) { + this.targetTime = expiresAt; + // ... or for a quantity of time. + } else if (expiresIn) { + this.targetTime = new Date().getTime() + expiresIn; + } else { + console.error; + throw new Error('Either "expiresAt" or "expiresIn" must be provided'); + } + this.tickInterval = tick || DEFAULT_TICK_INTERVAL; + // this.onTick = onTick; + // this.onExpired = onExpired; + this.timer = null; + this.status = CountdownClockStatus.NONE; + } + + remaining() { + const now = new Date().getTime(); + return this.targetTime - now; + } + + tick() { + if (this.status !== 'RUNNING') { + return; + } + const remaining = this.remaining(); + try { + this.params.onTick(remaining); + } catch (ex) { + console.error(`clock onRun: ${ex instanceof Error ? ex.message : 'Unknown Error'}`); + } + if (remaining > 0) { + this.tock(); + } else { + this.params.onExpired(); + } + } + + tock() { + this.timer = window.setTimeout(() => { + if (!this.timer) { + return; + } + this.tick(); + }, this.tickInterval); + } + + start() { + this.status = CountdownClockStatus.RUNNING; + this.tick(); + } + + stop() { + this.status = CountdownClockStatus.STOPPED; + if (this.timer) { + window.clearTimeout(this.timer); + this.timer = null; + } + } +} diff --git a/vite-app/src/apps/Auth2/LinkContinue/ContinueHeader.css b/vite-app/src/apps/Auth2/LinkContinue/ContinueHeader.css new file mode 100644 index 00000000..89f71f95 --- /dev/null +++ b/vite-app/src/apps/Auth2/LinkContinue/ContinueHeader.css @@ -0,0 +1,21 @@ +.ContinueHeader { + flex: 0 0 auto; + display: flex; + flex-direction: row; + padding-bottom: 0.25em; + margin-bottom: 0.25em; + /* border-bottom: 1px solid rgba(200, 200, 200, 0.5); */ +} + +.ContinueHeader .-col1 { + flex: 1 1 0; + font-weight: bold; + font-size: 120%; + display: flex; + flex-direction: row; + align-items: center; +} + +.ContinueHeader .-col2 { + flex: 0 0 auto; +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/LinkContinue/ContinueHeader.tsx b/vite-app/src/apps/Auth2/LinkContinue/ContinueHeader.tsx new file mode 100644 index 00000000..3f5bd1ce --- /dev/null +++ b/vite-app/src/apps/Auth2/LinkContinue/ContinueHeader.tsx @@ -0,0 +1,59 @@ +import CountdownClock from "components/CountdownClock"; +import { LinkChoice } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import { Alert } from "react-bootstrap"; +import TextSpan from "../TextSpan"; +import './ContinueHeader.css'; + +export interface ContinueHeaderProps { + choice: LinkChoice; + serverTimeOffset: number; + name: string; + cancelChoiceSession: () => void; +} + +export default class ContinueHeader extends Component { + render() { + if (this.props.choice === null) { + return; + } + // const render = (remainingTime: number) => { + // if (remainingTime > 0) { + // return
    + // + //
    + // You have + // ${niceDuration(remainingTime)} + // to complete ${this.props.name}. + //
    + //
    + //
    + // } + // }; + + // return
    + //
    + //
    + //
    + // {/* */} + // You have {' '}to complete sign-in. + //
    + //
    + + return + You have to complete sign-in. + + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/LinkContinue/controller.tsx b/vite-app/src/apps/Auth2/LinkContinue/controller.tsx new file mode 100644 index 00000000..33ce2932 --- /dev/null +++ b/vite-app/src/apps/Auth2/LinkContinue/controller.tsx @@ -0,0 +1,270 @@ +import ErrorAlert from "components/ErrorAlert"; +import Loading from "components/Loading"; +import { AuthenticationStateAuthenticated, notifySuccess } from "contexts/EuropaContext"; +import { AsyncProcess, AsyncProcessStatus } from "lib/AsyncProcess"; +import { Auth2, LinkChoice } from "lib/kb_lib/Auth2"; +import { AuthError } from "lib/kb_lib/Auth2Error"; +import { navigate } from "lib/navigation"; +import { Component } from "react"; +import { Button } from "react-bootstrap"; +import { Config } from "types/config"; +import { AlmostSimpleError } from "../SignInContinue/SignInContinue"; +import TextSpan from "../TextSpan"; +import LinkContinueView from "./view"; + + +export interface LinkContinueControllerProps { + authState: AuthenticationStateAuthenticated; + config: Config; + setTitle: (title: string) => void; +} + +export interface LinkController { + linkChoice: LinkChoice; + serverTimeOffset: number; +} + +type LinkContinueControllerState = AsyncProcess; + +export default class LinkContinueController extends Component { + constructor(props: LinkContinueControllerProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + }; + } + componentDidMount() { + this.start(); + } + + async cancelLink(message: string) { + const auth2Client = new Auth2({ + baseUrl: this.props.config.services.Auth2.url + }); + try { + await auth2Client.linkCancel(); + notifySuccess(message, 3000); + this.returnToLinkingTab(); + } catch (ex) { + console.error(ex); + // if (ex instanceof AuthError) { + // if (ex.code === '10010') { + // // simply continue + // } else { + // throw ex; + // } + // } + } + } + + returnToLinkingTab() { + navigate('account', { + params: { + tab: 'links' + } + }); + } + + async linkIdentity() { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + const authToken = this.props.authState.authInfo.token + const auth2 = new Auth2({ + baseUrl: this.props.config.services.Auth2.url + }); + + try { + await auth2.linkPick(authToken, this.state.value.linkChoice.id); + // this.props.runtime.notifySuccess('Successfully linked identity', 3000); + navigate('account', { + params: { + tab: 'links' + } + }); + } catch (ex) { + console.error(ex); + // this.props.runtime.notifyError( + // `Error linking: ${ex.message}` + // ); + } + } + + renderCancelAndReturnButton() { + return + } + + renderReturnButton() { + return + } + + async start() { + try { + this.setState({ + status: AsyncProcessStatus.PENDING + }); + + this.props.setTitle('Link a Provider'); + + const authToken = this.props.authState.authInfo.token + const auth2Client = new Auth2({ + baseUrl: this.props.config.services.Auth2.url + }); + + const root = await auth2Client.root(); + + const serverTimeOffset = new Date().getTime() - root.servertime; + + const linkChoice = await auth2Client.getLinkChoice(authToken); + const { canlink, linkeduser, provider, provusername } = linkChoice; + + const currentUsername = this.props.authState.authInfo.account.user; + + if (!canlink) { + if (linkeduser === currentUsername) { + const message =
    +

    + Sorry, you have already linked your current KBase account + {currentUsername} + to this + {provider} + sign-in account + {provusername} +

    +

    + A sign-in account may only be linked once to any KBase account. +

    +

    + You may {this.renderCancelAndReturnButton()} + and start again, this time choosing a different sign-in account to link to. +

    +
    + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Sign-in account already linked', + message + } + }); + return; + } + const message =
    +

    + Sorry, you have already linked this + {provider} + sign-in account + {provusername} + to the KBase account + {linkeduser} +

    +

    + A sign-in account may only be linked once to any KBase account. +

    +

    + You may {this.renderCancelAndReturnButton()} and start again, this time choosing a different sign-in account to link to. +

    +
    + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Sign-in account already linked', + message + } + }); + return; + } + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + linkChoice, + serverTimeOffset + } + }); + } catch (ex) { + console.error(ex); + if (ex instanceof AuthError) { + if (ex.code === '10010') { + const message =
    +

    A linking session was not found. This may be due to the expiration of the linking session, + which is valid for 10 minutes. Or it may be because you have visited this path from your browser history.

    +

    You may {this.renderReturnButton()} and try to link again.

    +
    ; + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Link Session Expired or Missing', + message + } + }); + } else if (ex.code === '10020') { + const message =
    +

    The linking session has expired. A linking session is valid for 30 minutes.

    +

    +
    + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Linking Session Expired', + message + } + }); + } else { + const message =
    +

    The linking session has experienced an error ({ex.code})

    +
    + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Linking Session Error', + message + } + }); + } + } else { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Error', + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }); + } + } + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return + case AsyncProcessStatus.SUCCESS: { + const { + linkChoice, + serverTimeOffset + } = this.state.value; + return + } + // case AsyncProcessStatus.ERROR: + // return html` + // <${Alert} variant="warning" title=${this.state.title} showIcon=${true} showTitle=${true} message=${this.state.message} /> + // `; + case AsyncProcessStatus.ERROR: + return + {this.state.error.message} + + } + } +} diff --git a/vite-app/src/apps/Auth2/LinkContinue/view.css b/vite-app/src/apps/Auth2/LinkContinue/view.css new file mode 100644 index 00000000..f03e4dd4 --- /dev/null +++ b/vite-app/src/apps/Auth2/LinkContinue/view.css @@ -0,0 +1,5 @@ +.LinkContinue { + flex: 1 1 0; + display: flex; + flex-direction: column; +} diff --git a/vite-app/src/apps/Auth2/LinkContinue/view.tsx b/vite-app/src/apps/Auth2/LinkContinue/view.tsx new file mode 100644 index 00000000..daf683b5 --- /dev/null +++ b/vite-app/src/apps/Auth2/LinkContinue/view.tsx @@ -0,0 +1,61 @@ +import Well from "components/Well"; +import { LinkChoice } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import { Button, ButtonToolbar } from "react-bootstrap"; +import { providerLabel } from "../Providers"; +import TextSpan from "../TextSpan"; +import ContinueHeader from "./ContinueHeader"; + +export interface LinkContinueViewProps { + linkChoice: LinkChoice + serverTimeOffset: number; + cancelLink: (message: string) => void; + linkIdentity: () => void; +} + +interface LinkContinueViewState { + +} + +export default class LinkContinueView extends Component { + renderContinueDialog() { + return
    +

    + You have requested to link the + {providerLabel(this.props.linkChoice.provider)} account + {this.props.linkChoice.provusername} to your KBase account + {this.props.linkChoice.user} +

    + + + + +
    + } + render() { + return
    + { + this.props.cancelLink('Your Linking session has expired'); + }} + serverTimeOffset={this.props.serverTimeOffset} + /> + + + Ready to Link + + + {this.renderContinueDialog()} + + +
    + } +} diff --git a/vite-app/src/apps/Auth2/Providers.ts b/vite-app/src/apps/Auth2/Providers.ts new file mode 100644 index 00000000..f5828fe6 --- /dev/null +++ b/vite-app/src/apps/Auth2/Providers.ts @@ -0,0 +1,79 @@ +import { IDProvider } from "types/config"; + +import globusButtonLogo from './resources/providers/globus/logo.png'; +import googleButtonLogo from './resources/providers/google/logo.png'; +import orcidButtonLogo from './resources/providers/orcid/logo.png'; + + +// Unfortunately the auth service does not have a concept of the +// "official label" for an id provider. +export function renderProviderLabel(providerId: string) { + return { + OrcID: 'ORCID', + Google: 'Google', + Globus: 'Globus' + }[providerId] || 'Unknown'; +} + +export function providerLogoSrc(providerId: string) { + switch (providerId) { + case 'Google': + return googleButtonLogo; + case 'Globus': + return globusButtonLogo; + case 'OrcID': + return orcidButtonLogo; + default: + return null; + } +} + +export function providerLabel(providerId: string) { + switch (providerId) { + case 'Google': + return 'Google'; + case 'Globus': + return 'Globus'; + case 'OrcID': + return 'ORCiD'; + default: + return null; + } +} + + +export interface ProvidersParams { + supportedProviders: Array; + providers?: Array; +} + +export class Providers { + providers: Array + constructor({supportedProviders, providers}: ProvidersParams) { + this.providers = supportedProviders + .filter((provider) => { + if (providers) { + return providers.includes(provider.id); + } + return true; + + }); + this.sortByPriority(); + } + + sortByPriority() { + this.providers.sort((a, b) => { + const priorityOrder = a.priority - b.priority; + if (priorityOrder !== 0) { + return priorityOrder; + } + + const labelOrder = a.label < b.label ? -1 : (a.label > b.label ? 0 : 1); + return labelOrder; + }); + } + + get() { + return this.providers; + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/SignIn/SignIn.tsx b/vite-app/src/apps/Auth2/SignIn/SignIn.tsx new file mode 100644 index 00000000..02bd2e8c --- /dev/null +++ b/vite-app/src/apps/Auth2/SignIn/SignIn.tsx @@ -0,0 +1,174 @@ +import ErrorMessage from "components/ErrorMessage"; +import Loading from "components/Loading"; +import { RouteProps } from "components/Router2"; +import { AuthenticationState, AuthenticationStatus } from "contexts/EuropaContext"; +import { AsyncProcess, AsyncProcessStatus } from "lib/AsyncProcess"; +import { NextRequestObject } from "lib/NextRequest"; +import { SimpleError } from 'lib/SimpleError'; +import { navigate2 } from "lib/navigation"; +import { Component } from "react"; +import { Config } from "types/config"; +import { SignInSource, SignInView } from "./SignInView"; + +export interface SignInParams { + nextrequest: string; +} + +export interface SignInProps extends RouteProps { + // params: SignInParams + // nextrequest: string, + authState: AuthenticationState, + config: Config, + source: SignInSource; + setTitle: (title: string) => void; +} + +export interface SignInSuccessState { + nextRequest: NextRequestObject | null +} + +export type SignInState = AsyncProcess; + + +export class SignIn extends Component { + constructor(props: SignInProps) { + super(props); + + this.state = { + status: AsyncProcessStatus.NONE + }; + } + + componentDidMount() { + this.prepare(); + } + + /** + * We use this lifecycle call because the sign-in component may be invoked + * repeatedly without any inetervening route if the user clicks on buttons or links + * which cause the signin compnent to be rendered for different target paths. + * + * The incoming prop for the hash path will have changed, but this will not + * naturally cause the re-rendering of the sign in component. We need it to + * re-render as part of the ui represents the "sign in required" notification which + * reflects the route the user intended to invoke w/o auth. + * + * Actually, the other approach is now used -- to place a key on the invocation of + * this component - with that key being the hash path of the target route. That + * causes this component to be remounted when the hash path changes. + * + * @param prevProps + * @param prevState + */ + // componentDidUpdate(prevProps: SignInProps, _: SignInState) { + // // TODO: should also compare params. + // if (prevProps.hashPath.hash !== this.props.hashPath.hash) { + // this.prepare(); + // } + // } + + getNextRequest(): NextRequestObject | null { + if (this.props.hashPath.params && Object.keys(this.props.hashPath.params).includes('nextrequest')) { + return JSON.parse(this.props.hashPath.params['nextrequest']!); + } + return null; + } + + // ?source=authorization&nextrequest=%7B%22realPath%22%3A%22%2F%22%2C%22path%22%3A%5B%22feeds%22%5D%2C%22original%22%3A%22feeds%22%2C%22query%22%3A%7B%7D%7D#login + async prepare() { + try { + this.setState({ + status: AsyncProcessStatus.PENDING + }); + + // If we land here and are logged in already, + // just go to the "dashboard" + const nextRequest = this.getNextRequest(); + + if (this.props.authState.status === AuthenticationStatus.AUTHENTICATED) { + if (nextRequest) { + // navigate(nextRequest.hash, nextRequest.params); + navigate2(nextRequest.path); + } else { + // TODO: navigate to default path... + navigate2({path: 'dashboard', type: 'kbaseui'}); + } + return; + } + + // await this.cancelLogin(); + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + nextRequest + } + }); + } catch (ex) { + const message = ex instanceof Error ? ex.message : 'Unknown error'; + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message + } + }); + } + } + + // async cancelLogin() { + // const auth2Client = new auth2.Auth2({ + // baseUrl: this.props.runtime.config('services.auth.url') + // }); + // try { + // await await auth2Client.loginCancel(); + // } catch (ex) { + // if (ex instanceof Auth2Error.AuthError) { + // if (ex.code !== '10010') { + // throw ex; + // } + // } + // } + // } + + renderPending() { + return + } + + renderError(message: string) { + return + } + + renderSuccess({ nextRequest }: SignInSuccessState) { + const whitelistedProviders = this.props.config.services.Auth2.providers; + const supportedProviders = this.props.config.services.Auth2.supportedProviders; + const providers = supportedProviders.filter((({ id }) => { + return whitelistedProviders.includes(id); + })); + + // TRY OUR origin + // const url = new URL(this.props.config.deploy.ui.origin); + // url.hostname = `legacy.${url.hostname}`; + // url.hostname = `FOO.${url.hostname}`; + // const origin = url.origin; + + return + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return this.renderPending(); + case AsyncProcessStatus.SUCCESS: + return this.renderSuccess(this.state.value); + case AsyncProcessStatus.ERROR: + return this.renderError(this.state.error.message); + } + } +} diff --git a/vite-app/src/apps/Auth2/SignIn/SignInButton.css b/vite-app/src/apps/Auth2/SignIn/SignInButton.css new file mode 100644 index 00000000..3cbea61d --- /dev/null +++ b/vite-app/src/apps/Auth2/SignIn/SignInButton.css @@ -0,0 +1,25 @@ +.SignInButton { + text-align: center; + margin: 4px; + padding: 4px; + position: relative; +} + +.SignInButton img { + cursor: pointer; +} + +.SignInButton .-loading { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; + padding-top: 4px; + pointer-events: none; +} + +.SignInButton .-loading > fa { + color: #FFF; +} diff --git a/vite-app/src/apps/Auth2/SignIn/SignInButton.tsx b/vite-app/src/apps/Auth2/SignIn/SignInButton.tsx new file mode 100644 index 00000000..7168c5a1 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignIn/SignInButton.tsx @@ -0,0 +1,84 @@ +import { Component } from 'react'; +import { Button } from 'react-bootstrap'; +import { IDProvider } from 'types/config'; +import globusButtonLogo from '../resources/providers/globus/logo.png'; +import googleButtonLogo from '../resources/providers/google/logo.png'; +import orcidButtonLogo from '../resources/providers/orcid/logo.png'; + +import './SignInButton.css'; + +export interface SignInButtonProps { + provider: IDProvider; + doSignIn: () => void; +} + +interface SignInButtonState { + loading: boolean; + imageState: string; +} + +export default class SignInButton extends Component { + constructor(props: SignInButtonProps) { + super(props); + this.state = { + loading: false, + imageState: 'normal' + }; + } + + renderSpinner() { + if (this.state.loading) { + return
    + +
    + } + } + + doSignIn() { + this.setState({ + loading: true, + imageState: 'disabled' + }, () => { + this.props.doSignIn(); + }); + } + + providerLogoSrc() { + switch (this.props.provider.id) { + case 'Google': + return googleButtonLogo; + case 'Globus': + return globusButtonLogo; + case 'OrcID': + return orcidButtonLogo; + default: + return null; + } + } + + renderProviderButtonLogo() { + const logoSrc = this.providerLogoSrc(); + if (logoSrc) { + return {this.props.provider.label} + } else { + return {this.props.provider.label} + } + } + + render() { + const buttonLabel = `Sign In button for the ${this.props.provider.label} identity provider`; + return + } +} diff --git a/vite-app/src/apps/Auth2/SignIn/SignInControls.css b/vite-app/src/apps/Auth2/SignIn/SignInControls.css new file mode 100644 index 00000000..1708d5d0 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignIn/SignInControls.css @@ -0,0 +1,67 @@ +.SignInControls { + +} + +.SignInControls .-row { + display: flex; + flex-direction: row +} + +.SignInControls .-col { + flex: 1 1 0; + display: flex; + flex-direction: column; +} + +.SignInControls .-col .-header { + text-align: center; + font-weight: bold; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + height: 30px; +} + +.SignInControls .-col .-header .-icon { + margin: 0 0.25rem; +} + +.SignInControls .-col .-header .-label { + margin: 0 0.25rem; + font-size: 120%; +} + +.SignInControls .-col .-body { + flex: 1 1 0; + /* margin-bottom: 20px; */ + padding: 4px; + text-align: center; + display: flex; + flex-direction: column; +} + +.SignInControls .-col .-row-fill-height { + flex: 1 1 0; + display: flex; + flex-direction: column; + justify-content: flex-end; + align-items: center; +} + +.SignInControls .-signup-button { + text-align: center; + margin-top: 10px; + width: 180px; + + font-weight: bold; + display: inline-flex; + flex-direction: row; + justify-content: center; + align-items: center; +} + +.SignInControls .-signup-button > .-label { + margin-left: 0.5em; +} + diff --git a/vite-app/src/apps/Auth2/SignIn/SignInControls.tsx b/vite-app/src/apps/Auth2/SignIn/SignInControls.tsx new file mode 100644 index 00000000..0130242c --- /dev/null +++ b/vite-app/src/apps/Auth2/SignIn/SignInControls.tsx @@ -0,0 +1,240 @@ +import Well from 'components/Well'; +import { NextRequestObject } from 'lib/NextRequest'; +import { Component } from 'react'; +import { Button, Col, Container, Row } from 'react-bootstrap'; +import { QuestionCircle } from 'react-bootstrap-icons'; +import { IDProvider } from 'types/config'; +import SignInButton from './SignInButton'; +import './SignInControls.css'; +import { SignInMode } from './SignInView'; + + +export interface SignInControlsProps { + authRequired: boolean; + nextRequest?: NextRequestObject; + providers: Array; + // assetsPath: string; + mode: SignInMode; + chooseSignUp: () => void; + chooseSignIn: () => void; + go: (provider: IDProvider) => void; +} + +interface SignInControlsState { + +} + +export default class SignInControls extends Component { + renderWillRedirect() { + const nextRequest = this.props.nextRequest; + if (typeof nextRequest === 'undefined' || nextRequest === null) { + return; + } + const {path: {path}, label} = nextRequest; + const pathLabel = + {' '} + {label || path} + ; + + return + + Redirect after Sign In + + +

    + After signing in, your browser will be redirected back to {pathLabel}. +

    +
    +
    + + } + + renderAuthorizationRequired() { + const nextRequest = this.props.nextRequest; + if (typeof nextRequest === 'undefined' || nextRequest === null) { + return; + } + const {path: {path}, label} = nextRequest; + const pathLabel = + {' '} + {label || path} + ; + + return + + Sign In Required + + +

    + Sign In is required to access {pathLabel}. +

    +

    + After signing in, your browser will be redirected back to {pathLabel}. +

    +
    +
    + + } + + renderProviders() { + const buttons = this.props.providers.map((provider) => { + return + { this.props.go(provider); }} + /> + ; + }); + return + + {buttons} + + + } + + renderSignupButton() { + switch (this.props.mode) { + case 'signin': + return + case 'signup': + return + } + } + + renderHelpLink() { + return + } + + renderSignInOrUpHeader() { + return
    + + + Sign In + + + or + + + + Sign Up + +
    + } + + renderPromptx() { + switch (this.props.mode) { + case 'signin': + return
    +
    + + + New to KBase? + +
    +
    +
    + {this.renderSignupButton()} +
    +
    +
    + case 'signup': + return
    +
    + + + Have a KBase Account? + +
    +
    +
    + {this.renderSignupButton()} +
    +
    +
    + } + } + + renderPrompt() { + return
    +

    + Whether you have a KBase account or not, your next step is to choose an + "Identity Provider" on the left. We currently support sign in in with Google, + ORCiD, and Globus +

    + +

    + If you are signing up, you will first sign in with one of the ID Providers, give + permission to KBase, then complete the KBase sign up form. After signing up, you + may continue to sign in to KBase using the ID Provider you originally selected. +

    + +

    + If you are signing in, you should choose the ID Provider you originally + signed up with, or subsequently linked to your account. +

    +
    + } + + + renderLoginControls() { + // TODO: switch to bootstrap grid here. + return
    +
    + {this.renderSignInOrUpHeader()} +
    + with one of our Identity Provider partners +
    +
    +
    + {this.renderProviders()} +
    +
    +
    + {this.renderPrompt()} +
    + } + + render() { + return
    + {this.props.authRequired ? this.renderAuthorizationRequired() : this.renderWillRedirect()} + + + {this.renderLoginControls()} + + + {this.renderHelpLink()} + + +
    + } +} diff --git a/vite-app/src/apps/Auth2/SignIn/SignInView.tsx b/vite-app/src/apps/Auth2/SignIn/SignInView.tsx new file mode 100644 index 00000000..b723917b --- /dev/null +++ b/vite-app/src/apps/Auth2/SignIn/SignInView.tsx @@ -0,0 +1,381 @@ +import { AuthenticationState, AuthenticationStatus } from "contexts/EuropaContext"; +import { Auth2 } from "lib/kb_lib/Auth2"; +import { AuthError } from "lib/kb_lib/Auth2Error"; +import { navigate, navigate2 } from "lib/navigation"; +import AutoPostForm from "pluginSupport/AutoPostForm"; +import { Component } from "react"; +import { IDProvider } from "types/config"; + +import { navigationPathToURL } from "contexts/RouterContext"; +import { NextRequestObject } from "lib/NextRequest"; +import kbaseLogo from "../resources/images/kbase-logo-99.png"; +import SignInControls from "./SignInControls"; + +/** + * Sign in can be triggered in two scenarios. + * + * - login - the user clicks the login button + * - authentication - the user attempts to access a resource which requires authentication. + */ +export type SignInSource = 'login' | 'authorization'; + +export interface SignInViewProps { + source: SignInSource; + providers: Array; + authURL: string; + authState: AuthenticationState; + nextRequest?: NextRequestObject; + setTitle: (title: string) => void; +} + +export type SignInMode = 'signup' | 'signin'; +export type SignInStatus = 'choosing' | 'go'; + +export interface SignInStateBase { + mode: SignInMode + status: SignInStatus; +} + +export interface SignInStateChoosing extends SignInStateBase { + status: 'choosing' +} + +export interface SignInStateSignIn extends SignInStateBase { + mode: 'signin', + status: 'go'; + provider: IDProvider; +} + +export interface SignInStateSignUp extends SignInStateBase { + mode: 'signup', + status: 'go'; + provider: IDProvider; +} + +export type SignInState = SignInStateChoosing | SignInStateSignIn | SignInStateSignUp; + + +interface SignInViewState { + signInState: SignInState +} + +export class SignInView extends Component { + constructor(props: SignInViewProps) { + super(props); + this.state = { + signInState: {mode: 'signin', status: 'choosing'} + } + } + componentDidMount() { + if (!this.possiblyRedirect()) { + const {mode, status} = this.state.signInState; + switch (status) { + case 'choosing': + switch (mode) { + case 'signin': + this.props.setTitle('KBase Sign In'); + break; + case 'signup': + this.props.setTitle('Sign Up for KBase'); + break; + } + } + } + } + + async cancelLogin() { + const auth2Client = new Auth2({ + baseUrl: this.props.authURL + }); + try { + await await auth2Client.loginCancel(); + } catch (ex) { + if (ex instanceof AuthError) { + if (ex.code !== '10010') { + throw ex; + } + } + } + } + + doRedirect(nextRequest?: NextRequestObject) { + if (nextRequest) { + try { + // const {hash, params} = nextRequest; + // navigate(hash, {params}); + // this.props.runtime.send('app', 'navigate', nextRequest); + navigate2(nextRequest.path); + } catch (ex) { + navigate('dashboard'); + } + } else { + navigate('dashboard'); + } + } + + possiblyRedirect() { + // if is logged in, just redirect to the nextrequest, + // or the nexturl, or dashboard. + + if (this.props.authState.status === AuthenticationStatus.AUTHENTICATED) { + this.doRedirect(this.props.nextRequest); + return true; + } + // TODO: restore this; it appears to handle the case of sitting on the signin + // page and then receiving a loggedin message, triggering a redirect to the next + // request. + // this.listeners.push( + // this.props.runtime.recv('session', 'loggedin', () => { + // this.doRedirect(nextRequest); + // }) + // ); + return false; + } + + /** + * Create a "redirect url" to be provided to the auth service. + * + * This url is not actually used as the target of redirection - rather it must + * match the redirect url base URL registered for the auth environment (determined + * by the auth service hostname we call). The state param is extracted from the + * redirect url and placed onto the configured redirect url actually used. + */ + makeRedirectURL() { + const params: Record = { + state: JSON.stringify({ + nextrequest: this.props.nextRequest, + origin + }) + }; + + // const search = Object.keys(query) + // .map((key) => { + // return [key, encodeURIComponent(query[key])].join('='); + // }) + // .join('&'); + + // The logical app origin is now provided by configuration, as the + // plugin/kbase-ui is probably running on a sub-domain host. + + // const appOrigin = this.props.origin; + + // return `${appOrigin}?${search}`; + + return navigationPathToURL({path: '', type: 'europaui', params }, false).toString(); + }; + + async doSignIn(provider: IDProvider) { + const auth2Client = new Auth2({ + baseUrl: this.props.authURL + }); + + try { + await auth2Client.loginCancel(); + } catch (ex) { + if (ex instanceof AuthError) { + // ignore this specific error... + if (ex.code !== '10010') { + // TODO: set error state + throw ex; + } + } else { + // TODO: show error. + console.error('Skipping error', ex); + } + } + + this.setState({ + signInState: { + mode: 'signin', + status: 'go', + provider + } + }); + } + + + async doSignUp(provider: IDProvider) { + const auth2Client = new Auth2({ + baseUrl: this.props.authURL + }); + + try { + await auth2Client.loginCancel(); + } catch (ex) { + if (ex instanceof AuthError) { + // ignore this specific error... + if (ex.code !== '10010') { + // TODO: set error state + throw ex; + } + } else { + // TODO: show error. + console.error('Skipping error', ex); + } + } + + this.setState({ + signInState: { + mode: 'signup', + status: 'go', + provider + } + }) + } + + // /** + // * + // * Primarily just redirects to the signup page. + // * + // * + // */ + // async doSignUp() { + // const auth2Client = new Auth2({ + // baseUrl: this.props.authURL + // }); + + // try { + // await auth2Client.loginCancel(); + // } catch (ex) { + // if (ex instanceof AuthError) { + // // ignore this specific error... + // if (ex.code !== '10010') { + // throw ex; + // } + // } else { + // // TODO: show error. + // console.error('Skipping error', ex); + // } + // } + // // don't care whether it succeeded or failed. + // // const params: Record = { + // // provider: provider.id, + // // redirecturl: this.makeRedirectURL() + // // // not used + // // // stayloggedin: false + // // }; + + // navigate('signup'); + // } + + chooseSignIn() { + this.setState ({ + signInState: { + ...this.state.signInState, + mode: 'signin' + } + }) + } + + chooseSignUp() { + this.setState ({ + signInState: { + ...this.state.signInState, + mode: 'signup' + } + }) + } + + doGo(provider: IDProvider) { + this.setState({ + signInState: { + ...this.state.signInState, + status: 'go', + provider + } + }) + } + + renderSigninChoosing() { + const source = this.props.source; + return
    +
    +
    + +

    + Welcome to KBase +

    +
    +
    +

    + A collaborative, open environment for systems biology of plants, microbes and their communities +

    +
    +
    + +
    + } + + renderSignInSignIn(provider: IDProvider) { + const redirectURL = this.makeRedirectURL(); + + const params: Record = { + provider: provider.id, + redirecturl: redirectURL + }; + + const action = `${this.props.authURL}/login/start`; + + return + } + + renderSignInSignUp(provider: IDProvider) { + const redirectURL = this.makeRedirectURL(); + + const params: Record = { + provider: provider.id, + redirecturl: redirectURL, + }; + + const action = `${this.props.authURL}/login/start`; + + return + } + + + render() { + const {mode, status} = this.state.signInState; + switch (status) { + case 'choosing': return this.renderSigninChoosing(); + case 'go': + switch (mode) { + case 'signin': return this.renderSignInSignIn(this.state.signInState.provider); + case 'signup': return this.renderSignInSignUp(this.state.signInState.provider); + } + } + } +} diff --git a/vite-app/src/apps/Auth2/SignInContinue/CheckUsernameField.tsx b/vite-app/src/apps/Auth2/SignInContinue/CheckUsernameField.tsx new file mode 100644 index 00000000..0b4e7a99 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/CheckUsernameField.tsx @@ -0,0 +1,61 @@ +import { Button } from "antd"; +import { Component } from "react"; + +export interface CheckUsernameFieldProps { + disabled: boolean; + value?: CheckState; + username?: string; + onChange?: (newValue: string) => void; // (event: ChangeEvent) => void + checkUsername: (username: string) => Promise +} + +export type CheckState = "na" | "required" | "available" | "unavailable"; + +interface CheckUsernameFieldState { + +} + +export default class CheckUsernameField extends Component { + renderStatus() { + switch (this.props.value) { + case "na": + return ""; + case "required": + return Please check if this username is available + case "available": + return Username {this.props.username} available for you to use + case "unavailable": + return Username {this.props.username} is not available + } + } + + + render() { + return
    + {/* */} + + + {' '} + {this.renderStatus()} +
    + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/SignInContinue/Policy.ts b/vite-app/src/apps/Auth2/SignInContinue/Policy.ts new file mode 100644 index 00000000..49ead29a --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/Policy.ts @@ -0,0 +1,83 @@ +import policyData from '../resources/agreements/terms-and-conditions.json'; + +/** + * These interfaces model the policy data stored in policies.json. + * Note that this is a long-term stopgap -- the policies should be served + * up by a service, like the auth service. + */ + +export interface PolicyDataVersion { + version: number; + publishedAt: string; + url: string; +} + +export interface PolicyData { + id: string; + title: string; + versions: Array +} + + + +export interface TermsAndConditionsPolicyVersion { + version: number; + publishedAt: Date; + url: URL; +} + +export interface TermsAndConditionsPolicy { + id: string; + title: string; + versions: Array +} + +export interface CurrentTermsAndConditionsPolicy { + id: string; + title: string; + version: number; + publishedAt: Date; + url: URL; +} + +const POLICY: TermsAndConditionsPolicy = { + id: policyData.id, + title: policyData.title, + versions: policyData.versions.map(({ version, publishedAt, url }) => { + return { + version, url: new URL(url), + publishedAt: new Date(publishedAt) + }; + }) +} + + +export default class Policy { + _policy: TermsAndConditionsPolicy = POLICY; + + currentPolicy(): CurrentTermsAndConditionsPolicy { + const now = Date.now(); + let currentVersion: TermsAndConditionsPolicyVersion | null = null; + for (const policyVersion of this._policy.versions) { + // If the publication of the T&C is in the future, we are done. + if (policyVersion.publishedAt.getTime() > now) { + break; + } + + // Otherwise, we continue marching through the T&C, bookmarking + // as we go. + + currentVersion = policyVersion; + } + + if (!currentVersion) { + throw new Error('No current T&C policy') + } + + return {id: this._policy.id, title: this._policy.title, ...currentVersion} + } + + policy(): TermsAndConditionsPolicy { + return this._policy; + } +} diff --git a/vite-app/src/apps/Auth2/SignInContinue/PolicyAndAgreement copy.ts b/vite-app/src/apps/Auth2/SignInContinue/PolicyAndAgreement copy.ts new file mode 100644 index 00000000..6d06cab3 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/PolicyAndAgreement copy.ts @@ -0,0 +1,293 @@ +// define([ +// 'bluebird', +// 'marked', +// 'lib/utils', +// 'kb_common_ts/Auth2', +// 'lib/Features' +// ], ( +// Promise, +// marked, +// Utils, +// auth2, +// Features +// ) => { + +import { UserPolicy } from "lib/kb_lib/Auth2"; + +import policiesData from '../resources/agreements/policies.json'; + +const policies = policiesData as unknown as Policies + +/** + * These interfaces model the policy data stored in policies.json. + * Note that this is a long-term stopgap -- the policies should be served + * up by a service, like the auth service. + */ + +export interface PolicyVersionBase { + version: number; + begin: string; + end?: string; +} + +export interface PolicyVersionWithDocument extends PolicyVersionBase { + document: string; +} + +export interface PolicyVersionWithURL extends PolicyVersionBase { + url: string; +} + +export type PolicyVersion = PolicyVersionWithDocument | PolicyVersionWithURL; + +export interface Policy { + id: string; + title: string; + versions: Array +} + +export type Policies = Array; + +export interface UserPolicyAgrement { + id: string; + version: number; + agreedAt: Date; +} + +/** + * This structure represents a policy and version in relation to the + * current user, and helps answer the question - which policies have been agreed to, + * which not yet, which are not yet effective, which are expired, etc. + */ + +export type PolicyAgreementStatus = 'expired' | 'new' | 'current' | 'updated'; + +export interface PolicyAgreement { + id: string; + version: number; + title: string; + publishedAt: Date; + expiredAt: Date | null; + agreedAt: Date | null; + status: PolicyAgreementStatus; + statusSort: number; + url: string | null; + document: string | null; +} + +/** + * Differentiated from a "UserPolicy" (probablyl better named "PolicyAgreement") because + * this one does not have an agreement timestamp, and the id and version or separated (!). + * The latter is a quirk of the auth2 api. The reason for the lack of timestamp is that + * the timestamp is added when the login "choice" is submitted, along with any "pending" + * new policy agreements. + */ +export interface PendingPolicyAgreement { + id: string; + version: number; +} + +export interface PolicyAndAgreementParams { + // authURL: string; + // authorization: string; + policyids: Array; // from the auth service user record +} + + + +export default class PolicyAndAgreement { + // auth2Client: Auth2; + policyAgreements: Array; + constructor({policyids}: PolicyAndAgreementParams) { + // this.runtime = runtime; + const userAgreements = this.parsePolicyAgreements(policyids); + this.policyAgreements = this.getPolicyAgreements(userAgreements); + // this.useAgreements = null; + + // this.auth2Client = new Auth2({ + // baseUrl: authURL + // }); + } + + // getLatestPolicies() { + // return policies.map(({id, title, versions}) => { + // const latestVersionId = Math.max.apply( + // null, + // versions.map((version) => { + // return version.version; + // }) + // ); + // const {version, begin, end, document} = versions.filter((version) => { + // return version.version === latestVersionId; + // })[0]; + + // return { + // id, title, version, begin, end, document + // }; + // }); + // } + + /** + * Returns all policies. + * The policy versions are modified to add a flag indicating whether + * the policy is covered by an agreement (isAgreedTo). + * + * @returns + */ + // getPolicies() { + // return policies.map(({id, title, versions}) => { + // const latestVersionId = Math.max.apply( + // null, + // versions.map((version) => { + // return version.version; + // }) + // ); + // const {version, begin, end, document} = versions.filter((version) => { + // return version.version === latestVersionId; + // })[0]; + + // return { + // id, title, version, begin, end, document + // }; + // }); + // } + + getPolicy(id: string) { + return policies.filter((policy) => { + return policy.id === id; + })[0]; + } + + getPolicyVersion(id: string, version: number) { + const policy = this.getPolicy(id); + if (!policy) { + throw new Error(`Policy does not exist ${id}`); + } + + const policyVersion = policy.versions.filter((ver) => { + return version === ver.version; + })[0]; + if (!policyVersion) { + throw new Error(`Policy version does not exist ${id}.${version}`); + } + + return policyVersion; + } + + /** + * Converts the policy agreements into something more directly usable. + * + * @param policyIds + * @returns + */ + parsePolicyAgreements(policyIds: Array): Array { + return policyIds.map(({id, agreedon}) => { + const [policyId, policyVersion] = id.split('.'); + return { + id: policyId, + version: parseInt(policyVersion, 10), + agreedAt: new Date(agreedon) + }; + }); + } + + // getUseAgreements() { + // return this.useAgreements; + // } + + // async loadUseAgremements() { + + // // if (!policyIds) { + // // const me = await this.auth2Client.getMe(this.authorization); + // // const policyIds = me.policyids; + // // } + + // const agreements = this.parsePolicyAgreements(policyIds); + // // this.agreements = agreements; + + // // Now add the policy information to the use agreements + // // TODO: ideally the auth service knows about policies themselves! + // const useAgreements = agreements.map(({date: agreedAt, id, version}) => { + // try { + // const {title} = this.getPolicy(id); + // const {begin: publishedAt, end: expiredAt} = this.getPolicyVersion(id, version); + // return { + // agreedAt, id, version, + // title, publishedAt, expiredAt + // }; + // } catch (ex) { + // console.error('Error fetching policy or version, skipped', ex); + // return null; + // } + // }) + // .filter((useAgreement) => {return !!useAgreement;}); + + // this.useAgreements = useAgreements; + // } + + getPolicyAgreements(userPolicyAgreements: Array): Array { + const now = Date.now(); + return policies.reduce>((policyAgreements, {id, title, versions}) => { + versions.forEach((policyVersion) => { + const document = 'document' in policyVersion ? policyVersion.document : null; + const url = 'url' in policyVersion ? policyVersion.url : null; + const {version, begin, end} = policyVersion; + // Simply gets the agreement time, if present for this user in their + // "policyids" list. + const agreedAt = userPolicyAgreements + .map(({id: idAgreed, version: versionAgreed, agreedAt}) => { + if (idAgreed === id && versionAgreed === version) { + return agreedAt; + } + }) + .filter((agreedAt) => { + return !!agreedAt; + })[0] || null; + + // Similar to above, but this is a boolean indicating whether the + // previous version of the current agreement was agreed to. This is used + // to differentiate between a totally new policy and a policy which has + // been updated. + // TODO: THIS IS WRONG! Fix! + const previouslyAgreedTo = userPolicyAgreements + .some(({id: idAgreed, version: versionAgreed}) => { + return (id == idAgreed && version == versionAgreed + 1); + }); + + const expiredAt = end ? new Date(end) : null; + + const [status, statusSort]: [PolicyAgreementStatus, number] = (() => { + if (expiredAt) { + if (expiredAt.getTime() <= now) { + // We don't care whether it was agreed to or not. + return ['expired', 3]; + } + // otherwise, this agreement version has not yet expired and is + // still effective. + } + if (agreedAt) { + return ['current', 2]; + } + return [previouslyAgreedTo ? 'updated' : 'new', 1]; + })(); + + policyAgreements.push({ + id, version, title, publishedAt: new Date(begin), expiredAt, agreedAt, status, statusSort, document, url + }); + }); + return policyAgreements; + }, []); + } + + /** + * Returns all policies which are "new" -- the user has never agreed to. + * + * @returns + */ + getNewPolicies() { + return this.policyAgreements + .filter(({status}) => { + return ['new', 'updated'].includes(status); + }); + } +} diff --git a/vite-app/src/apps/Auth2/SignInContinue/PolicyAndAgreement.ts b/vite-app/src/apps/Auth2/SignInContinue/PolicyAndAgreement.ts new file mode 100644 index 00000000..698e8929 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/PolicyAndAgreement.ts @@ -0,0 +1,285 @@ +import { UserPolicy } from "lib/kb_lib/Auth2"; +import Policy, { CurrentTermsAndConditionsPolicy } from "./Policy"; + +// import policyData from '../resources/agreements/terms-and-conditions.json'; + +// const POLICY = policyData as unknown as Policy; + +/** + * These interfaces model the policy data stored in policies.json. + * Note that this is a long-term stopgap -- the policies should be served + * up by a service, like the auth service. + */ + +// export interface PolicyVersion { +// version: number; +// begin: string; +// url: string; +// end?: string; +// } + +// export interface PolicyVersionWithDocument extends PolicyVersionBase { +// document: string; +// } + +// export interface PolicyVersionWithURL extends PolicyVersionBase { +// url: string; +// } + +// export type PolicyVersion = PolicyVersionWithDocument | PolicyVersionWithURL; + +// export interface Policy { +// id: string; +// title: string; +// versions: Array +// } + +// export type Policy = Array; + +export interface UserPolicyAgrement { + id: string; + version: number; + agreedAt: Date; +} + +/** + * This structure represents a policy and version in relation to the + * current user, and helps answer the question - which policies have been agreed to, + * which not yet, which are not yet effective, which are expired, etc. + */ + +export type PolicyAgreementStatus = 'expired' | 'new' | 'current' | 'updated'; + +// export interface PolicyAgreement { +// id: string; +// version: number; +// title: string; +// publishedAt: Date; +// expiredAt: Date | null; +// agreedAt: Date | null; +// status: PolicyAgreementStatus; +// statusSort: number; +// url: URL; +// } + +export interface PolicyAgreement { + currentPolicy: CurrentTermsAndConditionsPolicy; + agreement: UserPolicyAgrement | null; + hasPreviousAgreements: boolean; +} + +/** + * A policy agreement that only exists in memory - it is not committed to the user's + * account yet so does not have an "agreed at" timestamp. This is the form that is + * submitted to the auth service to signify an agreement to the indicated policy and version. + * + * Differentiated from a "UserPolicy" (probablyl better named "PolicyAgreement") because + * this one does not have an agreement timestamp, and the id and version or separated (!). + * The latter is a quirk of the auth2 api. The reason for the lack of timestamp is that + * the timestamp is added when the login "choice" is submitted, along with any "pending" + * new policy agreements. + */ +export interface PendingPolicyAgreement { + id: string; + version: number; +} + +export interface PolicyAndAgreementParams { + policyids: Array; // from the auth service user record +} + +export default class PolicyAndAgreement { + policy: Policy = new Policy(); + userAgreements: Array + // policyAgreements: Array; + constructor({policyids}: PolicyAndAgreementParams) { + this.userAgreements = this.parsePolicyAgreements(policyids); + // this.policyAgreements = this.getPolicyAgreements(this.userAgreements); + } + + // getPolicy(id: string) { + // return policies.filter((policy) => { + // return policy.id === id; + // })[0]; + // } + + // getPolicyVersion(id: string, version: number) { + // const policy = this.getPolicy(id); + // if (!policy) { + // throw new Error(`Policy does not exist ${id}`); + // } + + // const policyVersion = policy.versions.filter((ver) => { + // return version === ver.version; + // })[0]; + // if (!policyVersion) { + // throw new Error(`Policy version does not exist ${id}.${version}`); + // } + + // return policyVersion; + // } + + /** + * Converts the policy agreements (from a user's account) into something more directly usable. + * + * @param policyIds + * @returns + */ + parsePolicyAgreements(policyIds: Array): Array { + return policyIds.map(({id, agreedon}) => { + const [policyId, policyVersion] = id.split('.'); + return { + id: policyId, + version: parseInt(policyVersion, 10), + agreedAt: new Date(agreedon) + }; + }); + } + + /** + * Gets a list of "policy agreements" which are aligned to the current set of user + * agreements (as defined in "terms-and-conditions.json"). + * + * Note: Ideally, this logic would reside in the auth service. + * + * @param userPolicyAgreements + * @returns + */ + // getPolicyAgreements(userPolicyAgreements: Array): Array { + // const now = Date.now(); + // const agreements: Array = []; + // const policy = this.policy.policy(); + // // return POLICY.reduce>((policyAgreements, {begin, end, version, url}) => { + // policy.versions.forEach(({begin, end, version, url}) => { + // // const document = 'document' in policyVersion ? policyVersion.document : null; + // // const url = 'url' in policyVersion ? policyVersion.url : null; + // // const {version, begin, end} = policyVersion; + // // Simply gets the agreement time, if present for this user in their + // // "policyids" list. + // const agreedAt = userPolicyAgreements + // .map(({id: idAgreed, version: versionAgreed, agreedAt}) => { + // if (idAgreed === policy.id && versionAgreed === version) { + // return agreedAt; + // } + // }) + // .filter((agreedAt) => { + // return !!agreedAt; + // })[0] || null; + + // // Similar to above, but this is a boolean indicating whether the + // // previous version of the current agreement was agreed to. This is used + // // to differentiate between a totally new policy and a policy which has + // // been updated. + // const previouslyAgreedTo = userPolicyAgreements + // .some(({id: idAgreed, version: versionAgreed}) => { + // return (policy.id == idAgreed && version < versionAgreed); + // }); + + // const expiredAt = end ? new Date(end) : null; + + // const [status, statusSort]: [PolicyAgreementStatus, number] = (() => { + // if (expiredAt) { + // if (expiredAt.getTime() <= now) { + // // We don't care whether it was agreed to or not. + // return ['expired', 3]; + // } + // // otherwise, this agreement version has not yet expired and is + // // still effective. + // } + // if (agreedAt) { + // return ['current', 2]; + // } + // return [previouslyAgreedTo ? 'updated' : 'new', 1]; + // })(); + + // agreements.push({ + // id: policy.id, version, title: policy.title, + // publishedAt: new Date(begin), expiredAt, agreedAt, + // status, statusSort, url + // }); + // }); + // return agreements; + // } + + /** + * Returns all policies which are "new" -- the user has never agreed to. + * + * @returns + */ + // getNewPolicies() { + // return this.policyAgreements + // .filter(({status}) => { + // return ['new', 'updated'].includes(status); + // }); + // } + + /** + * Returns the current active policy, and whether the user has agreed to it yet or not. + * + * @returns + */ + getPolicyAgreement(): PolicyAgreement { + const currentPolicy = this.policy.currentPolicy(); + + const agreements = this.userAgreements + .filter(({id, version}) => { + return (currentPolicy.id === id && currentPolicy.version === version); + }); + + return { + currentPolicy: currentPolicy, + agreement: agreements.length > 0 ? agreements[0] : null, + hasPreviousAgreements: this.userAgreements.length > 0 + } + + // policy.versions.forEach(({begin, end, version, url}) => { + // // const document = 'document' in policyVersion ? policyVersion.document : null; + // // const url = 'url' in policyVersion ? policyVersion.url : null; + // // const {version, begin, end} = policyVersion; + // // Simply gets the agreement time, if present for this user in their + // // "policyids" list. + // const agreedAt = userPolicyAgreements + // .map(({id: idAgreed, version: versionAgreed, agreedAt}) => { + // if (idAgreed === policy.id && versionAgreed === version) { + // return agreedAt; + // } + // }) + // .filter((agreedAt) => { + // return !!agreedAt; + // })[0] || null; + + // // Similar to above, but this is a boolean indicating whether the + // // previous version of the current agreement was agreed to. This is used + // // to differentiate between a totally new policy and a policy which has + // // been updated. + // const previouslyAgreedTo = userPolicyAgreements + // .some(({id: idAgreed, version: versionAgreed}) => { + // return (policy.id == idAgreed && version < versionAgreed); + // }); + + // const expiredAt = end ? new Date(end) : null; + + // const [status, statusSort]: [PolicyAgreementStatus, number] = (() => { + // if (expiredAt) { + // if (expiredAt.getTime() <= now) { + // // We don't care whether it was agreed to or not. + // return ['expired', 3]; + // } + // // otherwise, this agreement version has not yet expired and is + // // still effective. + // } + // if (agreedAt) { + // return ['current', 2]; + // } + // return [previouslyAgreedTo ? 'updated' : 'new', 1]; + // })(); + + // agreements.push({ + // id: policy.id, version, title: policy.title, + // publishedAt: new Date(begin), expiredAt, agreedAt, + // status, statusSort, url + // }); + // }); + // return agreements; + } +} diff --git a/vite-app/src/apps/Auth2/SignInContinue/SignInContinue.tsx b/vite-app/src/apps/Auth2/SignInContinue/SignInContinue.tsx new file mode 100644 index 00000000..2d4b3c10 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/SignInContinue.tsx @@ -0,0 +1,861 @@ +import ErrorMessage from 'components/ErrorMessage'; +import Loading from 'components/Loading'; +import { RouteProps } from 'components/Router2'; +import { AuthenticationState, AuthenticationStatus } from 'contexts/EuropaContext'; +import { AsyncProcess, AsyncProcessStatus } from 'lib/AsyncProcess'; +import { NextRequestObject } from 'lib/NextRequest'; +import { Auth2, PolicyAgreement as AuthPolicyAgreement, LoginChoice } from 'lib/kb_lib/Auth2'; +import { AuthError } from 'lib/kb_lib/Auth2Error'; +import { JSONRPC11Exception } from 'lib/kb_lib/comm/JSONRPC11/JSONRPC11'; +import UserProfile from 'lib/kb_lib/comm/coreServices/UserProfile'; +import { Messenger } from 'lib/messenger'; +import { navigate } from 'lib/navigation'; +import { Component, ReactNode } from 'react'; +import { Button } from 'react-bootstrap'; +import { Md5 } from 'ts-md5'; +import { Config, IDProvider } from 'types/config'; +import { Providers } from '../Providers'; +import PolicyAndAgreement, { PendingPolicyAgreement, PolicyAgreement } from './PolicyAndAgreement'; +import SignInContinueView from './SignInContinueView'; + +export type ErrorDetail = Array; + +export interface AlmostSimpleError { + title: string; + message: ReactNode; +} + +export interface UIErrorParams { + code: string; + message: string; + detail: ErrorDetail; + data: any; +} + +class UIError extends Error { + code: string; + detail: ErrorDetail; + data: any; + constructor({ code, message, detail, data }: UIErrorParams) { + super(message); + this.code = code; + this.detail = detail; + this.data = data; + } +} + +export enum AuthSessionCancellationType { + USER = 'CancellationType_USER', + TIMEOUT = 'CancellationType_TIMEOUT', +} + +export enum AuthSessionType { + SIGNUP = 'AuthSession_SIGNUP', + SIGNIN = 'AuthSession_SIGNIN', +} + +export interface StateParam { + nextrequest?: NextRequestObject; + origin: string; +} + +function getStateParam(choice: LoginChoice): StateParam { + if (!choice.redirecturl) { + throw new UIError({ + code: 'parse-error', + message: 'Redirect url is missing or falsy.', + // data: null, + detail: [ + 'This is an error using the KBase auth flow.', + 'The choice object should have a property named "redirecturl", but it is either missing or falsy.', + ], + data: { + choice, + }, + }); + } + + let url; + try { + url = new URL(choice.redirecturl); + } catch (ex) { + const message = ex instanceof Error ? ex.message : 'Unknown Error'; + console.error(ex, choice.redirecturl); + throw new UIError({ + code: 'parse-error', + message: 'Error parsing redirecturl', + detail: [ + 'This is an error parsing the redirecturl in choice.redirecturl', + `The original error message is: ${message}`, + ], + data: { + choice, + }, + }); + } + + // we just expect a state param. + if (!url.searchParams.has('state')) { + throw new UIError({ + code: 'missing-state', + message: 'State query parameter missing from choice.redirecturl', + detail: [ + 'This is an error using the KBase auth flow.', + [ + 'The choice object should have a property named "redirecturl" which ', + 'should be a valid url with a query param named "state", which is in JSON format.', + ], + ], + data: { + choice, + }, + }); + } + + try { + return JSON.parse(url.searchParams.get('state')!); + } catch (ex) { + console.error('Error parsing state in redirect url', ex); + const message = ex instanceof Error ? ex.message : 'Unknown Error'; + throw new UIError({ + code: 'parse-error', + message: 'Error parsing state in redirect url', + detail: [ + 'This is an error parsing the KBase auth flow.', + [ + 'The choice object should have a property named "redirecturl" which ', + 'should be a valid url with a query param named "state", which is in JSON format.', + ], + ['The original error message is: ', message], + ], + data: { + choice, + }, + }); + } +} + +export interface SurveyItem { + question: string; + response: Record; +} + +// export interface SignUpInfo { +// // For account creation +// username: string; +// realname: string; +// email: string; +// agreements: Array + +// // For profile +// organization: string; +// department: string; +// hearAbout: SurveyItem +// } + +export interface SignUpFormInfo { + // For account creation + username: string; + realname: string; + email: string; + + // For profile + organization: string; + department: string; + hearAbout: SurveyItem; + agreement: AuthPolicyAgreement; +} + +export interface AccountCreationParams { + username: string; + realname: string; + email: string; + agreement: AuthPolicyAgreement; +} + +export interface ProfileCreationParams { + username: string; + realname: string; + organization: string; + department: string; + hearAbout: SurveyItem; +} + +export interface LoginContinueProps extends RouteProps { + // params: SignInParams + // nextrequest: string, + authState: AuthenticationState; + config: Config; + messenger: Messenger; + setTitle: (title: string) => void; +} + +export type LoginContinueLoginState = AsyncProcess; + +// TODO: finish definiing +interface LoginContinueSuccess { + nextRequest?: NextRequestObject; + // TODO: maybe this is typed correctly... + choice: LoginChoice; + provider: IDProvider; + // TODO: type this. + policyAgreement: PolicyAgreement; + serverTimeOffset: number; + loginState: LoginContinueLoginState; +} +type LoginContinueState = AsyncProcess; + +export default class LoginContinue extends Component { + constructor(props: LoginContinueProps) { + super(props); + + this.state = { + status: AsyncProcessStatus.NONE, + }; + } + + componentDidMount() { + this.startItUp(); + } + + async doSignIn(agreement?: PendingPolicyAgreement) { + // Can only sign in if we are in SUCCESS state. + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + // OR ?? + return; + } + + const auth2Client = new Auth2({ + baseUrl: this.props.config.services.Auth2.url, + }); + + const { + nextRequest, + choice: { + login: [{ id: identityId }], + }, + } = this.state.value; + + try { + if (this.props.authState.status !== AuthenticationStatus.UNAUTHENTICATED) { + // TODO: refactor to either: + // handle authenticated state nicely (e.g. sign out, sign in) + // only have the signin continue operate under unauthenticated + // for now, it will work, but not for edge cases. + throw new Error('Must be unauthenticated to sign in'); + } + + const { token: tokenInfo } = await auth2Client.loginPick({ + identityId, + linkAll: false, + agreements: agreement ? [agreement] : [], + }); + + // TODO: replace with direct call of a function provided by the + // EuropaContext. + this.props.messenger.send('session', 'loggedin', { + token: tokenInfo.token, + expires: tokenInfo.expires, + nextRequest, + }); + } catch (ex) { + console.log('ERROR', ex); + } + } + + async doSignInDirect(value: LoginContinueSuccess) { + const auth2Client = new Auth2({ + baseUrl: this.props.config.services.Auth2.url, + }); + + const { + nextRequest, + choice: { + login: [{ id: identityId }], + }, + } = value; + + try { + if (this.props.authState.status !== AuthenticationStatus.UNAUTHENTICATED) { + // TODO: refactor to either: + // handle authenticated state nicely (e.g. sign out, sign in) + // only have the signin continue operate under unauthenticated + // for now, it will work, but not for edge cases. + throw new Error('Must be unauthenticated to sign in'); + } + + const { token: tokenInfo } = await auth2Client.loginPick({ + identityId, + linkAll: false, + agreements: [], + }); + + // TODO: replace with direct call of a function provided by the + // EuropaContext. + this.props.messenger.send('session', 'loggedin', { + token: tokenInfo.token, + expires: tokenInfo.expires, + nextRequest, + }); + } catch (ex) { + console.log('ERROR', ex); + } + } + gravatarHash(emailAddress: string) { + return Md5.hashStr(emailAddress.trim().toLowerCase()); + } + + async createProfile( + token: string, + { username, realname, organization, department, hearAbout: { question, response } }: ProfileCreationParams, + ) { + const auth2Client = new Auth2({ + baseUrl: this.props.config.services.Auth2.url, + }); + const accountInfo = await auth2Client.getMe(token); + + const userProfileClient = new UserProfile({ + url: this.props.config.services.UserProfile.url, + token, + timeout: this.props.config.ui.constants.clientTimeout, + }); + const newProfile = { + user: { + username, + realname, + }, + profile: { + metadata: { + createdBy: 'userprofile_ui_service', + created: new Date().toISOString(), + }, + // was globus info, no longer used + preferences: {}, + // when auto-creating a profile, there is nothing to put here yet. + userdata: { + organization, + department, + avatarOption: 'gravatar', + gravatarDefault: 'identicon', + }, + synced: { + gravatarHash: this.gravatarHash(accountInfo.email), + }, + surveydata: { + referralSources: { + question, + response, + }, + }, + }, + }; + + try { + return userProfileClient.set_user_profile({ + profile: newProfile, + }); + } catch (ex) { + if (ex instanceof JSONRPC11Exception) { + // TODO: return fancy error. + throw new Error(`Profile creation failed: ${ex.error.message}`); + } else { + throw ex; + } + } + } + + createAccount(choiceId: string, { username, realname, email, agreement }: AccountCreationParams) { + const auth2Client = new Auth2({ + baseUrl: this.props.config.services.Auth2.url, + }); + const params = { + id: choiceId, + user: username, + display: realname, + email, + linkall: false, + policyids: [`${agreement.id}.${agreement.version}`], + }; + return auth2Client.loginCreate(params); + } + + // async doSignUp({username, realname, email, agreements}: SignUpFormInfo) { + // try { + // const {token: tokenInfo} = await this.createAccount({ + + // }); + + // // await this.createProfile(tokenInfo.token, account.realname, profile, survey); + + // // const nextRequest = this.getNextRequest(); + // // if (nextRequest) { + // // this.props.runtime.send('app', 'auth-navigate', {nextRequest, tokenInfo}); + // // } else { + // // this.props.runtime.send('app', 'auth-navigate', {nextRequest: {path: 'dashboard'}, tokenInfo}); + // // } + // } catch (ex) { + // console.error(ex); + // } + // } + + // TODO: wow, add more error handling, etc. + + async doSignUp({ username, realname, email, agreement, organization, department, hearAbout }: SignUpFormInfo) { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + // TODO: should be impossible, but runtime. + throw new Error('Invalid state for signup'); + } + const choiceId = this.state.value.choice.create[0].id; + try { + const createAccountResult = await this.createAccount(choiceId, { + username, + realname, + email, + agreement, + }); + + const { + token: { token, expires }, + } = createAccountResult; + + await this.createProfile(token, { + username, + realname, + organization, + department, + hearAbout, + }); + + // TODO: this should not be possible here ... move this method and others to + // the signup continue controller. + if (this.props.authState.status !== AuthenticationStatus.UNAUTHENTICATED) { + // TODO: refactor to either: + // handle authenticated state nicely (e.g. sign out, sign in) + // only have the signin continue operate under unauthenticated + // for now, it will work, but not for edge cases. + throw new Error('Must be unauthenticated to sign in'); + } + + this.props.messenger.send('session', 'loggedin', { + token, + expires, + nextRequest: this.state.value.nextRequest, + }); + + return; + + // this.props.authState.login(token, expires); + + // if (this.state.value.nextRequest) { + // try { + // // since the plugin is operating inside of the iframe, it needs + // // to send the token with the navigation path so the parent + // // window can also set the cookie. + + // // TODO: ***** + // // Here is where we change the behavior from a message to kbase-ui + // // to directly executing the auth and navigation! + // // + // // this.props.runtime.send('app', 'auth-navigate', { + // // nextRequest, + // // tokenInfo: pickResult.token + // // }); + + // // TODO: next request can also handle non-hash paths. + // // const {hash, params} = this.state.value.nextRequest; + // // navigate(hash, {params}); + // navigate2(this.state.value.nextRequest.path); + // } catch (ex) { + // console.error('[doSignIn] ERROR parsing next request', this.state.value.nextRequest, ex); + // // this.props.runtime.send('app', 'navigate', ''); + // // TODO: the default path can be external or internal, but + // // navigate doesn't handle this logic. + + // // TODO: wrong! + // const defaultPath = this.props.config.ui.defaults.path; + // navigate2(defaultPath); + // } + // } else { + // const defaultPath = this.props.config.ui.defaults.path; + // navigate2(defaultPath); + // } + } catch (ex) { + console.error(ex); + } + } + + async checkUsername(username: string): Promise { + const auth2Client = new Auth2({ + baseUrl: this.props.config.services.Auth2.url, + }); + try { + const { availablename } = await auth2Client.loginUsernameSuggest(username); + if (availablename === username) { + return null; + } + return `This username is not available: a suggested available username is ${availablename}`; + } catch (ex) { + return 'error looking up username in auth'; + } + } + + onDone() { + // TODO: Currently handled by the view, but should be handled here. + } + + async startItUp() { + try { + this.setState({ + status: AsyncProcessStatus.PENDING, + }); + + if (this.props.authState.status === AuthenticationStatus.AUTHENTICATED) { + // navigate2(this.props.config.ui.defaults.path); + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Invalid State', + message: 'This view only valid if not logged in.', + }, + }); + return; + } + + const providers = new Providers({ + supportedProviders: this.props.config.services.Auth2.supportedProviders, + providers: this.props.config.services.Auth2.providers, + }).get(); + + const providersMap: Record = providers.reduce>( + (accum, provider) => { + accum[provider.id] = provider; + return accum; + }, + {}, + ); + + this.props.setTitle('KBase'); + + const auth2Client = new Auth2({ + baseUrl: this.props.config.services.Auth2.url, + }); + + // Do a root request to synchronize our clocks, as signin continue enforces + // a time limit (determined by the server) + const root = await auth2Client.root(); + + const serverTimeOffset = new Date().getTime() - root.servertime; + + const choice = await auth2Client.getLoginChoice(); + + const stateParams = getStateParam(choice); + + // The "choice" may be of the "create" or "login" subtype. + // These are only distinguishable by which of these properties is a non-zero + // length array. + // + // TODO: here we seem to use the state parameter rather than the the choice + // itself... + + // TODO: Remove this logic; signin and signup are really the same thing + // now, without any redirections. + // HMM ... I don't think this flow is supported any longer. + + // if (stateParams.origin === 'signup' && this.props.match.params.get('override-source') !== 'signin') { + // const params: Record = {}; + // // The next request is pulled out of the state param. + // // It needs to be turned back into a JSON string in order to + // // pass it as a query param value. + + // if (stateParams.nextrequest) { + // params.nextrequest = JSON.stringify(stateParams.nextrequest); + // } + + // navigate('signup', {params}); + // return null; + // } + + // At this point, we have a "login" , not "signup". + + // Prove it! + + // All we care about for policies are which ones the user has not yet agreed + // to. + + // TODO: disabled; re-enable for policy resolution. + + // Here we "prove" that this is a login choice and if so extract the policyids. + const policyids = await (async () => { + if (choice.login && choice.login.length === 1) { + return choice.login[0].policyids; + } else if (choice.create && choice.create.length === 1) { + // just pass empty policy ids, since this user has none yet. + return []; + } + // should never get here. + throw new Error('Neither login nor signup available for this sign-up account'); + })(); + + const policies = new PolicyAndAgreement({ + policyids, + }); + + const policyAgreement = policies.getPolicyAgreement(); + + const choiceProvider = providersMap[choice.provider]; + + const value: LoginContinueSuccess = { + nextRequest: stateParams.nextrequest, + choice, + provider: choiceProvider, + policyAgreement, + serverTimeOffset, + loginState: { + status: AsyncProcessStatus.NONE, + }, + }; + + // If current policy is agreed to and auth provider does not require signin + // confirmation, then just auto-signin. + // TODO: This does not currently work. + if (policyAgreement.agreement && !choiceProvider.confirmSignin) { + await this.doSignInDirect(value); + return; + } + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value, + }); + } catch (ex) { + if (ex instanceof AuthError) { + console.error('Error starting up sign-in session', ex); + if (ex.code && ex.code === '10010') { + const message = ( +
    +

    + A sign-in session was not found. This may be due to the expiration of the sign-in or sign-up session, + which is valid for 30 minutes. Or it may be because you have visited this path from your browser + history. +

    +

    If you wish to sign-in or sign-up, please {this.renderSignInButton('visit the sign in page')}.

    +
    + ); + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Sign-In Session Expired', + message, + }, + }); + } else if (ex.code && ex.code === '10020') { + const message = ( +
    +

    The sign in session has expired. A sign in session is valid for 30 minutes.

    +

    If you wish to sign-in or sign-up, please {this.renderSignInButton('visit the sign in page')}.

    +
    + ); + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Sign-In Session Expired', + message, + }, + }); + } else { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Error', + message: ex instanceof Error ? ex.message : 'Unknown Error', + }, + }); + } + } else { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Error', + message: ex instanceof Error ? ex.message : 'Unknown Error', + }, + }); + } + } + } + + returnToSignIn() { + navigate('login'); + } + + renderSignInButton(message: string) { + return ( + + ); + } + + /** + * Called if the user explicitly cancels their sign in via a user control (e.g. Cancel + * button), or it times out. + * + * @param cancelMessage + */ + async cancelSignInOrUp( + cancellationType: AuthSessionCancellationType, + cancelMessage: string, + sessionType: AuthSessionType, + ) { + // TODO: use the cancel message! + + console.warn('cancellation message ignored', cancelMessage); + + const auth2Client = new Auth2({ + baseUrl: this.props.config.services.Auth2.url, + }); + + const [sessionNoun, sessionLabel] = (() => { + switch (sessionType) { + case AuthSessionType.SIGNIN: + return ['sign in', 'Sign In']; + case AuthSessionType.SIGNUP: + return ['sign up', 'Sign Up']; + } + })(); + + this.props.setTitle(`KBase ${sessionLabel} - Canceled`); + + const message = (() => { + switch (cancellationType) { + case AuthSessionCancellationType.USER: + return ( +
    +

    You have successfully cancelled your {sessionNoun} session.

    +

    If you wish to sign in or sign up, please {this.renderSignInButton('visit the sign in page')}.

    +
    + ); + + case AuthSessionCancellationType.TIMEOUT: + return ( +
    +

    + Your {sessionNoun} session has been canceled due to too much time elapsing. A {sessionNoun} session is + valid for 30 minutes. +

    +

    If you wish to sign in or sign up, please {this.renderSignInButton('visit the sign in page')}.

    +
    + ); + } + })(); + + const title = (() => { + switch (cancellationType) { + case AuthSessionCancellationType.USER: + return `${sessionLabel} Session Canceled`; + + case AuthSessionCancellationType.TIMEOUT: + return `${sessionLabel} Session Expired`; + } + })(); + + try { + await auth2Client.loginCancel(); + // TODO: hook up notifications here... + // this.props.runtime.send('notification', 'notify', { + // type: 'error', + // id: 'signin', + // icon: 'ban', + // message: cancelMessage || 'The Sign In session has been canceled', + // description: cancelMessage || 'The Sign In session has been canceled', + // autodismiss: 10000 + // }); + + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title, + message, + }, + }); + } catch (ex) { + // const errorMessage = (() => { + // if (ex instanceof Auth2Error.AuthError) { + // console.error(ex); + // // TODO: do something + // } else { + // console.error(ex); + // } + // })(); + console.error('Error canceling auth session', ex); + // TODO: add notification back here. + // this.props.runtime.send('notification', 'notify', { + // type: 'error', + // id: 'signin', + // icon: 'ban', + // message: cancelMessage || 'The Sign In session has been canceled', + // description: cancelMessage || 'The Sign In session has been canceled', + // autodismiss: 10000 + // }); + const message = ( +
    +

    An error was encountered canceling your {sessionNoun} session.

    +

    The {sessionNoun} session will be automatically removed from the system after 30 minutes,

    +

    If you wish to sign in or sign up again, please {this.renderSignInButton('visit the sign in page')}.

    +

    The error is: {ex instanceof Error ? ex.message : 'Unknown Error'}

    +
    + ); + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + title: 'Sign-In Session Expired', + message, + }, + }); + } + } + + cancelSignIn(cancelationType: AuthSessionCancellationType, cancelMessage: string) { + return this.cancelSignInOrUp(cancelationType, cancelMessage, AuthSessionType.SIGNIN); + } + + cancelSignUp(cancelationType: AuthSessionCancellationType, cancelMessage: string) { + return this.cancelSignInOrUp(cancelationType, cancelMessage, AuthSessionType.SIGNUP); + } + + renderLoading() { + return ; + } + + renderError(error: AlmostSimpleError) { + return ; + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return this.renderLoading(); + case AsyncProcessStatus.SUCCESS: { + return ( + + ); + } + case AsyncProcessStatus.ERROR: + return this.renderError(this.state.error); + } + } +} diff --git a/vite-app/src/apps/Auth2/SignInContinue/SignInContinueForm.css b/vite-app/src/apps/Auth2/SignInContinue/SignInContinueForm.css new file mode 100644 index 00000000..003ff4e3 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/SignInContinueForm.css @@ -0,0 +1,7 @@ +.SignInContinueForm { + +} + +.SignInContinueForm .-textSpan { + margin: 0 0.25em; +} diff --git a/vite-app/src/apps/Auth2/SignInContinue/SignInContinueForm.tsx b/vite-app/src/apps/Auth2/SignInContinue/SignInContinueForm.tsx new file mode 100644 index 00000000..77869370 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/SignInContinueForm.tsx @@ -0,0 +1,258 @@ +import CountdownClock from 'components/CountdownClock'; +import Well from 'components/Well'; +import { NextRequestObject } from 'lib/NextRequest'; +import { LoginChoice } from 'lib/kb_lib/Auth2'; +import { Component } from 'react'; +import { Alert, Button, Col, Row, Stack } from 'react-bootstrap'; +import { IDProvider } from 'types/config'; +import { renderProviderLabel } from '../Providers'; +import TextSpan from '../TextSpan'; +import UseAgreements from '../UseAgreements'; +import { CurrentTermsAndConditionsPolicy } from './Policy'; +import { PendingPolicyAgreement, PolicyAgreement } from './PolicyAndAgreement'; +import SignInOops from './SignInOops'; + +// TODO: what type is choice? +function providerUserName(choice: LoginChoice): string { + // if ('provusername' in choice.login[0]) { + // return choice.login[0].provusername; + // } + return choice.login[0].provusernames.join(', '); +} + +// TODO: okay, need to resolve next request! + +export interface SignInContinueProps { + source: string; + choice: LoginChoice; + provider: IDProvider; + nextRequest?: NextRequestObject; + policyAgreement: PolicyAgreement; + serverTimeOffset: number; + // doSignInSubmit: () => void; + setTitle: (title: string) => void; + doSignIn: (agreement?: PendingPolicyAgreement) => void; + doCancel: () => void; +} + +export enum SignInContinueStatus { + NEED_POLICY_AGREEMENT = 'NEED_POLICY_AGREEMENT', + POLICY_AGREED_TO = 'POLICY_AGREED_TO', + READY = 'READY', +} + +export interface SignInContinueBase { + status: SignInContinueStatus; +} + +export interface SignInContinueNeedPolicyAgreement extends SignInContinueBase { + status: SignInContinueStatus.NEED_POLICY_AGREEMENT; + policy: CurrentTermsAndConditionsPolicy; +} + +export interface SignInContinuePolicyAgreedTo extends SignInContinueBase { + status: SignInContinueStatus.POLICY_AGREED_TO; + agreement: PendingPolicyAgreement; +} + +export interface SignInContinueReady extends SignInContinueBase { + status: SignInContinueStatus.READY; +} + +export type SignInContinueState = + | SignInContinueNeedPolicyAgreement + | SignInContinuePolicyAgreedTo + | SignInContinueReady; + +// interface SignInContinueState { +// canSignIn: boolean; +// agreement: PendingPolicyAgreement | null; +// } + +export default class SignInContinue extends Component { + constructor(props: SignInContinueProps) { + super(props); + + if (props.policyAgreement.agreement) { + this.state = { + status: SignInContinueStatus.READY, + }; + } else { + this.state = { + status: SignInContinueStatus.NEED_POLICY_AGREEMENT, + policy: props.policyAgreement.currentPolicy, + }; + } + } + + componentDidMount() { + this.props.setTitle('Sign In'); + } + + onAgreed(agreedTo: boolean) { + if (agreedTo) { + const { id, version } = this.props.policyAgreement.currentPolicy; + this.setState({ + status: SignInContinueStatus.POLICY_AGREED_TO, + agreement: { id, version }, + }); + } else { + this.setState({ + status: SignInContinueStatus.NEED_POLICY_AGREEMENT, + policy: this.props.policyAgreement.currentPolicy, + }); + } + } + + renderNextRequestMessagex() { + if (!this.props.nextRequest) { + return; + } + const { + path: { path }, + label, + } = this.props.nextRequest; + return ( + + After signing in, you will returned to the {label || path} page. + + ); + } + + renderNextRequestMessage() { + if (!this.props.nextRequest) { + return; + } + const { + path: { path }, + label, + } = this.props.nextRequest; + return ( + + Post Sign-in + +

    + After signing in, you will be returned to the {label || path} page. +

    +
    +
    + ); + } + + renderAgreementRequiredMessage() { + if (this.state.status !== SignInContinueStatus.NEED_POLICY_AGREEMENT) { + return; + } + return ( + + Please read and agree to the "KBase Use Agreement" above in order to complete Sign-In to KBase. + + ); + } + + renderHeader() { + if (this.props.choice === null) { + return; + } + + return ( + + + + Ready to sign into KBase account {this.props.choice.login[0].user}, via the linked{' '} + {renderProviderLabel(this.props.choice.provider)} account{' '} + {providerUserName(this.props.choice)}. + + + + + + + {' '} + left to complete sign-in. + + + + ); + } + + renderSignInControl() { + const canSignIn = + this.state.status === SignInContinueStatus.READY || this.state.status === SignInContinueStatus.POLICY_AGREED_TO; + // const variant: Variant = canSignIn ? 'primary' : 'secondary'; + return ( + + Sign In to KBase + + {this.renderAgreementRequiredMessage()} +
    { + e.preventDefault(); + this.doSigninSubmit(); + }} + > + + + + +
    +
    +
    + ); + } + + async doSigninSubmit() { + switch (this.state.status) { + case SignInContinueStatus.NEED_POLICY_AGREEMENT: + break; + case SignInContinueStatus.POLICY_AGREED_TO: + this.props.doSignIn(this.state.agreement); + break; + case SignInContinueStatus.READY: + this.props.doSignIn(); + } + return false; + } + + renderUseAgreement() { + if (this.state.status === SignInContinueStatus.READY) { + return; + } + return ( + + ); + } + + render() { + return ( + + {this.renderHeader()} + + + +
    + + {this.renderUseAgreement()} + + {this.renderNextRequestMessage()} + + {this.renderSignInControl()} + + ); + } +} diff --git a/vite-app/src/apps/Auth2/SignInContinue/SignInContinueView.css b/vite-app/src/apps/Auth2/SignInContinue/SignInContinueView.css new file mode 100644 index 00000000..49a88575 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/SignInContinueView.css @@ -0,0 +1,26 @@ +.SignInContinueView { + flex: 1 1 0px; + display: flex; + flex-direction: column; + overflow-y: auto; + margin: 0 1rem; +} + +.SignInContinueView .-header { + flex: 0 0 auto; + display: flex; + flex-direction: row; +} + +.SignInContinueView .-header .-col1 { + flex: 1 1 0; + font-weight: bold; +} + +.SignInContinueView .-header .-col2 { + flex: 0 0 auto; +} + +.SignInContinueView .-body { + flex: 1 1 0; +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/SignInContinue/SignInContinueView.tsx b/vite-app/src/apps/Auth2/SignInContinue/SignInContinueView.tsx new file mode 100644 index 00000000..ddb1074a --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/SignInContinueView.tsx @@ -0,0 +1,183 @@ +import CountdownClock from "components/CountdownClock"; +import { NextRequestObject } from "lib/NextRequest"; +import { LoginChoice } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import { Alert, Col, Row } from "react-bootstrap"; +import { IDProvider } from "types/config"; +import { renderProviderLabel } from "../Providers"; +import TextSpan from "../TextSpan"; +import { PendingPolicyAgreement, PolicyAgreement } from "./PolicyAndAgreement"; +import { AuthSessionCancellationType, SignUpFormInfo } from "./SignInContinue"; +import SignInContinueForm from "./SignInContinueForm"; +import './SignInContinueView.css'; +import SignUpContinue from "./SignUpContinue"; + +// function provisionalUserName(choice: LoginChoice) { +// if (choice.create.length > 0) { +// return choice.create![0].provusername; +// } +// return choice.login![0].provusernames.join(', '); +// } + +export interface SignInContinueViewProps { + choice: LoginChoice; + provider: IDProvider; + source: string; + serverTimeOffset: number; + nextRequest?: NextRequestObject; + //TODO: type this + policyAgreement: PolicyAgreement; + setTitle: (title: string) => void; + onDone: () => void; + doSignIn: (agreement?: PendingPolicyAgreement) => void; + doSignUp: (signUpInfo: SignUpFormInfo) => void; + cancelSignIn: (type: AuthSessionCancellationType, message: string) => void; + cancelSignUp: (type: AuthSessionCancellationType, message: string) => void; + checkUsername: (username: string) => Promise +} + +export default class SignInContinueView extends Component { + getUIState() { + const choice = this.props.choice; + if (choice) { + return { + auth: true, + signin: choice.login.length > 0, + signup: choice.create.length > 0 + }; + } + return { + auth: false, signin: false, signup: false + }; + } + + renderStep2Inactive() { + return
    Step 2 Inactive
    + } + + renderOopsExplanation(provider: IDProvider) { + if (this.props.source === 'signin') { + return
    +

    + If this browser is already signed in to {provider.label}, a sign-in attempt + from KBase will route you to {provider.label} and back again without any warning. +

    +

    + If this just happened to you, and the account you see above is not + the one you want, you should use the logout link below to log out of + {provider.label}, and then try again. +

    +
    + } + return
    +

    + If this browser is already signed in to {provider.label}, a sign-in attempt + from KBase will route you to {provider.label} and back again without any warning. +

    +

    + If this just happened to you, and the account you see above is not + the one you want, you should use the link below to log out of {provider.label}, and then try again. +

    + +
    + } + + renderSignUp() { + return { + this.props.cancelSignUp(AuthSessionCancellationType.USER, message); + }} + onSignUp={this.props.doSignUp} + nextRequest={this.props.nextRequest} + /> + } + + renderSignIn() { + return {this.props.cancelSignIn(AuthSessionCancellationType.USER, "User canceled sign in")}} + /> + } + + renderSignupState() { + const uiState = this.getUIState(); + if (uiState.auth === false) { + return this.renderStep2Inactive(); + } else if (uiState.signin) { + return this.renderSignIn(); + } else if (uiState.signup) { + return this.renderSignUp(); + } + return
    + Invalid state +
    + } + + renderHeader() { + if (this.props.choice === null) { + return; + } + + function providerUserName(choice: LoginChoice): string { + return choice.create[0].provusername; + } + + // const progress = ((this.props.choice.expires + this.props.serverTimeOffset) - Date.now())/3000 + + return + + + You are ready to + sign in to + KBase account + {this.props.choice.login[0].user} + via the linked + {renderProviderLabel(this.props.choice.provider)} + account + {providerUserName(this.props.choice)} + + + + + You have { this.props.cancelSignIn(AuthSessionCancellationType.TIMEOUT, 'Sign In canceled due to timeout'); }} + />{' '}to complete Sign In. + + {/* */} + + + } + + // renderHeader(message: string) { + // return { + // this.props.cancelSignIn(AuthSessionCancellationType.TIMEOUT, 'Your Sign In session has expired'); + // }} + // serverTimeOffset={this.props.serverTimeOffset} + // /> + // } + + render() { + return
    +
    + {this.renderSignupState()} +
    +
    + } +} diff --git a/vite-app/src/apps/Auth2/SignInContinue/SignInOops.tsx b/vite-app/src/apps/Auth2/SignInContinue/SignInOops.tsx new file mode 100644 index 00000000..46f9a2bd --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/SignInOops.tsx @@ -0,0 +1,135 @@ +import { NextRequestObject } from "lib/NextRequest"; +import { urlToKBaseUI } from "lib/navigation"; +import { Component, Fragment } from "react"; +import { Button } from "react-bootstrap"; +import { IDProvider } from "types/config"; +import Collapsible from "../Collapsible"; +import TextSpan from "../TextSpan"; + +export interface SignInOopsProps { + provider: IDProvider + source: string; + nextRequest?: NextRequestObject +} + +export default class SignInOops extends Component { + renderOopsExplanation() { + const provider = this.props.provider; + if (this.props.source === 'signin') { + return +

    + If this browser is already signed in to {provider.label}, a sign-in attempt + from KBase will route you to {provider.label} and back again without any warning. +

    +

    + If this just happened to you, and the account you see above is not + the one you want, you should use the logout link below to log out + of {provider.label}, and then try again. +

    +
    + } + return +

    + If this browser is already signed in to {provider.label}, a sign-in attempt + from KBase will route you to {provider.label} and back again without any warning. +

    +

    + If this just happened to you, and the account you see above is not + the one you want, you should use the link below to log out + of {provider.label}, and then try again. +

    + {/*

    + If you have signed in with a {provider.label} account already linked to a KBase account, + you will be unable to create a new KBase account using that {provider.label} account. +

    */} +
    + } + + render() { + const explanation = this.renderOopsExplanation(); + + const params: Record = {}; + if (this.props.nextRequest) { + params['nextrequest'] = JSON.stringify(this.props.nextRequest); + } + + const signInURL = urlToKBaseUI({path: 'login', params}) + + const provider = this.props.provider; + + // return + // + // + // Not the account you were expecting? + // + // + + // {explanation} + //
    + // + //
    + //

    + // After signing out from + // {provider.label} + // you will need to + // + // again. + //

    + //
    + //
    + //
    + + // TODO: improve source with a enum + const label = (() => { + switch (this.props.source) { + case 'signin': return 'Sign In'; + case 'signup': return 'Sign Up'; + default: return 'Sign In'; + } + })(); + + return Didn't mean to {label} with this {provider.label} account?
    } + render={() => { + return <> + {explanation} +
    + +
    +

    + After signing out from + {provider.label} + you will need to + + again. +

    + + }} /> + } + } diff --git a/vite-app/src/apps/Auth2/SignInContinue/SignUpContinue.tsx b/vite-app/src/apps/Auth2/SignInContinue/SignUpContinue.tsx new file mode 100644 index 00000000..6d80e501 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/SignUpContinue.tsx @@ -0,0 +1,156 @@ +import CountdownClock from "components/CountdownClock"; +import Well from "components/Well"; +import { NextRequestObject } from "lib/NextRequest"; +import { LoginChoice } from "lib/kb_lib/Auth2"; +import { Component } from "react"; +import { Alert, Col, Container, Row } from 'react-bootstrap'; +import { IDProvider } from "types/config"; +import TextSpan from "../TextSpan"; +import { SignUpFormInfo } from "./SignInContinue"; +import SignInOops from "./SignInOops"; +import SignUpForm from "./SignUpForm"; + +/** + * Now we use ant design forms. Don't reinvent the wheel (yet again!) + */ + +export interface OptionItem { + value: string + label: string +} +export interface SignUpContinueProps { + choice: LoginChoice; + serverTimeOffset: number; + provider: IDProvider; + checkUsername: (username: string) => Promise + cancelSignUp: (message: string) => void; + onSignUp: (signUpInfo: SignUpFormInfo) => void; + setTitle: (title: string) => void; + nextRequest?: NextRequestObject; +} + +export default class SignUpContinue extends Component { + componentDidMount() { + this.props.setTitle('Sign Up for KBase') + } + + renderNextRequestMessage() { + if (!this.props.nextRequest) { + return; + } + const {path: {path}, label} = this.props.nextRequest; + return + + Post Sign-in + + +

    + After signing in, you will be returned to the {label || path} page. +

    +
    +
    + } + + renderHeader() { + if (this.props.choice === null) { + return; + } + + // function providerUserName(choice: LoginChoice): string { + // return choice.create[0].provusername; + // } + + return + + + {/* You are ready to + sign up + for a KBase account via the linked + {renderProviderLabel(this.props.choice.provider)} + account + {providerUserName(this.props.choice)} */} + Hi, it looks like this is your first time using KBase with your + {this.props.choice.provider} + account + {this.props.choice.create![0].provusername}. +
    + You may sign up for a free KBase account below., after which you may sign in + using this Globus account. +
    + + + + You have { this.props.cancelSignUp('Signup canceled due to timeout'); }} + />{' '}to complete sign-up. + + {/* */} + +
    + } + + render() { + return + + {this.renderHeader()} + + + + + + + + {this.renderNextRequestMessage()} + + + + {/* + + + + Sign Up for KBase + + +

    + Hi, it looks like this is your first time using KBase with your + {this.props.choice.provider} + account + {this.props.choice.create![0].provusername}. +

    + +

    + You may sign up for a free KBase account below. +

    +
    +
    + +
    */} + + + + + + Sign Up for KBase + + + { + this.props.cancelSignUp(message); + }} + onSignUp={this.props.onSignUp} + /> + + + + +
    + } +} diff --git a/vite-app/src/apps/Auth2/SignInContinue/SignUpForm.tsx b/vite-app/src/apps/Auth2/SignInContinue/SignUpForm.tsx new file mode 100644 index 00000000..25a8320c --- /dev/null +++ b/vite-app/src/apps/Auth2/SignInContinue/SignUpForm.tsx @@ -0,0 +1,459 @@ +import CloseOutlined from "@ant-design/icons/lib/icons/CloseOutlined"; +import SaveOutlined from "@ant-design/icons/lib/icons/SaveOutlined"; +import { Button, Checkbox, Form, FormInstance, Input, Space } from "antd"; +import { FieldData, FieldName } from "apps/UserProfile/Profile/ProfileEditor"; +import Organization from "apps/UserProfile/Profile/fields/Organization"; +import { LoginChoice } from "lib/kb_lib/Auth2"; +import { Component, ReactNode, createRef } from "react"; +import { Button as BSButton } from 'react-bootstrap'; +import { Asterisk } from "react-bootstrap-icons"; +import referralSourcesData from '../resources/data/referralSources.json'; +import CheckUsernameField from "./CheckUsernameField"; +import Policy, { CurrentTermsAndConditionsPolicy } from "./Policy"; +import { SignUpFormInfo } from "./SignInContinue"; + +/** + * Now we use ant design forms. Don't reinvent the wheel (yet again!) + */ + +export interface OptionItem { + value: string + label: string +} +const referralSources = referralSourcesData as unknown as Array + +const HEAR_ABOUT_QUESTION = 'How did you hear about us?'; + +export interface SignUpFormProps { + choice: LoginChoice; + serverTimeOffset: number; + checkUsername: (username: string) => Promise + cancelSignUp: (message: string) => void; + onSignUp: (signUpInfo: SignUpFormInfo) => void; +} + +interface SignUpFormState { + ready: boolean; + hearAboutOther: boolean; + canCheckUsername: boolean; + isUsernameAvailable: boolean; + termsAndConditionsOpened: boolean; + isFormValid: boolean; +} + +function fieldNameEqual(fieldName: FieldName, value: string) { + if (typeof fieldName === 'string') { + return fieldName === value; + } else if (Array.isArray(fieldName) && fieldName.length === 1) { + return fieldName[0] === value; + } + return false; +} + +export interface FormData { + realname: string; + username: string; + email: string; + organization: string; + department: string; + hearAbout: Array; + hearAboutOther?: string; + +} + +export default class SignUpForm extends Component { + formRef = createRef() + policy: CurrentTermsAndConditionsPolicy = new Policy().currentPolicy(); + constructor(props: SignUpFormProps) { + super(props); + + this.state = { + ready: true, + hearAboutOther: false, + canCheckUsername: false, + isUsernameAvailable: false, + termsAndConditionsOpened: false, + isFormValid: false + } + } + + componentDidMount() { + const {realname, email} = (() => { + const createChoice = this.props.choice.create[0]; + if (!createChoice) { + return {realname: '', email: ''} + } + return { + realname: createChoice.provfullname, + email: createChoice.provemail + } + })(); + + this.formRef.current?.setFieldsValue({realname, email}) + } + + checkForm(allFields: Array) { + const isValid = (() => { + const hearAboutField = allFields.filter(({name}) => { + if (typeof name === 'string') { + return name === "hearAbout" + } else if (Array.isArray(name)) { + return name[0] === 'hearAbout'; + } + + })[0]; + const needHearAboutOther = hearAboutField.touched && hearAboutField.errors?.length === 0 && hearAboutField.value === 'other'; + + // for the "heard about other" field, only consider it if + // the username is not empty + const fields = allFields.filter((field) => { + if (fieldNameEqual(field.name, 'hearAboutOther') && !needHearAboutOther) { + return false; + } + return true; + }) + + if (fields) { + // Invalid if there all fields are touched and have no errors. + const allValid = fields.every(({ errors, touched }) => { + return !errors || errors.length === 0 && touched; + }) + return allValid; + } + const fieldsError = this.formRef.current?.getFieldsError(); + if (!fieldsError) { + return true; + } + return fieldsError.every(({ errors }) => { + return errors.length === 0; + }) + })(); + + const isTouched = this.formRef.current?.isFieldsTouched(); + + return { isValid, isTouched } + } + + saveForm() { + const rawFormData = (this.formRef.current?.getFieldsValue()); + + if (typeof rawFormData !== 'object' || rawFormData === null) { + throw new Error('The update is not an object'); + } + + const formData = rawFormData as FormData; + + const formInfo: SignUpFormInfo = { + realname: formData.realname, + username: formData.username, + email: formData.email, + organization: formData.organization, + department: formData.organization, + hearAbout: { + question: HEAR_ABOUT_QUESTION, + response: formData.hearAbout.reduce>((accum, value) => { + if (value === 'other') { + accum[value] = formData.hearAboutOther! + } else { + accum[value] = ''; + } + return accum; + }, {}) + }, + agreement: { + id: this.policy.id, + version: this.policy.version + } + } + + this.props.onSignUp(formInfo); + } + + onFieldsChange(changedFields: FieldData[], allFields: Array) { + const newState = {...this.state} + + // Sets the "hearAboutOther" state flag if the hearAbout field is set to + // the value "other" + const hearAbout = changedFields.filter(({name}) => { + if (Array.isArray(name)) { + return name.includes('hearAbout'); + } + return false; + })[0]; + if (hearAbout) { + // TODO: assert this? but what then? it is, by definition, an array of + // strings since it comes from a checkbox group. + const hearAboutValue = hearAbout.value as Array; + newState.hearAboutOther = hearAboutValue.includes('other') + } + + // Sets the "canCheckUsername" state flag if the username is set to a valid + // value. + // Also esets the "check username availability" flag to "none" if the username was changed. + const username = changedFields.filter(({name}) => { + if (Array.isArray(name)) { + return name.includes('username'); + } else if (typeof name === 'string') { + return name === 'username'; + } + return false; + }); + + + if (username.length > 0) { + newState.canCheckUsername = true; + this.formRef.current?.setFieldsValue({usernameavailable: "required"}) + } + + // Get the global form validation state, and set the "isFormValid" state flag + // appropriately. + const {isValid} = this.checkForm(allFields); + newState.isFormValid = isValid; + + this.setState(newState); + } + + requiredMark(labelNode: ReactNode, {required}: {required: boolean}) { + if (required) { + return {' '}{labelNode} + } + return labelNode; + } + + openTermsAndConditions() { + const url = this.policy.url; + this.setState({ + termsAndConditionsOpened: true + }); + window.open(url, "_blank"); + } + + renderForm() { + return
    + + + + + + + + + { + if (/^\d+/.test(rawValue)) { + throw new Error('A username may not begin with a number'); + } + if (/^_+/.test(rawValue)) { + throw new Error('A username may not start with the underscore character') + } + if (/\s/.test(rawValue)) { + throw new Error('A username may not contain spaces') + } + } + }, + ]} + > + + + + { + switch (value) { + case "na": throw new Error('Can check when supply a valid username') + case "required": throw new Error('Need to check if username is available') + case "unavailable": throw new Error("Username not available") + } + } + + }, + // { + // validator: async(_, value: string) => { + // const username = this.formRef.current?.getFieldValue('username'); + // if (username.length === 0) { + + // } + // } + // } + ]} + > + + + + + + + + + + + + {referralSources.map(({value, label}) => { + return
    + {label} +
    + })} +
    +
    + + + + + Open and review the Terms and Conditions (v{this.policy.version}, {Intl.DateTimeFormat('en-US', {}).format(this.policy.publishedAt)})
    + (After opening the link above, you can agree to the terms below) +
    + + { + if (!value) { + throw new Error('You must agree to the Terms and Conditions in order Sign Up') + } + } + + }, + ]} + > + + I have read and agree to the KBase Terms and Conditions + + + + } + + render() { + return
    + {this.renderForm()} + + + + +
    + } +} diff --git a/vite-app/src/apps/Auth2/SignedOut/controller.tsx b/vite-app/src/apps/Auth2/SignedOut/controller.tsx new file mode 100644 index 00000000..ec924487 --- /dev/null +++ b/vite-app/src/apps/Auth2/SignedOut/controller.tsx @@ -0,0 +1,94 @@ + +import ErrorAlert from 'components/ErrorAlert'; +import Loading from 'components/Loading'; +import { AuthenticationState, AuthenticationStatus } from 'contexts/EuropaContext'; +import { AsyncProcess, AsyncProcessStatus } from 'lib/AsyncProcess'; +import { SimpleError } from 'lib/SimpleError'; +import { Component } from 'react'; +import { Config, IDProvider } from 'types/config'; +import { Providers } from '../Providers'; +import SignedOutView from './view'; + +export interface SignedOutControllerProps { + authState: AuthenticationState; + config: Config; + setTitle: (title: string) => void; +} + +export interface SignedOutControllerSuccess { + providers: Array; +} + +type SignedOutControllerState = AsyncProcess + +export default class SignedOutController extends Component { + constructor(props: SignedOutControllerProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + }; + } + + componentDidMount() { + this.start(); + } + + componentDidUpdate(prevProps: SignedOutControllerProps) { + if (prevProps.authState.status !== this.props.authState.status) { + this.start(); + } + } + + async start() { + try { + this.setState({ + status: AsyncProcessStatus.PENDING + }); + + if (this.props.authState.status !== AuthenticationStatus.UNAUTHENTICATED) { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: 'Unfortunately, it appears that kbase-ui is not actually logged out' + } + }); + return; + } + + this.props.setTitle('Signed Out'); + + const providers = new Providers({ + supportedProviders: this.props.config.services.Auth2.supportedProviders, + providers: this.props.config.services.Auth2.providers + }).get(); + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + providers + } + }); + } catch (ex) { + console.error(ex); + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }); + } + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return + case AsyncProcessStatus.SUCCESS: { + return + } + case AsyncProcessStatus.ERROR: + return + } + } +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/SignedOut/view.tsx b/vite-app/src/apps/Auth2/SignedOut/view.tsx new file mode 100644 index 00000000..f388f7ae --- /dev/null +++ b/vite-app/src/apps/Auth2/SignedOut/view.tsx @@ -0,0 +1,45 @@ +import Well from "components/Well"; +import { Component } from "react"; +import { IDProvider } from "types/config"; + +export interface SignedOutViewProps { + providers: Array +} + +export default class SignedOutView extends Component { + render() { + const providerLinksList = this.props.providers.map(({ id, logoutUrl, label }) => { + return
  • + Log out from {label} +
  • + }); + return + + You are signed out of KBase. + + +

    + Although signed out of KBase, you may still be logged into an identity + provider you have recently + used to sign in to KBase in this browser. + This could allow your KBase account to be accessed merely by + using the Sign In button and choosing the sign-in provider. +

    +

    + If you wish to ensure that your KBase account is inaccessible from this browser, + you should sign out of any accounts you have used to access KBase as well. +

    +
      + {providerLinksList} +
    +

    + Additional security measures include: +

    +
      +
    • Remove all browser cookies
    • +
    • Use your browser's private-browsing feature
    • +
    +
    +
    + } +} diff --git a/vite-app/src/apps/Auth2/Signout/controller.tsx b/vite-app/src/apps/Auth2/Signout/controller.tsx new file mode 100644 index 00000000..e69de29b diff --git a/vite-app/src/apps/Auth2/Signout/view.tsx b/vite-app/src/apps/Auth2/Signout/view.tsx new file mode 100644 index 00000000..e69de29b diff --git a/vite-app/src/apps/Auth2/TextSpan.tsx b/vite-app/src/apps/Auth2/TextSpan.tsx new file mode 100644 index 00000000..782bde5a --- /dev/null +++ b/vite-app/src/apps/Auth2/TextSpan.tsx @@ -0,0 +1,25 @@ +import { CSSProperties, Component, PropsWithChildren } from "react"; + +export interface TextSpanProps extends PropsWithChildren { + bold?: boolean; + last?: boolean; + style?: CSSProperties; +} + +export default class TextSpan extends Component { + render() { + const style: CSSProperties = this.props.style ? this.props.style : {}; + + if (this.props.bold) { + style.fontWeight = 'bold'; + } + if (this.props.last) { + style.margin = '0 0 0 0.25em'; + } else { + style.margin = '0 0.25em'; + } + return + {this.props.children} + + } +} diff --git a/vite-app/src/apps/Auth2/UseAgreements.css b/vite-app/src/apps/Auth2/UseAgreements.css new file mode 100644 index 00000000..2e1ce01d --- /dev/null +++ b/vite-app/src/apps/Auth2/UseAgreements.css @@ -0,0 +1,9 @@ +.UseAgreements { + +} + +.UseAgreements .-agreementMessage { + font-style: "italic"; + text-align: "center"; + margin-top: "20px" +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/UseAgreements.tsx b/vite-app/src/apps/Auth2/UseAgreements.tsx new file mode 100644 index 00000000..f9b72742 --- /dev/null +++ b/vite-app/src/apps/Auth2/UseAgreements.tsx @@ -0,0 +1,175 @@ +import Well from "components/Well"; +import { Component } from "react"; +import { Alert, Button } from "react-bootstrap"; +import { ExclamationTriangle } from "react-bootstrap-icons"; +import { CurrentTermsAndConditionsPolicy } from "./SignInContinue/Policy"; + +export interface UseAgreementsProps { + policyToResolve: CurrentTermsAndConditionsPolicy; + hasPreviousAgreements: boolean; + onAgreed: (agreedTo: boolean) => void; +} + +interface PolicyResolution { + policy: CurrentTermsAndConditionsPolicy + isViewed: boolean; + isAgreedTo: boolean; +} + +interface UseAgreementState { + policyResolution: PolicyResolution +} + +export default class UseAgreements extends Component { + constructor(props: UseAgreementsProps) { + super(props); + + this.state = { + policyResolution: { + policy: props.policyToResolve, + isViewed: false, + isAgreedTo: false + } + }; + } + + onViewPolicy() { + const { policy, isViewed } = this.state.policyResolution; + if (isViewed) { + return; + } + this.setState({ + policyResolution: { + ...this.state.policyResolution, + isViewed: true + } + }); + window.open(policy.url.toString(), '_blank'); + } + + toggleIsAgreedTo() { + const { isAgreedTo } = this.state.policyResolution; + this.setState({ + policyResolution: { + ...this.state.policyResolution, + isAgreedTo: !isAgreedTo + } + }, () => { + this.props.onAgreed(!isAgreedTo); + }); + } + + render() { + const { policy, isViewed, isAgreedTo } = this.state.policyResolution; + + const agreementLabel = (() => { + if (isViewed) { + if (isAgreedTo) { + return
    { this.toggleIsAgreedTo(); }} + className="text-success" + style={{ fontWeight: 'bold', cursor: 'pointer'}}> + I have read and agree to this policy +
    + } + return
    { this.toggleIsAgreedTo(); }} + className="text-danger" + style={{ fontWeight: 'bold', cursor: 'pointer' }}> + I have read and agree to this policy +
    + } + return
    + I have read and agree to this policy +
    + })(); + + const mustViewMessage = (() => { + if (isViewed) { + if (isAgreedTo) { + return + You have agreed to this policy. + + } + return + You have opened the policy document and must agree to it in order to complete sign in. + + } + return + You must open the {policy.title} before you may agree to it. + + })(); + + const openPolicyMessage = (() => { + if (isViewed) { + return

    + You have opened the {' '} + . +

    + } + return

    + Please open and review the {' '} + . +

    + })(); + + // const phrase = (() => { + // if (this.props.hasPreviousAgreements) { + // return 'has been updated'; + // } + // return 'has not yet been agreed to by this account'; + // })(); + + return
    + + KBase Terms and Conditions (T&C) have been updated. The new T&C was published on {Intl.DateTimeFormat('en-US', {}).format(this.props.policyToResolve.publishedAt)} + + {/*

    + The following KBase use policy {phrase}. +

    +

    + You may sign in to this account after you have agreed to this policy by checking the box next to it. +

    */} + + + KBase Terms and Conditions + + +
    +
    + {openPolicyMessage} + {mustViewMessage} +
    +
    +
    +
    + { this.toggleIsAgreedTo(); }} /> +
    +
    + {agreementLabel} +
    +
    +
    +
    +
    +
    +
    +
    +
    + } +} diff --git a/vite-app/src/apps/Auth2/resources/agreements/policies.json b/vite-app/src/apps/Auth2/resources/agreements/policies.json new file mode 100644 index 00000000..52b750d3 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/agreements/policies.json @@ -0,0 +1,31 @@ +[ + { + "id": "kbase-user", + "title": "KBase Use Agreement", + "versions": [ + { + "version": 1, + "begin": "2015-01-01T08:00:00Z", + "end": "2024-01-01T00:00:00Z", + "document": "# Terms and Conditions\n\n## Prohibited Behavior\n\nAs a condition of your use of KBase (the DOE Systems Biology Knowledgebase) you agree not to upload any type of human data or personally identifiable information.\n\n> Improper use of KBase, including uploading human data, may result in the termination of KBase access privileges.\n\n## Data Sharing\n\nKBase conforms to the Information and Data Sharing Policy of the Genomic Science Program of the Office of Biological and Environmental Research within the Office of Science. Please see the KBase Data Policy page for more information.\n\n## Responsibility for Data\n\nAs a condition of your use of KBase you accept sole responsibility for all files you upload or transfer through use of KBase. You recognize and accept that KBase does not guarantee long-term retention of user uploaded data, and will not be responsible for any failure to store or transfer, or deletion, corruption or loss for any data, information or content contained in your files. It is strongly recommended that you back up all files prior to using KBase.

    \n\n## Use Agreement\n\nBy using KBase, including its websites and services or via published APIs, you are agreeing to the terms stated in our Use Agreement. Please read them carefully. They include limitations on what is acceptable user behavior, accountability, availability, data retention, and conditions for account termination. If you do not agree, do not access or use KBase.\n\n## Privacy Policy\n\nKBase is provided as a public service. KBase reserves the right to monitor any and all use of kbase.us. KBase never collects information for commercial marketing or any purpose unrelated to KBase functions. The Privacy Policy describes the ways KBase collects, stores, uses, discloses and protects the personal information about users and how they use KBase.\n\n## Open Source License\n\nAll software developed by the KBase project team, and any contributed by you to KBase, is stored and maintained in the public KBase GitHub code repository under the MIT Open Source License (“License”). By contributing to or using KBase, you acknowledge having read and understood the License and agree to abide by it.\n" + }, + { + "version": 2, + "url": "https://www.kbase.us/about/terms-and-conditions-v2", + "begin": "2024-01-01T00:00:00Z" + } + ] + }, + { + "id": "data-policy", + "title": "KBase Data Policy", + "versions": [ + { + "version": 1, + "begin": "2015-01-01T08:00:00Z", + "end": "2024-01-01T00:00:00Z", + "document": "# Data Policy\n\n## Data Policies\n\nKBase conforms to the Information and Data Sharing Policy of the Genomic Science Program of the Office of Biological and Environmental Research within the Office of Science. This requires that all publishable data, metadata, and software resulting from research funded by the Genomic Science program must conform to community-recognized standard formats when they exist; be clearly attributable; and be deposited within a community-recognized public database(s) appropriate for the research.\n\nData publicly available in KBase comes from the sources listed on this page. Additionally, users can upload their own data to KBase to analyze it, and can choose how widely their data should be shared. (All data uploaded by users is private to them unless they choose to share it.)\n\n> NOTICE: KBase does not guarantee long-term retention of user-uploaded data. Please take appropriate precautions in storing and backing up your data locally.\n\n> WARNING: Improper use of KBase, including uploading human data, may result in the termination of KBase access privileges. Please see the Terms and Conditions page for more information.\n" + } + ] + } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/agreements/terms-and-conditions copy.json b/vite-app/src/apps/Auth2/resources/agreements/terms-and-conditions copy.json new file mode 100644 index 00000000..0ce6afde --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/agreements/terms-and-conditions copy.json @@ -0,0 +1,21 @@ +{ + "id": "kbase-user", + "title": "KBase Use Agreement", + "versions": [ + { + "version": 1, + "publishedAt": "2015-01-01T08:00:00Z", + "url": "https://www.kbase.us/about/terms-and-conditions-v1" + }, + { + "version": 2, + "url": "https://www.kbase.us/about/terms-and-conditions-v2", + "publishedAt": "2023-04-01T07:00:00Z" + }, + { + "version": 3, + "url": "https://www.kbase.us/about/terms-and-conditions-v2", + "publishedAt": "2023-05-01T07:00:00Z" + } + ] +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/agreements/terms-and-conditions.json b/vite-app/src/apps/Auth2/resources/agreements/terms-and-conditions.json new file mode 100644 index 00000000..32528747 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/agreements/terms-and-conditions.json @@ -0,0 +1,16 @@ +{ + "id": "kbase-user", + "title": "KBase Use Agreement", + "versions": [ + { + "version": 1, + "publishedAt": "2015-01-01T08:00:00Z", + "url": "https://www.kbase.us/about/terms-and-conditions-v1" + }, + { + "version": 2, + "url": "https://www.kbase.us/about/terms-and-conditions-v2", + "publishedAt": "2023-04-01T07:00:00Z" + } + ] +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/css/flex-tabs.css b/vite-app/src/apps/Auth2/resources/css/flex-tabs.css new file mode 100644 index 00000000..16fa25c6 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/css/flex-tabs.css @@ -0,0 +1,94 @@ +.flex-tabs { + display: flex; + flex-direction: column; + flex: 1 1 0px; +} + +.flex-tabs>.-tabs { + flex: 0 0 2.8em; + text-align: bottom; + display: flex; + flex-direction: row; + /* padding-left: 2em; */ + /* border-bottom: 1px rgba(200, 200, 200, 0.5) solid; */ + overflow: hidden; + text-overflow: ellipsis; +} + +.flex-tabs>.-tabs>.-tab { + cursor: pointer; + padding: 0 8px 0 8px; + background-color: transparent; + user-select: none; + border: 1px transparent solid; + border-radius: 4px 4px 0 0; + line-height: 2.8em; + border-bottom: 1px solid #ddd; +} + +.flex-tabs>.-tabs>.-tab-rest { + flex: 1 1 0px; + border-bottom: 1px solid #ddd; +} + +/* .flex-tabs>.-tabs>.-tab:nth-child(1) { + padding-left: 0px; +} */ + +.flex-tabs>.-tabs>.-tab>.-label { + line-height: 2.8em; + padding: 0 8px; + /* display: inline-block; +vertical-align: middle; */ + white-space: nowrap; + color: #337ab7; +} + + +.flex-tabs>.-tabs>.-tab:hover { + background-color: #eeeeee; +} + +.flex-tabs>.-tabs>.-tab.-active:hover { + background-color: transparent; +} + + +.flex-tabs>.-tabs>.-tab.-active>.-label { + color: #555555; +} + +.flex-tabs>.-tabs>.-tab.-active { + /*border: 2px rgba(200, 200, 200, 0.5) solid;*/ + /* background-color: rgba(200, 200, 200, 0.5); */ + color: #000; + border: 1px solid #ddd; + border-bottom-color: transparent; +} + +/* .flex-tabs>.-tabs>.-tab.-inactive { + background-color: transparent; +} */ + +/* Panels */ + +.flex-tabs>.-panels { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.flex-tabs .-panel { + padding: 3px; + background-color: transparent; + flex: 1 1 0px; + display: flex; + flex-direction: column; + overflow-y: auto; +} + +.flex-tabs>.-panels>.-panel.-inactive { + display: none; +} + +.flex-tabs>.-panels>.-panel.-active {} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/css/main.css b/vite-app/src/apps/Auth2/resources/css/main.css new file mode 100644 index 00000000..281b4840 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/css/main.css @@ -0,0 +1,105 @@ +@import url("flex-tabs.css"); + +.form-row:hover { + background-color: #CCC; +} + +.form-sub-row { + border: 1px transparent solid; + padding: 3px; + box-sizing: border-box; +} + +.form-sub-row:nth-last-child() {} + +.form-sub-row:hover { + border: 1px #EEE solid; +} + +.form-row { + padding: 4px; +} + +.field-doc { + margin-bottom: 4px; + color: #AAA; +} + +.form-row:hover .field-doc { + color: #000; +} + +/* Policy resolver component styles */ + +.policy-markdown { + font-family: Arial, sans-serif; +} + +.policy-markdown h1 { + font-family: Arial, sans-serif; + margin-top: 0; + margin-bottom: 0; + font-weight: bold; + font-size: 150%; +} + +.policy-markdown h2 { + font-family: Arial, sans-serif; + margin-top: 1em; + margin-bottom: 0; + font-weight: bold; + font-size: 135%; +} + +.policy-markdown h3 { + font-family: Arial, sans-serif; + margin-top: 1em; + margin-bottom: 0; + font-weight: bold; + font-size: 120%; +} + +.policy-markdown h4 { + font-family: Arial, sans-serif; + margin-top: 1em; + margin-bottom: 0; + font-weight: bold; + font-size: 100%; +} + +.policy-markdown p { + margin-top: 0.5em; +} + +.policy-markdown blockquote { + font-size: inherit; + margin-left: 1em; + padding-left: 1em; + border-left: 3px silver solid; +} + +.policy-markdown a {} + +.policy-markdown a:link, +.policy-markdown a:visited {} + +.policy-markdown a:hover, +.policy-markdown a:active {} + +/* responsive youtube */ + +.embed-container { + position: relative; + padding-bottom: 56.25%; + height: 0; + overflow: hidden; + max-width: 100%; +} + +.embed-container iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/data/config.yml b/vite-app/src/apps/Auth2/resources/data/config.yml new file mode 100644 index 00000000..b5c556b3 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/data/config.yml @@ -0,0 +1,3 @@ +# Config +--- +auth2-launch-date: '6/9/17' \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/data/globus-providers.json b/vite-app/src/apps/Auth2/resources/data/globus-providers.json new file mode 100644 index 00000000..adbbc1c1 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/data/globus-providers.json @@ -0,0 +1,1108 @@ + [{ + "id": "aalborg_university", + "label": "Aalborg University" + }, + { + "id": "aarhus_basic_health_care_college", + "label": "Aarhus Basic Health Care College" + }, + { + "id": "aarhus_school_of_marine_and_technical_engineering", + "label": "Aarhus School of Marine and Technical Engineering" + }, { + "id": "aarhus_university", + "label": "Aarhus University" + }, { + "id": "academic_computer_center_task_in_gdansk", + "label": "Academic Computer Center TASK in Gdansk" + }, { + "id": "aconet_team", + "label": "ACOnet Team" + }, { + "id": "alexander_stuart_test_idp_yin", + "label": "Alexander Stuart test IdP (yin)" + }, { + "id": "anton_bruckner_private_university", + "label": "Anton Bruckner Private University" + }, { + "id": "alcf", + "label": "Argonne LCF" + }, { + "id": "argonne_national_laboratory", + "label": "Argonne National Laboratory" + }, { + "id": "aristotle_university_of_thessaloniki", + "label": "Aristotle University of Thessaloniki" + }, { + "id": "arizona_state_university", + "label": "Arizona State University" + }, { + "id": "auburn_university", + "label": "Auburn University" + }, { + "id": "augusta_university", + "label": "Augusta University" + }, { + "id": "basic_health_care_college_silkeborg", + "label": "Basic Health Care College Silkeborg" + }, { + "id": "bates_college", + "label": "Bates College" + }, { + "id": "baylor_college_of_medicine", + "label": "Baylor College of Medicine" + }, { + "id": "baylor_university", + "label": "Baylor University" + }, { + "id": "bbfc", + "label": "BBFC" + }, { + "id": "bfh_berner_fachhochschule", + "label": "BFH - Berner Fachhochschule" + }, { + "id": "blekinge_tekniska_hogskola", + "label": "Blekinge Tekniska Högskola" + }, { + "id": "boise_state_university", + "label": "Boise State University" + }, { + "id": "boston_college", + "label": "Boston College" + }, { + "id": "boston_university", + "label": "Boston University" + }, { + "id": "brandeis_university", + "label": "Brandeis University" + }, { + "id": "brookhaven_national_laboratory", + "label": "Brookhaven National Laboratory" + }, { + "id": "brown_university", + "label": "Brown University" + }, { + "id": "business_academy_aarhus", + "label": "Business Academy Aarhus" + }, { + "id": "business_academy_southwest_easv", + "label": "Business Academy SouthWest (EASV)" + }, { + "id": "california_institute_of_technology", + "label": "California Institute of Technology" + }, { + "id": "california_state_polytechnic_university_pomona", + "label": "California State Polytechnic University, Pomona" + }, { + "id": "california_state_university_fresno", + "label": "California State University, Fresno" + }, { + "id": "california_state_university_fullerton", + "label": "California State University, Fullerton" + }, { + "id": "california_state_university_san_bernardino", + "label": "California State University, San Bernardino" + }, { + "id": "cardiff_university", + "label": "Cardiff University" + }, { + "id": "carleton_college", + "label": "Carleton College" + }, { + "id": "carnegie_mellon_university", + "label": "Carnegie Mellon University" + }, { + "id": "case_western_reserve_university", + "label": "Case Western Reserve University" + }, { + "id": "cern", + "label": "CERN" + }, { + "id": "clemson_university", + "label": "Clemson University" + }, { + "id": "cnr_institute_of_informatics_and_telematics", + "label": "CNR Institute of Informatics and Telematics" + }, { + "id": "coleg_sir_gar", + "label": "Coleg Sir Gar" + }, { + "id": "colorado_school_of_mines", + "label": "Colorado School of Mines" + }, { + "id": "colorado_state_university", + "label": "Colorado State University" + }, { + "id": "columbia_university", + "label": "Columbia University" + }, { + "id": "computecanada", + "label": "Compute Canada" + }, { + "id": "copenhagen_business_school", + "label": "Copenhagen Business School" + }, { + "id": "copenhagen_hospitality_college", + "label": "Copenhagen Hospitality College" + }, { + "id": "copenhagen_school_of_marine_engineering_and_technology_management", + "label": "Copenhagen School of Marine Engineering and Technology Management" + }, { + "id": "cornell_university", + "label": "Cornell University" + }, { + "id": "cphbusiness", + "label": "Cphbusiness" + }, { + "id": "dania_danish_academy_of_business_and_technology", + "label": "Dania – Danish Academy of Business and Technology" + }, { + "id": "danish_defence_library", + "label": "Danish Defence Library" + }, { + "id": "danish_research_centre_for_magnetic_resonance", + "label": "Danish Research Centre for Magnetic Resonance" + }, { + "id": "danish_school_of_media_and_journalism", + "label": "Danish School of Media and Journalism" + }, { + "id": "democritus_university_of_thrace", + "label": "Democritus University of Thrace" + }, { + "id": "design_school_kolding", + "label": "Design School Kolding" + }, { + "id": "dfn_verein_deutsches_forschungsnetz", + "label": "DFN-Verein - Deutsches Forschungsnetz" + }, { + "id": "dronninglund_gymnasium", + "label": "Dronninglund Gymnasium" + }, { + "id": "dublin_business_school", + "label": "Dublin Business School" + }, { + "id": "dublin_institute_of_technology", + "label": "Dublin Institute of Technology" + }, { + "id": "duke_university", + "label": "Duke University" + }, { + "id": "ehb_iffp_iuffp_das_eidgenossische_hochschulinstitut_fur_berufsbildung", + "label": "EHB / IFFP / IUFFP - Das eidgenössische Hochschulinstitut für Berufsbildung" + }, { + "id": "epfl_epf_lausanne", + "label": "EPFL - EPF Lausanne" + }, { + "id": "erhvervsakademi_midtvest", + "label": "Erhvervsakademi MidtVest" + }, { + "id": "esnet", + "label": "ESnet" + }, { + "id": "ethz_eth_zurich", + "label": "ETHZ - ETH Zürich" + }, { + "id": "euc_nord", + "label": "EUC Nord" + }, { + "id": "eupathdb", + "label": "EuPathDB" + }, { + "id": "euresearch_head_office", + "label": "Euresearch Head Office" + }, { + "id": "fachhochschule_karnten", + "label": "Fachhochschule Kärnten" + }, { + "id": "fachhochschule_vorarlberg", + "label": "Fachhochschule Vorarlberg" + }, { + "id": "feide", + "label": "Feide" + }, { + "id": "fermi_national_accelerator_laboratory", + "label": "Fermi National Accelerator Laboratory" + }, { + "id": "fh_joanneum", + "label": "FH Joanneum" + }, { + "id": "fhnw_fachhochschule_nordwestschweiz", + "label": "FHNW - Fachhochschule Nordwestschweiz" + }, { + "id": "fhs_st_gallen", + "label": "FHS St. Gallen" + }, { + "id": "fh_wiener_neustadt", + "label": "FH Wiener Neustadt" + }, { + "id": "florida_atlantic_university", + "label": "Florida Atlantic University" + }, { + "id": "florida_international_university", + "label": "Florida International University" + }, { + "id": "fredericia_maskinmesterskole", + "label": "Fredericia Maskinmesterskole" + }, { + "id": "frederikshavn_upper_secondary_school_and_hf_course", + "label": "Frederikshavn upper secondary school and HF-Course" + }, { + "id": "frederikssund_gymnasium", + "label": "Frederikssund Gymnasium" + }, { + "id": "ftl_facolta_di_teologia_di_lugano", + "label": "FTL - Facoltà di Teologia di Lugano" + }, { + "id": "george_mason_university", + "label": "George Mason University" + }, { + "id": "georgetown_university", + "label": "Georgetown University" + }, { + "id": "georgia_institute_of_technology", + "label": "Georgia Institute of Technology" + }, { + "id": "georgia_state_university", + "label": "Georgia State University" + }, { + "id": "gesellschaft_fur_wissenschaftliche_datenverarbeitung_mbh", + "label": "Gesellschaft für wissenschaftliche Datenverarbeitung mbH" + }, { + "id": "gettysburg_college", + "label": "Gettysburg College" + }, { + "id": "globusid", + "label": "Globus ID" + }, { + "id": "google", + "label": "Google" + }, { + "id": "goucher_college", + "label": "Goucher College" + }, { + "id": "gpn_great_plains_network", + "label": "GPN (Great Plains Network)" + }, { + "id": "graz_university_of_technology", + "label": "Graz University of Technology" + }, { + "id": "greek_research_and_technology_network", + "label": "Greek Research and Technology Network" + }, { + "id": "grenaa_gymnasium", + "label": "Grenaa Gymnasium" + }, { + "id": "harvey_mudd_college", + "label": "Harvey Mudd College" + }, { + "id": "haverford_college", + "label": "Haverford College" + }, { + "id": "heanet", + "label": "HEAnet" + }, { + "id": "hep_bejune_padagogische_hochschule_bejune", + "label": "HEP-BEJUNE – Pädagogische Hochschule - BEJUNE" + }, { + "id": "hep_ph_fr_university_of_teacher_education_fribourg", + "label": "HEP-PH FR - University of Teacher Education Fribourg" + }, { + "id": "hep_vaud_haute_ecole_pedagogique_du_canton_de_vaud", + "label": "HEP Vaud - Haute école pédagogique du canton de Vaud" + }, { + "id": "hes_so_uas_western_switzerland", + "label": "HES-SO : UAS Western Switzerland" + }, { + "id": "hochschule_osnabruck", + "label": "Hochschule Osnabrück" + }, { + "id": "hogskolan_kristianstad", + "label": "Högskolan Kristianstad" + }, { + "id": "hslu_hochschule_luzern", + "label": "HSLU - Hochschule Luzern" + }, { + "id": "hsr_hochschule_fur_technik_rapperswil", + "label": "HSR - Hochschule für Technik Rapperswil" + }, { + "id": "htw_chur_hochschule_fur_technik_und_wirtschaft", + "label": "HTW Chur - Hochschule für Technik und Wirtschaft" + }, { + "id": "ian_a_young", + "label": "Ian A. Young" + }, { + "id": "iba_international_business_academy", + "label": "IBA International Business Academy" + }, { + "id": "iccu_central_institute_for_the_union_catalogue", + "label": "ICCU - Central Institute for the Union Catalogue" + }, { + "id": "icer_mali", + "label": "ICER - Mali" + }, { + "id": "icer_uganda", + "label": "ICER - Uganda" + }, { + "id": "idiap_research_institute", + "label": "Idiap Research Institute" + }, { + "id": "indiana_university", + "label": "Indiana University" + }, { + "id": "indiana_university_of_pennsylvania", + "label": "Indiana University of Pennsylvania" + }, { + "id": "infn_istituto_nazionale_di_fisica_nucleare", + "label": "INFN - Istituto Nazionale di Fisica Nucleare" + }, { + "id": "insel_gruppe", + "label": "Insel Gruppe" + }, { + "id": "institute_of_science_and_technology_austria", + "label": "Institute of Science and Technology Austria" + }, { + "id": "institut_fur_hohere_studien_ihs", + "label": "Institut für Höhere Studien (IHS)" + }, { + "id": "international_business_college", + "label": "International Business College" + }, { + "id": "internet2", + "label": "Internet2" + }, { + "id": "iowa_state_university", + "label": "Iowa State University" + }, { + "id": "irccs_cro_di_aviano", + "label": "IRCCS CRO di Aviano" + }, { + "id": "istat_istituto_nazionale_di_statistica", + "label": "ISTAT - Istituto Nazionale di Statistica" + }, { + "id": "istituto_nazionale_di_astrofisica_inaf", + "label": "Istituto Nazionale di Astrofisica - INAF" + }, { + "id": "it_department_of_the_ministry_of_higher_education", + "label": "IT Department of the Ministry of Higher Education" + }, { + "id": "its_it_support_centre", + "label": "ITS (IT Support Centre)" + }, { + "id": "it_university_of_copenhagen", + "label": "IT University of Copenhagen" + }, { + "id": "izs_sicilia", + "label": "IZS Sicilia" + }, { + "id": "johannes_kepler_universitat_linz", + "label": "Johannes Kepler Universität Linz" + }, { + "id": "johns_hopkins", + "label": "Johns Hopkins" + }, { + "id": "kansas_state_university", + "label": "Kansas State University" + }, { + "id": "kaunas_university_of_technology", + "label": "Kaunas University of Technology" + }, { + "id": "kea_copenhagen_school_of_design_and_technology", + "label": "KEA – Copenhagen School of Design and Technology" + }, { + "id": "kielce_university_of_technology", + "label": "Kielce University of Technology" + }, { + "id": "koebenhavn_nord", + "label": "Koebenhavn Nord" + }, { + "id": "korea_institute_of_science_and_technology_information", + "label": "Korea Institute of Science and Technology Information" + }, { + "id": "lafayette_college", + "label": "Lafayette College" + }, { + "id": "lamar_university", + "label": "Lamar University" + }, { + "id": "lawrence_berkeley_national_laboratory", + "label": "Lawrence Berkeley National Laboratory" + }, { + "id": "lehigh_university", + "label": "Lehigh University" + }, { + "id": "leibniz_rechenzentrum_der_bayerischen_akademie_der_wissenschaften", + "label": "Leibniz-Rechenzentrum der Bayerischen Akademie der Wissenschaften" + }, { + "id": "ligo_scientific_collaboration", + "label": "LIGO Scientific Collaboration" + }, { + "id": "lillebaelt_academy", + "label": "Lillebaelt Academy" + }, { + "id": "linkopings_universitet", + "label": "Linköpings Universitet" + }, { + "id": "lodz_university_of_technology", + "label": "Lodz University of Technology" + }, { + "id": "louisiana_state_university", + "label": "Louisiana State University" + }, { + "id": "loyola_university_of_chicago", + "label": "Loyola University of Chicago" + }, { + "id": "ludwig_maximilians_universitat_munchen", + "label": "Ludwig-Maximilians-Universität München" + }, { + "id": "lunds_universitet", + "label": "Lunds universitet" + }, { + "id": "malmo_hogskola", + "label": "Malmö högskola" + }, { + "id": "marine_biological_laboratory", + "label": "Marine Biological Laboratory" + }, { + "id": "marselisborg_gymnasium", + "label": "Marselisborg Gymnasium" + }, { + "id": "marshall_university", + "label": "Marshall University" + }, { + "id": "massachusetts_institute_of_technology", + "label": "Massachusetts Institute of Technology" + }, { + "id": "mcnc", + "label": "MCNC" + }, { + "id": "medical_university_of_south_carolina", + "label": "Medical University of South Carolina" + }, { + "id": "metropolitan_university_college", + "label": "Metropolitan University College" + }, { + "id": "michigan_state_university", + "label": "Michigan State University" + }, { + "id": "mississippi_state_university", + "label": "Mississippi State University" + }, { + "id": "montana_state_university_bozeman", + "label": "Montana State University - Bozeman" + }, { + "id": "moss_landing_marine_laboratories", + "label": "Moss Landing Marine Laboratories" + }, { + "id": "national_institutes_of_health", + "label": "National Institutes of Health" + }, { + "id": "naval_postgraduate_school", + "label": "Naval Postgraduate School" + }, { + "id": "rda", + "label": "NCAR RDA" + }, { + "id": "ncsa", + "label": "NCSA" + }, { + "id": "nersc", + "label": "NERSC" + }, { + "id": "new_york_university", + "label": "New York University" + }, { + "id": "nicolaus_copernicus_university_in_torun", + "label": "Nicolaus Copernicus University in Torun" + }, { + "id": "nikhef", + "label": "Nikhef" + }, { + "id": "north_carolina_state_university", + "label": "North Carolina State University" + }, { + "id": "northern_illinois_university", + "label": "Northern Illinois University" + }, { + "id": "northwestern_university", + "label": "Northwestern University" + }, { + "id": "ntb_hochschule_fur_technik_buchs", + "label": "NTB - Hochschule für Technik Buchs" + }, { + "id": "oak_ridge_national_laboratory", + "label": "Oak Ridge National Laboratory" + }, { + "id": "ohio_state_university", + "label": "Ohio State University" + }, { + "id": "ohio_technology_consortium_oh_tech", + "label": "Ohio Technology Consortium (OH-TECH)" + }, { + "id": "ohio_university_main_campus", + "label": "Ohio University Main Campus" + }, { + "id": "oklahoma_state_university_system", + "label": "Oklahoma State University System" + }, { + "id": "old_dominion_university", + "label": "Old Dominion University" + }, { + "id": "opole_university", + "label": "Opole University" + }, { + "id": "orcid", + "label": "ORCID" + }, { + "id": "oregon_state_university", + "label": "Oregon State University" + }, { + "id": "paderup_gymnasium", + "label": "Paderup Gymnasium" + }, { + "id": "penn_state", + "label": "Penn State" + }, { + "id": "pharmakon", + "label": "Pharmakon" + }, { + "id": "phgr_padagogische_hochschule_graubunden", + "label": "PHGR - Pädagogische Hochschule Graubünden" + }, { + "id": "phlu_padagogische_hochschule_luzern", + "label": "PHLU - Pädagogische Hochschule Luzern" + }, { + "id": "phsg_padagogische_hochschule_st_gallen", + "label": "PHSG - Pädagogische Hochschule St.Gallen" + }, { + "id": "phtg_padagogische_hochschule_thurgau", + "label": "PHTG - Pädagogische Hochschule Thurgau" + }, { + "id": "phvs_padagogische_hochschule_wallis", + "label": "PHVS - Pädagogische Hochschule Wallis" + }, { + "id": "ph_zug_padagogische_hochschule_zug", + "label": "PH Zug - Pädagogische Hochschule Zug" + }, { + "id": "ph_zurich_padagogische_hochschule_zurich", + "label": "PH Zürich - Pädagogische Hochschule Zürich" + }, { + "id": "pmod_wrc_observatorium_davos", + "label": "PMOD/WRC - Observatorium Davos" + }, { + "id": "pomona_college", + "label": "Pomona College" + }, { + "id": "portland_state_university", + "label": "Portland State University" + }, { + "id": "princeton_university", + "label": "Princeton University" + }, { + "id": "protectnetwork", + "label": "ProtectNetwork" + }, { + "id": "psi_paul_scherrer_institut", + "label": "PSI - Paul Scherrer Institut" + }, { + "id": "purdue_university_main_campus", + "label": "Purdue University Main Campus" + }, { + "id": "reed_college", + "label": "Reed College" + }, { + "id": "region_zealand", + "label": "Region Zealand" + }, { + "id": "rice_university", + "label": "Rice University" + }, { + "id": "rockefeller_university", + "label": "Rockefeller University" + }, { + "id": "rosborg_gymnasium_hf", + "label": "Rosborg Gymnasium & HF" + }, { + "id": "roskilde_university", + "label": "Roskilde University" + }, { + "id": "royal_academy_of_music_aarhus_aalborg_rama", + "label": "Royal Academy of Music Aarhus/Aalborg (RAMA)" + }, { + "id": "royal_college_of_physicians_of_ireland", + "label": "Royal College of Physicians of Ireland" + }, { + "id": "rungsted_high_school", + "label": "Rungsted High School" + }, { + "id": "rutgers_the_state_university_of_new_jersey", + "label": "Rutgers, The State University of New Jersey" + }, { + "id": "san_diego_state_university", + "label": "San Diego State University" + }, { + "id": "schools_of_architecture_design_and_conservation", + "label": "Schools of Architecture, Design and Conservation" + }, { + "id": "second_university_of_naplesi", + "label": "Second University of Naplesi" + }, { + "id": "silkeborg_business_college", + "label": "Silkeborg Business College" + }, { + "id": "simac", + "label": "SIMAC" + }, { + "id": "sissa", + "label": "SISSA" + }, { + "id": "smithsonian_institution", + "label": "Smithsonian Institution" + }, { + "id": "southern_illinois_university", + "label": "Southern Illinois University" + }, { + "id": "southern_methodist_university", + "label": "Southern Methodist University" + }, { + "id": "sscol_soprintendenza_speciale_per_il_colosseo", + "label": "SSCOL - Soprintendenza Speciale per il Colosseo" + }, { + "id": "stanford_university", + "label": "Stanford University" + }, { + "id": "state_and_university_library_employees", + "label": "State and University Library - employees" + }, { + "id": "statens_museum_for_kunst_smk", + "label": "Statens Museum for Kunst – SMK" + }, { + "id": "stevens_institute_of_technology", + "label": "Stevens Institute of Technology" + }, { + "id": "stockholms_universitet", + "label": "Stockholms universitet" + }, { + "id": "stony_brook_university", + "label": "Stony Brook University" + }, { + "id": "switch", + "label": "SWITCH" + }, { + "id": "syddansk_erhvervsskole", + "label": "Syddansk Erhvervsskole" + }, { + "id": "syracuse_university", + "label": "Syracuse University" + }, { + "id": "technical_university_of_denmark", + "label": "Technical University of Denmark" + }, { + "id": "technische_universitat_wien", + "label": "Technische Universität Wien" + }, { + "id": "texas_a_m_university", + "label": "Texas A & M University" + }, { + "id": "texas_a_m_university_corpus_christi", + "label": "Texas A&M University-Corpus Christi" + }, { + "id": "texas_state_university_san_marcos", + "label": "Texas State University - San Marcos" + }, { + "id": "texas_tech_university", + "label": "Texas Tech University" + }, { + "id": "the_broad_institute_of_mit_and_harvard", + "label": "The Broad Institute of MIT and Harvard" + }, { + "id": "the_christian_gymnasium", + "label": "The Christian Gymnasium" + }, { + "id": "the_george_washington_university", + "label": "The George Washington University" + }, { + "id": "the_state_university_of_new_york_at_buffalo", + "label": "The State University of New York at Buffalo" + }, { + "id": "the_university_of_arizona", + "label": "The University of Arizona" + }, { + "id": "the_university_of_memphis", + "label": "The University of Memphis" + }, { + "id": "towson_university", + "label": "Towson University" + }, { + "id": "tufts_university", + "label": "Tufts University" + }, { + "id": "united_id", + "label": "United ID" + }, { + "id": "universita_degli_studi_di_perugia", + "label": "Università degli studi di Perugia" + }, { + "id": "universita_di_modena_e_reggio_emilia", + "label": "Università di Modena e Reggio Emilia" + }, { + "id": "universita_di_trieste", + "label": "Università di Trieste" + }, { + "id": "universita_di_urbino", + "label": "Università di Urbino" + }, { + "id": "universita_politecnica_delle_marche", + "label": "Universita Politecnica delle Marche" + }, { + "id": "universitare_fernstudien_schweiz", + "label": "Universitäre Fernstudien Schweiz" + }, { + "id": "universitat_basel", + "label": "Universität Basel" + }, { + "id": "universitat_bern", + "label": "Universität Bern" + }, { + "id": "universitat_freiburg", + "label": "Universität Freiburg" + }, { + "id": "universitat_genf", + "label": "Universität Genf" + }, { + "id": "universitat_liechtenstein", + "label": "Universität Liechtenstein" + }, { + "id": "universitat_luzern", + "label": "Universität Luzern" + }, { + "id": "universitat_st_gallen", + "label": "Universität St. Gallen" + }, { + "id": "universitat_zurich", + "label": "Universität Zürich" + }, { + "id": "universite_de_lausanne", + "label": "Université de Lausanne" + }, { + "id": "universite_de_neuchatel", + "label": "Université de Neuchâtel" + }, { + "id": "university_at_albany_state_university_of_new_york", + "label": "University At Albany, State University of New York" + }, { + "id": "university_college_capital", + "label": "University College Capital" + }, { + "id": "university_college_cork", + "label": "University College Cork" + }, { + "id": "university_college_dublin", + "label": "University College Dublin" + }, { + "id": "university_college_lillebaelt", + "label": "University College Lillebaelt" + }, { + "id": "university_college_of_northern_denmark", + "label": "University College of Northern Denmark" + }, { + "id": "university_college_of_teacher_education_in_lower_austria", + "label": "University College of Teacher Education in Lower Austria" + }, { + "id": "university_college_of_teacher_education_styria", + "label": "University College of Teacher Education Styria" + }, { + "id": "university_college_south_denmark", + "label": "University College South Denmark" + }, { + "id": "university_college_zealand", + "label": "University College Zealand" + }, { + "id": "university_of_alabama_at_birmingham", + "label": "University of Alabama at Birmingham" + }, { + "id": "university_of_alabama_the", + "label": "University of Alabama, The" + }, { + "id": "university_of_alaska_statewide_system", + "label": "University of Alaska Statewide System" + }, { + "id": "university_of_arkansas", + "label": "University of Arkansas" + }, { + "id": "university_of_california_berkeley", + "label": "University of California, Berkeley" + }, { + "id": "university_of_california_davis", + "label": "University of California, Davis" + }, { + "id": "university_of_california_irvine", + "label": "University of California-Irvine" + }, { + "id": "university_of_california_los_angeles", + "label": "University of California-Los Angeles" + }, { + "id": "university_of_california_office_of_the_president", + "label": "University of California - Office of the President" + }, { + "id": "university_of_california_riverside", + "label": "University of California, Riverside" + }, { + "id": "university_of_california_san_diego", + "label": "University of California-San Diego" + }, { + "id": "university_of_california_san_francisco", + "label": "University of California, San Francisco" + }, { + "id": "university_of_california_santa_barbara", + "label": "University of California-Santa Barbara" + }, { + "id": "university_of_california_santa_cruz", + "label": "University of California, Santa Cruz" + }, { + "id": "university_of_central_florida", + "label": "University of Central Florida" + }, { + "id": "uchicago", + "label": "University of Chicago" + }, { + "id": "university_of_cincinnati_main_campus", + "label": "University of Cincinnati Main Campus" + }, { + "id": "university_of_colorado_at_boulder", + "label": "University of Colorado at Boulder" + }, { + "id": "university_of_copenhagen", + "label": "University of Copenhagen" + }, { + "id": "university_of_dayton", + "label": "University of Dayton" + }, { + "id": "university_of_delaware", + "label": "University of Delaware" + }, { + "id": "exeter", + "label": "University of Exeter" + }, { + "id": "university_of_florida", + "label": "University of Florida" + }, { + "id": "university_of_glasgow", + "label": "University of Glasgow" + }, { + "id": "university_of_hawaii", + "label": "University of Hawaii" + }, { + "id": "university_of_helsinki", + "label": "University of Helsinki" + }, { + "id": "university_of_houston_libraries", + "label": "University of Houston Libraries" + }, { + "id": "university_of_iceland", + "label": "University of Iceland" + }, { + "id": "university_of_illinois_at_chicago", + "label": "University of Illinois at Chicago" + }, { + "id": "university_of_illinois_at_springfield", + "label": "University of Illinois At Springfield" + }, { + "id": "university_of_illinois_at_urbana_champaign", + "label": "University of Illinois at Urbana-Champaign" + }, { + "id": "university_of_iowa", + "label": "University of Iowa" + }, { + "id": "university_of_kansas", + "label": "University of Kansas" + }, { + "id": "university_of_kansas_medical_center", + "label": "University of Kansas Medical Center" + }, { + "id": "university_of_maryland_baltimore", + "label": "University of Maryland Baltimore" + }, { + "id": "university_of_maryland_baltimore_county", + "label": "University of Maryland Baltimore County" + }, { + "id": "university_of_maryland_college_park", + "label": "University of Maryland College Park" + }, { + "id": "university_of_massachusetts_amherst", + "label": "University of Massachusetts Amherst" + }, { + "id": "university_of_miami", + "label": "University of Miami" + }, { + "id": "university_of_michigan", + "label": "University of Michigan" + }, { + "id": "university_of_minnesota", + "label": "University of Minnesota" + }, { + "id": "university_of_mississippi", + "label": "University of Mississippi" + }, { + "id": "university_of_missouri_system", + "label": "University of Missouri System" + }, { + "id": "university_of_nebraska_lincoln", + "label": "University of Nebraska-Lincoln" + }, { + "id": "university_of_nebraska_medical_center", + "label": "University of Nebraska Medical Center" + }, { + "id": "university_of_nevada_reno", + "label": "University of Nevada, Reno" + }, { + "id": "university_of_new_mexico", + "label": "University of New Mexico" + }, { + "id": "university_of_north_carolina_at_chapel_hill", + "label": "University of North Carolina at Chapel Hill" + }, { + "id": "university_of_north_carolina_at_charlotte", + "label": "University of North Carolina At Charlotte" + }, { + "id": "university_of_north_carolina_at_greensboro", + "label": "University of North Carolina at Greensboro" + }, { + "id": "university_of_notre_dame", + "label": "University of Notre Dame" + }, { + "id": "university_of_oklahoma", + "label": "University of Oklahoma" + }, { + "id": "university_of_oregon", + "label": "University of Oregon" + }, { + "id": "university_of_padova", + "label": "University of Padova" + }, { + "id": "university_of_pennsylvania", + "label": "University of Pennsylvania" + }, { + "id": "university_of_pittsburgh", + "label": "University of Pittsburgh" + }, { + "id": "university_of_rochester", + "label": "University of Rochester" + }, { + "id": "university_of_science_and_technology_in_bydgoszcz", + "label": "University of Science and Technology in Bydgoszcz" + }, { + "id": "university_of_south_carolina", + "label": "University of South Carolina" + }, { + "id": "university_of_south_dakota", + "label": "University of South Dakota" + }, { + "id": "university_of_southern_california", + "label": "University of Southern California" + }, { + "id": "university_of_southern_denmark", + "label": "University of Southern Denmark" + }, { + "id": "university_of_south_florida", + "label": "University of South Florida" + }, { + "id": "university_of_texas_at_austin", + "label": "University of Texas at Austin" + }, { + "id": "university_of_texas_at_dallas", + "label": "University of Texas at Dallas" + }, { + "id": "university_of_texas_m_d_anderson_cancer_center", + "label": "University of Texas M.D. Anderson Cancer Center" + }, { + "id": "university_of_utah", + "label": "University of Utah" + }, { + "id": "university_of_vermont", + "label": "University of Vermont" + }, { + "id": "university_of_virginia", + "label": "University of Virginia" + }, { + "id": "university_of_washington", + "label": "University of Washington" + }, { + "id": "university_of_west_florida", + "label": "University of West Florida" + }, { + "id": "university_of_wisconsin_madison", + "label": "University of Wisconsin-Madison" + }, { + "id": "university_of_wisconsin_milwaukee", + "label": "University of Wisconsin-Milwaukee" + }, { + "id": "university_of_wyoming", + "label": "University of Wyoming" + }, { + "id": "uppsala_universitet", + "label": "Uppsala universitet" + }, { + "id": "utah_state_university", + "label": "Utah State University" + }, { + "id": "utah_valley_university", + "label": "Utah Valley University" + }, { + "id": "vanderbilt_university", + "label": "Vanderbilt University" + }, { + "id": "veterinarmedizinische_universitat_wien", + "label": "Veterinärmedizinische Universität Wien" + }, { + "id": "via_university_college", + "label": "VIA University College" + }, { + "id": "virginia_polytechnic_institute_and_state_university", + "label": "Virginia Polytechnic Institute and State University" + }, { + "id": "vordingborg_gymnasium_and_higher_prep_exam", + "label": "Vordingborg Gymnasium and Higher Prep Exam" + }, { + "id": "wayf_orphanage", + "label": "WAYF Orphanage" + }, { + "id": "wayne_state_university", + "label": "Wayne State University" + }, { + "id": "weill_cornell_medical_college", + "label": "Weill Cornell Medical College" + }, { + "id": "western_michigan_university", + "label": "Western Michigan University" + }, { + "id": "westgrid", + "label": "WestGrid" + }, { + "id": "west_virginia_university", + "label": "West Virginia University" + }, { + "id": "wheaton_college_ma", + "label": "Wheaton College (MA)" + }, { + "id": "woods_hole_oceanographic_institution", + "label": "Woods Hole Oceanographic Institution" + }, { + "id": "wsl_eidg_forschungsanstalt_fur_wald_schnee_und_landschaft", + "label": "WSL - Eidg. Forschungsanstalt für Wald, Schnee und Landschaft" + }, { + "id": "xsede", + "label": "XSEDE" + }, { + "id": "yale_university", + "label": "Yale University" + }, { + "id": "zealand_business_college", + "label": "Zealand Business College" + }, { + "id": "zentral_und_hochschulbibliothek_luzern", + "label": "Zentral- und Hochschulbibliothek Luzern" + }, { + "id": "zhaw_zurcher_hochschule_fur_angewandte_wissenschaften", + "label": "ZHAW - Zürcher Hochschule für Angewandte Wissenschaften" + } + ] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/data/institutions.csv b/vite-app/src/apps/Auth2/resources/data/institutions.csv new file mode 100644 index 00000000..67ede2fb --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/data/institutions.csv @@ -0,0 +1,4666 @@ +UNITID,NAME,CITY,STABBR +177834,A T Still University of Health Sciences,Kirksville,MO +180203,Aaniiih Nakoda College,Harlem,MT +222178,Abilene Christian University,Abilene,TX +138558,Abraham Baldwin Agricultural College,Tifton,GA +172866,Academy College,Minneapolis,MN +451079,Academy for Five Element Acupuncture,Gainesville,FL +457271,Academy for Jewish Religion-California,Los Angeles,CA +412173,Academy for Nursing and Health Occupations,West Palm Beach,FL +108232,Academy of Art University,San Francisco,CA +108269,Academy of Chinese Culture and Health Sciences,Oakland,CA +475635,Academy of Couture Art,Beverly Hills,CA +449454,Academy of Natural Therapy Inc,Greeley,CO +384306,Acupuncture and Integrative Medicine College-Berkeley,Berkeley,CA +439969,Acupuncture and Massage College,Miami,FL +126182,Adams State University,Alamosa,CO +188429,Adelphi University,Garden City,NY +188438,Adirondack Community College,Queensbury,NY +374024,Adler Graduate School,Richfield,MN +142832,Adler University,Chicago,IL +168528,Adrian College,Adrian,MI +444343,Advanced College,South Gate,CA +481234,Advanced Computing Institute,Los Angeles,CA +231411,Advanced Technology Institute,Virginia Beach,VA +444361,Advanced Training Associates,El Cajon,CA +133872,Adventist University of Health Sciences,Orlando,FL +205391,Advertising Art Educational Services DBA School of Advertising Art,Kettering,OH +138600,Agnes Scott College,Decatur,GA +134811,AI Miami International University of Art and Design,Miami,FL +152822,AIB College of Business,Des Moines,IA +217615,Aiken Technical College,Graniteville,SC +126207,Aims Community College,Greeley,CO +200697,Air Force Institute of Technology-Graduate School of Engineering & Management,Wright-Patterson AFB,OH +200785,Akron Institute of Herzing University,Akron,OH +100654,Alabama A & M University,Normal,AL +101949,Alabama Southern Community College,Monroeville,AL +100724,Alabama State University,Montgomery,AL +199786,Alamance Community College,Graham,NC +102580,Alaska Bible College,Palmer,AK +103501,Alaska Career College,Anchorage,AK +442523,Alaska Christian College,Soldotna,AK +102669,Alaska Pacific University,Anchorage,AK +188526,Albany College of Pharmacy and Health Sciences,Albany,NY +188535,Albany Law School,Albany,NY +188580,Albany Medical College,Albany,NY +138716,Albany State University,Albany,GA +138682,Albany Technical College,Albany,GA +128498,Albertus Magnus College,New Haven,CT +168546,Albion College,Albion,MI +210571,Albright College,Reading,PA +175342,Alcorn State University,Alcorn State,MS +237118,Alderson Broaddus University,Philippi,WV +172918,Alexandria Technical & Community College,Alexandria,MN +188641,Alfred University,Alfred,NY +156189,Alice Lloyd College,Pippa Passes,KY +108807,Allan Hancock College,Santa Maria,CA +161688,Allegany College of Maryland,Cumberland,MD +210669,Allegheny College,Meadville,PA +200873,Allegheny Wesleyan College,Salem,OH +152798,Allen College,Waterloo,IA +154642,Allen County Community College,Iola,KS +217624,Allen University,Columbia,SC +110468,Alliant International University-San Diego,San Diego,CA +460729,Allied American University,Laguna Hills,CA +168591,Alma College,Alma,MI +168607,Alpena Community College,Alpena,MI +210775,Alvernia University,Reading,PA +238193,Alverno College,Milwaukee,WI +222567,Alvin Community College,Alvin,TX +222576,Amarillo College,Amarillo,TX +222628,Amberton University,Garland,TX +457527,Ambria College of Nursing,Hoffman Estates,IL +188687,American Academy McAllister Institute of Funeral Service,New York,NY +446002,American Academy of Acupuncture and Oriental Medicine,Roseville,MN +142887,American Academy of Art,Chicago,IL +108852,American Academy of Dramatic Arts-Los Angeles,Los Angeles,CA +188678,American Academy of Dramatic Arts-New York,New York,NY +219505,American Baptist College,Nashville,TN +108861,American Baptist Seminary of the West,Berkeley,CA +457688,American Business and Technology University,St Joseph,MO +441052,American Career College-Anaheim,Anaheim,CA +109040,American Career College-Los Angeles,Los Angeles,CA +447768,American Career College-Ontario,Ontario,CA +461005,American College for Medical Careers,Orlando,FL +429085,American College of Acupuncture and Oriental Med,Houston,TX +449889,American College of Education,Indianapolis,IN +210809,American College of Financial Services,Bryn Mawr,PA +443599,American College of Healthcare Sciences,Portland,OR +430591,American College of Traditional Chinese Medicine,San Francisco,CA +109086,American Conservatory Theater,San Francisco,CA +108870,American Film Institute Conservatory,Los Angeles,CA +103787,American Indian College Inc,Phoenix,AZ +441636,American Institute of Alternative Medicine,Columbus,OH +438586,American InterContinental University-Atlanta,Atlanta,GA +445133,American InterContinental University-Houston,Houston,TX +445027,American InterContinental University-Online,Schaumburg,IL +438601,American InterContinental University-South Florida,Weston,FL +164447,American International College,Springfield,MA +116846,American Jewish University,Los Angeles,CA +475714,American Medical Academy,Miami,FL +188854,American Musical and Dramatic Academy,New York,NY +232797,American National University,Salem,VA +449339,American Public University System,Charles Town,WV +109208,American River College,Sacramento,CA +240736,American Samoa Community College,Pago Pago,AS +460738,American Sentinel University,Aurora,CO +131159,American University,Washington,DC +433004,American University of Health Sciences,Signal Hill,CA +241100,American University of Puerto Rico-Bayamon,Bayamon,PR +241128,American University of Puerto Rico-Manati,Manati,PR +447263,AmeriTech College-Draper,Draper,UT +164465,Amherst College,Amherst,MA +100690,Amridge University,Montgomery,AL +151865,Anabaptist Mennonite Biblical Seminary,Elkhart,IN +150048,Ancilla College,Donaldson,IN +150066,Anderson University-Anderson,Anderson,IN +217633,Anderson University-Anderson,Anderson,SC +164474,Andover Newton Theological School,Newton Centre,MA +138761,Andrew College,Cuthbert,GA +168740,Andrews University,Berrien Springs,MI +457299,Angeles College,Los Angeles,CA +222822,Angelina College,Lufkin,TX +222831,Angelo State University,San Angelo,TX +164492,Anna Maria College,Paxton,MA +161767,Anne Arundel Community College,Arnold,MD +172954,Anoka Technical College,Anoka,MN +172963,Anoka-Ramsey Community College,Coon Rapids,MN +109350,Antelope Valley College,Lancaster,CA +245838,Antioch University-Los Angeles,Culver City,CA +245892,Antioch University-Midwest,Yellow Springs,OH +245865,Antioch University-New England,Keene,NH +442392,Antioch University-PhD Program in Leadership and Change,Yellow Springs,OH +245847,Antioch University-Santa Barbara,Santa Barbara,CA +245883,Antioch University-Seattle,Seattle,WA +201016,Antonelli College-Cincinnati,Cincinnati,OH +383950,Antonelli College-Hattiesburg,Hattiesburg,MS +175528,Antonelli College-Jackson,Jackson,MS +210890,Antonelli Institute,Erdenheim,PA +429094,AOMA Graduate School of Integrative Medicine,Austin,TX +441511,Apex School of Theology,Durham,NC +237136,Appalachian Bible College,Mount Hope,WV +449922,Appalachian College of Pharmacy,Oakwood,VA +432348,Appalachian School of Law,Grundy,VA +197869,Appalachian State University,Boone,NC +168786,Aquinas College-Grand Rapids,Grand Rapids,MI +219578,Aquinas College-Nashville,Nashville,TN +176600,Aquinas Institute of Theology,Saint Louis,MO +126289,Arapahoe Community College,Littleton,CO +211088,Arcadia University,Glenside,PA +367936,Argosy University-Atlanta,Atlanta,GA +145770,Argosy University-Chicago,Chicago,IL +442222,Argosy University-Dallas,Farmers Branch,TX +448734,Argosy University-Denver,Denver,CO +366748,Argosy University-Hawaii,Honolulu,HI +450526,Argosy University-Inland Empire,Ontario,CA +447272,Argosy University-Los Angeles,Los Angeles,CA +450535,Argosy University-Nashville,Nashville,TN +436438,Argosy University-Orange County,Orange,CA +436094,Argosy University-Phoenix,Phoenix,AZ +456348,Argosy University-Phoenix Online Division,Phoenix,AZ +452090,Argosy University-Salt Lake City,Draper,UT +450544,Argosy University-San Diego,San Diego,CA +121983,Argosy University-San Francisco Bay Area,Alameda,CA +137148,Argosy University-Sarasota,Sarasota,FL +420866,Argosy University-Schaumburg,Schaumburg,IL +439057,Argosy University-Seattle,Seattle,WA +428268,Argosy University-Tampa,Tampa,FL +410502,Argosy University-The Art Institute of California-Hollywood,North Hollywood,CA +448576,Argosy University-The Art Institute of California-Inland Empire,San Bernardino,CA +432533,Argosy University-The Art Institute of California-Los Angeles,Santa Monica,CA +441973,Argosy University-The Art Institute of California-Orange County,Santa Ana,CA +450094,Argosy University-The Art Institute of California-Sacramento,Sacramento,CA +117113,Argosy University-The Art Institute of California-San Diego,San Diego,CA +117928,Argosy University-The Art Institute of California-San Francisco,San Francisco,CA +451848,Argosy University-The Art Institute of California-Silicon Valley,Sunnyvale,CA +173984,Argosy University-Twin Cities,Eagan,MN +419457,Argosy University-Washington DC,Arlington,VA +105899,Arizona Christian University,Phoenix,AZ +421708,Arizona College-Glendale,Glendale,AZ +482990,Arizona College-Mesa,Mesa,AZ +446039,Arizona School of Acupuncture and Oriental Medicine,Tucson,AZ +448886,Arizona State University-Downtown Phoenix,Phoenix,AZ +420574,Arizona State University-Polytechnic,Mesa,AZ +483124,Arizona State University-Skysong,Scottsdale,AZ +104151,Arizona State University-Tempe,Tempe,AZ +407009,Arizona State University-West,Glendale,AZ +450942,Arizona Summit Law School,Phoenix,AZ +104160,Arizona Western College,Yuma,AZ +106306,Arkansas Baptist College,Little Rock,AR +107327,Arkansas Northeastern College,Blytheville,AR +106449,Arkansas State University-Beebe,Beebe,AR +106458,Arkansas State University-Main Campus,Jonesboro,AR +107318,Arkansas State University-Mid-South,West Memphis,AR +420538,Arkansas State University-Mountain Home,Mountain Home,AR +440402,Arkansas State University-Newport,Newport,AR +106467,Arkansas Tech University,Russellville,AR +222877,Arlington Baptist College,Arlington,TX +138789,Armstrong State University,Savannah,GA +201061,Art Academy of Cincinnati,Cincinnati,OH +109651,Art Center College of Design,Pasadena,CA +404994,ASA College,Brooklyn,NY +156222,Asbury Theological Seminary,Wilmore,KY +156213,Asbury University,Wilmore,KY +461777,Ashdown College of Health Sciences,Redlands,CA +447777,Asher College,Sacramento,CA +197887,Asheville-Buncombe Technical Community College,Asheville,NC +154022,Ashford University,San Diego,CA +156231,Ashland Community and Technical College,Ashland,KY +201104,Ashland University,Ashland,OH +128577,Asnuntuck Community College,Enfield,CT +454829,Aspen University,Denver,CO +176619,Assemblies of God Theological Seminary,Springfield,MO +164562,Assumption College,Worcester,MA +183600,Assumption College for Sisters,Mendham,NJ +446127,ATA Career Education,Spring Hill,FL +447935,ATA College,Louisville,KY +440651,Atenas College,Manati,PR +201140,Athenaeum of Ohio,Cincinnati,OH +100812,Athens State University,Athens,AL +246813,Athens Technical College,Athens,GA +138901,Atlanta Metropolitan State College,Atlanta,GA +138840,Atlanta Technical College,Atlanta,GA +138929,Atlanta's John Marshall Law School,Atlanta,GA +183655,Atlantic Cape Community College,Mays Landing,NJ +439446,Atlantic Institute of Oriental Medicine,Fort Lauderdale,FL +241216,Atlantic University College,Guaynabo,PR +100858,Auburn University,Auburn University,AL +100830,Auburn University at Montgomery,Montgomery,AL +173045,Augsburg College,Minneapolis,MN +138956,Augusta Technical College,Augusta,GA +482149,Augusta University,Augusta,GA +143084,Augustana College-Rock Island,Rock Island,IL +219000,Augustana University,Sioux Falls,SD +201177,Aultman College of Nursing and Health Sciences,Canton,OH +143118,Aurora University,Aurora,IL +222983,Austin College,Sherman,TX +222992,Austin Community College District,Austin,TX +247825,Austin Graduate School of Theology,Austin,TX +219602,Austin Peay State University,Clarksville,TN +223001,Austin Presbyterian Theological Seminary,Austin,TX +442295,Ave Maria School of Law,Naples,FL +446048,Ave Maria University,Ave Maria,FL +231420,Averett University,Danville,VA +449931,Averett University-Non-Traditional Programs,Danville,VA +447847,Aviator College of Aeronautical Science and Technology,Fort Pierce,FL +176628,Avila University,Kansas City,MO +102711,AVTEC-Alaska's Institute of Technology,Seward,AK +483762,Azure College,Miami Gardens,FL +109785,Azusa Pacific University,Azusa,CA +474863,Azusa Pacific University College,Glendora,CA +164580,Babson College,Wellesley,MA +206817,Bacone College,Muskogee,OK +139010,Bainbridge State College,Bainbridge,GA +476601,Bais HaMedrash and Mesivta of Baltimore,Baltimore,MD +245777,Bais Medrash Elyon,Monsey,NY +449658,Bais Medrash Toras Chesed,Lakewood,NJ +168847,Baker College,Flint,MI +414708,Baker College Center for Graduate Studies,Flint,MI +444167,Baker College of Allen Park,Allen Park,MI +404073,Baker College of Auburn Hills,Auburn Hills,MI +404648,Baker College of Cadillac,Cadillac,MI +404082,Baker College of Clinton Township,Clinton Township,MI +414160,Baker College of Jackson,Jackson,MI +171298,Baker College of Muskegon,Muskegon,MI +168838,Baker College of Owosso,Owosso,MI +381617,Baker College of Port Huron,Port Huron,MI +154688,Baker University,Baldwin City,KS +109819,Bakersfield College,Bakersfield,CA +420705,Bakke Graduate University,Dallas,TX +201195,Baldwin Wallace University,Berea,OH +150136,Ball State University,Muncie,IN +161864,Baltimore City Community College,Baltimore,MD +189015,Bank Street College of Education,New York,NY +176664,Baptist Bible College,Springfield,MO +211024,Clarks Summit University,Clarks Summit,PA +223083,Baptist Health System School of Health Professions,San Antonio,TX +219639,Baptist Memorial College of Health Sciences,Memphis,TN +223117,Baptist Missionary Association Theological Seminary,Jacksonville,TX +366793,Baptist Theological Seminary at Richmond,Henrico,VA +444398,Baptist University of the Americas,San Antonio,TX +155070,Barclay College,Haviland,KS +189088,Bard College,Annandale-On-Hudson,NY +167792,Bard College at Simon's Rock,Great Barrington,MA +189097,Barnard College,New York,NY +177719,Barnes-Jewish College Goldfarb School of Nursing,Saint Louis,MO +132471,Barry University,Miami,FL +109907,Barstow Community College,Barstow,CA +197911,Barton College,Wilson,NC +154697,Barton County Community College,Great Bend,KS +235547,Bastyr University,Kenmore,WA +160977,Bates College,Lewiston,ME +235671,Bates Technical College,Tacoma,WA +437103,Baton Rouge Community College,Baton Rouge,LA +158343,Baton Rouge School of Computers,Baton Rouge,LA +139074,Bauder College,Atlanta,GA +168883,Bay de Noc Community College,Escanaba,MI +380359,Bay Mills Community College,Brimley,MI +164632,Bay Path University,Longmeadow,MA +164641,Bay State College,Boston,MA +223223,Baylor College of Medicine,Houston,TX +223232,Baylor University,Waco,TX +384254,Beacon College,Leesburg,FL +160995,Beal College,Bangor,ME +197966,Beaufort County Community College,Washington,NC +164720,Becker College,Worcester,MA +247065,Beckfield College-Florence,Florence,KY +452373,Beckfield College-Tri-County,Springdale,OH +476717,Be'er Yaakov Talmudic Seminary,Spring Valley,NY +444413,Beis Medrash Heichal Dovid,Far Rockaway,NY +190956,Belanger School of Nursing,Schenectady,NY +175421,Belhaven University,Jackson,MS +156286,Bellarmine University,Louisville,KY +234669,Bellevue College,Bellevue,WA +180814,Bellevue University,Bellevue,NE +238324,Bellin College,Green Bay,WI +234696,Bellingham Technical College,Bellingham,WA +197984,Belmont Abbey College,Belmont,NC +201283,Belmont College,Saint Clairsville,OH +219709,Belmont University,Nashville,TN +238333,Beloit College,Beloit,WI +126359,Bel-Rea Institute of Animal Technology,Denver,CO +173124,Bemidji State University,Bemidji,MN +217721,Benedict College,Columbia,SC +154712,Benedictine College,Atchison,KS +145619,Benedictine University,Lisle,IL +165884,Benjamin Franklin Institute of Technology,Boston,MA +197993,Bennett College,Greensboro,NC +230816,Bennington College,Bennington,VT +164739,Bentley University,Waltham,MA +156295,Berea College,Berea,KY +183743,Bergen Community College,Paramus,NJ +461643,Bergin University of Canine Studies,Rohnert Park,CA +125170,Berkeley City College,Berkeley,CA +189228,Berkeley College-New York,New York,NY +183789,Berkeley College-Woodland Park,Woodland Park,NJ +164748,Berklee College of Music,Boston,MA +213534,Berks Technical Institute,Wyomissing,PA +164775,Berkshire Community College,Pittsfield,MA +139144,Berry College,Mount Berry,GA +189273,Beth Hamedrash Shaarei Yosher Institute,Brooklyn,NY +189264,Beth Hatalmud Rabbinical College,Brooklyn,NY +183804,Beth Medrash Govoha,Lakewood,NJ +237181,Bethany College-Bethany,Bethany,WV +154721,Bethany College-Lindsborg,Lindsborg,KS +173142,Bethany Lutheran College,Mankato,MN +143233,Bethany Theological Seminary,Richmond,IN +458113,Bethel College,Hampton,VA +150145,Bethel College-Indiana,Mishawaka,IN +154749,Bethel College-North Newton,North Newton,KS +262022,Bethel Seminary-San Diego,San Diego,CA +173179,Bethel Seminary-St Paul,Saint Paul,MN +219718,Bethel University-McKenzie,McKenzie,TN +173160,Bethel University-Saint Paul,Saint Paul,MN +110060,Bethesda University,Anaheim,CA +132602,Bethune-Cookman University,Daytona Beach,FL +139153,Beulah Heights University,Atlanta,GA +102429,Bevill State Community College,Jasper,AL +148724,Bexley Hall Seabury Western Theological Seminary Federation,Chicago,IL +443702,Bexley Hall Seabury Western Theological Seminary Federation ,Columbus,OH +211130,Biblical Theological Seminary,Hatfield,PA +211149,Bidwell Training Center Inc,Pittsburgh,PA +234711,Big Bend Community College,Moses Lake,WA +157553,Big Sandy Community and Technical College,Prestonsburg,KY +110097,Biola University,La Mirada,CA +100937,Birmingham Southern College,Birmingham,AL +442949,Birthingway College of Midwifery,Portland,OR +102030,Bishop State Community College,Mobile,AL +200022,Bismarck State College,Bismarck,ND +143279,Black Hawk College,Moline,IL +219046,Black Hills State University,Spearfish,SD +106625,Black River Technical College,Pocahontas,AR +143288,Blackburn College,Carlinville,IL +180054,Blackfeet Community College,Browning,MT +238397,Blackhawk Technical College,Janesville,WI +198011,Bladen Community College,Dublin,NC +143297,Blessing Rieman College of Nursing,Quincy,IL +223427,Blinn College,Brenham,TX +183822,Bloomfield College,Bloomfield,NJ +211158,Bloomsburg University of Pennsylvania,Bloomsburg,PA +441502,Blue Cliff College-Gulfport,Gulfport,MS +175430,Blue Mountain College,Blue Mountain,MS +208275,Blue Mountain Community College,Pendleton,OR +446774,Blue Ridge Community and Technical College,Martinsburg,WV +198039,Blue Ridge Community College-Flat Rock,Flat Rock,NC +231536,Blue Ridge Community College-Weyers Cave,Weyers Cave,VA +231554,Bluefield College,Bluefield,VA +237215,Bluefield State College,Bluefield,WV +156392,Bluegrass Community and Technical College,Lexington,KY +201371,Bluffton University,Bluffton,OH +217749,Bob Jones University,Greenville,SC +142090,Boise Bible College,Boise,ID +142115,Boise State University,Boise,ID +233356,Bon Secours Memorial College of Nursing,Richmond,VA +189413,Boricua College,New York,NY +158431,Bossier Parish Community College,Bossier City,LA +164872,Boston Architectural College,Boston,MA +164614,Boston Baptist College,Boston,MA +164924,Boston College,Chestnut Hill,MA +164915,Boston Graduate School of Psychoanalysis Inc,Brookline,MA +164988,Boston University,Boston,MA +161004,Bowdoin College,Brunswick,ME +162007,Bowie State University,Bowie,MD +201432,Bowling Green State University-Firelands,Huron,OH +201441,Bowling Green State University-Main Campus,Bowling Green,OH +202161,Bradford School-Columbus,Columbus,OH +211200,Bradford School-Pittsburgh,Pittsburgh,PA +143358,Bradley University,Peoria,IL +189422,Bramson ORT College,Forest Hills,NY +165015,Brandeis University,Waltham,MA +262086,Brandman University,Irvine,CA +223506,Brazosport College,Lake Jackson,TX +139199,Brenau University,Gainesville,GA +156356,Brescia University,Owensboro,KY +198066,Brevard College,Brevard,NC +139205,Brewton-Parker College,Mount Vernon,GA +152992,Briar Cliff University,Sioux City,IA +189459,Briarcliffe College,Bethpage,NY +231581,Bridgewater College,Bridgewater,VA +165024,Bridgewater State University,Bridgewater,MA +230047,Brigham Young University-Hawaii,Laie,HI +142522,Brigham Young University-Idaho,Rexburg,ID +230038,Brigham Young University-Provo,Provo,UT +215646,Brightwood Career Institute-Broomall,Broomall,PA +251075,Brightwood Career Institute-Harrisburg,Harrisburg,PA +214254,Brightwood Career Institute-Philadelphia,Philadelphia,PA +211617,Brightwood Career Institute-Philadelphia Mills,Philadelphia,PA +213002,Brightwood Career Institute-Pittsburgh,Pittsburgh,PA +458690,Brightwood College-Arlington,Arlington,TX +447102,Brightwood College-Bakersfield,Bakersfield,CA +163736,Brightwood College-Baltimore,Baltimore,MD +440323,Brightwood College-Beaumont,Beaumont,TX +164058,Brightwood College-Beltsville,Beltsville,MD +443827,Brightwood College-Brownsville,Brownsville,TX +458706,Brightwood College-Charlotte,Charlotte,NC +458186,Brightwood College-Chula Vista,Chula Vista,CA +443836,Brightwood College-Corpus Christi,Corpus Christi,TX +382896,Brightwood College-Dallas,Dallas,TX +204626,Brightwood College-Dayton,Dayton,OH +246266,Brightwood College-El Paso,El Paso,TX +445328,Brightwood College-Fort Worth,Fort Worth,TX +447120,Brightwood College-Fresno,Clovis,CA +458283,Brightwood College-Indianapolis,Indianapolis,IN +440332,Brightwood College-Laredo,Laredo,TX +374875,Brightwood College-Las Vegas,Las Vegas,NV +227836,Brightwood College-McAllen,McAllen,TX +366960,Brightwood College-Modesto,Salida,CA +246202,Brightwood College-Nashville,Nashville,TN +447634,Brightwood College-Palm Springs,Palm Springs,CA +432302,Brightwood College-Riverside,Riverside,CA +118259,Brightwood College-Sacramento,Sacramento,CA +431886,Brightwood College-San Antonio-Ingram,San Antonio,TX +364955,Brightwood College-San Antonio-San Pedro,San Antonio,TX +118277,Brightwood College-San Diego,San Diego,CA +161776,Brightwood College-Towson,Towson,MD +118286,Brightwood College-Vista,Vista,CA +165033,Bristol Community College,Fall River,MA +397270,Bristol University,Anaheim,CA +450304,Brite Divinity School,Fort Worth,TX +459091,Broadview Entertainment Arts University,Salt Lake City,UT +467793,Broadview University-Boise,Meridian,ID +450429,Broadview University-Layton,Layton,UT +454591,Broadview University-Orem,Orem,UT +230056,Broadview University-West Jordan,West Jordan,UT +183859,Brookdale Community College,Lincroft,NJ +223524,Brookhaven College,Farmers Branch,TX +444088,Brookline College-Albuquerque,Albuquerque,NM +104090,Brookline College-Phoenix,Phoenix,AZ +404055,Brookline College-Tempe,Tempe,AZ +438179,Brookline College-Tucson,Tucson,AZ +189501,Brooklyn Law School,Brooklyn,NY +110185,Brooks Institute,Ventura,CA +132709,Broward College,Fort Lauderdale,FL +205647,Brown Mackie College-Akron,Akron,OH +460039,Brown Mackie College-Albuquerque,Albuquerque,NM +410283,Brown Mackie College-Atlanta,Atlanta,GA +470162,Brown Mackie College-Birmingham,Birmingham,AL +455600,Brown Mackie College-Boise,Boise,ID +205610,Brown Mackie College-Cincinnati,Cincinnati,OH +482954,Brown Mackie College-Dallas,Bedford,TX +375489,Brown Mackie College-Findlay,Findlay,OH +408039,Brown Mackie College-Fort Wayne,Fort Wayne,IN +456791,Brown Mackie College-Greenville,Greenville,SC +421513,Brown Mackie College-Hopkinsville,Hopkinsville,KY +451699,Brown Mackie College-Indianapolis,Indianapolis,IN +154767,Brown Mackie College-Kansas City,Lenexa,KS +157599,Brown Mackie College-Louisville,Louisville,KY +151616,Brown Mackie College-Merrillville,Merrillville,IN +447290,Brown Mackie College-Miami,Miramar,FL +151625,Brown Mackie College-Michigan City,Michigan City,IN +204316,Brown Mackie College-North Canton,Canton,OH +157696,Brown Mackie College-Northern Kentucky,Fort Mitchell,KY +475042,Brown Mackie College-Oklahoma City,Oklahoma City,OK +456612,Brown Mackie College-Phoenix,Phoenix,AZ +373085,Brown Mackie College-Quad Cities,Bettendorf,IA +154776,Brown Mackie College-Salina,Salina,KS +460613,Brown Mackie College-San Antonio,San Antonio,TX +151944,Brown Mackie College-South Bend,South Bend,IN +460048,Brown Mackie College-St Louis,Fenton,MO +104364,Brown Mackie College-Tucson,Tucson,AZ +455619,Brown Mackie College-Tulsa,Tulsa,OK +217156,Brown University,Providence,RI +198084,Brunswick Community College,Bolivia,NC +180878,Bryan College of Health Sciences,Lincoln,NE +219790,Bryan College-Dayton,Dayton,TN +439826,Bryan College-Gold River,Gold River,CA +475583,Bryan University-Columbia,Columbia,MO +110219,Bryan University-Los Angeles,Los Angeles,CA +454458,Bryan University-Rogers,Rogers,AR +369516,Bryan University-Springfield,Springfield,MO +154794,Bryan University-Topeka,Topeka,KS +475699,Bryant & Stratton College-Akron,Copley,OH +188517,Bryant & Stratton College-Albany,Albany,NY +189556,Bryant & Stratton College-Amherst,Getzville,NY +458502,Bryant & Stratton College-Bayshore,Glendale,WI +189583,Bryant & Stratton College-Buffalo,Buffalo,NY +202684,Bryant & Stratton College-Cleveland,Cleveland,OH +369905,Bryant & Stratton College-Eastlake,Eastlake,OH +189592,Bryant & Stratton College-Greece,Rochester,NY +459107,Bryant & Stratton College-Hampton,Hampton,VA +410496,Bryant & Stratton College-Henrietta,Rochester,NY +239929,Bryant & Stratton College-Milwaukee,Milwaukee,WI +480091,Bryant & Stratton College-Online,Orchard Park,NY +201469,Bryant & Stratton College-Parma,Parma,OH +231828,Bryant & Stratton College-Richmond,North Chesterfield,VA +374972,Bryant & Stratton College-Southtowns,Orchard Park,NY +189574,Bryant & Stratton College-Syracuse,Syracuse,NY +189565,Bryant & Stratton College-Syracuse North,Liverpool,NY +231785,Bryant & Stratton College-Virginia Beach,Virginia Beach,VA +451750,Bryant & Stratton College-Wauwatosa,Wauwatosa,WI +217165,Bryant University,Smithfield,RI +210492,Bryn Athyn College of the New Church,Bryn Athyn,PA +211273,Bryn Mawr College,Bryn Mawr,PA +211291,Bucknell University,Lewisburg,PA +211307,Bucks County Community College,Newtown,PA +211316,Bucks County School of Beauty Culture Inc,Feasterville,PA +153001,Buena Vista University,Storm Lake,IA +165112,Bunker Hill Community College,Boston,MA +230825,Burlington College,Burlington,VT +484181,Burnett International College,Boynton Beach,FL +189653,Business Informatics Center Inc,Valley Stream,NY +154800,Butler Community College,El Dorado,KS +211343,Butler County Community College,Butler,PA +150163,Butler University,Indianapolis,IN +110246,Butte College,Oroville,CA +444103,Byzantine Catholic Seminary of Saints Cyril and Methodius,Pittsburgh,PA +198109,Cabarrus College of Health Sciences,Concord,NC +110334,Cabrillo College,Aptos,CA +211352,Cabrini University,Radnor,PA +215114,Cairn University-Langhorne,Langhorne,PA +198118,Caldwell Community College and Technical Institute,Hudson,NC +183910,Caldwell University,Caldwell,NJ +110361,California Baptist University,Riverside,CA +110918,California Christian College,Fresno,CA +110370,California College of the Arts,San Francisco,CA +485263,California College San Diego-San Diego,San Diego,CA +478634,California College San Diego-San Marcos,San Marcos,CA +110316,California Institute of Integral Studies,San Francisco,CA +110404,California Institute of Technology,Pasadena,CA +111081,California Institute of the Arts,Valencia,CA +110413,California Lutheran University,Thousand Oaks,CA +480781,California Miramar University,San Diego,CA +110422,California Polytechnic State University-San Luis Obispo,San Luis Obispo,CA +110529,California State Polytechnic University-Pomona,Pomona,CA +110486,California State University-Bakersfield,Bakersfield,CA +441937,California State University-Channel Islands,Camarillo,CA +110538,California State University-Chico,Chico,CA +110547,California State University-Dominguez Hills,Carson,CA +110574,California State University-East Bay,Hayward,CA +110556,California State University-Fresno,Fresno,CA +110565,California State University-Fullerton,Fullerton,CA +110583,California State University-Long Beach,Long Beach,CA +110592,California State University-Los Angeles,Los Angeles,CA +409698,California State University-Monterey Bay,Seaside,CA +110608,California State University-Northridge,Northridge,CA +110617,California State University-Sacramento,Sacramento,CA +110510,California State University-San Bernardino,San Bernardino,CA +366711,California State University-San Marcos,San Marcos,CA +110495,California State University-Stanislaus,Turlock,CA +460075,California University of Management and Sciences,Anaheim,CA +211361,California University of Pennsylvania,California,PA +111391,California Western School of Law,San Diego,CA +150172,Calumet College of Saint Joseph,Whiting,IN +176789,Calvary Bible College and Theological Seminary,Kansas City,MO +169080,Calvin College,Grand Rapids,MI +169099,Calvin Theological Seminary,Grand Rapids,MI +428329,Cambria-Rowe Business College-Indiana,Indiana,PA +211398,Cambria-Rowe Business College-Johnstown,Johnstown,PA +165167,Cambridge College,Cambridge,MA +454865,Cambridge College of Healthcare & Technology,Delray Beach,FL +446093,Cambridge Junior College-Yuba City,Yuba City,CA +183938,Camden County College,Blackwood,NJ +158440,Cameron College,New Orleans,LA +206914,Cameron University,Lawton,OK +198136,Campbell University,Buies Creek,NC +156365,Campbellsville University,Campbellsville,KY +111434,Canada College,Redwood City,CA +189705,Canisius College,Buffalo,NY +200208,Cankdeska Cikana Community College,Fort Totten,ND +165194,Cape Cod Community College,West Barnstable,MA +198154,Cape Fear Community College,Wilmington,NC +413413,Capella University,Minneapolis,MN +158352,Capital Area Technical College,Baton Rouge,LA +129367,Capital Community College,Hartford,CT +201548,Capital University,Columbus,OH +162061,Capitol Technology University,Laurel,MD +238430,Cardinal Stritch University,Milwaukee,WI +181941,Career College of Northern Nevada,Sparks,NV +224439,Career Point College-San Antonio,San Antonio,TX +246008,Career Point College-Tulsa,Tulsa,OK +454306,Career Quest Learning Centers-Jackson,Jackson,MI +446136,Career Quest Learning Centers-Lansing,Lansing,MI +367112,Career Technical College-Monroe,Monroe,LA +446880,Career Technical College-Shreveport,Shreveport,LA +210951,Career Training Academy-Lower Burrell,New Kensington,PA +408312,Career Training Academy-Monroeville,Monroeville,PA +440174,Career Training Academy-Pittsburgh,Pittsburgh,PA +448239,Careers Unlimited,Orem,UT +241377,Caribbean University-Bayamon,Bayamon,PR +241386,Caribbean University-Carolina,Carolina,PR +363907,Caribbean University-Ponce,Ponce,PR +363916,Caribbean University-Vega Baja,Vega Baja,PR +206923,Carl Albert State College,Poteau,OK +143613,Carl Sandburg College,Galesburg,IL +173258,Carleton College,Northfield,MN +132842,Carlos Albizu University-Miami,Miami,FL +241331,Carlos Albizu University-San Juan,San Juan,PR +211431,Carlow University,Pittsburgh,PA +211440,Carnegie Mellon University,Pittsburgh,PA +199971,Carolina Christian College,Winston Salem,NC +461032,Carolina College of Biblical Studies,Fayetteville,NC +433174,Carolinas College of Health Sciences,Charlotte,NC +442602,Carrington College-Albuquerque,Albuquerque,NM +142054,Carrington College-Boise,Boise,ID +450702,Carrington College-Citrus Heights,Citrus Heights,CA +457101,Carrington College-Las Vegas,Las Vegas,NV +103909,Carrington College-Mesa,Mesa,AZ +103893,Carrington College-Phoenix,Phoenix,AZ +438258,Carrington College-Pleasant Hill,Pleasant Hill,CA +467368,Carrington College-Pomona,Pomona,CA +246035,Carrington College-Portland,Portland,OR +457110,Carrington College-Reno,Reno,NV +125532,Carrington College-Sacramento,Sacramento,CA +437936,Carrington College-San Jose,San Jose,CA +246974,Carrington College-San Leandro,San Leandro,CA +439118,Carrington College-Spokane,Spokane,WA +450696,Carrington College-Stockton,Stockton,CA +103927,Carrington College-Tucson,Tucson,AZ +250601,Carrington College-Westside,Phoenix,AZ +180106,Carroll College,Helena,MT +405872,Carroll Community College,Westminster,MD +238458,Carroll University,Waukesha,WI +219806,Carson-Newman University,Jefferson City,TN +198206,Carteret Community College,Morehead City,NC +238476,Carthage College,Kenosha,WI +139287,Carver Bible College,Atlanta,GA +430795,Carver Career Center,Charleston,WV +111638,Casa Loma College-Van Nuys,Van Nuys,CA +439190,Cascadia College,Bothell,WA +201645,Case Western Reserve University,Cleveland,OH +240505,Casper College,Casper,WY +230834,Castleton State College,Castleton,VT +198215,Catawba College,Salisbury,NC +198233,Catawba Valley Community College,Hickory,NC +475398,Catholic Distance University,Hamilton,VA +143659,Catholic Theological Union at Chicago,Chicago,IL +131283,Catholic University of America,Washington,DC +189839,Cayuga County Community College,Auburn,NY +189848,Cazenovia College,Cazenovia,NY +162104,Cecil College,North East,MD +211468,Cedar Crest College,Allentown,PA +223773,Cedar Valley College,Lancaster,TX +201654,Cedarville University,Cedarville,OH +183974,Centenary College,Hackettstown,NJ +158477,Centenary College of Louisiana,Shreveport,LA +379782,Center for Advanced Legal Studies,Houston,TX +241793,Center for Advanced Studies On Puerto Rico and the Caribbean,San Juan,PR +232618,Centra College of Nursing,Lynchburg,VA +100760,Central Alabama Community College,Alexander City,AL +104346,Central Arizona College,Coolidge,AZ +106713,Central Baptist College,Conway,AR +154837,Central Baptist Theological Seminary,Shawnee,KS +198251,Central Carolina Community College,Sanford,NC +218858,Central Carolina Technical College,Sumter,SC +154855,Central Christian College of Kansas,McPherson,KS +176910,Central Christian College of the Bible,Moberly,MO +153108,Central College,Pella,IA +180902,Central Community College,Grand Island,NE +128771,Central Connecticut State University,New Britain,CT +439525,Central Florida Institute,Palm Harbor,FL +483045,Central Georgia Technical College,Warner Robins,GA +173203,Central Lakes College-Brainerd,Brainerd,MN +158088,Central Louisiana Technical Community College,Alexandria,LA +161077,Central Maine Community College,Auburn,ME +445267,Central Methodist University-College of Graduate and Extended Studies,Fayette,MO +176947,Central Methodist University-College of Liberal Arts and Sciences,Fayette,MO +169248,Central Michigan University,Mount Pleasant,MI +187532,Central New Mexico Community College,Albuquerque,NM +201672,Central Ohio Technical College,Newark,OH +208318,Central Oregon Community College,Bend,OR +211477,Central Penn College,Summerdale,PA +198260,Central Piedmont Community College,Charlotte,NC +201690,Central State University,Wilberforce,OH +223816,Central Texas College,Killeen,TX +231697,Central Virginia Community College,Lynchburg,VA +234827,Central Washington University,Ellensburg,WA +240514,Central Wyoming College,Riverton,WY +189857,Central Yeshiva Tomchei Tmimim Lubavitz,Brooklyn,NY +234845,Centralia College,Centralia,WA +156408,Centre College,Danville,KY +451741,Centro de Estudios Multidisciplinarios-Bayamon,Bayamón,PR +376224,Centro de Estudios Multidisciplinarios-Humacao,Humacao,PR +241517,Centro de Estudios Multidisciplinarios-San Juan,San Juan,PR +420024,Centura College-Chesapeake,Chesapeake,VA +444972,Centura College-Columbia,Columbia,SC +377449,Centura College-Newport News,Newport News,VA +377458,Centura College-Norfolk,Norfolk,VA +427982,Centura College-Richmond Main,Richmond,VA +232016,Centura College-Virginia Beach,Virginia Beach,VA +175315,Century College-White Bear Lake,White Bear Lake,MN +111887,Cerritos College,Norwalk,CA +111896,Cerro Coso Community College,Ridgecrest,CA +111920,Chabot College,Hayward,CA +180948,Chadron State College,Chadron,NE +111939,Chaffey College,Rancho Cucamonga,CA +454245,Chamberlain College of Nursing-Arizona,Phoenix,AZ +457129,Chamberlain College of Nursing-Florida,Jacksonville,FL +475732,Chamberlain College of Nursing-Georgia,Atlanta,GA +454227,Chamberlain College of Nursing-Illinois,Addison,IL +466921,Chamberlain College of Nursing-Missouri,St. Louis,MO +454236,Chamberlain College of Nursing-Ohio,Columbus,OH +466930,Chamberlain College of Nursing-Texas,Houston,TX +460871,Chamberlain College of Nursing-Virginia,Arlington,VA +141486,Chaminade University of Honolulu,Honolulu,HI +230852,Champlain College,Burlington,VT +364025,Chandler-Gilbert Community College,Chandler,AZ +111948,Chapman University,Orange,CA +111966,Charles R Drew University of Medicine and Science,Los Angeles,CA +451510,Charleston School of Law,Charleston,SC +217688,Charleston Southern University,Charleston,SC +444778,Charlotte Christian College and Theological Seminary,Charlotte,NC +455169,Charlotte School of Law,Charlotte,NC +102845,Charter College-Anchorage,Anchorage,AK +434317,Charter College-Canyon Country,Canyon Country,CA +128780,Charter Oak State College,New Britain,CT +201751,Chatfield College,Saint Martin,OH +211556,Chatham University,Pittsburgh,PA +140331,Chattahoochee Technical College,Marietta,GA +101028,Chattahoochee Valley Community College,Phenix City,AL +220118,Chattanooga College Medical Dental and Technical Careers,Chattanooga,TN +219824,Chattanooga State Community College,Chattanooga,TN +208390,Chemeketa Community College,Salem,OR +162168,Chesapeake College,Wye Mills,MD +437769,Chester Career College,CHESTER,VA +211583,Chestnut Hill College,Philadelphia,PA +211608,Cheyney University of Pennsylvania,Cheyney,PA +181145,CHI Health School of Radiologic Technology,Omaha,NE +393180,Chicago ORT Technical Institute,Skokie,IL +144005,Chicago State University,Chicago,IL +144014,Chicago Theological Seminary,Chicago,IL +180160,Chief Dull Knife College,Lame Deer,MT +133021,Chipola College,Marianna,FL +240116,Chippewa Valley Technical College,Eau Claire,WI +198303,Chowan University,Murfreesboro,NC +189981,Christ the King Seminary,East Aurora,NY +219833,Christian Brothers University,Memphis,TN +260947,Christian Life College,Mount Prospect,IL +150215,Christian Theological Seminary,Indianapolis,IN +475510,Christie's Education,New York,NY +231712,Christopher Newport University,Newport News,VA +112127,Church Divinity School of the Pacific,Berkeley,CA +201858,Cincinnati Christian University,Cincinnati,OH +201867,Cincinnati College of Mortuary Science,Cincinnati,OH +201928,Cincinnati State Technical and Community College,Cincinnati,OH +223898,Cisco College,Cisco,TX +217864,Citadel Military College of South Carolina,Charleston,SC +112172,Citrus College,Glendora,CA +112190,City College of San Francisco,San Francisco,CA +417327,City College-Altamonte Springs,Altamonte Springs,FL +244233,City College-Fort Lauderdale,Fort Lauderdale,FL +406547,City College-Gainesville,Gainesville,FL +475477,City College-Hollywood,Hollywood,FL +434539,City College-Miami,Miami,FL +144209,City Colleges of Chicago-Harold Washington College,Chicago,IL +144184,City Colleges of Chicago-Harry S Truman College,Chicago,IL +144157,City Colleges of Chicago-Kennedy-King College,Chicago,IL +144166,City Colleges of Chicago-Malcolm X College,Chicago,IL +144175,City Colleges of Chicago-Olive-Harvey College,Chicago,IL +144193,City Colleges of Chicago-Richard J Daley College,Chicago,IL +144218,City Colleges of Chicago-Wilbur Wright College,Chicago,IL +234915,City University of Seattle,Seattle,WA +457697,City Vision University,Kansas City,MO +208406,Clackamas Community College,Oregon City,OR +217873,Claflin University,Orangeburg,SC +112251,Claremont Graduate University,Claremont,CA +112260,Claremont McKenna College,Claremont,CA +124283,Claremont School of Theology,Claremont,CA +223922,Clarendon College,Clarendon,TX +211644,Clarion University of Pennsylvania,Clarion,PA +138947,Clark Atlanta University,Atlanta,GA +234933,Clark College,Vancouver,WA +201973,Clark State Community College,Springfield,OH +165334,Clark University,Worcester,MA +153126,Clarke University,Dubuque,IA +180832,Clarkson College,Omaha,NE +190044,Clarkson University,Potsdam,NY +450401,Clary Sage College,Tulsa,OK +208415,Clatsop Community College,Astoria,OR +139311,Clayton State University,Morrow,GA +156417,Clear Creek Baptist Bible College,Pineville,KY +133085,Clearwater Christian College,Clearwater,FL +169327,Cleary University,Ann Arbor,MI +217882,Clemson University,Clemson,SC +198321,Cleveland Community College,Shelby,NC +202046,Cleveland Institute of Art,Cleveland,OH +202073,Cleveland Institute of Music,Cleveland,OH +219879,Cleveland State Community College,Cleveland,TN +202134,Cleveland State University,Cleveland,OH +177038,Cleveland University-Kansas City,Overland Park,KS +217891,Clinton College,Rock Hill,SC +190053,Clinton Community College,Plattsburgh,NY +154907,Cloud County Community College,Concordia,KS +234951,Clover Park Technical College,Lakewood,WA +187639,Clovis Community College,Clovis,NM +175519,Coahoma Community College,Clarksdale,MS +223320,Coastal Bend College,Beeville,TX +198330,Coastal Carolina Community College,Jacksonville,NC +218724,Coastal Carolina University,Conway,SC +485458,Coastal Pines Technical College-Waycross,Waycross,GA +112385,Coastline Community College,Fountain Valley,CA +104425,Cochise County Community College District,Douglas,AZ +190071,Cochran School of Nursing,Yonkers,NY +404426,Coconino Community College,Flagstaff,AZ +153144,Coe College,Cedar Rapids,IA +154925,Coffeyville Community College,Coffeyville,KS +112394,Cogswell College,Sunnyvale,CA +217907,Coker College,Hartsville,SC +161086,Colby College,Waterville,ME +154934,Colby Community College,Colby,KS +182634,Colby-Sawyer College,New London,NH +430935,Colegio de Cinematografía Artes y Television,Bayamon,PR +241720,Colegio Universitario de San Juan,San Juan,PR +112446,Coleman University,San Diego,CA +190080,Colgate Rochester Crozer Divinity School,Rochester,NY +190099,Colgate University,Hamilton,NY +169442,College for Creative Studies,Detroit,MI +108667,College of Alameda,Alameda,CA +388520,College of Biblical Studies-Houston,Houston,TX +456977,College of Business and Technology-Cutler Bay,Cutler Bay,FL +449083,College of Business and Technology-Flagler,Miami,FL +449092,College of Business and Technology-Hialeah,Hialeah,FL +417318,College of Business and Technology-Kendall,Miami,FL +482024,College of Business and Technology-Miami Gardens,Miami Gardens,FL +132851,College of Central Florida,Ocala,FL +217819,College of Charleston,Charleston,SC +139250,College of Coastal Georgia,Brunswick,GA +150251,College of Court Reporting Inc,Hobart,IN +144865,College of DuPage,Glen Ellyn,IL +392257,College of Health Care Professions-Northwest,Houston,TX +146472,College of Lake County,Grayslake,IL +118347,College of Marin,Kentfield,CA +413617,College of Menominee Nation,Keshena,WI +243638,College of Micronesia-FSM,Pohnpei,FM +193399,College of Mount Saint Vincent,Bronx,NY +167394,College of Our Lady of the Elms,Chicopee,MA +174747,College of Saint Benedict,Saint Joseph,MN +186618,College of Saint Elizabeth,Morristown,NJ +181604,College of Saint Mary,Omaha,NE +122791,College of San Mateo,San Mateo,CA +142559,College of Southern Idaho,Twin Falls,ID +162122,College of Southern Maryland,La Plata,MD +182005,College of Southern Nevada,Las Vegas,NV +231077,College of St Joseph,Rutland,VT +190558,College of Staten Island CUNY,Staten Island,NY +197814,College of the Albemarle,Elizabeth City,NC +160959,College of the Atlantic,Bar Harbor,ME +111461,College of the Canyons,Santa Clarita,CA +113573,College of the Desert,Palm Desert,CA +166124,College of the Holy Cross,Worcester,MA +226408,College of the Mainland,Texas City,TX +376695,College of the Marshall Islands,Majuro,MH +480967,College of the Muscogee Nation,Okmulgee,OK +107521,College of the Ouachitas,Malvern,AR +178697,College of the Ozarks,Point Lookout,MO +121707,College of the Redwoods,Eureka,CA +123217,College of the Sequoias,Visalia,CA +123484,College of the Siskiyous,Weed,CA +455114,College of Western Idaho,Nampa,ID +231624,College of William and Mary,Williamsburg,VA +451705,CollegeAmerica-Cheyenne,Cheyenne,WY +448752,CollegeAmerica-Colorado Springs,Colorado Springs,CO +126872,CollegeAmerica-Denver,Denver,CO +103945,CollegeAmerica-Flagstaff,Flagstaff,AZ +448761,CollegeAmerica-Fort Collins,Fort Collins,CO +474890,CollegeAmerica-Phoenix,Phoenix,AZ +247834,Collin County Community College District,McKinney,TX +103723,Collins College,Phoenix,AZ +461953,Colorado Academy of Veterinary Technology,Colorado Springs,CO +126669,Colorado Christian University,Lakewood,CO +126678,Colorado College,Colorado Springs,CO +367839,Colorado Heights University,Denver,CO +127556,Colorado Mesa University,Grand Junction,CO +126711,Colorado Mountain College,Glenwood Springs,CO +126748,Colorado Northwestern Community College,Rangely,CO +381732,Colorado School of Healing Arts,Lakewood,CO +126775,Colorado School of Mines,Golden,CO +126784,Colorado School of Trades,Lakewood,CO +381352,Colorado School of Traditional Chinese Medicine,Denver,CO +126818,Colorado State University-Fort Collins,Fort Collins,CO +476975,Colorado State University-Global Campus,Greenwood Village,CO +128106,Colorado State University-Pueblo,Pueblo,CO +126827,Colorado Technical University-Colorado Springs,Colorado Springs,CO +430087,Colorado Technical University-Greenwood Village,Aurora,CO +444158,Colorado Technical University-Online,Colorado Springs,CO +402615,Colorado Technical University-Sioux Falls,Sioux Falls,SD +234979,Columbia Basin College,Pasco,WA +241304,Columbia Central University-Caguas,Caguas,PR +404806,Columbia Central University-Yauco,Yauco,PR +238573,Columbia College of Nursing,Glendale,WI +144281,Columbia College-Chicago,Chicago,IL +177065,Columbia College-Columbia,Columbia,MO +217934,Columbia College-Columbia,Columbia,SC +455983,Columbia College-Fairfax,Fairfax,VA +112570,Columbia College-Hollywood,Tarzana,CA +112561,Columbia College-Sonora,Sonora,CA +420556,Columbia Gorge Community College,The Dalles,OR +217925,Columbia International University,Columbia,SC +450933,Columbia Southern University,Orange Beach,AL +219888,Columbia State Community College,Columbia,TN +139348,Columbia Theological Seminary,Decatur,GA +190150,Columbia University in the City of New York,New York,NY +190169,Columbia-Greene Community College,Hudson,NY +202170,Columbus College of Art and Design,Columbus,OH +202222,Columbus State Community College,Columbus,OH +139366,Columbus State University,Columbus,GA +139357,Columbus Technical College,Columbus,GA +483522,Comanche Nation College,Lawton,OK +366261,Commonwealth Institute of Funeral Service,Houston,TX +212975,Commonwealth Technical Institute,Johnstown,PA +439570,Community Care College,Tulsa,OK +446163,Community Christian College,Redlands,CA +210605,Community College of Allegheny County,Pittsburgh,PA +126863,Community College of Aurora,Aurora,CO +211079,Community College of Beaver County,Monaca,PA +126942,Community College of Denver,Denver,CO +215239,Community College of Philadelphia,Philadelphia,PA +217475,Community College of Rhode Island,Warwick,RI +230861,Community College of Vermont,Winooski,VT +459417,Compass College of Cinematic Arts,Grand Rapids,MI +177083,Conception Seminary College,Conception,MO +237330,Concord University,Athens,WV +126687,Concorde Career College-Aurora,Aurora,CO +460181,Concorde Career College-Dallas,Dallas,TX +123679,Concorde Career College-Garden Grove,Garden Grove,CA +441742,Concorde Career College-Grand Prairie,Grand Prairie,TX +155283,Concorde Career College-Kansas City,Kansas City,MO +219903,Concorde Career College-Memphis,Memphis,TN +124937,Concorde Career College-North Hollywood,North Hollywood,CA +208479,Concorde Career College-Portland,Portland,OR +460206,Concorde Career College-San Antonio,San Antonio,TX +124706,Concorde Career College-San Bernardino,San Bernardino,CA +120661,Concorde Career College-San Diego,San Diego,CA +133845,Concorde Career Institute-Jacksonville,Jacksonville,FL +133854,Concorde Career Institute-Miramar,Miramar,FL +460190,Concorde Career Institute-Orlando,Orlando,FL +133863,Concorde Career Institute-Tampa,Tampa,FL +101073,Concordia College Alabama,Selma,AL +173300,Concordia College at Moorhead,Moorhead,MN +190248,Concordia College-New York,Bronxville,NY +177092,Concordia Seminary,Saint Louis,MO +150288,Concordia Theological Seminary,Fort Wayne,IN +169363,Concordia University-Ann Arbor,Ann Arbor,MI +144351,Concordia University-Chicago,River Forest,IL +112075,Concordia University-Irvine,Irvine,CA +180984,Concordia University-Nebraska,Seward,NE +208488,Concordia University-Portland,Portland,OR +173328,Concordia University-Saint Paul,Saint Paul,MN +224004,Concordia University-Texas,Austin,TX +238616,Concordia University-Wisconsin,Mequon,WI +128902,Connecticut College,New London,CT +206996,Connors State College,Warner,OK +260354,Consolidated School of Business-Lancaster,Lancaster,PA +211820,Consolidated School of Business-York,York,PA +112826,Contra Costa College,San Pablo,CA +217961,Converse College,Spartanburg,SC +165495,Conway School of Landscape Design,Conway,MA +190372,Cooper Union for the Advancement of Science and Art,New York,NY +175573,Copiah-Lincoln Community College,Wesson,MS +395362,Copper Mountain Community College,Joshua Tree,CA +162283,Coppin State University,Baltimore,MD +210331,Corban University,Salem,OR +153162,Cornell College,Mount Vernon,IA +190415,Cornell University,Ithaca,NY +170037,Cornerstone University,Grand Rapids,MI +190442,Corning Community College,Corning,NY +235024,Cornish College of the Arts,Seattle,WA +106795,Cossatot Community College of the University of Arkansas,De Queen,AR +113096,Cosumnes River College,Sacramento,CA +177117,Cottey College,Nevada,MO +184180,County College of Morris,Randolph,NJ +224183,Court Reporting Institute of Dallas,Dallas,TX +139393,Covenant College,Lookout Mountain,GA +177126,Covenant Theological Seminary,Saint Louis,MO +154952,Cowley County Community College,Arkansas City,KS +176770,Cox College,Springfield,MO +144485,Coyne College,Chicago,IL +113111,Crafton Hills College,Yucaipa,CA +169424,Cranbrook Academy of Art,Bloomfield Hills,MI +198367,Craven Community College,New Bern,NC +181002,Creighton University,Omaha,NE +475608,Criswell College,Dallas,TX +439613,Crossroads Bible College,Indianapolis,IN +174206,Crossroads College,Rochester,MN +177135,Crowder College,Neosho,MO +106810,Crowley's Ridge College,Paragould,AR +174862,Crown College,Saint Bonifacius,MN +113193,Cuesta College,San Luis Obispo,CA +444565,Culinary Institute Inc,Houston,TX +190503,Culinary Institute of America,Hyde Park,NY +177144,Culver-Stockton College,Canton,MO +184205,Cumberland County College,Vineland,NJ +219949,Cumberland University,Lebanon,TN +190512,CUNY Bernard M Baruch College,New York,NY +190521,CUNY Borough of Manhattan Community College,New York,NY +190530,CUNY Bronx Community College,Bronx,NY +190549,CUNY Brooklyn College,Brooklyn,NY +190567,CUNY City College,New York,NY +190576,CUNY Graduate School and University Center,New York,NY +190585,CUNY Hostos Community College,Bronx,NY +190594,CUNY Hunter College,New York,NY +190600,CUNY John Jay College of Criminal Justice,New York,NY +190619,CUNY Kingsborough Community College,Brooklyn,NY +190628,CUNY LaGuardia Community College,Long Island City,NY +190637,CUNY Lehman College,Bronx,NY +190646,CUNY Medgar Evers College,Brooklyn,NY +190655,CUNY New York City College of Technology,Brooklyn,NY +190664,CUNY Queens College,Flushing,NY +190673,CUNY Queensborough Community College,Bayside,NY +190682,CUNY School of Law,Long Island City,NY +190691,CUNY York College,Jamaica,NY +165529,Curry College,Milton,MA +211893,Curtis Institute of Music,Philadelphia,PA +202356,Cuyahoga Community College District,Cleveland,OH +113218,Cuyamaca College,El Cajon,CA +113236,Cypress College,Cypress,CA +231873,Dabney S Lancaster Community College,Clifton Forge,VA +458797,Dade Medical College-Hollywood,Hollywood,FL +458247,Dade Medical College-Homestead,Homestead,FL +476391,Dade Medical College-Jacksonville,Jacksonville,FL +444574,Dade Medical College-Miami,Miami,FL +454175,Dade Medical College-Miami Lakes,Miami Lakes,FL +476382,Dade Medical College-West Palm Beach,West Palm Beach,FL +190725,Daemen College,Amherst,NY +200314,Dakota College at Bottineau,Bottineau,ND +173416,Dakota County Technical College,Rosemount,MN +219082,Dakota State University,Madison,SD +219091,Dakota Wesleyan University,Mitchell,SD +224226,Dallas Baptist University,Dallas,TX +224244,Dallas Christian College,Dallas,TX +224271,Dallas Institute of Funeral Service,Dallas,TX +437732,Dallas Nursing Institute,Dallas,TX +224305,Dallas Theological Seminary,Dallas,TX +139463,Dalton State College,Dalton,GA +182661,Daniel Webster College,Nashua,NH +144564,Danville Area Community College,Danville,IL +231882,Danville Community College,Danville,VA +455178,Daoist Traditions College of Chinese Medical Arts,Asheville,NC +182670,Dartmouth College,Hanover,NH +138691,Darton State College,Albany,GA +169479,Davenport University,Grand Rapids,MI +198385,Davidson College,Davidson,NC +198376,Davidson County Community College,Thomasville,NC +237358,Davis & Elkins College,Elkins,WV +194569,Davis College-Johnson City,Johnson City,NY +202435,Davis College-Toledo,Toledo,OH +180151,Dawson Community College,Glendive,MT +447476,Daymar College-Bellevue,Bellevue,KY +363439,Daymar College-Bowling Green,Bowling Green,KY +205568,Daymar College-Chillicothe,Chillicothe,OH +205531,Daymar College-Jackson,Jackson,OH +205559,Daymar College-Lancaster,Lancaster,OH +406219,Daymar College-Louisville-Louisville,Louisville,KY +449302,Daymar College-Madisonville,Madisonville,KY +205522,Daymar College-New Boston,New Boston,OH +458557,Daymar College-Online,Louisville,KY +157465,Daymar College-Owensboro,Owensboro,KY +156903,Daymar College-Paducah Main,Paducah,KY +368443,Daymar Institute-Clarksville,Clarksville,TN +444255,Daymar Institute-Murfreesboro,Murfreesboro,TN +220002,Daymar Institute-Nashville,Nashville,TN +447014,Daytona College,Ormond Beach,FL +133386,Daytona State College,Daytona Beach,FL +113333,De Anza College,Cupertino,CA +165574,Dean College,Franklin,MA +211909,Dean Institute of Technology,Pittsburgh,PA +202514,Defiance College,Defiance,OH +224350,Del Mar College,Corpus Christi,TX +432524,Delaware College of Art and Design,Wilmington,DE +211927,Delaware County Community College,Media,PA +130934,Delaware State University,Dover,DE +130891,Delaware Technical Community College-Owens,Georgetown,DE +130916,Delaware Technical Community College-Stanton/Wilmington,Wilmington,DE +130907,Delaware Technical Community College-Terry,Dover,DE +211981,Delaware Valley University,Doylestown,PA +158662,Delgado Community College,New Orleans,LA +113537,Dell'Arte International School of Physical Theatre,Blue Lake,CA +169521,Delta College,University Center,MI +366270,Delta College of Arts & Technology,Baton Rouge,LA +158723,Delta School of Business and Technology,Lake Charles,LA +175616,Delta State University,Cleveland,MS +202523,Denison University,Granville,OH +217989,Denmark Technical College,Denmark,SC +454856,Denver School of Nursing,Denver,CO +126979,Denver Seminary,Littleton,CO +144740,DePaul University,Chicago,IL +150400,DePauw University,Greencastle,IN +153214,Des Moines Area Community College,Ankeny,IA +154156,Des Moines University-Osteopathic Medical Center,Des Moines,IA +210739,DeSales University,Center Valley,PA +113582,Design Institute of San Diego,San Diego,CA +482413,DeVry College of New York,New York,NY +482422,DeVry University-Arizona,Phoenix,AZ +482431,DeVry University-California,Pomona,CA +482440,DeVry University-Colorado,Westminster,CO +482459,DeVry University-Florida,Miramar,FL +482468,DeVry University-Georgia,Decatur,GA +482477,DeVry University-Illinois,Chicago,IL +482486,DeVry University-Indiana,Indianapolis,IN +482501,DeVry University-Maryland,Bethesda,MD +482510,DeVry University-Michigan,Southfield,MI +482529,DeVry University-Minnesota,Edina,MN +482538,DeVry University-Missouri,Kansas City,MO +482547,DeVry University-Nevada,Henderson,NV +482556,DeVry University-New Jersey,North Brunswick,NJ +482565,DeVry University-North Carolina,Charlotte,NC +482574,DeVry University-Ohio,Columbus,OH +482583,DeVry University-Oklahoma,Oklahoma City,OK +482592,DeVry University-Oregon,Portland,OR +482608,DeVry University-Pennsylvania,Fort Washington,PA +482617,DeVry University-Tennessee,Memphis,TN +482635,DeVry University-Texas,Irving,TX +482644,DeVry University-Utah,Sandy,UT +482653,DeVry University-Virginia,Arlington,VA +482662,DeVry University-Washington,Federal Way,WA +482671,DeVry University-Wisconsin,Milwaukee,WI +443562,Dewey University-Hato Rey-Hato Rey,Hato Rey,PR +113634,Diablo Valley College,Pleasant Hill,CA +212009,Dickinson College,Carlisle,PA +200059,Dickinson State University,Dickinson,ND +443410,DigiPen Institute of Technology,Redmond,WA +451060,Digital Media Arts College,Boca Raton,FL +158802,Dillard University,New Orleans,LA +105297,Dine College,Tsaile,AZ +153241,Divine Word College,Epworth,IA +230171,Dixie State University,Saint George,UT +181020,Doane University-Arts & Sciences,Crete,NE +448284,Doane University-Graduate and Professional Studies,Lincoln,NE +154998,Dodge City Community College,Dodge City,KS +190761,Dominican College of Blauvelt,Orangeburg,NY +113704,Dominican School of Philosophy & Theology,Berkeley,CA +148496,Dominican University,River Forest,IL +113698,Dominican University of California,San Rafael,CA +122117,Dongguk University-Los Angeles,Los Angeles,CA +155007,Donnelly College,Kansas City,KS +153250,Dordt College,Sioux Center,IA +212045,Douglas Education Center,Monessen,PA +190770,Dowling College,Oakdale,NY +153269,Drake University,Des Moines,IA +184348,Drew University,Madison,NJ +212054,Drexel University,Philadelphia,PA +177214,Drury University,Springfield,MO +212072,Du Bois Business College-Du Bois,Du Bois,PA +439303,Du Bois Business College-Huntingdon,Huntingdon,PA +439312,Du Bois Business College-Oil City,Oil City,PA +198419,Duke University,Durham,NC +173489,Duluth Business University,Duluth,MN +175227,Dunwoody College of Technology,Minneapolis,MN +212106,Duquesne University,Pittsburgh,PA +198455,Durham Technical Community College,Durham,NC +190840,Dutchess Community College,Poughkeepsie,NY +220057,Dyersburg State Community College,Dyersburg,TN +190716,D'Youville College,Buffalo,NY +447421,Eagle Gate College-Layton,Layton,UT +230366,Eagle Gate College-Murray,Murray,UT +447625,Eagle Gate College-Salt Lake City,Salt Lake City,UT +150455,Earlham College,Richmond,IN +106883,East Arkansas Community College,Forrest City,AR +198464,East Carolina University,Greenville,NC +177250,East Central College,Union,MO +175643,East Central Community College,Decatur,MS +207041,East Central University,Ada,OK +139621,East Georgia State College,Swainsboro,GA +113856,East Los Angeles College,Monterey Park,CA +175652,East Mississippi Community College,Scooba,MS +413802,East San Gabriel Valley Regional Occupational Program,West Covina,CA +212115,East Stroudsburg University of Pennsylvania,East Stroudsburg,PA +220075,East Tennessee State University,Johnson City,TN +224527,East Texas Baptist University,Marshall,TX +439394,East West College of Natural Medicine,Sarasota,FL +104577,Eastern Arizona College,Thatcher,AZ +129215,Eastern Connecticut State University,Willimantic,CT +132693,Eastern Florida State College,Cocoa,FL +203331,Eastern Gateway Community College,Steubenville,OH +142179,Eastern Idaho Technical College,Idaho Falls,ID +144892,Eastern Illinois University,Charleston,IL +448354,Eastern International College-Belleville,Belleville,NJ +421878,Eastern International College-Jersey City,Jersey City,NJ +153311,Eastern Iowa Community College District,Davenport,IA +156620,Eastern Kentucky University,Richmond,KY +161138,Eastern Maine Community College,Bangor,ME +232043,Eastern Mennonite University,Harrisonburg,VA +169798,Eastern Michigan University,Ypsilanti,MI +165644,Eastern Nazarene College,Quincy,MA +187648,Eastern New Mexico University-Main Campus,Portales,NM +187666,Eastern New Mexico University-Roswell Campus,Roswell,NM +383996,Eastern New Mexico University-Ruidoso Campus,Ruidoso,NM +207050,Eastern Oklahoma State College,Wilburton,OK +208646,Eastern Oregon University,La Grande,OR +232052,Eastern Shore Community College,Melfa,VA +212133,Eastern University,Saint Davids,PA +441858,Eastern Virginia Career College,Fredericksburg,VA +231970,Eastern Virginia Medical School,Norfolk,VA +235097,Eastern Washington University,Cheney,WA +438708,Eastern West Virginia Community and Technical College,Moorefield,WV +240596,Eastern Wyoming College,Torrington,WY +224572,Eastfield College,Mesquite,TX +144883,East-West University,Chicago,IL +183488,Eastwick College-Hackensack,Hackensack,NJ +184959,Eastwick College-Ramsey,Ramsey,NJ +446233,Ecclesia College,Springdale,AR +133492,Eckerd College,Saint Petersburg,FL +460215,Ecotech Institute,Aurora,CO +248934,ECPI University,Virginia Beach,VA +247162,Ecumenical Theological Seminary,Detroit,MI +177278,Eden Theological Seminary,Webster Groves,MO +198491,Edgecombe Community College,Tarboro,NC +238661,Edgewood College,Madison,WI +376321,EDIC College,Caguas,PR +212160,Edinboro University of Pennsylvania,Edinboro,PA +202648,Edison State Community College,Piqua,OH +235103,Edmonds Community College,Lynnwood,WA +243832,EDP Univeristy of Puerto Rico Inc-San Juan,San Juan,PR +241836,EDP University of Puerto Rico Inc-San Sebastian,San Sebastian,PR +442806,Edward Via College of Osteopathic Medicine,Blacksburg,VA +133526,Edward Waters College,Jacksonville,FL +112686,El Camino College-Compton Center,Compton,CA +113980,El Camino Community College District,Torrance,CA +224615,El Centro College,Dallas,TX +224642,El Paso Community College,El Paso,TX +144944,Elgin Community College,Elgin,IL +198507,Elizabeth City State University,Elizabeth City,NC +212197,Elizabethtown College,Elizabethtown,PA +480134,Elizabethtown College School of Continuing and Professional Studies,Elizabethtown,PA +156648,Elizabethtown Community and Technical College,Elizabethtown,KY +153296,Ellsworth Community College,Iowa Falls,IA +144962,Elmhurst College,Elmhurst,IL +190974,Elmira Business Institute,Elmira,NY +190983,Elmira College,Elmira,NY +198516,Elon University,Elon,NC +133553,Embry-Riddle Aeronautical University-Daytona Beach,Daytona Beach,FL +104586,Embry-Riddle Aeronautical University-Prescott,Prescott,AZ +426314,Embry-Riddle Aeronautical University-Worldwide,Daytona Beach,FL +165662,Emerson College,Boston,MA +220136,Emmanuel Christian Seminary,Johnson City,TN +165671,Emmanuel College-Boston,Boston,MA +139630,Emmanuel College-Franklin Springs,Franklin Springs,GA +153302,Emmaus Bible College,Dubuque,IA +232025,Emory & Henry College,Emory,VA +139658,Emory University,Atlanta,GA +114114,Emperor's College of Traditional Oriental Medicine,Santa Monica,CA +114123,Empire College,Santa Rosa,CA +155025,Emporia State University,Emporia,KS +165699,Endicott College,Beverly,MA +101143,Enterprise State Community College,Enterprise,AL +124487,Epic Bible College,Sacramento,CA +165705,Episcopal Divinity School,Cambridge,MA +224712,Episcopal Theological Seminary of the Southwest,Austin,TX +191083,Erie Community College,Buffalo,NY +212434,Erie Institute of Technology Inc,Erie,PA +409254,Erikson Institute,Chicago,IL +217998,Erskine College,Due West,SC +241951,Escuela de Artes Plasticas de Puerto Rico,San Juan,PR +184481,Essex County College,Newark,NJ +384333,Estrella Mountain Community College,Avondale,AZ +200590,ETI Technical College,Niles,OH +144971,Eureka College,Eureka,IL +177339,Evangel University,Springfield,MO +212443,Evangelical Theological Seminary,Myerstown,PA +371982,Everest College-Anaheim,Anaheim,CA +443854,Everest College-Arlington,Arlington,TX +366544,Everest College-Aurora,Aurora,CO +234739,Everest College-Bremerton,Bremerton,WA +438647,Everest College-Chesapeake,Chesapeake,VA +372037,Everest College-City of Industry,City of Industry,CA +126401,Everest College-Colorado Springs,Colorado Springs,CO +442790,Everest College-Dallas,Dallas,TX +363590,Everest College-Everett,Everett,WA +445197,Everest College-Fort Worth,Fort Worth,TX +460358,Everest College-Fort Worth South,Ft Worth,TX +182148,Everest College-Henderson,Henderson,NV +445470,Everest College-McLean,Vienna,VA +447236,Everest College-Mesa,Mesa,AZ +232502,Everest College-Newport News,Newport News,VA +440299,Everest College-Ontario Metro,Ontario,CA +103644,Everest College-Phoenix,Phoenix,AZ +210359,Everest College-Portland,Portland,OR +119359,Everest College-Reseda,Reseda,CA +230472,Everest College-Salt Lake City,West Valley City,UT +119508,Everest College-San Bernardino,San Bernardino,CA +179070,Everest College-Springfield,Springfield,MO +444024,Everest College-Tacoma,Tacoma,WA +127787,Everest College-Thornton,Thornton,CO +236993,Everest College-Vancouver,Vancouver,WA +368805,Everest College-West Los Angeles,Los Angeles,CA +237604,Everest Institute-Cross Lanes,Cross Lanes,WV +409670,Everest Institute-Kendall,Miami,FL +443748,Everest Institute-Norcross,Norcross,GA +135957,Everest Institute-North Miami,Miami,FL +212090,Everest Institute-Pittsburgh,Pittsburgh,PA +194967,Everest Institute-Rochester,Rochester,NY +260293,Everest University-Brandon,Tampa,FL +438902,Everest University-Jacksonville,Jacksonville,FL +367909,Everest University-Lakeland,Lakeland,FL +137810,Everest University-Largo,Largo,FL +420006,Everest University-Melbourne,Melbourne,FL +136288,Everest University-North Orlando,Orlando,FL +445434,Everest University-Orange Park,Orange Park,FL +134149,Everest University-Pompano Beach,Pompano Beach,FL +390701,Everest University-South Orlando,Orlando,FL +137801,Everest University-Tampa,Tampa,FL +235149,Everett Community College,Everett,WA +385619,Everglades University,Boca Raton,FL +114266,Evergreen Valley College,San Jose,CA +196680,Excelsior College,Albany,NY +447458,Expression College for Digital Arts,Emeryville,CA +129242,Fairfield University,Fairfield,CT +184694,Fairleigh Dickinson University-College at Florham,Madison,NJ +184603,Fairleigh Dickinson University-Metropolitan Campus,Teaneck,NJ +237367,Fairmont State University,Fairmont,WV +153320,Faith Baptist Bible College and Theological Seminary,Ankeny,IA +443049,Faith Evangelical College & Seminary,Tacoma,WA +212452,Faith Theological Seminary,Baltimore,MD +443058,Family of Faith College,Shawnee,OK +196042,Farmingdale State College,Farmingdale,NY +114354,Fashion Institute of Design & Merchandising-Los Angeles,Los Angeles,CA +248846,Fashion Institute of Design & Merchandising-San Diego,San Diego,CA +114390,Fashion Institute of Design & Merchandising-San Francisco,San Francisco,CA +191126,Fashion Institute of Technology,New York,NY +101189,Faulkner University,Montgomery,AL +198543,Fayetteville State University,Fayetteville,NC +198534,Fayetteville Technical Community College,Fayetteville,NC +114433,Feather River Community College District,Quincy,CA +184612,Felician University,Lodi,NJ +169910,Ferris State University,Big Rapids,MI +232089,Ferrum College,Ferrum,VA +114549,Fielding Graduate University,Santa Barbara,CA +436599,FINE Mortuary College,Norwood,MA +191199,Finger Lakes Community College,Canandaigua,NY +475422,Finger Lakes Health College of Nursing,Geneva,NY +172440,Finlandia University,Hancock,MI +165802,Fisher College,Boston,MA +220181,Fisk University,Nashville,TN +165820,Fitchburg State University,Fitchburg,MA +114585,Five Branches University,Santa Cruz,CA +191205,Five Towns College,Dix Hills,NY +133711,Flagler College-St Augustine,Saint Augustine,FL +444990,Flagler College-Tallahassee,Tallahassee,FL +180197,Flathead Valley Community College,Kalispell,MT +160481,Fletcher Technical Community College,Schriever,LA +155052,Flint Hills Technical College,Emporia,KS +218025,Florence-Darlington Technical College,Florence,SC +133650,Florida Agricultural and Mechanical University,Tallahassee,FL +133669,Florida Atlantic University,Boca Raton,FL +133997,Florida Career College-Miami,Miami,FL +434715,Florida Coastal School of Law,Jacksonville,FL +133809,Florida College,Temple Terrace,FL +434441,Florida College of Integrative Medicine,Orlando,FL +438294,Florida College of Natural Health-Bradenton,Bradenton,FL +438285,Florida College of Natural Health-Maitland,Maitland,FL +420103,Florida College of Natural Health-Miami,Miami,FL +387925,Florida College of Natural Health-Pompano Beach,Pompano Beach,FL +135160,Florida Gateway College,Lake City,FL +433660,Florida Gulf Coast University,Fort Myers,FL +133881,Florida Institute of Technology,Melbourne,FL +480569,Florida Institute of Technology-Online,Melbourne,FL +133951,Florida International University,Miami,FL +133960,Florida Keys Community College,Key West,FL +133979,Florida Memorial University,Miami Gardens,FL +408844,Florida National University-Main Campus,Hialeah,FL +134079,Florida Southern College,Lakeland,FL +133508,Florida SouthWestern State College,Fort Myers,FL +133702,Florida State College at Jacksonville,Jacksonville,FL +134097,Florida State University,Tallahassee,FL +134112,Florida Technical College,Orlando,FL +444219,Folsom Lake College,Folsom,CA +380368,Fond du Lac Tribal and Community College,Cloquet,MN +177418,Fontbonne University,Saint Louis,MO +114716,Foothill College,Los Altos Hills,CA +191241,Fordham University,Bronx,NY +177427,Forest Institute of Professional Psychology,Springfield,MO +218043,Forrest College,Anderson,SC +198552,Forsyth Technical Community College,Winston Salem,NC +155061,Fort Hays State University,Hays,KS +127185,Fort Lewis College,Durango,CO +180212,Fort Peck Community College,Poplar,MT +155098,Fort Scott Community College,Fort Scott,KS +139719,Fort Valley State University,Fort Valley,GA +439738,Fortis College-Baton Rouge,Baton Rouge,LA +205179,Fortis College-Centerville,Centerville,OH +450067,Fortis College-Cincinnati,Cincinnati,OH +460020,Fortis College-Columbia,Columbia,SC +450058,Fortis College-Columbus,Westerville,OH +480143,Fortis College-Cutler Bay,Cutler Bay,FL +204307,Fortis College-Cuyahoga Falls,Cuyahoga Falls,OH +458681,Fortis College-Indianapolis,Indianapolis,IN +451909,Fortis College-Landover,Landover,MD +447360,Fortis College-Largo,Largo,FL +371052,Fortis College-Mobile,Mobile,AL +455488,Fortis College-Montgomery-Montgomery,Montgomery,AL +233329,Fortis College-Norfolk,Norfolk,VA +439792,Fortis College-Orange Park,Orange Park,FL +456180,Fortis College-Phoenix,Phoenix,AZ +201399,Fortis College-Ravenna,Ravenna,OH +382957,Fortis College-Richmond,Richmond,VA +456454,Fortis College-Salt Lake City,Salt Lake City,UT +372921,Fortis College-Smyrna,Smyrna,GA +132806,Fortis College-Winter Park,Winter Park,FL +442745,Fortis Institute,Palm Springs,FL +455628,Fortis Institute-Birmingham,Birmingham,AL +418870,Fortis Institute-Cookeville,Cookeville,TN +216418,Fortis Institute-Erie,Erie,PA +443438,Fortis Institute-Fort Lauderdale,Lauderdale Lakes,FL +249609,Fortis Institute-Forty Fort,Forty Fort,PA +445753,Fortis Institute-Miami,Miami,FL +452124,Fortis Institute-Nashville,Nashville,TN +455479,Fortis Institute-Pensacola,Pensacola,FL +445744,Fortis Institute-Port Saint Lucie,Port Saint Lucie,FL +385503,Fortis Institute-Scranton,Scranton,PA +221795,Fountainhead College of Technology,Knoxville,TN +415774,Four-D College,Colton,CA +145239,Fox College,Bedford Park,IL +238722,Fox Valley Technical College,Appleton,WI +165866,Framingham State University,Framingham,MA +218061,Francis Marion University,Florence,SC +114734,Franciscan School of Theology,Oceanside,CA +205957,Franciscan University of Steubenville,Steubenville,OH +104665,Frank Lloyd Wright School of Architecture,Scottsdale,AZ +224891,Frank Phillips College,Borger,TX +212577,Franklin and Marshall College,Lancaster,PA +150604,Franklin College,Franklin,IN +182795,Franklin Pierce University,Rindge,NH +202806,Franklin University,Columbus,OH +441982,Franklin W Olin College of Engineering,Needham,MA +162557,Frederick Community College,Frederick,MD +220215,Freed-Hardeman University,Henderson,TN +372073,Fremont College,Cerritos,CA +114789,Fresno City College,Fresno,CA +114813,Fresno Pacific University,Fresno,CA +155089,Friends University,Wichita,KS +127200,Front Range Community College,Westminster,CO +403469,Frontier Community College,Fairfield,IL +156727,Frontier Nursing University,Hyden,KY +162584,Frostburg State University,Frostburg,MD +134237,Full Sail University,Winter Park,FL +114840,Fuller Theological Seminary in California,Pasadena,CA +114859,Fullerton College,Fullerton,CA +191302,Fulton-Montgomery Community College,Johnstown,NY +218070,Furman University,Greenville,SC +481030,Future Generations Graduate School,Franklin,WV +101240,Gadsden State Community College,Gadsden,AL +452948,Galen College of Nursing-Cincinnati,Cincinnati,OH +156471,Galen College of Nursing-Louisville,Louisville,KY +406033,Galen College of Nursing-San Antonio,San Antonio,TX +406024,Galen College of Nursing-Tampa Bay,Saint Petersburg,FL +131450,Gallaudet University,Washington,DC +205513,Gallipolis Career College,Gallipolis,OH +224961,Galveston College,Galveston,TX +212601,Gannon University,Erie,PA +155104,Garden City Community College,Garden City,KS +198561,Gardner-Webb University,Boiling Springs,NC +162609,Garrett College,McHenry,MD +145275,Garrett-Evangelical Theological Seminary,Evanston,IL +198570,Gaston College,Dallas,NC +157438,Gateway Community and Technical College,Florence,KY +130396,Gateway Community College-New Haven,New Haven,CT +105145,GateWay Community College-Phoenix,Phoenix,AZ +238759,Gateway Technical College,Kenosha,WI +114938,Gavilan College,Gilroy,CA +191339,Genesee Community College,Batavia,NY +212656,Geneva College,Beaver Falls,PA +101286,George C Wallace State Community College-Dothan,Dothan,AL +101295,George C Wallace State Community College-Hanceville,Hanceville,AL +101301,George C Wallace State Community College-Selma,Selma,AL +208822,George Fox University,Newberg,OR +232186,George Mason University,Fairfax,VA +131469,George Washington University,Washington,DC +156745,Georgetown College,Georgetown,KY +131496,Georgetown University,Washington,DC +461236,Georgia Christian University,Atlanta,GA +139861,Georgia College and State University,Milledgeville,GA +447689,Georgia Gwinnett College,Lawrenceville,GA +139700,Georgia Highlands College,Rome,GA +139755,Georgia Institute of Technology-Main Campus,Atlanta,GA +485111,Georgia Military College-Milledgeville,Milledgeville,GA +139384,Georgia Northwestern Technical College,Rome,GA +244437,Georgia Perimeter College,Decatur,GA +244446,Georgia Piedmont Technical College,Clarkston,GA +139931,Georgia Southern University,Statesboro,GA +139764,Georgia Southwestern State University,Americus,GA +139940,Georgia State University,Atlanta,GA +184773,Georgian Court University,Lakewood,NJ +232195,Germanna Community College,Locust Grove,VA +212674,Gettysburg College,Gettysburg,PA +169974,Glen Oaks Community College,Centreville,MI +104708,Glendale Community College-Glendale,Glendale,AZ +115001,Glendale Community College-Glendale,Glendale,CA +237385,Glenville State College,Glenville,WV +455390,Global Health College,Alexandria,VA +188465,Globe Institute of Technology,New York,NY +466514,Globe University-Appleton,Grand Chute,WI +456816,Globe University-Eau Claire,Eau Claire,WI +458751,Globe University–Green Bay,Green Bay,WI +458991,Globe University-La Crosse,Onalaska,WI +458733,Globe University-Madison East,Madison,WI +458760,Globe University–Madison West,Middleton,WI +456834,Globe University-Minneapolis,Minneapolis,MN +456807,Globe University-Sioux Falls,Sioux Falls,SD +458779,Globe University–Wausau,Rothschild,WI +173629,Globe University-Woodbury,Woodbury,MN +230889,Goddard College,Plainfield,VT +202903,Gods Bible School and College,Cincinnati,OH +169992,Gogebic Community College,Ironwood,MI +115083,Golden Gate University-San Francisco,San Francisco,CA +115126,Golden West College,Huntington Beach,CA +130989,Goldey-Beacom College,Wilmington,DE +430157,Golf Academy of America-Altamonte Springs,Apopka,FL +122366,Golf Academy of America-Carlsbad,Carlsbad,CA +476337,Golf Academy of America-Farmers Branch,Farmers Branch,TX +434690,Golf Academy of America-Myrtle Beach,Myrtle Beach,SC +430166,Golf Academy of America-Phoenix,Chandler,AZ +235316,Gonzaga University,Spokane,WA +202912,Good Samaritan College of Nursing and Health Science,Cincinnati,OH +132523,Gooding Institute of Nurse Anesthesia,Panama City,FL +129154,Goodwin College,East Hartford,CT +165936,Gordon College,Wenham,MA +139968,Gordon State College,Barnesville,GA +165945,Gordon-Conwell Theological Seminary,South Hamilton,MA +150668,Goshen College,Goshen,IN +162654,Goucher College,Baltimore,MD +145336,Governors State University,University Park,IL +170000,Grace Bible College,Wyoming,MI +150677,Grace College and Theological Seminary,Winona Lake,IN +461528,Grace College of Divinity,Fayetteville,NC +481058,Grace Mission University,Fullerton,CA +481401,Grace School of Theology,Conroe,TX +181093,Grace University,Omaha,NE +153366,Graceland University-Lamoni,Lamoni,IA +483285,Graduate School USA,Washington,DC +115214,Graduate Theological Union,Berkeley,CA +159009,Grambling State University,Grambling,LA +104717,Grand Canyon University,Phoenix,AZ +170055,Grand Rapids Community College,Grand Rapids,MI +170082,Grand Valley State University,Allendale,MI +153375,Grand View University,Des Moines,IA +183257,Granite State College,Concord,NH +442569,Grantham University,Lenexa,KS +212771,Gratz College,Melrose Park,PA +235334,Grays Harbor College,Aberdeen,WA +225070,Grayson College,Denison,TX +182306,Great Basin College,Elko,NV +183150,Great Bay Community College,Portsmouth,NH +180249,Great Falls College Montana State University,Great Falls,MT +170091,Great Lakes Christian College,Lansing,MI +213181,Great Lakes Institute of Technology,Erie,PA +230898,Green Mountain College,Poultney,VT +235343,Green River College,Auburn,WA +165981,Greenfield Community College,Greenfield,MA +198598,Greensboro College,Greensboro,NC +145372,Greenville College,Greenville,IL +218113,Greenville Technical College,Greenville,SC +153384,Grinnell College,Grinnell,IA +115296,Grossmont College,El Cajon,CA +212805,Grove City College,Grove City,PA +240745,Guam Community College,Mangilao,GU +198613,Guilford College,Greensboro,NC +198622,Guilford Technical Community College,Jamestown,NC +134343,Gulf Coast State College,Panama City,FL +139995,Gupton Jones College of Funeral Service,Decatur,GA +173647,Gustavus Adolphus College,Saint Peter,MN +140003,Gwinnett College-Lilburn,Lilburn,GA +140012,Gwinnett Technical College,Lawrenceville,GA +212832,Gwynedd Mercy University,Gwynedd Valley,PA +102313,H Councill Trenholm State Community College,Montgomery,AL +162690,Hagerstown Community College,Hagerstown,MD +198640,Halifax Community College,Weldon,NC +225201,Hallmark University,San Antonio,TX +191515,Hamilton College,Clinton,NY +153427,Hamilton Technical College,Davenport,IA +173665,Hamline University,Saint Paul,MN +232256,Hampden-Sydney College,Hampden-Sydney,VA +166018,Hampshire College,Amherst,MA +232265,Hampton University,Hampton,VA +177542,Hannibal-LaGrange University,Hannibal,MO +150756,Hanover College,Hanover,IN +212869,Harcum College,Bryn Mawr,PA +107044,Harding University,Searcy,AR +225247,Hardin-Simmons University,Abilene,TX +162706,Harford Community College,Bel Air,MD +145460,Harrington College of Design,Chicago,IL +212878,Harrisburg Area Community College-Harrisburg,Harrisburg,PA +446640,Harrisburg University of Science and Technology,Harrisburg,PA +458432,Harrison College-Grove City,Grove City,OH +151166,Harrison College-Indianapolis,Indianapolis,IN +468398,Harrison College-Morrisville,Morrisville,NC +177551,Harris-Stowe State University,Saint Louis,MO +129491,Hartford Seminary,Hartford,CT +115393,Hartnell College,Salinas,CA +191533,Hartwick College,Oneonta,NY +166027,Harvard University,Cambridge,MA +115409,Harvey Mudd College,Claremont,CA +155140,Haskell Indian Nations University,Lawrence,KS +181127,Hastings College,Hastings,NE +212911,Haverford College,Haverford,PA +383190,Hawaii Community College,Hilo,HI +141644,Hawaii Pacific University,Honolulu,HI +153445,Hawkeye Community College,Waterloo,IA +198668,Haywood Community College,Clyde,NC +156790,Hazard Community and Technical College,Hazard,KY +173683,Hazelden Betty Ford Graduate School of Addiction Studies,Center City,MN +115533,Heald College-Concord,Concord,CA +115472,Heald College-Fresno,Fresno,CA +371779,Heald College-Hayward,Hayward,CA +141468,Heald College-Honolulu,Honolulu,HI +459930,Heald College-Modesto,Salida,CA +430148,Heald College-Portland,Portland,OR +115454,Heald College-Rancho Cordova,Rancho Cordova,CA +363387,Heald College-Roseville,Roseville,CA +409874,Heald College-Salinas,Salinas,CA +115515,Heald College-San Francisco,San Francisco,CA +115490,Heald College-San Jose,Milpitas,CA +371760,Heald College-Stockton,Stockton,CA +384342,Heartland Community College,Normal,IL +166045,Hebrew College,Newton Centre,MA +145497,Hebrew Theological College,Skokie,IL +203067,Hebrew Union College-Jewish Institute of Religion,New York,NY +203085,Heidelberg University,Tiffin,OH +180276,Helena College University of Montana,Helena,MT +191597,Helene Fuld College of Nursing,New York,NY +166054,Hellenic College-Holy Cross Greek Orthodox School of Theology,Brookline,MA +156851,Henderson Community College,Henderson,KY +107071,Henderson State University,Arkadelphia,AR +107080,Hendrix College,Conway,AR +173708,Hennepin Technical College,Brooklyn Park,MN +170240,Henry Ford College,Dearborn,MI +198677,Heritage Bible College,Dunn,NC +101453,Heritage Christian University,Florence,AL +262509,Heritage College-Denver,Denver,CO +445814,Heritage College-Kansas City,Kansas City,MO +410070,Heritage College-Oklahoma City,Oklahoma City,OK +456320,Heritage College-Wichita,Wichita,KS +135124,Heritage Institute-Ft Myers,Fort Myers,FL +372772,Heritage Institute-Jacksonville,Jacksonville,FL +235422,Heritage University,Toppenish,WA +191612,Herkimer County Community College,Herkimer,NY +140340,Herzing University-Atlanta,Atlanta,GA +101365,Herzing University-Birmingham,Birmingham,AL +459851,Herzing University-Brookfield,Brookfield,WI +433536,Herzing University-Kenner,Kenner,LA +459842,Herzing University-Kenosha,Kenosha,WI +240392,Herzing University-Madison,Madison,WI +174154,Herzing University-Minneapolis,Minneapolis,MN +457022,Herzing University-Toledo,Toledo,OH +386472,Herzing University-Winter Park,Winter Park,FL +155177,Hesston College,Hesston,KS +173735,Hibbing Community College,Hibbing,MN +177579,Hickey College,Saint Louis,MO +198695,High Point University,High Point,NC +145521,Highland Community College-Freeport,Freeport,IL +155186,Highland Community College-Highland,Highland,KS +180081,Highlands College of Montana Tech,Butte,MT +235431,Highline College,Des Moines,WA +191621,Hilbert College,Hamburg,NY +225371,Hill College,Hillsboro,TX +134495,Hillsborough Community College,Tampa,FL +170286,Hillsdale College,Hillsdale,MI +207157,Hillsdale Free Will Baptist College,Moore,OK +175786,Hinds Community College,Raymond,MS +203128,Hiram College,Hiram,OH +220312,Hiwassee College,Madisonville,TN +191630,Hobart William Smith Colleges,Geneva,NY +134510,Hobe Sound Bible College,Hobe Sound,FL +203155,Hocking College,Nelsonville,OH +367884,Hodges University,Naples,FL +191649,Hofstra University,Hempstead,NY +232308,Hollins University,Roanoke,VA +175810,Holmes Community College,Goodman,MS +129534,Holy Apostles College and Seminary,Cromwell,CT +150774,Holy Cross College,Notre Dame,IN +212984,Holy Family University,Philadelphia,PA +115728,Holy Names University,Oakland,CA +166133,Holyoke Community College,Holyoke,MA +203386,Hondros College,Westerville,OH +141680,Honolulu Community College,Honolulu,HI +162760,Hood College,Frederick,MD +443076,Hood Theological Seminary,Salisbury,NC +170301,Hope College,Holland,MI +120537,Hope International University,Fullerton,CA +156860,Hopkinsville Community College,Hopkinsville,KY +457226,Horizon University,San Diego,CA +218140,Horry-Georgetown Technical College,Conway,SC +191676,Houghton College,Houghton,NY +129543,Housatonic Community College,Bridgeport,CT +225399,Houston Baptist University,Houston,TX +225423,Houston Community College,Houston,TX +246345,Houston Graduate School of Theology,Houston,TX +225520,Howard College,Big Spring,TX +162779,Howard Community College,Columbia,MD +225548,Howard Payne University,Brownwood,TX +131520,Howard University,Washington,DC +184995,Hudson County Community College,Jersey City,NJ +191719,Hudson Valley Community College,Troy,NY +242112,Huertas College,Caguas,PR +164368,Hult International Business School,Cambridge,MA +242121,Humacao Community College,Humacao,PR +115755,Humboldt State University,Arcata,CA +115773,Humphreys College-Stockton and Modesto Campuses,Stockton,CA +101435,Huntingdon College,Montgomery,AL +237437,Huntington Junior College,Huntington,WV +150941,Huntington University,Huntington,IN +449348,Huntsville Bible College,Huntsville,AL +212993,Hussian College School of Art,Philadelphia,PA +161165,Husson University,Bangor,ME +225575,Huston-Tillotson University,Austin,TX +155195,Hutchinson Community College,Hutchinson,KS +127839,IBMC College,Colorado Springs,CO +372329,IBMC College,Fort Collins,CO +193405,Icahn School of Medicine at Mount Sinai,New York,NY +437662,ICDC College,Huntington Park,CA +242130,ICPR Junior College-Arecibo,Arecibo,PR +243841,ICPR Junior College-General Institutional,Hato Rey,PR +460677,ICPR Junior College-Manati,Manatí,PR +242149,ICPR Junior College-Mayaguez,Mayaguez,PR +142276,Idaho State University,Pocatello,ID +483780,IGlobal University,Annandale,VA +127273,Iliff School of Theology,Denver,CO +434584,Ilisagvik College,Barrow,AK +145682,Illinois Central College,East Peoria,IL +145691,Illinois College,Jacksonville,IL +145628,Illinois College of Optometry,Chicago,IL +145725,Illinois Institute of Technology,Chicago,IL +145813,Illinois State University,Normal,IL +145831,Illinois Valley Community College,Oglesby,IL +145646,Illinois Wesleyan University,Bloomington,IL +213011,Immaculata University,Immaculata,PA +115861,Imperial Valley College,Imperial,CA +155201,Independence Community College,Independence,KS +465812,Independence University,Salt Lake City,UT +153472,Indian Hills Community College,Ottumwa,IA +134608,Indian River State College,Fort Pierce,FL +151290,Indiana Institute of Technology,Fort Wayne,IN +151324,Indiana State University,Terre Haute,IN +213020,Indiana University of Pennsylvania-Main Campus,Indiana,PA +151351,Indiana University-Bloomington,Bloomington,IN +151388,Indiana University-East,Richmond,IN +151333,Indiana University-Kokomo,Kokomo,IN +151360,Indiana University-Northwest,Gary,IN +151102,Indiana University-Purdue University-Fort Wayne,Fort Wayne,IN +151111,Indiana University-Purdue University-Indianapolis,Indianapolis,IN +151342,Indiana University-South Bend,South Bend,IN +151379,Indiana University-Southeast,New Albany,IN +151801,Indiana Wesleyan University,Marion,IN +145886,Institute for Clinical Social Work,Chicago,IL +462044,Institute for Doctoral Studies in the Visual Arts,Portland,ME +445869,Institute for the Psychological Sciences,Arlington,VA +187745,Institute of American Indian and Alaska Native Culture,Santa Fe,NM +444699,Institute of Clinical Acupuncture & Oriental Med,Honolulu,HI +191764,Institute of Design and Construction,Brooklyn,NY +454616,Institute of Production and Recording,Minneapolis,MN +454838,Institute of Taoist Education and Acupuncture,Louisville,CO +431141,Institute of Technology Inc-Clovis,Clovis,CA +455804,Institute of World Politics,Washington,DC +242422,Instituto de Banca y Comercio Inc,Guaynabo,PR +242556,Instituto Tecnologico de Puerto Rico-Recinto de Guayama,Guayama,PR +242042,Instituto Tecnologico de Puerto Rico-Recinto de Manati,Manati,PR +242565,Instituto Tecnologico de Puerto Rico-Recinto de Ponce,Ponce,PR +242583,Instituto Tecnologico de Puerto Rico-Recinto de San Juan,San Juan,PR +128179,Intellitec College-Colorado Springs,Colorado Springs,CO +128188,Intellitec College-Grand Junction,Grand Junction,CO +242626,Inter American University of Puerto Rico-Aguadilla,Aguadilla,PR +242635,Inter American University of Puerto Rico-Arecibo,Arecibo,PR +242644,Inter American University of Puerto Rico-Barranquitas,Barranquitas,PR +242705,Inter American University of Puerto Rico-Bayamon,Bayamon,PR +242680,Inter American University of Puerto Rico-Fajardo,Fajardo,PR +242699,Inter American University of Puerto Rico-Guayama,Guayama,PR +242653,Inter American University of Puerto Rico-Metro,San Juan,PR +242662,Inter American University of Puerto Rico-Ponce,Mercedita,PR +242617,Inter American University of Puerto Rico-San German,San German,PR +242723,Inter American University of Puerto Rico-School of Law,San Juan,PR +404222,Inter American University of Puerto Rico-School of Optometry,Bayamon,PR +138655,Interactive College of Technology-Chamblee,Chamblee,GA +442435,Interactive College of Technology-Gainesville,Gainesville,GA +367361,Interactive College of Technology-Houston,Houston,TX +443696,Interactive College of Technology-Houston,Houston,TX +138664,Interactive College of Technology-Morrow,Morrow,GA +367103,Interactive College of Technology-Newport,Newport,KY +440776,Interactive College of Technology-Pasadena,Pasadena,TX +366289,InterCoast Colleges-Orange,Orange,CA +140146,Interdenominational Theological Center,Atlanta,GA +235495,Interface College-Spokane,Spokane,WA +116226,Interior Designers Institute,Newport Beach,CA +446817,International Academy of Design and Technology-Nashville,Nashville,TN +450447,International Academy of Design and Technology-Sacramento,Sacramento,CA +445124,International Academy of Design and Technology-Troy,Troy,MI +436614,International Baptist College and Seminary,Chandler,AZ +225779,International Business College-El Paso-El Paso,El Paso,TX +225788,International Business College-El Paso-El Paso,El Paso,TX +151458,International Business College-Fort Wayne,Fort Wayne,IN +151467,International Business College-Indianapolis,Indianapolis,IN +203289,International College of Broadcasting,Dayton,OH +448691,International Institute for Restorative Practices,Bethlehem,PA +454740,International Professional School of Bodywork,San Diego,CA +443128,International Technological University,San Jose,CA +173799,Inver Hills Community College,Inver Grove Heights,MN +191931,Iona College,New Rochelle,NY +153524,Iowa Central Community College,Fort Dodge,IA +153533,Iowa Lakes Community College,Estherville,IA +153603,Iowa State University,Ames,IA +153621,Iowa Wesleyan University,Mount Pleasant,IA +153630,Iowa Western Community College,Council Bluffs,IA +441238,Irell & Manella Graduate School of Biological Sciences at City of Hope,Duarte,CA +116439,Irvine Valley College,Irvine,CA +191959,Island Drafting and Technical Institute,Amityville,NY +198710,Isothermal Community College,Spindale,NC +173805,Itasca Community College,Grand Rapids,MN +175829,Itawamba Community College,Fulton,MS +191968,Ithaca College,Ithaca,NY +159197,ITI Technical College,Baton Rouge,LA +459611,ITT Technical Institute-Akron,Akron,OH +434566,ITT Technical Institute-Albany,Albany,NY +369084,ITT Technical Institute-Albuquerque,Albuquerque,NM +225849,ITT Technical Institute-Arlington,Arlington,TX +260974,ITT Technical Institute-Arlington Heights,Arlington Heights,IL +434548,ITT Technical Institute-Arnold,Arnold,MO +450243,ITT Technical Institute-Atlanta,Atlanta,GA +459675,ITT Technical Institute-Aurora,Aurora,CO +366678,ITT Technical Institute-Austin,Austin,TX +450216,ITT Technical Institute-Baton Rouge,Baton Rouge,LA +414568,ITT Technical Institute-Bessemer,Bessemer,AL +142337,ITT Technical Institute-Boise,Boise,ID +470852,ITT Technical Institute-Bradenton,Bradenton,FL +470870,ITT Technical Institute-Brooklyn Center,Brooklyn Center,MN +442338,ITT Technical Institute-Canton,Canton,MI +451936,ITT Technical Institute-Cary,Cary,NC +441964,ITT Technical Institute-Chantilly,Chantilly,VA +456445,ITT Technical Institute-Charlotte North,Charlotte,NC +448442,ITT Technical Institute-Charlotte South,Charlotte,NC +450261,ITT Technical Institute-Chattanooga,Chattanooga,TN +451954,ITT Technical Institute-Clive,Clive,IA +448451,ITT Technical Institute-Clovis,Clovis,CA +450225,ITT Technical Institute-Columbia,Columbia,SC +451963,ITT Technical Institute-Columbus,Columbus,OH +456427,ITT Technical Institute-Concord,Concord,CA +413884,ITT Technical Institute-Cordova,Cordova,TN +459639,ITT Technical Institute-Corona,Corona,CA +459693,ITT Technical Institute-Culver City,Culver City,CA +203313,ITT Technical Institute-Dayton,Dayton,OH +459709,ITT Technical Institute-Dearborn,Dearborn,MI +479619,ITT Technical Institute-Deerfield Beach,Fort Lauderdale,FL +459657,ITT Technical Institute-DeSoto,DeSoto,TX +479637,ITT Technical Institute-Douglasville,Douglasville,GA +443526,ITT Technical Institute-Duluth,Duluth,GA +448460,ITT Technical Institute-Dunmore,Dunmore,PA +462363,ITT Technical Institute-Durham,Durham,NC +176637,ITT Technical Institute-Earth City,Earth City,MO +445081,ITT Technical Institute-Eden Prairie,Eden Prairie,MN +414531,ITT Technical Institute-Everett,Everett,WA +409069,ITT Technical Institute-Fort Lauderdale,Fort Lauderdale,FL +456436,ITT Technical Institute-Fort Myers,Fort Myers,FL +151500,ITT Technical Institute-Fort Wayne,Fort Wayne,IN +479567,ITT Technical Institute-Germantown,Greenfield,WI +420404,ITT Technical Institute-Getzville,Getzville,NY +440165,ITT Technical Institute-Green Bay,Green Bay,WI +238892,ITT Technical Institute-Greenfield,Greenfield,WI +413866,ITT Technical Institute-Greenville,Greenville,SC +462372,ITT Technical Institute-Hanover,Hanover,MD +430351,ITT Technical Institute-Harrisburg,Harrisburg,PA +429599,ITT Technical Institute-Henderson,Henderson,NV +430263,ITT Technical Institute-Hialeah,Hialeah,FL +451990,ITT Technical Institute-High Point,High Point,NC +443535,ITT Technical Institute-Hilliard,Hilliard,OH +366696,ITT Technical Institute-Houston North,Houston,TX +225858,ITT Technical Institute-Houston West,Houston,TX +456418,ITT Technical Institute-Huntington,Huntington,WV +151519,ITT Technical Institute-Indianapolis,Indianapolis,IN +479628,ITT Technical Institute-Indianapolis East,Indianapolis,IN +407063,ITT Technical Institute-Jacksonville,Jacksonville,FL +459648,ITT Technical Institute-Johnson City,Johnson City,TN +446899,ITT Technical Institute-Kansas City,Kansas City,MO +446905,ITT Technical Institute-Kennesaw,Kennesaw,GA +366650,ITT Technical Institute-Knoxville,Knoxville,TN +372578,ITT Technical Institute-Lake Mary,Lake Mary,FL +459718,ITT Technical Institute-Las Vegas,North Las Vegas,NV +437219,ITT Technical Institute-Lathrop,Lathrop,CA +440642,ITT Technical Institute-Levittown,Levittown,PA +448488,ITT Technical Institute-Lexington,Lexington,KY +413839,ITT Technical Institute-Little Rock,Little Rock,AR +434575,ITT Technical Institute-Liverpool,Liverpool,NY +413857,ITT Technical Institute-Louisville,Louisville,KY +451945,ITT Technical Institute-Madison-Madison,Madison,AL +451981,ITT Technical Institute-Madison-Madison,Madison,WI +456393,ITT Technical Institute-Madison-Madison,Madison,MS +479558,ITT Technical Institute-Marlton,Marlton,NJ +448497,ITT Technical Institute-Maumee,Maumee,OH +459587,ITT Technical Institute-Merrillville,Merrillville,IN +450252,ITT Technical Institute-Mobile,Mobile,AL +230384,ITT Technical Institute-Murray,Murray,UT +470904,ITT Technical Institute-Myrtle Beach,Myrtle Beach,SC +151494,ITT Technical Institute-Nashville,Nashville,TN +116466,ITT Technical Institute-National City,National City,CA +251251,ITT Technical Institute-Newburgh,Newburgh,IN +368601,ITT Technical Institute-Norfolk,Norfolk,VA +459666,ITT Technical Institute-North Charleston,North Charleston,SC +366580,ITT Technical Institute-Norwood-Norwood,Norwood,MA +430379,ITT Technical Institute-Norwood-Norwood,Norwood,OH +434557,ITT Technical Institute-Oak Brook,Oak Brook,IL +467058,ITT Technical Institute-Oakland,Oakland,CA +448503,ITT Technical Institute-Oklahoma City,Oklahoma City,OK +407319,ITT Technical Institute-Omaha,Omaha,NE +116484,ITT Technical Institute-Orange,Orange,CA +414586,ITT Technical Institute-Orland Park,Orland Park,IL +470889,ITT Technical Institute-Orlando,Lake Mary,FL +479646,ITT Technical Institute-Overland Park,Overland Park,KS +446914,ITT Technical Institute-Owings Mills,Owings Mills,MD +413848,ITT Technical Institute-Oxnard,Oxnard,CA +479549,ITT Technical Institute-Philadelphia,Philadelphia,PA +451972,ITT Technical Institute-Phoenix,Phoenix,AZ +470861,ITT Technical Institute-Phoenix West,Phoenix,AZ +414841,ITT Technical Institute-Pittsburgh,Pittsburgh,PA +442347,ITT Technical Institute-Plymouth Meeting,Plymouth Meeting,PA +208965,ITT Technical Institute-Portland,Portland,OR +108250,ITT Technical Institute-Rancho Cordova,Rancho Cordova,CA +434052,ITT Technical Institute-Richardson,Richardson,TX +437051,ITT Technical Institute-Richmond,Richmond,VA +437042,ITT Technical Institute-Saint Rose,Saint Rose,LA +459602,ITT Technical Institute-Salem-Salem,Salem,VA +479600,ITT Technical Institute-Salem-Salem,Salem,OR +377069,ITT Technical Institute-San Antonio,San Antonio,TX +481623,ITT Technical Institute-San Antonio East,San Antonio,TX +381909,ITT Technical Institute-San Bernardino,San Bernardino,CA +116475,ITT Technical Institute-San Dimas,San Dimas,CA +235510,ITT Technical Institute-Seattle,Seattle,WA +450270,ITT Technical Institute-South Bend,South Bend,IN +479585,ITT Technical Institute-Southfield,Troy,MI +235529,ITT Technical Institute-Spokane Valley,Spokane Valley,WA +441955,ITT Technical Institute-Springfield-Springfield,Springfield,VA +456409,ITT Technical Institute-Springfield-Springfield,Springfield,MO +479655,ITT Technical Institute-Springfield-Springfield,Springfield,IL +450207,ITT Technical Institute-St Petersburg,Tampa,FL +430388,ITT Technical Institute-Strongsville,Strongsville,OH +448479,ITT Technical Institute-Swartz Creek,Swartz Creek,MI +244011,ITT Technical Institute-Sylmar,Sylmar,CA +459596,ITT Technical Institute-Tallahassee,Tallahassee,FL +134909,ITT Technical Institute-Tampa,Tampa,FL +430360,ITT Technical Institute-Tarentum,Tarentum,PA +105172,ITT Technical Institute-Tempe,Tempe,AZ +378406,ITT Technical Institute-Torrance,Torrance,CA +261472,ITT Technical Institute-Troy,Troy,MI +105163,ITT Technical Institute-Tucson,Tucson,AZ +448512,ITT Technical Institute-Tulsa,Tulsa,OK +470898,ITT Technical Institute-Waco,Waco,TX +446923,ITT Technical Institute-Warrensville Heights,Warrensville Heights,OH +427663,ITT Technical Institute-Webster,Webster,TX +479664,ITT Technical Institute-West Chester,Norwood,OH +459684,ITT Technical Institute-West Covina,San Dimas,CA +479594,ITT Technical Institute-West Palm Beach,West Palm Beach,FL +244154,ITT Technical Institute-Westminster,Westminster,CO +450234,ITT Technical Institute-Wichita,Wichita,KS +439136,ITT Technical Institute-Wilmington,Wilmington,MA +170417,ITT Technical Institute-Wyoming,Wyoming,MI +206631,ITT Technical Institute-Youngstown,Youngstown,OH +150987,Ivy Tech Community College,Indianapolis,IN +101462,J F Drake State Community and Technical College,Huntsville,AL +101471,J F Ingram State Technical College,Deatsville,AL +232414,J Sargeant Reynolds Community College,Richmond,VA +170444,Jackson College,Jackson,MI +220400,Jackson State Community College,Jackson,TN +175856,Jackson State University,Jackson,MS +225876,Jacksonville College-Main Campus,Jacksonville,TX +101480,Jacksonville State University,Jacksonville,AL +134945,Jacksonville University,Jacksonville,FL +203678,James A Rhodes State College,Lima,OH +101161,James H Faulkner State Community College,Bay Minette,AL +232423,James Madison University,Harrisonburg,VA +198729,James Sprunt Community College,Kenansville,NC +192004,Jamestown Business College,Jamestown,NY +191986,Jamestown Community College,Jamestown,NY +225885,Jarvis Christian College,Hawkins,TX +177676,Jefferson College,Hillsboro,MO +231837,Jefferson College of Health Sciences,Roanoke,VA +156921,Jefferson Community and Technical College,Louisville,KY +192022,Jefferson Community College,Watertown,NY +101499,Jefferson Davis Community College,Brewton,AL +101505,Jefferson State Community College,Birmingham,AL +455196,Jersey College,Teterboro,NJ +192040,Jewish Theological Seminary of America,New York,NY +419341,Jna Institute of Culinary Arts,Philadelphia,PA +220464,John A Gupton College,Nashville,TN +146205,John A Logan College,Carterville,IL +107141,John Brown University,Siloam Springs,AR +101514,John C Calhoun State Community College,Tanner,AL +203368,John Carroll University,University Heights,OH +116712,John F. Kennedy University,Pleasant Hill,CA +462354,John Paul the Great Catholic University,Escondido,CA +232450,John Tyler Community College,Chester,VA +146278,John Wood Community College,Quincy,IL +162928,Johns Hopkins University,Baltimore,MD +445708,Johnson & Wales University-Charlotte,Charlotte,NC +439288,Johnson & Wales University-Denver,Denver,CO +414823,Johnson & Wales University-North Miami,North Miami,FL +460349,Johnson & Wales University-Online,Providence,RI +217235,Johnson & Wales University-Providence,Providence,RI +198756,Johnson C Smith University,Charlotte,NC +213233,Johnson College,Scranton,PA +155210,Johnson County Community College,Overland Park,KS +230913,Johnson State College,Johnson,VT +220473,Johnson University,Knoxville,TN +132879,Johnson University Florida,Kissimmee,FL +198774,Johnston Community College,Smithfield,NC +146296,Joliet Junior College,Joliet,IL +135063,Jones College-Jacksonville,Jacksonville,FL +175883,Jones County Junior College,Ellisville,MS +444723,Jones International University,Centennial,CO +461281,Jose Maria Vargas University,Pembroke Pines,FL +101541,Judson College,Marion,AL +146339,Judson University,Elgin,IL +461139,Jung Tao School of Classical Chinese Medicine,Sugar Grove,NC +213251,Juniata College,Huntingdon,PA +170532,Kalamazoo College,Kalamazoo,MI +170541,Kalamazoo Valley Community College,Kalamazoo,MI +146348,Kankakee Community College,Kankakee,IL +177746,Kansas City Art Institute,Kansas City,MO +155308,Kansas City College & Bible School,Overland Park,KS +155292,Kansas City Kansas Community College,Kansas City,KS +179812,Kansas City University of Medicine and Biosciences,Kansas City,MO +155399,Kansas State University,Manhattan,KS +155414,Kansas Wesleyan University,Salina,KS +141796,Kapiolani Community College,Honolulu,HI +458715,Kaplan College-Jacksonville,Jacksonville,FL +445346,Kaplan College-Lubbock,Lubbock,TX +480064,Kaplan University-Augusta Campus,Augusta,ME +260910,Kaplan University-Cedar Falls Campus,Cedar Falls,IA +153418,Kaplan University-Cedar Rapids Campus,Cedar Rapids,IA +260901,Kaplan University-Davenport Campus,Davenport,IA +367024,Kaplan University-Des Moines Campus,Urbandale,IA +162681,Kaplan University-Hagerstown Campus,Hagerstown,MD +181242,Kaplan University-Lincoln Campus,Lincoln,NE +160940,Kaplan University-Maine Campus,S Portland,ME +153409,Kaplan University-Mason City Campus,Mason City,IA +181400,Kaplan University-Omaha Campus,Omaha,NE +146366,Kaskaskia College,Centralia,IL +141802,Kauai Community College,Lihue,HI +225991,KD College Conservatory of Film and Dramatic Arts,Dallas,TX +185262,Kean University,Union,NJ +440031,Keck Graduate Institute,Claremont,CA +183062,Keene State College,Keene,NH +192165,Kehilath Yakov Rabbinical Seminary,Ossining,NY +135081,Keiser University-Ft Lauderdale,Fort Lauderdale,FL +170550,Kellogg Community College,Battle Creek,MI +146393,Kendall College,Chicago,IL +161192,Kennebec Valley Community College,Fairfield,ME +140164,Kennesaw State University,Kennesaw,GA +177816,Kenrick Glennon Seminary,Saint Louis,MO +203447,Kent State University at Ashtabula,Ashtabula,OH +203456,Kent State University at East Liverpool,East Liverpool,OH +203526,Kent State University at Geauga,Burton,OH +203517,Kent State University at Kent,Kent,OH +203492,Kent State University at Salem,Salem,OH +203465,Kent State University at Stark,Canton,OH +203474,Kent State University at Trumbull,Warren,OH +203483,Kent State University at Tuscarawas,New Philadelphia,OH +157100,Kentucky Christian University,Grayson,KY +157030,Kentucky Mountain Bible College,Vancleve,KY +157058,Kentucky State University,Frankfort,KY +157076,Kentucky Wesleyan College,Owensboro,KY +203535,Kenyon College,Gambier,OH +203544,Kettering College,Kettering,OH +169983,Kettering University,Flint,MI +192192,Keuka College,Keuka Park,NY +461315,Keweenaw Bay Ojibwa Community College,Baraga,MI +134422,Key College,Dania Beach,FL +213303,Keystone College,La Plume,PA +210483,Keystone Technical Institute,Harrisburg,PA +226019,Kilgore College,Kilgore,TX +219055,Kilian Community College,Sioux Falls,SD +220516,King University,Bristol,TN +382504,King's College-Charlotte,Charlotte,NC +213321,King's College-Wilkes-Barre,Wilkes-Barre,PA +153737,Kirkwood Community College,Cedar Rapids,IA +170587,Kirtland Community College,Roscommon,MI +146418,Kishwaukee College,Malta,IL +428392,Klamath Community College,Klamath Falls,OR +260956,Knowledge Systems Institute,Skokie,IL +146427,Knox College,Galesburg,IL +484288,Knox Theological Seminary,Fort Lauderdale,FL +213349,Kutztown University of Pennsylvania,Kutztown,PA +171881,Kuyper College,Grand Rapids,MI +213358,La Roche College,Pittsburgh,PA +213367,La Salle University,Philadelphia,PA +117627,La Sierra University,Riverside,CA +155450,Labette Community College,Parsons,KS +165264,Laboure College,Milton,MA +260372,Lac Courte Oreilles Ojibwa Community College,Hayward,WI +213376,Lackawanna College,Scranton,PA +213385,Lafayette College,Easton,PA +140234,LaGrange College,Lagrange,GA +117168,Laguna College of Art and Design,Laguna Beach,CA +219143,Lake Area Technical Institute,Watertown,SD +203580,Lake Erie College,Painesville,OH +407629,Lake Erie College of Osteopathic Medicine,Erie,PA +146481,Lake Forest College,Lake Forest,IL +146490,Lake Forest Graduate School of Management,Lake Forest,IL +146506,Lake Land College,Mattoon,IL +170620,Lake Michigan College,Benton Harbor,MI +200192,Lake Region State College,Devils Lake,ND +173461,Lake Superior College,Duluth,MN +170639,Lake Superior State University,Sault Ste Marie,MI +117195,Lake Tahoe Community College,South Lake Tahoe,CA +235699,Lake Washington Institute of Technology,Kirkland,WA +238980,Lakeland College,Plymouth,WI +203599,Lakeland Community College,Kirtland,OH +183123,Lakes Region Community College,Laconia,NH +239008,Lakeshore Technical College,Cleveland,WI +135188,Lake-Sumter State College,Leesburg,FL +146533,Lakeview College of Nursing,Danville,IL +127389,Lamar Community College,Lamar,CO +441760,Lamar Institute of Technology,Beaumont,TX +226107,Lamar State College-Orange,Orange,TX +226116,Lamar State College-Port Arthur,Port Arthur,TX +226091,Lamar University,Beaumont,TX +213400,Lancaster Bible College,Lancaster,PA +418533,Lancaster County Career and Technology Center,Willow Street,PA +213446,Lancaster Theological Seminary,Lancaster,PA +218229,Lander University,Greenwood,SC +247649,Landmark College,Putney,VT +220598,Lane College,Jackson,TN +209038,Lane Community College,Eugene,OR +117247,Laney College,Oakland,CA +207209,Langston University,Langston,OK +140243,Lanier Technical College,Oakwood,GA +213473,Lansdale School of Business,North Wales,PA +170657,Lansing Community College,Lansing,MI +240620,Laramie County Community College,Cheyenne,WY +226134,Laredo Community College,Laredo,TX +366401,Las Positas College,Livermore,CA +166391,Lasell College,Newton,MA +117274,Lassen Community College,Susanville,CA +230418,Latter-day Saints Business College,Salt Lake City,UT +250027,Laurel Business Institute,Uniontown,PA +408729,Laurel Technical Institute-MEADVILLE,MEADVILLE,PA +215992,Laurel Technical Institute-Sharon,Sharon,PA +198747,Laurel University,High Point,NC +166407,Lawrence Memorial Hospital School of Nursing,Medford,MA +170675,Lawrence Technological University,Southfield,MI +239017,Lawrence University,Appleton,WI +101569,Lawson State Community College-Birmingham Campus,Birmingham,AL +443623,Le Cordon Bleu College of Culinary Arts-Atlanta,Tucker,GA +364973,Le Cordon Bleu College of Culinary Arts-Austin,Austin,TX +452054,Le Cordon Bleu College of Culinary Arts-Cambridge,Cambridge,MA +144467,Le Cordon Bleu College of Culinary Arts-Chicago,Chicago,IL +452063,Le Cordon Bleu College of Culinary Arts-Dallas,Dallas,TX +445115,Le Cordon Bleu College of Culinary Arts-Las Vegas,Las Vegas,NV +446835,Le Cordon Bleu College of Culinary Arts-Miami,Miramar,FL +446844,Le Cordon Bleu College of Culinary Arts-Minneapolis,Mendota Heights,MN +442231,Le Cordon Bleu College of Culinary Arts-Orlando,Orlando,FL +423980,Le Cordon Bleu College of Culinary Arts-Pasadena,Pasadena,CA +375841,Le Cordon Bleu College of Culinary Arts-Portland,Portland,OR +111009,Le Cordon Bleu College of Culinary Arts-San Francisco,San Francisco,CA +262332,Le Cordon Bleu College of Culinary Arts-Scottsdale,Scottsdale,AZ +192323,Le Moyne College,Syracuse,NY +220604,Le Moyne-Owen College,Memphis,TN +213507,Lebanon Valley College,Annville,PA +456940,L'Ecole Culinaire-Memphis,Cordova,TN +445726,L'Ecole Culinaire-St Louis,St. Louis,MO +226204,Lee College,Baytown,TX +220613,Lee University,Cleveland,TN +413626,Leech Lake Tribal College,Cass Lake,MN +198808,Lees-McRae College,Banner Elk,NC +141811,Leeward Community College,Pearl City,HI +213525,Lehigh Carbon Community College,Schnecksville,PA +213543,Lehigh University,Bethlehem,PA +198817,Lenoir Community College,Kinston,NC +198835,Lenoir-Rhyne University,Hickory,NC +218265,Lenoir-Rhyne University-Lutheran Theological Southern Seminary,Columbia,SC +166452,Lesley University,Cambridge,MA +226231,LeTourneau University,Longview,TX +209056,Lewis & Clark College,Portland,OR +146603,Lewis and Clark Community College,Godfrey,IL +146612,Lewis University,Romeoville,IL +142328,Lewis-Clark State College,Lewiston,ID +157207,Lexington Theological Seminary,Lexington,KY +232557,Liberty University,Lynchburg,VA +117520,Life Chiropractic College West,Hayward,CA +117104,Life Pacific College,San Dimas,CA +140252,Life University,Marietta,GA +192271,LIM College,New York,NY +218238,Limestone College,Gaffney,SC +146667,Lincoln Christian University,Lincoln,IL +146676,Lincoln College,Lincoln,IL +128683,Lincoln College of New England-Southington,Southington,CT +163028,Lincoln College of Technology-Columbia,Columbia,MD +126951,Lincoln College of Technology-Denver,Denver,CO +151661,Lincoln College of Technology-Indianapolis,Indianapolis,IN +434159,Lincoln College of Technology-Marietta,Marietta,GA +146700,Lincoln College of Technology-Melrose Park,Melrose Park,IL +221148,Lincoln College of Technology-Nashville,Nashville,TN +136066,Lincoln College of Technology-West Palm Beach,West Palm Beach,FL +146685,Lincoln Land Community College,Springfield,IL +220631,Lincoln Memorial University,Harrogate,TN +213570,Lincoln Technical Institute-Allentown,Allentown,PA +442037,Lincoln Technical Institute-Northeast Philadelphia,Philadelphia,PA +213589,Lincoln Technical Institute-Philadelphia,Philadelphia,PA +403478,Lincoln Trail College,Robinson,IL +177940,Lincoln University-Jefferson City,Jefferson City,MO +117557,Lincoln University-Oakland,Oakland,CA +177968,Lindenwood University,Saint Charles,MO +157216,Lindsey Wilson College,Columbia,KY +437325,Linfield College-Adult Degree Program,McMinnville,OR +209065,Linfield College-McMinnville Campus,McMinnville,OR +437316,Linfield College-School of Nursing,Portland,OR +209074,Linn-Benton Community College,Albany,OR +219976,Lipscomb University,Nashville,TN +180328,Little Big Horn College,Crow Agency,MT +434016,Little Priest Tribal College,Winnebago,NE +192563,LIU Brentwood,Brentwood,NY +192439,LIU Brooklyn,Brooklyn,NY +192554,LIU Hudson at Rockland,Orangeburg,NY +432357,LIU Hudson at Westchester,Purchase,NY +192448,LIU Post,Brookville,NY +450766,LIU Riverhead,Riverhead,NY +421832,Living Arts College,Raleigh,NC +198862,Livingstone College,Salisbury,NC +213613,Lock Haven University,Lock Haven,PA +177986,Logan University,Chesterfield,MO +117636,Loma Linda University,Loma Linda,CA +227182,Lone Star College System,The Woodlands,TX +117645,Long Beach City College,Long Beach,CA +192509,Long Island Business Institute,Flushing,NY +232566,Longwood University,Farmville,VA +166489,Longy School of Music of Bard College,Cambridge,MA +203748,Lorain County Community College,Elyria,OH +153825,Loras College,Dubuque,IA +232575,Lord Fairfax Community College,Middletown,VA +117788,Los Angeles City College,Los Angeles,CA +446385,Los Angeles College of Music,Pasadena,CA +117803,Los Angeles County College of Nursing and Allied Health,Los Angeles,CA +436429,Los Angeles Film School,Hollywood,CA +117690,Los Angeles Harbor College,Wilmington,CA +117867,Los Angeles Mission College,Sylmar,CA +368780,Los Angeles ORT College-Los Angeles Campus,Los Angeles,CA +381945,Los Angeles ORT College-Van Nuys Campus,Van Nuys,CA +117706,Los Angeles Pierce College,Woodland Hills,CA +117715,Los Angeles Southwest College,Los Angeles,CA +117724,Los Angeles Trade Technical College,Los Angeles,CA +117733,Los Angeles Valley College,Valley Glen,CA +117894,Los Medanos College,Pittsburg,CA +198871,Louisburg College,Louisburg,NC +159568,Louisiana College,Pineville,LA +449612,Louisiana Culinary Institute,Baton Rouge,LA +483212,Louisiana Delta Community College,Monroe,LA +159391,Louisiana State University and Agricultural & Mechanical College,Baton Rouge,LA +159373,Louisiana State University Health Sciences Center-New Orleans,New Orleans,LA +435000,Louisiana State University Health Sciences Center-Shreveport,Shreveport,LA +159382,Louisiana State University-Alexandria,Alexandria,LA +159407,Louisiana State University-Eunice,Eunice,LA +159416,Louisiana State University-Shreveport,Shreveport,LA +159647,Louisiana Tech University,Ruston,LA +157298,Louisville Presbyterian Theological Seminary,Louisville,KY +203757,Lourdes University,Sylvania,OH +235750,Lower Columbia College,Longview,WA +117946,Loyola Marymount University,Los Angeles,CA +146719,Loyola University Chicago,Chicago,IL +163046,Loyola University Maryland,Baltimore,MD +159656,Loyola University New Orleans,New Orleans,LA +226383,Lubbock Christian University,Lubbock,TX +363633,Luna Community College,Las Vegas,NM +101602,Lurleen B Wallace Community College,Andalusia,AL +153834,Luther College,Decorah,IA +135364,Luther Rice University & Seminary,Lithonia,GA +173896,Luther Seminary,Saint Paul,MN +146728,Lutheran School of Theology at Chicago,Chicago,IL +213631,Lutheran Theological Seminary at Gettysburg,Gettysburg,PA +213640,Lutheran Theological Seminary at Philadelphia,Philadelphia,PA +213659,Luzerne County Community College,Nanticoke,PA +213668,Lycoming College,Williamsport,PA +232609,Lynchburg College,Lynchburg,VA +230931,Lyndon State College,Lyndonville,VT +132657,Lynn University,Boca Raton,FL +106342,Lyon College,Batesville,AR +173902,Macalester College,Saint Paul,MN +146816,MacCormac College,Chicago,IL +192624,Machzikei Hadath Rabbinical College,Brooklyn,NY +146825,MacMurray College,Jacksonville,IL +170790,Macomb Community College,Warren,MI +238263,Madison Area Technical College,Madison,WI +364168,Madison Media Institute,Madison,WI +148399,Madison Media Institute-Rockford Career College,Rockford,IL +157304,Madisonville Community College,Madisonville,KY +170806,Madonna University,Livonia,MI +153861,Maharishi University of Management,Fairfield,IA +161509,Maine College of Art,Portland,ME +161022,Maine College of Health Professions,Lewiston,ME +161299,Maine Maritime Academy,Castine,ME +203775,Malone University,Canton,OH +451103,Management Resources College,Miami,FL +129695,Manchester Community College-Manchester,Manchester,CT +183132,Manchester Community College-Manchester,Manchester,NH +151777,Manchester University,North Manchester,IN +192688,Mandl School-The College of Allied Health,New York,NY +155487,Manhattan Area Technical College,Manhattan,KS +155496,Manhattan Christian College,Manhattan,KS +192703,Manhattan College,Riverdale,NY +192712,Manhattan School of Music,New York,NY +192749,Manhattanville College,Purchase,NY +213774,Manor College,Jenkintown,PA +213783,Mansfield University of Pennsylvania,Mansfield,PA +446394,Maple Springs Baptist Bible College and Seminary,Capitol Heights,MD +239071,Maranatha Baptist University,Watertown,WI +192785,Maria College of Albany,Albany,NY +166601,Marian Court College,Swampscott,MA +239080,Marian University-Fond Du Lac,Fond Du Lac,WI +151786,Marian University-Indianapolis,Indianapolis,IN +203845,Marietta College,Marietta,OH +101648,Marion Military Institute,Marion,AL +203881,Marion Technical College,Marion,OH +192819,Marist College,Poughkeepsie,NY +230940,Marlboro College,Marlboro,VT +440411,Marlboro College Graduate & Professional Studies,Brattleboro,VT +239105,Marquette University,Milwaukee,WI +198899,Mars Hill University,Mars Hill,NC +123943,Marshall B Ketchum University,Fullerton,CA +237525,Marshall University,Huntington,WV +153922,Marshalltown Community College,Marshalltown,IA +198905,Martin Community College,Williamston,NC +173452,Martin Luther College,New Ulm,MN +220701,Martin Methodist College,Pulaski,TN +151810,Martin University,Indianapolis,IN +232672,Mary Baldwin College,Staunton,VA +170842,Marygrove College,Detroit,MI +163295,Maryland Institute College of Art,Baltimore,MD +164085,Maryland University of Integrative Health,Laurel,MD +209108,Marylhurst University,Marylhurst,OR +118541,Marymount California University,Rancho Palos Verdes,CA +192864,Marymount Manhattan College,New York,NY +232706,Marymount University,Arlington,VA +220710,Maryville College,Maryville,TN +178059,Maryville University of Saint Louis,Saint Louis,MO +213826,Marywood University,Scranton,PA +166647,Massachusetts Bay Community College,Wellesley Hills,MA +166674,Massachusetts College of Art and Design,Boston,MA +167288,Massachusetts College of Liberal Arts,North Adams,MA +166683,Massachusetts Institute of Technology,Cambridge,MA +166692,Massachusetts Maritime Academy,Buzzards Bay,MA +369002,Massachusetts School of Law,Andover,MA +166823,Massasoit Community College,Brockton,MA +436702,Mattia College,Miami,FL +454698,Mayfield College,Cathedral City,CA +198914,Mayland Community College,Spruce Pine,NC +365426,Mayo Graduate School,Rochester,MN +173957,Mayo Medical School,Rochester,MN +173966,Mayo School of Health Sciences,Rochester,MN +157331,Maysville Community and Technical College,Maysville,KY +200226,Mayville State University,Mayville,ND +438212,McCann School of Business & Technology,Pottsville,PA +146977,McCormick Theological Seminary,Chicago,IL +164270,McDaniel College,Westminster,MD +198923,McDowell Technical Community College,Marion,NC +147004,McHenry County College,Crystal Lake,IL +147013,McKendree University,Lebanon,IL +226578,McLennan Community College,Waco,TX +226587,McMurry University,Abilene,TX +367194,McNally Smith College of Music,Saint Paul,MN +159717,McNeese State University,Lake Charles,LA +155511,McPherson College,McPherson,KS +166656,MCPHS University,Boston,MA +147031,Meadville Lombard Theological School,Chicago,IL +414461,Mech-Tech College,Caguas,PR +192925,Medaille College,Buffalo,NY +239169,Medical College of Wisconsin,Milwaukee,WI +218335,Medical University of South Carolina,Charleston,SC +448415,MedTech College,Indianapolis,IN +456366,MedTech College-Ft Wayne Campus,Ft. Wayne,IN +456357,MedTech College-Greenwood Campus,Greenwood,IN +456375,MedTech College-Lexington Campus,Lexington,KY +131742,Medtech Institute,Falls Church,VA +444714,MedTech Institute-Atlanta Campus,Atlanta,GA +220792,Meharry Medical College,Nashville,TN +192961,Memorial School of Nursing,Albany,NY +220808,Memphis College of Art,Memphis,TN +220871,Memphis Theological Seminary,Memphis,TN +118684,Mendocino College,Ukiah,CA +118693,Menlo College,Atherton,CA +118718,Merced College,Merced,CA +185509,Mercer County Community College,West Windsor,NJ +140447,Mercer University,Macon,GA +193016,Mercy College,Dobbs Ferry,NY +153977,Mercy College of Health Sciences,Des Moines,IA +203960,Mercy College of Ohio,Toledo,OH +213987,Mercyhurst University,Erie,PA +480189,Mercyhurst University-North East Campus,North East,PA +198950,Meredith College,Raleigh,NC +244279,Meridian College,Sarasota,FL +175935,Meridian Community College,Meridian,MS +166850,Merrimack College,North Andover,MA +118772,Merritt College,Oakland,CA +105154,Mesa Community College,Mesa,AZ +173993,Mesabi Range College,Virginia,MN +188261,Mesalands Community College,Tucumcari,NM +461847,Mesivta Keser Torah,Belmar,NJ +193061,Mesivta of Eastern Parkway-Yeshiva Zichron Meilech,Brooklyn,NY +193052,Mesivta Torah Vodaath Rabbinical Seminary,Brooklyn,NY +193070,Mesivtha Tifereth Jerusalem of America,New York,NY +417752,Messenger College,Euless,TX +213996,Messiah College,Mechanicsburg,PA +147129,Methodist College,Peoria,IL +203997,Methodist Theological School in Ohio,Delaware,OH +198969,Methodist University,Fayetteville,NC +455673,Metro Business College-Arnold,Arnold,MO +178110,Metro Business College-Cape Girardeau,Cape Girardeau,MO +245430,Metro Business College-Jefferson City,Jefferson City,MO +245421,Metro Business College-Rolla,Rolla,MO +214023,Metropolitan Career Center Computer Technology Institute,Philadelphia,PA +190114,Metropolitan College of New York,New York,NY +181303,Metropolitan Community College Area,Omaha,NE +177995,Metropolitan Community College-Kansas City-Kansas City,Kansas City,MO +174020,Metropolitan State University,Saint Paul,MN +127565,Metropolitan State University of Denver,Denver,CO +166869,MGH Institute of Health Professions,Boston,MA +135717,Miami Dade College,Miami,FL +204006,Miami University-Hamilton,Hamilton,OH +204015,Miami University-Middletown,Middletown,OH +204024,Miami University-Oxford,Oxford,OH +369862,Miami-Jacobs Career College-Columbus,Columbus,OH +204060,Miami-Jacobs Career College-Dayton,Dayton,OH +200633,Miami-Jacobs Career College-Independence,Independence,OH +441201,Miami-Jacobs Career College-Sharonville,Sharonville,OH +449126,Miami-Jacobs Career College-Springboro,Springboro,OH +450003,Miami-Jacobs Career College-Troy,Troy,OH +169655,MIAT College of Technology,Canton,MI +434414,Michigan Jewish Institute,W Bloomfield,MI +169220,Michigan School of Professional Psychology,Farmington Hills,MI +171100,Michigan State University,East Lansing,MI +169628,Michigan State University-College of Law,East Lansing,MI +171128,Michigan Technological University,Houghton,MI +171155,Mid Michigan Community College,Harrison,MI +245953,Mid-America Christian University,Oklahoma City,OK +151962,Mid-America College of Funeral Service,Jeffersonville,IN +155520,MidAmerica Nazarene University,Olathe,KS +199458,Mid-Atlantic Christian University,Elizabeth City,NC +482158,Middle Georgia State College,Macon,GA +220996,Middle Tennessee School of Anesthesia Inc,Madison,TN +220978,Middle Tennessee State University,Murfreesboro,TN +230959,Middlebury College,Middlebury,VT +166887,Middlesex Community College-Bedford,Bedford,MA +129756,Middlesex Community College-Middletown,Middletown,CT +185536,Middlesex County College,Edison,NJ +226806,Midland College,Midland,TX +181330,Midland University,Fremont,NE +218353,Midlands Technical College,West Columbia,SC +181312,Mid-Plains Community College,North Platte,NE +481225,Mid-South Christian College,Memphis,TN +147165,Midstate College,Peoria,IL +239220,Mid-State Technical College,Wisconsin Rapids,WI +157377,Midway College,Midway,KY +439020,Midwest College of Oriental Medicine-Chicago,Chicago,IL +383020,Midwest College of Oriental Medicine-Racine,Racine,WI +178183,Midwest Institute,Fenton,MO +178208,Midwestern Baptist Theological Seminary,Kansas City,MO +226833,Midwestern State University,Wichita Falls,TX +143853,Midwestern University-Downers Grove,Downers Grove,IL +423643,Midwestern University-Glendale,Glendale,AZ +480985,Midwives College of Utah,Salt Lake City,UT +193201,Mildred Elley School-Albany Campus,Albany,NY +461014,Mildred Elley-New York Campus,New York,NY +101675,Miles College,Fairfield,AL +180373,Miles Community College,Miles City,MT +461883,Millennia Atlantic University,Doral,FL +449117,Miller-Motte College-Cary,Cary,NC +458405,Miller-Motte College-Fayetteville,Fayetteville,NC +455655,Miller-Motte College-Greenville,Greenville,NC +460817,Miller-Motte College-Jacksonville,Jacksonville,NC +456205,Miller-Motte College-Raleigh,Raleigh,NC +198978,Miller-Motte College-Wilmington,Wilmington,NC +460826,Miller-Motte Technical College-Augusta,Augusta,GA +441025,Miller-Motte Technical College-Charleston,Charleston,SC +443650,Miller-Motte Technical College-Chattanooga,Chattanooga,TN +382771,Miller-Motte Technical College-Clarksville,Clarksville,TN +458441,Miller-Motte Technical College-Columbus,Columbus,GA +460835,Miller-Motte Technical College-Conway,Conway,SC +475079,Miller-Motte Technical College-Gulfport,Gulfport,MS +233091,Miller-Motte Technical College-Lynchburg,Lynchburg,VA +475060,Miller-Motte Technical College-Macon,Macon,GA +448664,Miller-Motte Technical College-Madison,Madison,TN +475194,Miller-Motte Technical College-Roanoke,Roanoke,VA +214041,Millersville University of Pennsylvania,Millersville,PA +221014,Milligan College,Milligan College,TN +147244,Millikin University,Decatur,IL +118888,Mills College,Oakland,CA +175980,Millsaps College,Jackson,MS +239248,Milwaukee Area Technical College,Milwaukee,WI +239309,Milwaukee Institute of Art & Design,Milwaukee,WI +239318,Milwaukee School of Engineering,Milwaukee,WI +178217,Mineral Area College,Park Hills,MO +174118,Minneapolis Business College,Roseville,MN +174127,Minneapolis College of Art and Design,Minneapolis,MN +174136,Minneapolis Community and Technical College,Minneapolis,MN +474881,Minneapolis Media Institute,Edina,MN +451769,Minnesota School of Business-Blaine,Blaine,MN +407285,Minnesota School of Business-Brooklyn Center,Brooklyn Center,MN +456782,Minnesota School of Business-Elk River,Elk River,MN +458742,Minnesota School of Business-Lakeville,Lakeville,MN +455585,Minnesota School of Business-Moorhead,Moorhead,MN +442578,Minnesota School of Business-Plymouth,Plymouth,MN +174279,Minnesota School of Business-Richfield,Richfield,MN +447670,Minnesota School of Business-Rochester,Rochester,MN +445920,Minnesota School of Business-Waite Park,Waite Park,MN +175263,Minnesota State College-Southeast Technical,Winona,MN +173559,Minnesota State Community and Technical College,Fergus Falls,MN +174358,Minnesota State University Moorhead,Moorhead,MN +173920,Minnesota State University-Mankato,Mankato,MN +173638,Minnesota West Community and Technical College,Granite Falls,MN +200253,Minot State University,Minot,ND +118912,MiraCosta College,Oceanside,CA +193247,Mirrer Yeshiva Cent Institute,Brooklyn,NY +214069,Misericordia University,Dallas,PA +118930,Mission College,Santa Clara,CA +176053,Mississippi College,Clinton,MS +176008,Mississippi Delta Community College,Moorhead,MS +176071,Mississippi Gulf Coast Community College,Perkinston,MS +176080,Mississippi State University,Mississippi State,MS +176035,Mississippi University for Women,Columbus,MS +176044,Mississippi Valley State University,Itta Bena,MS +178244,Missouri Baptist University,Saint Louis,MO +178305,Missouri College,Brentwood,MO +178341,Missouri Southern State University,Joplin,MO +179566,Missouri State University-Springfield,Springfield,MO +179344,Missouri State University-West Plains,West Plains,MO +178350,Missouri Tech,Saint Charles,MO +178411,Missouri University of Science and Technology,Rolla,MO +178369,Missouri Valley College,Marshall,MO +178387,Missouri Western State University,Saint Joseph,MO +129774,Mitchell College,New London,CT +198987,Mitchell Community College,Statesville,NC +219189,Mitchell Technical Institute,Mitchell,SD +178448,Moberly Area Community College,Moberly,MO +118976,Modesto Junior College,Modesto,CA +105206,Mohave Community College,Kingman,AZ +193283,Mohawk Valley Community College,Utica,NY +193292,Molloy College,Rockville Centre,NY +147341,Monmouth College,Monmouth,IL +185572,Monmouth University,West Long Branch,NJ +193308,Monroe College,Bronx,NY +193326,Monroe Community College,Rochester,NY +171225,Monroe County Community College,Monroe,MI +262165,Montana Bible College,Bozeman,MT +180461,Montana State University,Bozeman,MT +180179,Montana State University-Billings,Billings,MT +180522,Montana State University-Northern,Havre,MT +180416,Montana Tech of the University of Montana,Butte,MT +171234,Montcalm Community College,Sidney,MI +185590,Montclair State University,Montclair,NJ +119058,Monterey Institute of International Studies,Monterey,CA +119067,Monterey Peninsula College,Monterey,CA +163426,Montgomery College,Rockville,MD +199023,Montgomery Community College,Troy,NC +214111,Montgomery County Community College,Blue Bell,PA +199032,Montreat College,Montreat,NC +166911,Montserrat College of Art,Beverly,MA +147369,Moody Bible Institute,Chicago,IL +214148,Moore College of Art and Design,Philadelphia,PA +119137,Moorpark College,Moorpark,CA +239372,Moraine Park Technical College,Fond du Lac,WI +147378,Moraine Valley Community College,Palos Hills,IL +214157,Moravian College,Bethlehem,PA +157386,Morehead State University,Morehead,KY +140553,Morehouse College,Atlanta,GA +140562,Morehouse School of Medicine,Atlanta,GA +460394,Moreno Valley College,Moreno Valley,CA +127617,Morgan Community College,Fort Morgan,CO +163453,Morgan State University,Baltimore,MD +154004,Morningside College,Sioux City,IA +218399,Morris College,Sumter,SC +147396,Morrison Institute of Technology,Morrison,IL +196051,Morrisville State College,Morrisville,NY +147411,Morton College,Cicero,IL +221096,Motlow State Community College,Tullahoma,TN +169275,Mott Community College,Flint,MI +140599,Moultrie Technical College,Moultrie,GA +214166,Mount Aloysius College,Cresson,PA +209241,Mount Angel Seminary,Saint Benedict,OR +204176,Mount Carmel College of Nursing,Columbus,OH +166939,Mount Holyoke College,South Hadley,MA +166948,Mount Ida College,Newton,MA +219198,Mount Marty College,Yankton,SD +239390,Mount Mary University,Milwaukee,WI +154013,Mount Mercy University,Cedar Rapids,IA +204200,Mount Saint Joseph University,Cincinnati,OH +193353,Mount Saint Mary College,Newburgh,NY +119173,Mount Saint Mary's University,Los Angeles,CA +163462,Mount St Mary's University,Emmitsburg,MD +204194,Mount Vernon Nazarene University,Mount Vernon,OH +166957,Mount Wachusett Community College,Gardner,MA +182865,Mount Washington College,Manchester,NH +232788,Mountain Empire Community College,Big Stone Gap,VA +237598,Mountain State College,Parkersburg,WV +226930,Mountain View College,Dallas,TX +444954,Mountwest Community and Technical College,Huntington,WV +209250,Mt Hood Community College,Gresham,OR +119164,Mt San Antonio College,Walnut,CA +119216,Mt San Jacinto Community College District,San Jacinto,CA +398130,Mt Sierra College,Monrovia,CA +118198,MTI College,Sacramento,CA +214175,Muhlenberg College,Allentown,PA +209287,Multnomah University,Portland,OR +207236,Murray State College,Tishomingo,OK +157401,Murray State University,Murray,KY +119270,Musicians Institute,Hollywood,CA +171304,Muskegon Community College,Muskegon,MI +204264,Muskingum University,New Concord,OH +434432,Myotherapy Institute,Lincoln,NE +119331,Napa Valley College,Napa,CA +127653,Naropa University,Boulder,CO +199087,Nash Community College,Rocky Mount,NC +239424,Nashotah House,Nashotah,WI +183141,Nashua Community College,Nashua,NH +221184,Nashville State Community College,Nashville,TN +193478,Nassau Community College,Garden City,NY +248882,National American University-Albuquerque,Albuquerque,NM +440758,National American University-Albuquerque West,Albuquerque,NM +451875,National American University-Austin,Austin,TX +482307,National American University-Austin South,Austin,TX +477996,National American University-Bellevue,Bellevue,NE +436483,National American University-Bloomington,Bloomington,MN +440767,National American University-Brooklyn Center,Brooklyn Center,MN +478005,National American University-Burnsville,Burnsville,MN +466161,National American University-Centennial,Centennial,CO +127680,National American University-Colorado Springs,Colorado Springs,CO +466189,National American University-Colorado Springs South,Colorado Springs,CO +127699,National American University-Denver,Denver,CO +440749,National American University-Ellsworth AFB Extension,Ellsworth Air Force Base,SD +482325,National American University-Georgetown,Georgetown,TX +485290,National American University-Harold D. Buckingham Graduate School,Austin,TX +247700,National American University-Independence,Independence,MO +482370,National American University-Indianapolis,Indianapolis,IN +466170,National American University-Lee's Summit,Lee's Summit,MO +482316,National American University-Lewisville,Lewisville,TX +442718,National American University-Overland Park,Overland Park,KS +219204,National American University-Rapid City,Rapid City,SD +482343,National American University-Rochester,Rochester,MN +174385,National American University-Roseville,Roseville,MN +219213,National American University-Sioux Falls,Sioux Falls,SD +466152,National American University-Tulsa,Tulsa,OK +482352,National American University-Weldon Spring,Weldon Spring,MO +451884,National American University-Wichita,Wichita,KS +482361,National American University-Wichita West,Wichita,KS +448585,National American University-Zona Rosa,Kansas City,MO +209296,National College of Natural Medicine,Portland,OR +480480,National College-Canton,Canton,OH +453473,National College-Cincinnati,Cincinnati,OH +457004,National College-Columbus,Columbus,OH +453455,National College-Dayton,Kettering,OH +157021,National College-Lexington,Lexington,KY +388043,National College-Nashville,Nashville,TN +453482,National College-Stow,Stow,OH +459833,National College-Willoughby Hills,Willoughby Hills,OH +453464,National College-Youngstown,Youngstown,OH +441478,National Graduate School of Quality Management,Falmouth,MA +412003,National Institute of Massotherapy,Akron,OH +147536,National Louis University,Chicago,IL +448114,National Massage Therapy Institute,Philadelphia,PA +461023,National Paralegal College,Phoenix,AZ +106980,National Park Community College,Hot Springs,AR +119605,National University,La Jolla,CA +242981,National University College-Arecibo,Arecibo,PR +242972,National University College-Bayamon,Bayamon,PR +468723,National University College-Caguas,Caguas,PR +458469,National University College-Ponce,Ponce,PR +444042,National University College-Rio Grande,Rio Grande,PR +147590,National University of Health Sciences,Lombard,IL +129729,Naugatuck Valley Community College,Waterbury,CT +187596,Navajo Technical University,Crownpoint,NM +119678,Naval Postgraduate School,Monterey,CA +227146,Navarro College,Corsicana,TX +127714,Nazarene Bible College,Colorado Springs,CO +178518,Nazarene Theological Seminary,Kansas City,MO +193584,Nazareth College,Rochester,NY +181376,Nebraska Christian College,Papillion,NE +181765,Nebraska College of Technical Agriculture,Curtis,NE +181419,Nebraska Indian Community College,Macy,NE +181297,Nebraska Methodist College of Nursing & Allied Health,Omaha,NE +181446,Nebraska Wesleyan University,Lincoln,NE +155566,Neosho County Community College,Chanute,KS +163532,Ner Israel Rabbinical College,Baltimore,MD +214272,Neumann University,Aston,PA +445692,Neumont University,Salt Lake City,UT +441900,Nevada State College,Henderson,NV +185758,New Brunswick Theological Seminary,New Brunswick,NJ +214290,New Castle School of Trades,New Castle,PA +262129,New College of Florida,Sarasota,FL +182980,New England College,Henniker,NH +164438,New England College of Business and Finance,Boston,MA +167093,New England College of Optometry,Boston,MA +230977,New England Culinary Institute,Montpelier,VT +217305,New England Institute of Technology,East Greenwich,RI +167215,New England Law-Boston,Boston,MA +167181,New England School of Acupuncture,Newton,MA +430810,New Hampshire Institute of Art,Manchester,NH +208725,New Hope Christian College-Eugene,Eugene,OR +185129,New Jersey City University,Jersey City,NJ +185828,New Jersey Institute of Technology,Newark,NJ +187897,New Mexico Highlands University,Las Vegas,NM +187967,New Mexico Institute of Mining and Technology,Socorro,NM +187903,New Mexico Junior College,Hobbs,NM +187912,New Mexico Military Institute,Roswell,NM +187994,New Mexico State University-Alamogordo,Alamogordo,NM +188003,New Mexico State University-Carlsbad,Carlsbad,NM +187620,New Mexico State University-Dona Ana,Las Cruces,NM +188021,New Mexico State University-Grants,Grants,NM +188030,New Mexico State University-Main Campus,Las Cruces,NM +159948,New Orleans Baptist Theological Seminary,New Orleans,LA +447582,New River Community and Technical College,Beaver,WV +232867,New River Community College,Dublin,VA +366368,New York Academy of Art,New York,NY +195845,New York Career Institute,New York,NY +193751,New York Chiropractic College,Seneca Falls,NY +418126,New York College of Health Professions,Syosset,NY +194073,New York College of Podiatric Medicine,New York,NY +439783,New York College of Traditional Chinese Medicine,Mineola,NY +421841,New York Conservatory for Dramatic Arts,New York,NY +461148,New York Film Academy,Burbank,CA +194091,New York Institute of Technology,Old Westbury,NY +193821,New York Law School,New York,NY +193830,New York Medical College,Valhalla,NY +194116,New York School of Interior Design,New York,NY +193894,New York Theological Seminary,New York,NY +193900,New York University,New York,NY +218414,Newberry College,Newberry,SC +167251,Newbury College,Brookline,MA +155335,Newman University,Wichita,KS +119775,Newschool of Architecture and Design,San Diego,CA +183099,NHTI-Concord's Community College,Concord,NH +193946,Niagara County Community College,Sanborn,NY +193973,Niagara University,Niagara University,NY +159966,Nicholls State University,Thibodaux,LA +167260,Nichols College,Dudley,MA +239442,Nicolet Area Technical College,Rhinelander,WI +444787,Nightingale College,Ogden,UT +460464,Norco College,Norco,CA +232937,Norfolk State University,Norfolk,VA +174428,Normandale Community College,Bloomington,MN +461795,North American University,Houston,TX +107460,North Arkansas College,Harrison,AR +199102,North Carolina A & T State University,Greensboro,NC +199157,North Carolina Central University,Durham,NC +199193,North Carolina State University at Raleigh,Raleigh,NC +199209,North Carolina Wesleyan College,Rocky Mount,NC +147660,North Central College,Naperville,IL +418889,North Central Institute,Clarksville,TN +155593,North Central Kansas Technical College,Beloit,KS +171395,North Central Michigan College,Petoskey,MI +179715,North Central Missouri College,Trenton,MO +204422,North Central State College,Mansfield,OH +224110,North Central Texas College,Gainesville,TX +174437,North Central University,Minneapolis,MN +194028,North Country Community College,Saranac Lake,NY +200305,North Dakota State College of Science,Wahpeton,ND +200332,North Dakota State University-Main Campus,Fargo,ND +136145,North Florida Community College,Madison,FL +140678,North Georgia Technical College,Clarkesville,GA +218441,North Greenville University,Tigerville,SC +174376,North Hennepin Community College,Brooklyn Park,MN +142443,North Idaho College,Coeur d'Alene,ID +154059,North Iowa Area Community College,Mason City,IA +227191,North Lake College,Irving,TX +147679,North Park University,Chicago,IL +236072,North Seattle College,Seattle,WA +167312,North Shore Community College,Danvers,MA +214379,Northampton County Area Community College,Bethlehem,PA +239460,Northcentral Technical College,Wausau,WI +444130,Northcentral University,Prescott Valley,AZ +101897,Northeast Alabama Community College,Rainsville,AL +182917,Northeast Catholic College,Warner,NH +181491,Northeast Community College,Norfolk,NE +154110,Northeast Iowa Community College,Calmar,IA +176169,Northeast Mississippi Community College,Booneville,MS +204477,Northeast Ohio Medical University,Rootstown,OH +221908,Northeast State Community College,Blountville,TN +227225,Northeast Texas Community College,Mount Pleasant,TX +239488,Northeast Wisconsin Technical College,Green Bay,WI +147776,Northeastern Illinois University,Chicago,IL +127732,Northeastern Junior College,Sterling,CO +207290,Northeastern Oklahoma A&M College,Miami,OK +439817,Northeastern Seminary,Rochester,NY +207263,Northeastern State University,Tahlequah,OK +217837,Northeastern Technical College,Cheraw,SC +167358,Northeastern University,Boston,MA +482705,Northeastern University Global Network,Boston,MA +105330,Northern Arizona University,Flagstaff,AZ +147697,Northern Baptist Theological Seminary,Lombard,IL +167376,Northern Essex Community College,Haverhill,MA +147703,Northern Illinois University,Dekalb,IL +157447,Northern Kentucky University,Highland Heights,KY +161484,Northern Maine Community College,Presque Isle,ME +240790,Northern Marianas College,Saipan,MP +171456,Northern Michigan University,Marquette,MI +188058,Northern New Mexico College,Espanola,NM +207281,Northern Oklahoma College,Tonkawa,OK +219259,Northern State University,Aberdeen,SD +232946,Northern Virginia Community College,Annandale,VA +239512,Northland College,Ashland,WI +174473,Northland Community and Technical College,Thief River Falls,MN +239503,Northland International University,Dunbar,WI +105349,Northland Pioneer College,Holbrook,AZ +217606,Northpoint Bible College,Haverhill,MA +160667,Northshore Technical Community College,Bogalusa,LA +367459,NorthWest Arkansas Community College,Bentonville,AR +445948,Northwest Career College,Las Vegas,NV +209409,Northwest Christian University,Eugene,OR +240657,Northwest College,Powell,WY +377546,Northwest College of Art & Design,Poulsbo,WA +136233,Northwest Florida State College,Niceville,FL +380377,Northwest Indian College,Bellingham,WA +460941,Northwest Institute of Literary Arts,Langley,WA +154129,Northwest Iowa Community College,Sheldon,IA +155618,Northwest Kansas Technical College,Goodland,KS +160010,Northwest Louisiana Technical College,Minden,LA +176178,Northwest Mississippi Community College,Senatobia,MS +178624,Northwest Missouri State University,Maryville,MO +142461,Northwest Nazarene University,Nampa,ID +458140,Northwest School of Wooden Boat Building,Port Hadlock,WA +204440,Northwest State Community College,Archbold,OH +173115,Northwest Technical College,Bemidji,MN +236133,Northwest University,Kirkland,WA +420398,Northwest Vista College,San Antonio,TX +154101,Northwestern College,Orange City,IA +147749,Northwestern College-Chicago Campus,Chicago,IL +260992,Northwestern College-Southwestern Campus,Bridgeview,IL +130040,Northwestern Connecticut Community College,Winsted,CT +174507,Northwestern Health Sciences University,Bloomington,MN +171483,Northwestern Michigan College,Traverse City,MI +207306,Northwestern Oklahoma State University,Alva,OK +160038,Northwestern State University of Louisiana,Natchitoches,LA +147767,Northwestern University,Evanston,IL +101736,Northwest-Shoals Community College,Muscle Shoals,AL +136206,Northwood University-Florida,West Palm Beach,FL +171492,Northwood University-Michigan,Midland,MI +227243,Northwood University-Texas,Cedar Hill,TX +130004,Norwalk Community College,Norwalk,CT +230995,Norwich University,Northfield,VT +368452,Nossi College of Art,Madison,TN +204468,Notre Dame College,Cleveland,OH +120184,Notre Dame de Namur University,Belmont,CA +163578,Notre Dame of Maryland University,Baltimore,MD +160029,Notre Dame Seminary Graduate School of Theology,New Orleans,LA +136215,Nova Southeastern University,Fort Lauderdale,FL +200086,Nueta Hidatsa Sahnish College,New Town,ND +158884,Nunez Community College,Chalmette,LA +194161,Nyack College,Nyack,NY +174525,Oak Hills Christian College,Bemidji,MN +152099,Oakland City University,Oakland City,IN +171535,Oakland Community College,Bloomfield Hills,MI +171571,Oakland University,Rochester Hills,MI +147800,Oakton Community College,Des Plaines,IL +101912,Oakwood University,Huntsville,AL +204501,Oberlin College,Oberlin,OH +227289,Oblate School of Theology,San Antonio,TX +120254,Occidental College,Los Angeles,CA +185873,Ocean County College,Toms River,NJ +420431,Oconee Fall Line Technical College,Sandersville,GA +227304,Odessa College,Odessa,TX +366465,Ogeechee Technical College,Statesboro,GA +219277,Oglala Lakota College,Kyle,SD +140696,Oglethorpe University,Atlanta,GA +453747,Ohio Business College-Hilliard,Columbu,OH +203739,Ohio Business College-Sandusky,Sandusky,OH +203720,Ohio Business College-Sheffield,Sheffield Village,OH +201964,Ohio Christian University,Circleville,OH +204592,Ohio College of Massotherapy Inc,Akron,OH +204617,Ohio Dominican University,Columbus,OH +206002,Ohio Mid-Western College,Cincinnati,OH +204635,Ohio Northern University,Ada,OH +204662,Ohio State University Agricultural Technical Institute,Wooster,OH +204671,Ohio State University-Lima Campus,Lima,OH +204796,Ohio State University-Main Campus,Columbus,OH +204680,Ohio State University-Mansfield Campus,Mansfield,OH +204699,Ohio State University-Marion Campus,Marion,OH +204705,Ohio State University-Newark Campus,Newark,OH +204608,Ohio Technical College,Cleveland,OH +453817,Ohio Technical College-PowerSport Institute,North Randall,OH +204820,Ohio University-Chillicothe Campus,Chillicothe,OH +204802,Ohio University-Eastern Campus,Saint Clairsville,OH +204848,Ohio University-Lancaster Campus,Lancaster,OH +204857,Ohio University-Main Campus,Athens,OH +204839,Ohio University-Southern Campus,Ironton,OH +204866,Ohio University-Zanesville Campus,Zanesville,OH +204884,Ohio Valley College of Technology,East Liverpool,OH +237640,Ohio Valley University,Vienna,WV +204909,Ohio Wesleyan University,Delaware,OH +120290,Ohlone College,Fremont,CA +194189,Ohr Hameir Theological Seminary,Peekskill,NY +207403,Oklahoma Baptist University,Shawnee,OK +207324,Oklahoma Christian University,Edmond,OK +207449,Oklahoma City Community College,Oklahoma City,OK +207458,Oklahoma City University,Oklahoma City,OK +207351,Oklahoma Panhandle State University,Goodwell,OK +207315,Oklahoma State University Center for Health Sciences,Tulsa,OK +207564,Oklahoma State University Institute of Technology,Okmulgee,OK +207388,Oklahoma State University-Main Campus,Stillwater,OK +207397,Oklahoma State University-Oklahoma City,Oklahoma City,OK +469629,Oklahoma Technical College,Tulsa,OK +206835,Oklahoma Wesleyan University,Bartlesville,OK +232982,Old Dominion University,Norfolk,VA +171599,Olivet College,Olivet,MI +147828,Olivet Nazarene University,Bourbonnais,IL +145707,Olney Central College,Olney,IL +236188,Olympic College,Bremerton,WA +407328,Omaha School of Massage and Healthcare of Herzing University,Omaha,NE +221254,O'More College of Design,Franklin,TN +194222,Onondaga Community College,Syracuse,NY +207582,Oral Roberts University,Tulsa,OK +120342,Orange Coast College,Costa Mesa,CA +194240,Orange County Community College,Middletown,NY +218487,Orangeburg Calhoun Technical College,Orangeburg,SC +423652,Oregon Coast Community College,Newport,OR +209533,Oregon College of Art and Craft,Portland,OR +369659,Oregon College of Oriental Medicine,Portland,OR +209490,Oregon Health & Science University,Portland,OR +209506,Oregon Institute of Technology,Klamath Falls,OR +209542,Oregon State University,Corvallis,OR +454883,Orion College,Plantation,FL +214528,Orleans Technical Institute,Philadelphia,PA +127778,Otero Junior College,La Junta,CO +120403,Otis College of Art and Design,Los Angeles,CA +442897,Ottawa University-Jeffersonville,Jeffersonville,IN +155636,Ottawa University-Kansas City,Overland Park,KS +428259,Ottawa University-Milwaukee,Brookfield,WI +454582,Ottawa University-Online,Ottawa,KS +155627,Ottawa University-Ottawa,Ottawa,KS +105367,Ottawa University-Phoenix,Phoenix,AZ +204936,Otterbein University,Westerville,OH +107512,Ouachita Baptist University,Arkadelphia,AR +160074,Our Lady of the Lake College,Baton Rouge,LA +227331,Our Lady of the Lake University,San Antonio,TX +204945,Owens Community College,Perrysburg,OH +247940,Owensboro Community and Technical College,Owensboro,KY +461120,Oxford Graduate School,Dayton,TN +120421,Oxnard College,Oxnard,CA +178679,Ozark Christian College,Joplin,MO +107549,Ozarka College,Melbourne,AR +177472,Ozarks Technical Community College,Springfield,MO +214838,Pace Institute,Reading,PA +194310,Pace University-New York,New York,NY +422695,Pacific College,Costa Mesa,CA +442842,Pacific College of Oriental Medicine-Chicago,Chicago,IL +414595,Pacific College of Oriental Medicine-New York,New York,NY +378576,Pacific College of Oriental Medicine-San Diego,San Diego,CA +439862,Pacific Islands University,Mangilao,GU +120740,Pacific Lutheran Theological Seminary,Berkeley,CA +236230,Pacific Lutheran University,Tacoma,WA +209603,Pacific Northwest College of Art,Portland,OR +455406,Pacific Northwest University of Health Sciences,Yakima,WA +120768,Pacific Oaks College,Pasadena,CA +457484,Pacific Rim Christian University,Honolulu,HI +120795,Pacific School of Religion,Berkeley,CA +120838,Pacific States University,Los Angeles,CA +120865,Pacific Union College,Angwin,CA +209612,Pacific University,Forest Grove,OR +115746,Pacifica Graduate Institute,Carpinteria,CA +130110,Paier College of Art Inc,Hamden,CT +140720,Paine College,Augusta,GA +243647,Palau Community College,Koror,PW +136330,Palm Beach Atlantic University,West Palm Beach,FL +136358,Palm Beach State College,Lake Worth,FL +154174,Palmer College of Chiropractic,Davenport,IA +246354,Palo Alto College,San Antonio,TX +120698,Palo Alto University,Palo Alto,CA +120953,Palo Verde College,Blythe,CA +120971,Palomar College,San Marcos,CA +199263,Pamlico Community College,Grantsboro,NC +227386,Panola College,Carthage,TX +364016,Paradise Valley Community College,Phoenix,AZ +121628,Pardee RAND Graduate School,Santa Monica,CA +227401,Paris Junior College,Paris,TX +178721,Park University,Parkville,MO +243823,Parker University,Dallas,TX +147916,Parkland College,Champaign,IL +121044,Pasadena City College,Pasadena,CA +136400,Pasco-Hernando State College,New Port Richey,FL +186034,Passaic County Community College,Paterson,NJ +666666,Patrick Henry College,Purcellville,VA +233019,Patrick Henry Community College,Martinsville,VA +233037,Paul D Camp Community College,Franklin,VA +227429,Paul Quinn College,Dallas,TX +194392,Paul Smiths College of Arts and Science,Paul Smiths,NY +204990,Payne Theological Seminary,Wilberforce,OH +176239,Pearl River Community College,Poplarville,MS +214883,Peirce College,Philadelphia,PA +221643,Pellissippi State Community College,Knoxville,TN +236258,Peninsula College,Port Angeles,WA +214892,Penn Commercial Business/Technical School,Washington,PA +214944,Pennco Tech-Bristol,Bristol,PA +214971,Pennsylvania Academy of the Fine Arts,Philadelphia,PA +215053,Pennsylvania College of Art and Design,Lancaster,PA +442356,Pennsylvania College of Health Sciences,Lancaster,PA +366252,Pennsylvania College of Technology,Williamsport,PA +414911,Pennsylvania Highlands Community College,Johnstown,PA +261861,Pennsylvania Institute of Health and Technology,Mount Braddock,PA +214582,Pennsylvania Institute of Technology,Media,PA +214616,Pennsylvania State University-College of Medicine,Hershey,PA +212018,Pennsylvania State University-Dickinson Law,Carlisle,PA +214777,Pennsylvania State University-Main Campus,University Park,PA +214801,Pennsylvania State University-Penn State Abington,Abington,PA +214689,Pennsylvania State University-Penn State Altoona,Altoona,PA +214698,Pennsylvania State University-Penn State Beaver,Monaca,PA +214704,Pennsylvania State University-Penn State Berks,Reading,PA +214731,Pennsylvania State University-Penn State Brandywine,Media,PA +214740,Pennsylvania State University-Penn State DuBois,DuBois,PA +214591,Pennsylvania State University-Penn State Erie-Behrend College,Erie,PA +214759,Pennsylvania State University-Penn State Fayette- Eberly,Lemont Furnace,PA +214607,Pennsylvania State University-Penn State Great Valley,Malvern,PA +214786,Pennsylvania State University-Penn State Greater Allegheny,McKeesport,PA +214713,Pennsylvania State University-Penn State Harrisburg,Middletown,PA +214768,Pennsylvania State University-Penn State Hazleton,Hazleton,PA +214670,Pennsylvania State University-Penn State Lehigh Valley,Center Valley,PA +214795,Pennsylvania State University-Penn State Mont Alto,Mont Alto,PA +214625,Pennsylvania State University-Penn State New Kensington,New Kensington,PA +214810,Pennsylvania State University-Penn State Schuylkill,Schuylkill Haven,PA +214634,Pennsylvania State University-Penn State Shenango,Sharon,PA +214643,Pennsylvania State University-Penn State Wilkes-Barre,Lehman,PA +214652,Pennsylvania State University-Penn State Worthington Scranton,Dunmore,PA +214829,Pennsylvania State University-Penn State York,York,PA +479956,Pennsylvania State University-World Campus,University Park,PA +136473,Pensacola State College,Pensacola,FL +219842,Pentecostal Theological Seminary,Cleveland,TN +121150,Pepperdine University,Malibu,CA +181534,Peru State College,Peru,NE +199306,Pfeiffer University,Misenheimer,NC +215123,Philadelphia College of Osteopathic Medicine,Philadelphia,PA +215099,Philadelphia University,Philadelphia,PA +107600,Philander Smith College,Little Rock,AR +189282,Phillips Beth Israel School of Nursing,New York,NY +107619,Phillips Community College of the University of Arkansas,Helena,AR +110307,Phillips Graduate Institute,Chatsworth,CA +414966,Phillips Theological Seminary,Tulsa,OK +105428,Phoenix College,Phoenix,AZ +447698,Phoenix Institute of Herbal Medicine & Acupuncture,Phoenix,AZ +381459,Phoenix Seminary,Phoenix,AZ +140818,Piedmont College,Demorest,GA +199324,Piedmont Community College,Roxboro,NC +199315,Piedmont International University,Winston Salem,NC +218520,Piedmont Technical College,Greenwood,SC +233116,Piedmont Virginia Community College,Charlottesville,VA +235237,Pierce College-Fort Steilacoom,Lakewood,WA +439145,Pierce College-Puyallup,Puyallup,WA +443492,Pierpont Community and Technical College,Fairmont,WV +127820,Pikes Peak Community College,Colorado Springs,CO +440794,Pillar College,Newark,NJ +105525,Pima Community College,Tucson,AZ +105543,Pima Medical Institute-Albuquerque,Albuquerque,NM +461689,Pima Medical Institute-Aurora,Aurora,CO +434140,Pima Medical Institute-Chula Vista,Chula Vista,CA +442134,Pima Medical Institute-Colorado Springs,Colorado Springs,CO +404912,Pima Medical Institute-Denver,Denver,CO +456038,Pima Medical Institute-East Valley,Mesa,AZ +460136,Pima Medical Institute-Houston,Houston,TX +445230,Pima Medical Institute-Las Vegas,Las Vegas,NV +260691,Pima Medical Institute-Mesa,Mesa,AZ +449074,Pima Medical Institute-Renton,Renton,WA +368629,Pima Medical Institute-Seattle,Seattle,WA +105534,Pima Medical Institute-Tucson,Tucson,AZ +458159,Pinchot University,Seattle,WA +167455,Pine Manor College,Chestnut Hill,MA +174570,Pine Technical & Community College,Pine City,MN +367097,Pinnacle Career Institute-Lawrence,Lawrence,KS +453109,Pinnacle Career Institute-North Kansas City,Kansas City,MO +177302,Pinnacle Career Institute-South Kansas City,Kansas City,MO +210076,Pioneer Pacific College,Wilsonville,OR +199333,Pitt Community College,Winterville,NC +155681,Pittsburg State University,Pittsburg,KS +216782,Pittsburgh Career Institute,Pittsburgh,PA +215381,Pittsburgh Institute of Aeronautics,West Mifflin,PA +215390,Pittsburgh Institute of Mortuary Science Inc,Pittsburgh,PA +215415,Pittsburgh Technical Institute,Oakdale,PA +215424,Pittsburgh Theological Seminary,Pittsburgh,PA +121257,Pitzer College,Claremont,CA +260813,Platt College-Aurora,Aurora,CO +207625,Platt College-Central OKC,Oklahoma City,OK +260789,Platt College-Los Angeles,Alhambra,CA +447379,Platt College-Moore,Moore,OK +445258,Platt College-North OKC,Oklahoma City,OK +432384,Platt College-Ontario,Ontario,CA +480204,Platt College-Riverside,Riverside,CA +121275,Platt College-San Diego,San Diego,CA +245962,Platt College-Tulsa,Tulsa,OK +194499,Plaza College,Forest Hills,NY +183080,Plymouth State University,Plymouth,NH +121309,Point Loma Nazarene University,San Diego,CA +215442,Point Park University,Pittsburgh,PA +138868,Point University,West Point,GA +136516,Polk State College,Winter Haven,FL +456481,Polytechnic University of Puerto Rico-Miami,Miami,FL +456490,Polytechnic University of Puerto Rico-Orlando,Orlando,FL +190451,Pomeroy College of Nursing at Crouse Hospital,Syracuse,NY +121345,Pomona College,Claremont,CA +243081,Ponce Health Sciences University,Ponce,PR +243072,Ponce Paramedical College Inc,Ponce,PR +241395,Pontifical Catholic University of Puerto Rico-Arecibo,Arecibo,PR +243586,Pontifical Catholic University of Puerto Rico-Mayaguez,Mayaguez,PR +241410,Pontifical Catholic University of Puerto Rico-Ponce,Ponce,PR +205027,Pontifical College Josephinum,Columbus,OH +131405,Pontifical Faculty of the Immaculate Conception at the Dominican House of Studies,Washington,DC +455813,Pontifical John Paul II Institute for Studies on Marriage and Family,Washington,DC +167464,Pope St John XXIII National Seminary,Weston,MA +121363,Porterville College,Porterville,CA +209746,Portland Community College,Portland,OR +209807,Portland State University,Portland,OR +130183,Post University,Waterbury,CT +237701,Potomac State College of West Virginia University,Keyser,WV +148007,Prairie State College,Chicago Heights,IL +227526,Prairie View A & M University,Prairie View,TX +155715,Pratt Community College,Pratt,KS +194578,Pratt Institute-Main,Brooklyn,NY +218539,Presbyterian College,Clinton,SC +105589,Prescott College,Prescott,AZ +219295,Presentation College,Aberdeen,SD +163657,Prince George's Community College,Largo,MD +101958,Prince Institute-Southeast,Montgomery,AL +186122,Princeton Theological Seminary,Princeton,NJ +186131,Princeton University,Princeton,NJ +148016,Principia College,Elsah,IL +215433,Prism Career Institute-Upper Darby,Upper Darby,PA +437750,Professional Golfers Career College,Temecula,CA +205054,Professional Skills Institute,Maumee,OH +455770,Providence Christian College,Pasadena,CA +217402,Providence College,Providence,RI +380438,Provo College,Provo,UT +127884,Pueblo Community College,Pueblo,CO +241766,Puerto Rico Conservatory of Music,San Juan,PR +107664,Pulaski Technical College,North Little Rock,AR +152248,Purdue University-Calumet Campus,Hammond,IN +243780,Purdue University-Main Campus,West Lafayette,IN +152266,Purdue University-North Central Campus,Westville,IN +199412,Queens University of Charlotte,Charlotte,NC +167525,Quincy College,Quincy,MA +148131,Quincy University,Quincy,IL +130217,Quinebaug Valley Community College,Danielson,CT +130226,Quinnipiac University,Hamden,CT +167534,Quinsigamond Community College,Worcester,MA +384421,Rabbi Jacob Joseph School,Edison,NJ +194657,Rabbinical Academy Mesivta Rabbi Chaim Berlin,Brooklyn,NY +194693,Rabbinical College Beth Shraga,Monsey,NY +194666,Rabbinical College Bobover Yeshiva Bnei Zion,Brooklyn,NY +186186,Rabbinical College of America,Morristown,NJ +194675,Rabbinical College of Ch'san Sofer New York,Brooklyn,NY +194736,Rabbinical College of Long Island,Long Beach,NY +405854,Rabbinical College of Ohr Shimon Yisroel,Brooklyn,NY +484871,Rabbinical College Ohr Yisroel,Brooklyn,NY +205124,Rabbinical College Telshe,Wickliffe,OH +194763,Rabbinical Seminary of America,Flushing,NY +233277,Radford University,Radford,VA +481119,Radians College,Washington,DC +174604,Rainy River Community College,International Falls,MN +186201,Ramapo College of New Jersey,Mahwah,NJ +233301,Randolph College,Lynchburg,VA +199421,Randolph Community College,Asheboro,NC +233295,Randolph-Macon College,Ashland,VA +227687,Ranger College,Ranger,TX +178891,Ranken Technical College,Saint Louis,MO +233310,Rappahannock Community College,Glenns,VA +186645,Raritan Valley Community College,Branchburg,NJ +138309,Rasmussen College-Florida,Ocala,FL +448673,Rasmussen College-Illinois,Rockford,IL +175014,Rasmussen College-Minnesota,St. Cloud,MN +200013,Rasmussen College-North Dakota,Fargo,ND +450571,Rasmussen College-Wisconsin,Green Bay,WI +215585,Reading Area Community College,Reading,PA +215619,Reconstructionist Rabbinical College,Wyncote,PA +127909,Red Rocks Community College,Lakewood,CO +207069,Redlands Community College,El Reno,OK +126605,Redstone College,Broomfield,CO +209922,Reed College,Portland,OR +117052,Reedley College,Reedley,CA +215628,Reformed Presbyterian Theological Seminary,Pittsburgh,PA +105659,Refrigeration School Inc,Phoenix,AZ +231651,Regent University,Virginia Beach,VA +167598,Regis College,Weston,MA +127918,Regis University,Denver,CO +101994,Reid State Technical College,Evergreen,AL +140872,Reinhardt University,Waleska,GA +475033,Relay Graduate School of Education,New York,NY +457183,Remington College of Nursing Orlando,Lake Mary,FL +440271,Remington College-Baton Rouge Campus,Baton Rouge,LA +375416,Remington College-Cleveland Campus,Cleveland,OH +223463,Remington College-Dallas Campus,Garland,TX +377111,Remington College-Fort Worth Campus,Fort Worth,TX +460783,Remington College-Heathrow Campus,Heathrow,FL +372958,Remington College-Honolulu Campus,Honolulu,HI +380094,Remington College-Houston Campus,Houston,TX +160524,Remington College-Lafayette Campus,Lafayette,LA +438869,Remington College-Little Rock Campus,Little Rock,AR +412599,Remington College-Memphis Campus,Memphis,TN +366535,Remington College-Mobile Campus,Mobile,AL +445249,Remington College-Nashville Campus,Nashville,TN +445203,Remington College-North Houston Campus,Houston,TX +451866,Remington College-Shreveport Campus,Shreveport,LA +135939,Remington College-Tampa Campus,Tampa,FL +148256,Rend Lake College,Ina,IL +129428,Rensselaer Hartford Graduate Center Inc,Hartford,CT +194824,Rensselaer Polytechnic Institute,Troy,NY +236382,Renton Technical College,Renton,WA +178989,Research College of Nursing,Kansas City,MO +149763,Resurrection University,Chicago,IL +217420,Rhode Island College,Providence,RI +217493,Rhode Island School of Design,Providence,RI +221351,Rhodes College,Memphis,TN +227757,Rice University,Houston,TX +107743,Rich Mountain Community College,Mena,AR +233338,Richard Bland College of the College of William and Mary,Petersburg,VA +227766,Richland College,Dallas,TX +148292,Richland Community College,Decatur,IL +199449,Richmond Community College,Hamlet,NC +441104,Richmont Graduate University,Chattanooga,TN +186283,Rider University,Lawrenceville,NJ +175236,Ridgewater College,Willmar,MN +136774,Ringling College of Art and Design,Sarasota,FL +475185,Rio Grande Bible Institute,Edinburg,TX +121886,Rio Hondo College,Whittier,CA +105668,Rio Salado College,Tempe,AZ +239628,Ripon College,Ripon,WI +436304,River Parishes Community College,Gonzales,LA +183114,River Valley Community College,Claremont,NH +173063,Riverland Community College,Austin,MN +121901,Riverside City College,Riverside,CA +233408,Riverside College of Health Careers,Newport News,VA +183211,Rivier University,Nashua,NH +221397,Roane State Community College,Harriman,TN +233426,Roanoke College,Salem,VA +199467,Roanoke-Chowan Community College,Ahoskie,NC +215655,Robert Morris University,Moon Township,PA +148335,Robert Morris University Illinois,Chicago,IL +194958,Roberts Wesleyan College,Rochester,NY +199476,Robeson Community College,Lumberton,NC +170967,Rochester College,Rochester Hills,MI +174738,Rochester Community and Technical College,Rochester,MN +195003,Rochester Institute of Technology,Rochester,NY +148380,Rock Valley College,Rockford,IL +195049,Rockefeller University,New York,NY +148405,Rockford University,Rockford,IL +179043,Rockhurst University,Kansas City,MO +199485,Rockingham Community College,Wentworth,NC +195058,Rockland Community College,Suffern,NY +180595,Rocky Mountain College,Billings,MT +127945,Rocky Mountain College of Art and Design,Lakewood,CO +475495,Rocky Mountain University of Health Professions,Provo,UT +480790,Rocky Vista University,Parker,CO +217518,Roger Williams University,Bristol,RI +409616,Roger Williams University School of Law,Bristol,RI +207661,Rogers State University,Claremore,OK +209940,Rogue Community College,Grants Pass,OR +136950,Rollins College,Winter Park,FL +148487,Roosevelt University,Chicago,IL +145558,Rosalind Franklin University of Medicine and Science,North Chicago,IL +207670,Rose State College,Midwest City,OK +439899,Rosedale Bible College,Irwin,OH +215682,Rosedale Technical Institute,Pittsburgh,PA +152318,Rose-Hulman Institute of Technology,Terre Haute,IN +445735,Roseman University of Health Sciences,Henderson,NV +215691,Rosemont College,Rosemont,PA +452081,Ross College-Sylvania,Sylvania,OH +183877,Rowan College at Burlington County,Pemberton,NJ +184791,Rowan College at Gloucester County,Sewell,NJ +184782,Rowan University,Glassboro,NJ +199494,Rowan-Cabarrus Community College,Salisbury,NC +167631,Roxbury Community College,Roxbury Crossing,MA +148511,Rush University,Chicago,IL +176318,Rust College,Holly Springs,MS +186371,Rutgers University-Camden,Camden,NJ +186380,Rutgers University-New Brunswick,New Brunswick,NJ +186399,Rutgers University-Newark,Newark,NJ +449506,SABER College,Miami,FL +122180,Sacramento City College,Sacramento,CA +172033,Sacred Heart Major Seminary,Detroit,MI +239637,Sacred Heart School of Theology,Franklin,WI +130253,Sacred Heart University,Fairfield,CT +122205,Saddleback College,Mission Viejo,CA +476948,SAE Institute of Technology-Atlanta,Atlanta,GA +446525,SAE Institute of Technology-Nashville,Nashville,TN +410520,Sage College,Moreno Valley,CA +441070,Saginaw Chippewa Tribal College,Mount Pleasant,MI +172051,Saginaw Valley State University,University Center,MI +154235,Saint Ambrose University,Davenport,IA +183239,Saint Anselm College,Manchester,NH +149028,Saint Anthony College of Nursing,Rockford,IL +148876,Saint Augustine College,Chicago,IL +199582,Saint Augustine's University,Raleigh,NC +157632,Saint Catharine College,Saint Catharine,KY +216047,Saint Charles Borromeo Seminary-Overbrook,Wynnewood,PA +174783,Saint Cloud State University,Saint Cloud,MN +227845,Saint Edward's University,Austin,TX +195702,Saint Elizabeth College of Nursing-Utica,Utica,NY +148575,Saint Francis Medical Center College of Nursing,Peoria,IL +215743,Saint Francis University,Loretto,PA +195720,Saint John Fisher College,Rochester,NY +137272,Saint John Vianney College Seminary,Miami,FL +137281,Saint Johns River State College,Palatka,FL +167677,Saint John's Seminary,Brighton,MA +174792,Saint Johns University,Collegeville,MN +160409,Saint Joseph Seminary College,St. Benedict,LA +152363,Saint Josephs College,Rensselaer,IN +161518,Saint Joseph's College of Maine,Standish,ME +195544,Saint Joseph's College-New York,Brooklyn,NY +215770,Saint Joseph's University,Philadelphia,PA +137032,Saint Leo University,Saint Leo,FL +179256,Saint Louis Christian College,Florissant,MO +179308,Saint Louis Community College,Saint Louis,MO +179159,Saint Louis University,Saint Louis,MO +179450,Saint Luke's College of Health Sciences,Kansas City,MO +236452,Saint Martin's University,Lacey,WA +152381,Saint Mary-of-the-Woods College,Saint Mary of the Woods,IN +152390,Saint Mary's College,Notre Dame,IN +123554,Saint Mary's College of California,Moraga,CA +174817,Saint Mary's University of Minnesota,Winona,MN +152451,Saint Meinrad School of Theology,St. Meinrad,IN +231059,Saint Michael's College,Colchester,VT +239716,Saint Norbert College,De Pere,WI +175041,Saint Paul College,Saint Paul,MN +179317,Saint Paul School of Theology,Leawood,KS +186432,Saint Peter's University,Jersey City,NJ +215798,Saint Vincent College,Latrobe,PA +136701,Saint Vincent de Paul Regional Seminary,Boynton Beach,FL +215813,Saint Vincent Seminary,Latrobe,PA +195580,Saint Vladimirs Orthodox Theological Seminary,Yonkers,NY +148627,Saint Xavier University,Chicago,IL +199607,Salem College,Winston Salem,NC +186469,Salem Community College,Carneys Point,NJ +237783,Salem International University,Salem,WV +167729,Salem State University,Salem,MA +155830,Salina Area Technical College,Salina,KS +163851,Salisbury University,Salisbury,MD +180647,Salish Kootenai College,Pablo,MT +230746,Salt Lake Community College,Salt Lake City,UT +466523,Salter College-Chicopee,Chicopee,MA +167738,Salter College-West Boylston,West Boylston,MA +214564,Salus University,Elkins Park,PA +217536,Salve Regina University,Newport,RI +227881,Sam Houston State University,Huntsville,TX +195289,Samaritan Hospital School of Nursing,Troy,NY +102049,Samford University,Birmingham,AL +199625,Sampson Community College,Clinton,NC +122296,Samuel Merritt University,Oakland,CA +227924,San Antonio College,San Antonio,TX +123527,San Bernardino Valley College,San Bernardino,CA +112084,San Diego Christian College,Santee,CA +122339,San Diego City College,San Diego,CA +122375,San Diego Mesa College,San Diego,CA +122384,San Diego Miramar College,San Diego,CA +122409,San Diego State University,San Diego,CA +122454,San Francisco Art Institute,San Francisco,CA +122506,San Francisco Conservatory of Music,San Francisco,CA +122597,San Francisco State University,San Francisco,CA +122603,San Francisco Theological Seminary,San Anselmo,CA +227979,San Jacinto Community College,Pasadena,TX +122649,San Joaquin College of Law,Clovis,CA +122658,San Joaquin Delta College,Stockton,CA +122685,San Joaquin Valley College-Visalia,Visalia,CA +122746,San Jose City College,San Jose,CA +122755,San Jose State University,San Jose,CA +430670,San Juan Bautista School of Medicine,Caguas,PR +188100,San Juan College,Farmington,NM +199634,Sandhills Community College,Pinehurst,NC +481535,Sanford Burnham Prybis Medical Discovery Institute,La Jolla,CA +420495,Sanford-Brown College-Atlanta,Atlanta,GA +475291,Sanford-Brown College-Brooklyn Center,Brooklyn Center,MN +146010,Sanford-Brown College-Chicago,Chicago,IL +404514,Sanford-Brown College-Dallas,Dallas,TX +179201,Sanford-Brown College-Fenton,Fenton,MO +404499,Sanford-Brown College-Houston,Houston,TX +446792,Sanford-Brown College-Las Vegas,Henderson,NV +174394,Sanford-Brown College-Mendota Heights,Mendota Heights,MN +420501,Sanford-Brown College-Middleburg Heights,Middleburg Heights,OH +456296,Sanford-Brown College-Online,Tampa,FL +440925,Sanford-Brown College-Orlando,Orlando,FL +450465,Sanford-Brown College-San Antonio-San Antonio,San Antonio,TX +446808,Sanford-Brown College-Seattle,Tukwila,WA +134680,Sanford-Brown College-Tampa,Tampa,FL +234216,Sanford-Brown College-Tysons Corner,McLean,VA +385008,Sanford-Brown Institute-Ft Lauderdale,Fort Lauderdale,FL +404505,Sanford-Brown Institute-Jacksonville,Jacksonville,FL +121619,Santa Ana College,Santa Ana,CA +122834,Santa Barbara Business College-Bakersfield,Bakersfield,CA +122852,Santa Barbara Business College-Santa Maria,Santa Maria,CA +433420,Santa Barbara Business College-Ventura,Ventura,CA +122889,Santa Barbara City College,Santa Barbara,CA +122931,Santa Clara University,Santa Clara,CA +137096,Santa Fe College,Gainesville,FL +188137,Santa Fe Community College,Santa Fe,NM +188146,Santa Fe University of Art and Design,Santa Fe,NM +122977,Santa Monica College,Santa Monica,CA +123013,Santa Rosa Junior College,Santa Rosa,CA +399212,Santiago Canyon College,Orange,CA +195304,Sarah Lawrence College,Bronxville,NY +148672,Sauk Valley Community College,Dixon,IL +140951,Savannah College of Art and Design,Savannah,GA +140960,Savannah State University,Savannah,GA +140942,Savannah Technical College,Savannah,GA +123095,Saybrook University,Oakland,CA +192156,SBI Campus-An Affiliate of Sanford-Brown,Melville,NY +195322,Schenectady County Community College,Schenectady,NY +404338,Schiller International University,Largo,FL +143048,School of the Art Institute of Chicago,Chicago,IL +166984,School of the Museum of Fine Arts-Boston,Boston,MA +197151,School of Visual Arts,New York,NY +172200,Schoolcraft College,Livonia,MI +228042,Schreiner University,Kerrville,TX +105747,Scottsdale Community College,Scottsdale,AZ +123165,Scripps College,Claremont,CA +236513,Seattle Central College,Seattle,WA +439914,Seattle Institute of Oriental Medicine,Seattle,WA +236577,Seattle Pacific University,Seattle,WA +236595,Seattle University,Seattle,WA +102058,Selma University,Selma,AL +243498,Seminario Evangelico de Puerto Rico,San Juan,PR +207740,Seminole State College,Seminole,OK +137209,Seminole State College of Florida,Sanford,FL +232885,Sentara College of Health Sciences,Chesapeake,VA +475839,Sessions College for Professional Design,Tempe,AZ +186584,Seton Hall University,South Orange,NJ +215947,Seton Hill University,Greensburg,PA +221519,Sewanee-The University of the South,Sewanee,TN +155858,Seward County Community College and Area Technical School,Liberal,KS +123280,Shasta Bible College and Graduate School,Redding,CA +123299,Shasta College,Redding,CA +199643,Shaw University,Raleigh,NC +148821,Shawnee Community College,Ullin,IL +205443,Shawnee State University,Portsmouth,OH +102067,Shelton State Community College,Tuscaloosa,AL +233541,Shenandoah University,Winchester,VA +237792,Shepherd University,Shepherdstown,WV +461485,Shepherds Theological Seminary,Cary,NC +240666,Sheridan College,Sheridan,WY +218751,Sherman College of Straight Chiropractic,Spartanburg,SC +480499,Shiloh University,Kalona,IA +148849,Shimer College,Chicago,IL +216010,Shippensburg University of Pennsylvania,Shippensburg,PA +195438,Sh'or Yoshuv Rabbinical College,Lawrence,NY +236610,Shoreline Community College,Shoreline,WA +107840,Shorter College,N Little Rock,AR +140988,Shorter University,Rome,GA +448309,Shorter University-College of Adult & Professional Programs,Marietta,GA +195474,Siena College,Loudonville,NY +172264,Siena Heights University,Adrian,MI +123341,Sierra College,Rocklin,CA +182458,Sierra Nevada College,Incline Village,NV +239743,Silver Lake College of the Holy Family,Manitowoc,WI +167783,Simmons College,Boston,MA +461759,Simmons College of Kentucky,Louisville,KY +154350,Simpson College,Indianola,IA +123457,Simpson University,Redding,CA +205470,Sinclair Community College,Dayton,OH +219374,Sinte Gleska University,Mission,SD +219240,Sioux Falls Seminary,Sioux Falls,SD +219408,Sisseton Wahpeton College,Sisseton,SD +231068,SIT Graduate Institute,Brattleboro,VT +200466,Sitting Bull College,Fort Yates,ND +236638,Skagit Valley College,Mount Vernon,WA +195526,Skidmore College,Saratoga Springs,NY +123509,Skyline College,San Bruno,CA +261931,Skyline College-Roanoke,Roanoke,VA +216038,Slippery Rock University of Pennsylvania,Slippery Rock,PA +167835,Smith College,Northampton,MA +102076,Snead State Community College,Boaz,AL +230597,Snow College,Ephraim,UT +110778,Sofia University,Palo Alto,CA +163921,Sojourner-Douglass College,Baltimore,MD +399911,Soka University of America,Aliso Viejo,CA +123563,Solano Community College,Fairfield,CA +459356,SOLEX College,Wheeling,IL +157711,Somerset Community College,Somerset,KY +123572,Sonoma State University,Rohnert Park,CA +481094,Sotheby's Institute of Art-NY,New York,NY +107974,South Arkansas Community College,El Dorado,AR +123633,South Baylo University,Anaheim,CA +218733,South Carolina State University,Orangeburg,SC +173911,South Central College,North Mankato,MN +160913,South Central Louisiana Technical College-Young Memorial Campus,Morgan City,LA +123642,South Coast College,Orange,CA +220552,South College,Knoxville,TN +198242,South College-Asheville,Asheville,NC +219347,South Dakota School of Mines and Technology,Rapid City,SD +219356,South Dakota State University,Brookings,SD +366003,South Florida Bible College and Theological Seminary,Deerfield Beach,FL +137315,South Florida State College,Avon Park,FL +482699,South Georgia State College,Douglas,GA +141006,South Georgia Technical College,Americus,GA +216083,South Hills School of Business & Technology,State College,PA +434061,South Louisiana Community College,Lafayette,LA +105792,South Mountain Community College,Phoenix,AZ +197850,South Piedmont Community College,Polkton,NC +228158,South Plains College,Levelland,TX +236656,South Puget Sound Community College,Olympia,WA +236504,South Seattle College,Seattle,WA +149365,South Suburban College,South Holland,IL +409315,South Texas College,McAllen,TX +228194,South Texas College of Law,Houston,TX +468006,South University-Accelerated Graduate Programs,Atlanta,GA +480073,South University-Austin,Austin,TX +480082,South University-Cleveland,Cleveland,OH +251312,South University-Columbia,Columbia,SC +481720,South University-High Point,High Point,NC +101116,South University-Montgomery,Montgomery,AL +468024,South University-Novi,Novi,MI +459259,South University–Richmond,Glen Allen,VA +139579,South University-Savannah,Savannah,GA +475121,South University–Savannah Online,Savannah,GA +449898,South University-Tampa,Tampa,FL +224776,South University-The Art Institute of Dallas,Dallas,TX +468015,South University-The Art Institute of Fort Worth,Fort Worth,TX +459268,South University–Virginia Beach,Virginia Beach,VA +133465,South University-West Palm Beach,Royal Palm Beach,FL +156338,Southcentral Kentucky Community and Technical College,Bowling Green,KY +107637,Southeast Arkansas College,Pine Bluff,AR +181640,Southeast Community College Area,Lincoln,NE +157739,Southeast Kentucky Community and Technical College,Cumberland,KY +417734,Southeast Missouri Hospital College of Nursing and Health Sciences,Cape Girardeau,MO +179557,Southeast Missouri State University,Cape Girardeau,MO +219426,Southeast Technical Institute,Sioux Falls,SD +176336,Southeastern Baptist College,Laurel,MS +199759,Southeastern Baptist Theological Seminary,Wake Forest,NC +102261,Southeastern Bible College,Birmingham,AL +443270,Southeastern College-Jacksonville,Jacksonville,FL +428170,Southeastern College-West Palm Beach,Greenacres,FL +154378,Southeastern Community College-West Burlington,West Burlington,IA +199722,Southeastern Community College-Whiteville,Whiteville,NC +148937,Southeastern Illinois College,Harrisburg,IL +160612,Southeastern Louisiana University,Hammond,LA +207847,Southeastern Oklahoma State University,Durant,OK +368911,Southeastern Technical College,Vidalia,GA +137564,Southeastern University,Lakeland,FL +221661,Southern Adventist University,Collegedale,TN +107983,Southern Arkansas University Main Campus,Magnolia,AR +107992,Southern Arkansas University Tech,Camden,AR +123952,Southern California Institute of Architecture,Los Angeles,CA +399869,Southern California Institute of Technology,Anaheim,CA +117575,Southern California Seminary,El Cajon,CA +117672,Southern California University of Health Sciences,Whittier,CA +459222,Southern California University SOMA,Los Angeles,CA +221670,Southern College of Optometry,Memphis,TN +130493,Southern Connecticut State University,New Haven,CT +139986,Southern Crescent Technical College,Griffin,GA +149222,Southern Illinois University-Carbondale,Carbondale,IL +149231,Southern Illinois University-Edwardsville,Edwardsville,IL +161545,Southern Maine Community College,South Portland,ME +228246,Southern Methodist University,Dallas,TX +206862,Southern Nazarene University,Bethany,OK +183026,Southern New Hampshire University,Manchester,NH +210146,Southern Oregon University,Ashland,OR +141097,Southern Polytechnic State University,Marietta,GA +205966,Southern State Community College,Hillsboro,OH +366553,Southern Technical College-Fort Myers,Fort Myers,FL +446552,Southern Technical College-Orlando,Orlando,FL +251260,Southern Union State Community College,Wadley,AL +160621,Southern University and A & M College,Baton Rouge,LA +160630,Southern University at New Orleans,New Orleans,LA +160649,Southern University at Shreveport,Shreveport,LA +440916,Southern University Law Center,Baton Rouge,LA +230603,Southern Utah University,Cedar City,UT +231086,Southern Vermont College,Bennington,VT +233611,Southern Virginia University,Buena Vista,VA +217776,Southern Wesleyan University,Central,SC +237817,Southern West Virginia Community and Technical College,Mount Gay,WV +233082,Southside Regional Medical Center Professional Schools,Colonial Heights,VA +233639,Southside Virginia Community College,Alberta,VA +413644,Southwest Acupuncture College-Albuquerque,Albuquerque,NM +436261,Southwest Acupuncture College-Boulder,Boulder,CO +366605,Southwest Acupuncture College-Santa Fe,Santa Fe,NM +179326,Southwest Baptist University,Bolivar,MO +420246,Southwest College of Naturopathic Medicine & Health Sciences,Tempe,AZ +382911,Southwest Collegiate Institute for the Deaf,Big Spring,TX +141158,Southwest Georgia Technical College,Thomasville,GA +442879,Southwest Institute of Healing Arts,Tempe,AZ +175078,Southwest Minnesota State University,Marshall,MN +176354,Southwest Mississippi Community College,Summit,MS +221485,Southwest Tennessee Community College,Memphis,TN +228316,Southwest Texas Junior College,Uvalde,TX +451556,Southwest University at El Paso,El Paso,TX +402776,Southwest University of Visual Arts-Albuquerque,Albuquerque,NM +104188,Southwest University of Visual Arts-Tucson,Tucson,AZ +233648,Southwest Virginia Community College,Richlands,VA +239910,Southwest Wisconsin Technical College,Fennimore,WI +228468,Southwestern Adventist University,Keene,TX +228325,Southwestern Assemblies of God University,Waxahachie,TX +228486,Southwestern Christian College,Terrell,TX +207856,Southwestern Christian University,Bethany,OK +123800,Southwestern College-Chula Vista,Chula Vista,CA +188207,Southwestern College-Santa Fe,Santa Fe,NM +155900,Southwestern College-Winfield,Winfield,KS +154396,Southwestern Community College-Creston,Creston,IA +199731,Southwestern Community College-Sylva,Sylva,NC +143215,Southwestern Illinois College,Belleville,IL +188216,Southwestern Indian Polytechnic Institute,Albuquerque,NM +123970,Southwestern Law School,Los Angeles,CA +172307,Southwestern Michigan College,Dowagiac,MI +207865,Southwestern Oklahoma State University,Weatherford,OK +210155,Southwestern Oregon Community College,Coos Bay,OR +228343,Southwestern University,Georgetown,TX +160579,SOWELA Technical Community College,Lake Charles,LA +157757,Spalding University,Louisville,KY +207254,Spartan College of Aeronautics and Technology,Tulsa,OK +218830,Spartanburg Community College,Spartanburg,SC +218821,Spartanburg Methodist College,Spartanburg,SC +141060,Spelman College,Atlanta,GA +433563,Spencerian College-Lexington,Lexington,KY +157766,Spencerian College-Louisville,Louisville,KY +148982,Spertus College,Chicago,IL +236692,Spokane Community College,Spokane,WA +236708,Spokane Falls Community College,Spokane,WA +148991,Spoon River College,Canton,IL +172334,Spring Arbor University,Spring Arbor,MI +102234,Spring Hill College,Mobile,AL +167899,Springfield College,Springfield,MA +475273,Springfield College-School of Professional and Continuing Studies,Springfield,MA +167905,Springfield Technical Community College,Springfield,MA +199698,St Andrews University,Laurinburg,NC +195155,St Bernard's School of Theology and Ministry,Rochester,NY +195164,St Bonaventure University,Saint Bonaventure,NY +175005,St Catherine University,Saint Paul,MN +262031,St Charles Community College,Cottleville,MO +172291,St Clair County Community College,Port Huron,MI +174756,St Cloud Technical and Community College,Saint Cloud,MN +195173,St Francis College,Brooklyn Heights,NY +163976,St John's College,Annapolis,MD +123855,St John's Seminary,Camarillo,CA +195809,St John's University-New York,Queens,NY +183248,St Joseph School of Nursing-Nashua,Nashua,NH +195191,St Joseph's College of Nursing at St Joseph's Hospital Health Center,Syracuse,NY +195216,St Lawrence University,Canton,NY +442426,St Louis College of Health Careers-Fenton,Fenton,MO +179511,St Louis College of Health Careers-St Louis,Saint Louis,MO +179265,St Louis College of Pharmacy,Saint Louis,MO +154262,St Luke's College,Sioux City,IA +163912,St Mary's College of Maryland,St. Mary's City,MD +228149,St Mary's University,San Antonio,TX +174844,St Olaf College,Northfield,MN +189811,St Paul's School of Nursing-Queens,Rego Park,NY +195784,St Paul's School of Nursing-Staten Island,Staten Island,NY +137078,St Petersburg College,Clearwater,FL +227854,St Philip's College,San Antonio,TX +137476,St Thomas University,Miami Gardens,FL +130448,St Vincent's College,Bridgeport,CT +207689,St. Gregory's University,Shawnee,OK +245652,St. John's College,Santa Fe,NM +148593,St. John's College-Department of Nursing,Springfield,IL +195243,St. Thomas Aquinas College,Sparkill,NY +446561,Stanbridge College,Irvine,CA +483814,Standard Healthcare Services-College of Nursing,Falls Church,VA +243744,Stanford University,Stanford,CA +199740,Stanly Community College,Albemarle,NC +205841,Stark State College,North Canton,OH +123916,Starr King School for Ministry,Berkeley,CA +135391,State College of Florida-Manatee-Sarasota,Bradenton,FL +179539,State Fair Community College,Sedalia,MO +177977,State Technical College of Missouri,Linn,MO +196176,State University of New York at New Paltz,New Paltz,NY +448600,Stautzenberger College-Brecksville,Brecksville,OH +205887,Stautzenberger College-Maumee,Maumee,OH +228431,Stephen F Austin State University,Nacogdoches,TX +179548,Stephens College,Columbia,MO +231095,Sterling College-Craftsbury Common,Craftsbury Common,VT +155937,Sterling College-Sterling,Sterling,KS +137546,Stetson University,DeLand,FL +186867,Stevens Institute of Technology,Hoboken,NJ +460899,Stevens-Henager College-Boise,Boise,ID +474906,Stevens-Henager College-Idaho Falls,Idaho Falls,ID +446677,Stevens-Henager College-Logan,Logan,UT +438151,Stevens-Henager College-Murray,Murray,UT +230630,Stevens-Henager College-Orem,Orem,UT +477950,Stevens-Henager College-St. George,St. George,UT +230621,Stevens-Henager College-West Haven,West Haven,UT +164173,Stevenson University,Stevenson,MD +178767,Stevens-The Institute of Business & Arts,Saint Louis,MO +102270,Stillman College,Tuscaloosa,AL +186876,Stockton University,Galloway,NJ +366340,Stone Child College,Box Elder,MT +167996,Stonehill College,Easton,MA +196097,Stony Brook University,Stony Brook,NY +438498,Stratford University,Fairfax,VA +450377,Strayer University-Alabama,Birmingham,AL +458885,Strayer University-Arkansas,Little Rock,AR +450298,Strayer University-Delaware,Newark,DE +131803,Strayer University-District of Columbia,Washington,DC +449038,Strayer University-Florida,Tampa,FL +458919,Strayer University-Georgia,Atlanta,GA +459994,Strayer University-Global Region,Washington,DC +458937,Strayer University-Louisiana,Metairie,LA +430184,Strayer University-Maryland,Suitland,MD +458955,Strayer University-Mississippi,Jackson,MS +453215,Strayer University-New Jersey,Cherry Hill,NJ +453163,Strayer University-North Carolina,Morrisville,NC +443784,Strayer University-Pennsylvania,Trevose,PA +458964,Strayer University-South Carolina,Greenville,SC +443766,Strayer University-Tennessee,Memphis,TN +458973,Strayer University-Texas,Austin,TX +233684,Strayer University-Virginia,Arlington,VA +456621,Strayer University-West Virginia,Scott Depot,WV +366395,Suffolk County Community College,Selden,NY +168005,Suffolk University,Boston,MA +228501,Sul Ross State University,Alpine,TX +157270,Sullivan College of Technology and Design,Louisville,KY +195988,Sullivan County Community College,Loch Sheldrake,NY +157793,Sullivan University,Louisville,KY +447953,SUM Bible College and Theological Seminary,Oakland,CA +181543,Summit Christian College,Gering,NE +208512,Sumner College,Portland,OR +196060,SUNY at Albany,Albany,NY +196079,SUNY at Binghamton,Vestal,NY +196158,SUNY at Fredonia,Fredonia,NY +196219,SUNY at Purchase College,Purchase,NY +189547,SUNY Broome Community College,Binghamton,NY +196130,SUNY Buffalo State,Buffalo,NY +196121,SUNY College at Brockport,Brockport,NY +196149,SUNY College at Cortland,Cortland,NY +196167,SUNY College at Geneseo,Geneseo,NY +196237,SUNY College at Old Westbury,Old Westbury,NY +196194,SUNY College at Oswego,Oswego,NY +196246,SUNY College at Plattsburgh,Plattsburgh,NY +196200,SUNY College at Potsdam,Potsdam,NY +196033,SUNY College of Agriculture and Technology at Cobleskill,Cobleskill,NY +196103,SUNY College of Environmental Science and Forestry,Syracuse,NY +196228,SUNY College of Optometry,New York,NY +196006,SUNY College of Technology at Alfred,Alfred,NY +196015,SUNY College of Technology at Canton,Canton,NY +196024,SUNY College of Technology at Delhi,Delhi,NY +196255,SUNY Downstate Medical Center,Brooklyn,NY +196264,SUNY Empire State College,Saratoga Springs,NY +196291,SUNY Maritime College,Throggs Neck,NY +196185,SUNY Oneonta,Oneonta,NY +196112,SUNY Polytechnic Institute,Utica,NY +197294,SUNY Westchester Community College,Valhalla,NY +199768,Surry Community College,Dobson,NC +216278,Susquehanna University,Selinsgrove,PA +247603,Sussex County Community College,Newton,NJ +216287,Swarthmore College,Swarthmore,PA +196389,Swedish Institute a College of Health Sciences,New York,NY +233718,Sweet Briar College,Sweet Briar,VA +196413,Syracuse University,Syracuse,NY +155973,Tabor College,Hillsboro,KS +236753,Tacoma Community College,Tacoma,WA +124113,Taft College,Taft,CA +454689,Taft University System,Denver,CO +102298,Talladega College,Talladega,AL +137759,Tallahassee Community College,Tallahassee,FL +137777,Talmudic College of Florida,Miami Beach,FL +186900,Talmudical Academy-New Jersey,Adelphia,NJ +196440,Talmudical Institute of Upstate New York,Rochester,NY +451404,Talmudical Seminary of Bobov,Brooklyn,NY +196431,Talmudical Seminary Oholei Torah,Brooklyn,NY +216311,Talmudical Yeshiva of Philadelphia,Philadelphia,PA +228529,Tarleton State University,Stephenville,TX +228547,Tarrant County College District,Fort Worth,TX +149310,Taylor Business Institute,Chicago,IL +449524,Taylor College,Belleview,FL +152530,Taylor University,Upland,IN +196468,Teachers College at Columbia University,New York,NY +196477,Technical Career Institutes,New York,NY +217712,Technical College of the Lowcountry,Beaufort,SC +149329,Telshe Yeshiva-Chicago,Chicago,IL +228608,Temple College,Temple,TX +216339,Temple University,Philadelphia,PA +221838,Tennessee State University,Nashville,TN +221847,Tennessee Technological University,Cookeville,TN +221856,Tennessee Temple University,Chattanooga,TN +221731,Tennessee Wesleyan College,Athens,TN +206011,Terra State Community College,Fremont,OH +228699,Texarkana College,Texarkana,TX +226152,Texas A & M International University,Laredo,TX +483036,Texas A & M University-Central Texas,Killeen,TX +228723,Texas A & M University-College Station,College Station,TX +224554,Texas A & M University-Commerce,Commerce,TX +224147,Texas A & M University-Corpus Christi,Corpus Christi,TX +228705,Texas A & M University-Kingsville,Kingsville,TX +224545,Texas A & M University-Texarkana,Texarkana,TX +228866,Texas Chiropractic College Foundation Inc,Pasadena,TX +228875,Texas Christian University,Fort Worth,TX +228884,Texas College,Tyler,TX +441487,Texas County Technical College,Houston,MO +430704,Texas Health and Science University,Austin,TX +228981,Texas Lutheran University,Seguin,TX +229063,Texas Southern University,Houston,TX +229319,Texas State Technical College-Harlingen,Harlingen,TX +408394,Texas State Technical College-Marshall,Marshall,TX +228680,Texas State Technical College-Waco,Waco,TX +229328,Texas State Technical College-West Texas,Sweetwater,TX +228459,Texas State University,San Marcos,TX +229115,Texas Tech University,Lubbock,TX +229337,Texas Tech University Health Sciences Center,Lubbock,TX +229160,Texas Wesleyan University,Fort Worth,TX +229179,Texas Woman's University,Denton,TX +216296,Thaddeus Stevens College of Technology,Lancaster,PA +138813,The Art Institute of Atlanta,Atlanta,GA +451820,The Art Institute of Austin,Austin,TX +450085,The Art Institute of Charleston,Charleston,SC +197832,The Art Institute of Charlotte,Charlotte,NC +200624,The Art Institute of Cincinnati-AIC College of Design,Cincinnati,OH +126702,The Art Institute of Colorado,Denver,CO +132338,The Art Institute of Fort Lauderdale,Fort Lauderdale,FL +222938,The Art Institute of Houston,Houston,TX +448345,The Art Institute of Indianapolis,Indianapolis,IN +182111,The Art Institute of Las Vegas,Henderson,NV +451796,The Art Institute of Michigan,Novi,MI +365055,The Art Institute of New York City,New York,NY +446668,The Art Institute of Ohio-Cincinnati,Cincinnati,OH +210942,The Art Institute of Philadelphia,Philadelphia,PA +428444,The Art Institute of Phoenix,Phoenix,AZ +210960,The Art Institute of Pittsburgh,Pittsburgh,PA +451662,The Art Institute of Pittsburgh-Online Division,Pittsburgh,PA +208239,The Art Institute of Portland,Portland,OR +452027,The Art Institute of Raleigh-Durham,Durham,NC +450049,The Art Institute of Salt Lake City,Draper,UT +458982,The Art Institute of San Antonio,San Antonio,TX +234492,The Art Institute of Seattle,Seattle,WA +482398,The Art Institute of St Louis,St Charles,MO +449010,The Art Institute of Tennessee-Nashville,Nashville,TN +444927,The Art Institute of Tucson,Tucson,AZ +458496,The Art Institute of Virginia Beach,Virginia Beach,VA +440341,The Art Institute of Washington,Arlington,VA +456010,The Art Institute of Washington-Dulles,Sterling,VA +470092,The Art Institute of Wisconsin,Milwaukee,WI +452018,The Art Institutes International–Kansas City,Lenexa,KS +173887,The Art Institutes International-Minnesota,Minneapolis,MN +210906,The Art Institutes of York-PA,York,PA +132408,The Baptist College of Florida,Graceville,FL +164933,The Boston Conservatory,Boston,MA +111188,The California Maritime Academy,Vallejo,CA +143978,The Chicago School of Professional Psychology at Chicago,Chicago,IL +455433,The Chicago School of Professional Psychology at Irvine,Irvine,CA +455664,The Chicago School of Professional Psychology at Los Angeles,Los Angeles,CA +459745,The Chicago School of Professional Psychology at Washington DC,Washington,DC +455682,The Chicago School of Professional Psychology at Westwood,Los Angeles,CA +201821,The Christ College of Nursing and Health Sciences,Cincinnati,OH +437635,The College of Health Care Professions-Austin,Austin,TX +480824,The College of Health Care Professions-Dallas,Dallas,TX +480833,The College of Health Care Professions-Fort Worth,Fort Worth,TX +142294,The College of Idaho,Caldwell,ID +187134,The College of New Jersey,Ewing,NJ +193645,The College of New Rochelle,New Rochelle,NY +195234,The College of Saint Rose,Albany,NY +174899,The College of Saint Scholastica,Duluth,MN +197285,The College of Westchester,White Plains,NY +206589,The College of Wooster,Wooster,OH +456542,The Commonwealth Medical College,Scranton,PA +434672,The Community College of Baltimore County,Baltimore,MD +430485,The Creative Center,Omaha,NE +235167,The Evergreen State College,Olympia,WA +191320,The General Theological Seminary,New York,NY +148177,The Illinois Institute of Art-Chicago,Chicago,IL +428286,The Illinois Institute of Art-Schaumburg,Schaumburg,IL +146241,The John Marshall Law School,Chicago,IL +192110,The Juilliard School,New York,NY +454184,The King’s College,New York,NY +439701,The King's University,Southlake,TX +161208,The Landing School,Arundel,ME +213598,The Lincoln University,Lincoln University,PA +117751,The Master's College and Seminary,Santa Clarita,CA +119544,The National Hispanic University,San Jose,CA +167057,The New England Conservatory of Music,Boston,MA +167321,The New England Institute of Art,Brookline,MA +193654,The New School,New York,NY +215637,The Restaurant School at Walnut Hill College,Philadelphia,PA +448804,The Robert B Miller College,Battle Creek,MI +195128,The Sage Colleges,Troy,NY +475228,The Santa Barbara and Ventura Colleges of Law–Santa Barbara,Santa Barbara,CA +125037,The Santa Barbara and Ventura Colleges of Law-Ventura,Ventura,CA +441131,The Seattle School of Theology & Psychology,Seattle,WA +157748,The Southern Baptist Theological Seminary,Louisville,KY +100751,The University of Alabama,Tuscaloosa,AL +202763,The University of Findlay,Findlay,OH +180489,The University of Montana,Missoula,MT +180692,The University of Montana-Western,Dillon,MT +137847,The University of Tampa,Tampa,FL +221740,The University of Tennessee-Chattanooga,Chattanooga,TN +221759,The University of Tennessee-Knoxville,Knoxville,TN +221768,The University of Tennessee-Martin,Martin,TN +227368,The University of Texas - Rio Grande Valley,Edinburg,TX +228769,The University of Texas at Arlington,Arlington,TX +228778,The University of Texas at Austin,Austin,TX +228787,The University of Texas at Dallas,Richardson,TX +228796,The University of Texas at El Paso,El Paso,TX +229027,The University of Texas at San Antonio,San Antonio,TX +228802,The University of Texas at Tyler,Tyler,TX +229300,The University of Texas Health Science Center at Houston,Houston,TX +228644,The University of Texas Health Science Center at San Antonio,San Antonio,TX +416801,The University of Texas MD Anderson Cancer Center,Houston,TX +228653,The University of Texas Medical Branch,Galveston,TX +229018,The University of Texas of the Permian Basin,Odessa,TX +215105,The University of the Arts,Philadelphia,PA +233897,The University of Virginia's College at Wise,Wise,VA +138354,The University of West Florida,Pensacola,FL +126012,The Wright Institute,Berkeley,CA +216357,Thiel College,Greenville,PA +124292,Thomas Aquinas College,Santa Paula,CA +161563,Thomas College,Waterville,ME +187046,Thomas Edison State University,Trenton,NJ +126049,Thomas Jefferson School of Law,San Diego,CA +216366,Thomas Jefferson University,Philadelphia,PA +157809,Thomas More College,Crestview Hills,KY +183275,Thomas More College of Liberal Arts,Merrimack,NH +233754,Thomas Nelson Community College,Hampton,VA +141167,Thomas University,Thomasville,GA +129808,Three Rivers Community College-Norwich,Norwich,CT +179645,Three Rivers Community College-Poplar Bluff,Poplar Bluff,MO +103778,Thunderbird School of Global Management,Glendale,AZ +233772,Tidewater Community College,Norfolk,VA +206048,Tiffin University,Tiffin,OH +420723,Tillamook Bay Community College,Tillamook,OR +141185,Toccoa Falls College,Toccoa Falls,GA +442781,Tohono O'Odham Community College,Sells,AZ +196565,Tompkins Cortland Community College,Dryden,NY +196583,Torah Temimah Talmudical Seminary,Brooklyn,NY +176406,Tougaloo College,Tougaloo,MS +196592,Touro College,New York,NY +459736,Touro University California,Vallejo,CA +459824,Touro University Nevada,Henderson,NV +459727,Touro University Worldwide,Los Alamitos,CA +164076,Towson University,Towson,MD +157818,Transylvania University,Lexington,KY +210234,Treasure Valley Community College,Ontario,OR +221892,Trevecca Nazarene University,Nashville,TN +448859,Triangle Tech Inc-Bethlehem,Bethlehem,PA +216454,Triangle Tech Inc-Dubois,Falls Creek,PA +216427,Triangle Tech Inc-Erie,Erie,PA +216445,Triangle Tech Inc-Greensburg,Greensburg,PA +216436,Triangle Tech Inc-Pittsburgh,Pittsburgh,PA +443377,Triangle Tech Inc-Sunbury,Sunbury,PA +460747,Tribeca Flashpoint College,Chicago,IL +199795,Tri-County Community College,Murphy,NC +218885,Tri-County Technical College,Pendleton,SC +218894,Trident Technical College,Charleston,SC +450979,Trident University International,Cypress,CA +152567,Trine University,Angola,IN +414878,Trine University-Regional/Non-Traditional Campuses,Fort Wayne,IN +128258,Trinidad State Junior College,Trinidad,CO +137953,Trinity Baptist College,Jacksonville,FL +200484,Trinity Bible College,Ellendale,ND +149505,Trinity Christian College,Palos Heights,IL +130590,Trinity College,Hartford,CT +137962,Trinity College of Florida,Trinity,FL +146755,Trinity College of Nursing & Health Sciences,Rock Island,IL +216463,Trinity Episcopal School for Ministry,Ambridge,PA +135610,Trinity International University-Florida,Davie,FL +149514,Trinity International University-Illinois,Deerfield,IL +123448,Trinity Law School,Santa Ana,CA +235769,Trinity Lutheran College,Everett,WA +206215,Trinity Lutheran Seminary,Columbus,OH +229267,Trinity University,San Antonio,TX +225308,Trinity Valley Community College,Athens,TX +131876,Trinity Washington University,Washington,DC +206154,Tri-State Bible College,South Point,OH +130581,Tri-State College of Acupuncture,New York,NY +149532,Triton College,River Grove,IL +196653,Trocaire College,Buffalo,NY +102368,Troy University,Troy,AL +182500,Truckee Meadows Community College,Reno,NV +141237,Truett-McConnell College,Cleveland,GA +178615,Truman State University,Kirksville,MO +206224,Trumbull Business College,Warren,OH +168148,Tufts University,Medford,MA +160755,Tulane University of Louisiana,New Orleans,LA +207935,Tulsa Community College,Tulsa,OK +207962,Tulsa Welding School-Tulsa-Tulsa,Tulsa,OK +130606,Tunxis Community College,Farmington,CT +200527,Turtle Mountain Community College,Belcourt,ND +221953,Tusculum College,Greeneville,TN +102377,Tuskegee University,Tuskegee,AL +229355,Tyler Junior College,Tyler,TX +196699,Ulster County Community College,Stone Ridge,NY +441371,Ultimate Medical Academy-Clearwater,Clearwater,FL +450173,Ultimate Medical Academy-Tampa,Tampa,FL +481252,Ultrasound Medical Institute,Royal Palm Beach,FL +210270,Umpqua Community College,Roseburg,OR +246789,Unification Theological Seminary,Barrytown,NY +157863,Union College-Barbourville,Barbourville,KY +181738,Union College-Lincoln,Lincoln,NE +196866,Union College-Schenectady,Schenectady,NY +187198,Union County College,Cranford,NJ +446932,Union Graduate College,Schenectady,NY +206279,Union Institute & University,Cincinnati,OH +233842,Union Presbyterian Seminary,Richmond,VA +196884,Union Theological Seminary in the City of New York,New York,NY +221971,Union University,Jackson,TN +124681,United Education Institute-Huntington Park Campus,Huntington Park,CA +128328,United States Air Force Academy,USAFA,CO +130624,United States Coast Guard Academy,New London,CT +197027,United States Merchant Marine Academy,Kings Point,NY +197036,United States Military Academy,West Point,NY +164155,United States Naval Academy,Annapolis,MD +102395,United States Sports Academy,Daphne,AL +447050,United States University,Chula Vista,CA +197018,United Talmudical Seminary,Brooklyn,NY +206288,United Theological Seminary,Dayton,OH +175139,United Theological Seminary of the Twin Cities,New Brighton,MN +200554,United Tribes Technical College,Bismarck,ND +459204,Unitek College,Fremont,CA +161572,Unity College,Unity,ME +446598,Universal College of Healing Arts,Omaha,NE +106041,Universal Technical Institute of Arizona Inc,Avondale,AZ +376385,Universal Technology College of Puerto Rico,Aguadilla,PR +241191,Universidad Adventista de las Antillas,Mayaguez,PR +241225,Universidad Central de Bayamon,Bayamón,PR +243568,Universidad Central Del Caribe,Bayamon,PR +243346,Universidad Del Este,Carolina,PR +243443,Universidad del Sagrado Corazon,Santurce,PR +243601,Universidad Del Turabo,Gurabo,PR +475811,Universidad Internacional Iberoamericana,Arecibo,PR +241739,Universidad Metropolitana,Cupey,PR +441690,Universidad Pentecostal Mizpa,Rio Piedras,PR +243577,Universidad Politecnica de Puerto Rico,Hato Rey,PR +241614,Universidad Teologica del Caribe,Trujillo Alto,PR +196088,University at Buffalo,Buffalo,NY +363934,University of Advancing Technology,Tempe,AZ +200800,University of Akron Main Campus,Akron,OH +200846,University of Akron Wayne College,Orrville,OH +100663,University of Alabama at Birmingham,Birmingham,AL +100706,University of Alabama in Huntsville,Huntsville,AL +102553,University of Alaska Anchorage,Anchorage,AK +102614,University of Alaska Fairbanks,Fairbanks,AK +102632,University of Alaska Southeast,Juneau,AK +442930,University of Antelope Valley,Lancaster,CA +104179,University of Arizona,Tucson,AZ +106397,University of Arkansas,Fayetteville,AR +106245,University of Arkansas at Little Rock,Little Rock,AR +106485,University of Arkansas at Monticello,Monticello,AR +106412,University of Arkansas at Pine Bluff,Pine Bluff,AR +106999,University of Arkansas Community College-Batesville,Batesville,AR +107725,University of Arkansas Community College-Hope,Hope,AR +107585,University of Arkansas Community College-Morrilton,Morrilton,AR +106263,University of Arkansas for Medical Sciences,Little Rock,AR +108092,University of Arkansas-Fort Smith,Fort Smith,AR +161873,University of Baltimore,Baltimore,MD +128744,University of Bridgeport,Bridgeport,CT +110635,University of California-Berkeley,Berkeley,CA +110644,University of California-Davis,Davis,CA +110398,University of California-Hastings College of Law,San Francisco,CA +110653,University of California-Irvine,Irvine,CA +110662,University of California-Los Angeles,Los Angeles,CA +445188,University of California-Merced,Merced,CA +110671,University of California-Riverside,Riverside,CA +110680,University of California-San Diego,La Jolla,CA +110699,University of California-San Francisco,San Francisco,CA +110705,University of California-Santa Barbara,Santa Barbara,CA +110714,University of California-Santa Cruz,Santa Cruz,CA +106704,University of Central Arkansas,Conway,AR +132903,University of Central Florida,Orlando,FL +176965,University of Central Missouri,Warrensburg,MO +206941,University of Central Oklahoma,Edmond,OK +237312,University of Charleston,Charleston,WV +144050,University of Chicago,Chicago,IL +201955,University of Cincinnati-Blue Ash College,Blue Ash,OH +201946,University of Cincinnati-Clermont College,Batavia,OH +201885,University of Cincinnati-Main Campus,Cincinnati,OH +126614,University of Colorado Boulder,Boulder,CO +126580,University of Colorado Colorado Springs,Colorado Springs,CO +126562,University of Colorado Denver,Denver,CO +129020,University of Connecticut,Storrs,CT +224323,University of Dallas,Irving,TX +202480,University of Dayton,Dayton,OH +130943,University of Delaware,Newark,DE +127060,University of Denver,Denver,CO +169716,University of Detroit Mercy,Detroit,MI +153278,University of Dubuque,Dubuque,IA +447801,University of East-West Medicine,Sunnyvale,CA +150534,University of Evansville,Evansville,IN +134130,University of Florida,Gainesville,FL +457402,University of Fort Lauderdale,Lauderhill,FL +139959,University of Georgia,Athens,GA +180258,University of Great Falls,Great Falls,MT +240754,University of Guam,Mangilao,GU +129525,University of Hartford,West Hartford,CT +141565,University of Hawaii at Hilo,Hilo,HI +141574,University of Hawaii at Manoa,Honolulu,HI +141839,University of Hawaii Maui College,Kahului,HI +141981,University of Hawaii-West Oahu,Kapolei,HI +160065,University of Holy Cross,New Orleans,LA +225511,University of Houston,Houston,TX +225414,University of Houston-Clear Lake,Houston,TX +225432,University of Houston-Downtown,Houston,TX +225502,University of Houston-Victoria,Victoria,TX +142285,University of Idaho,Moscow,ID +145600,University of Illinois at Chicago,Chicago,IL +148654,University of Illinois at Springfield,Springfield,IL +145637,University of Illinois at Urbana-Champaign,Champaign,IL +151263,University of Indianapolis,Indianapolis,IN +153658,University of Iowa,Iowa City,IA +200156,University of Jamestown,Jamestown,ND +155317,University of Kansas,Lawrence,KS +157085,University of Kentucky,Lexington,KY +117140,University of La Verne,La Verne,CA +160658,University of Louisiana at Lafayette,Lafayette,LA +159993,University of Louisiana at Monroe,Monroe,LA +157289,University of Louisville,Louisville,KY +161253,University of Maine,Orono,ME +161217,University of Maine at Augusta,Augusta,ME +161226,University of Maine at Farmington,Farmington,ME +161235,University of Maine at Fort Kent,Fort Kent,ME +161244,University of Maine at Machias,Machias,ME +161341,University of Maine at Presque Isle,Presque Isle,ME +437097,University of Management and Technology,Arlington,VA +200217,University of Mary,Bismarck,ND +226471,University of Mary Hardin-Baylor,Belton,TX +232681,University of Mary Washington,Fredericksburg,VA +163338,University of Maryland Eastern Shore,Princess Anne,MD +163259,University of Maryland-Baltimore,Baltimore,MD +163268,University of Maryland-Baltimore County,Baltimore,MD +163286,University of Maryland-College Park,College Park,MD +163204,University of Maryland-University College,Adelphi,MD +166708,University of Massachusetts Medical School Worcester,Worcester,MA +166629,University of Massachusetts-Amherst,Amherst,MA +166638,University of Massachusetts-Boston,Boston,MA +167987,University of Massachusetts-Dartmouth,North Dartmouth,MA +166513,University of Massachusetts-Lowell,Lowell,MA +220862,University of Memphis,Memphis,TN +135726,University of Miami,Coral Gables,FL +170976,University of Michigan-Ann Arbor,Ann Arbor,MI +171137,University of Michigan-Dearborn,Dearborn,MI +171146,University of Michigan-Flint,Flint,MI +174075,University of Minnesota-Crookston,Crookston,MN +174233,University of Minnesota-Duluth,Duluth,MN +174251,University of Minnesota-Morris,Morris,MN +456959,University of Minnesota-Rochester,Rochester,MN +174066,University of Minnesota-Twin Cities,Minneapolis,MN +176017,University of Mississippi,University,MS +178396,University of Missouri-Columbia,Columbia,MO +178402,University of Missouri-Kansas City,Kansas City,MO +178420,University of Missouri-St Louis,Saint Louis,MO +101693,University of Mobile,Mobile,AL +101709,University of Montevallo,Montevallo,AL +199069,University of Mount Olive,Mount Olive,NC +204185,University of Mount Union,Alliance,OH +181215,University of Nebraska at Kearney,Kearney,NE +181394,University of Nebraska at Omaha,Omaha,NE +181428,University of Nebraska Medical Center,Omaha,NE +181464,University of Nebraska-Lincoln,Lincoln,NE +182281,University of Nevada-Las Vegas,Las Vegas,NV +182290,University of Nevada-Reno,Reno,NV +161457,University of New England,Biddeford,ME +183071,University of New Hampshire at Manchester,Manchester,NH +183044,University of New Hampshire-Main Campus,Durham,NH +182829,University of New Hampshire-School of Law,Concord,NH +129941,University of New Haven,West Haven,CT +187958,University of New Mexico-Gallup Campus,Gallup,NM +187976,University of New Mexico-Los Alamos Campus,Los Alamos,NM +187985,University of New Mexico-Main Campus,Albuquerque,NM +188225,University of New Mexico-Taos Campus,Ranchos de Taos,NM +188049,University of New Mexico-Valencia County Campus,Los Lunas,NM +159939,University of New Orleans,New Orleans,LA +101879,University of North Alabama,Florence,AL +199111,University of North Carolina at Asheville,Asheville,NC +199120,University of North Carolina at Chapel Hill,Chapel Hill,NC +199139,University of North Carolina at Charlotte,Charlotte,NC +199148,University of North Carolina at Greensboro,Greensboro,NC +199281,University of North Carolina at Pembroke,Pembroke,NC +199184,University of North Carolina School of the Arts,Winston-Salem,NC +199218,University of North Carolina Wilmington,Wilmington,NC +200280,University of North Dakota,Grand Forks,ND +136172,University of North Florida,Jacksonville,FL +482680,University of North Georgia,Dahlonega,GA +227216,University of North Texas,Denton,TX +484905,University of North Texas at Dallas,Dallas,TX +228909,University of North Texas Health Science Center,Fort Worth,TX +127741,University of Northern Colorado,Greeley,CO +154095,University of Northern Iowa,Cedar Falls,IA +204486,University of Northwestern Ohio,Lima,OH +174491,University of Northwestern-St Paul,Saint Paul,MN +152080,University of Notre Dame,Notre Dame,IN +207342,University of Oklahoma-Health Sciences Center,Oklahoma City,OK +207500,University of Oklahoma-Norman Campus,Norman,OK +209551,University of Oregon,Eugene,OR +215062,University of Pennsylvania,Philadelphia,PA +450456,University of Phoenix-Alabama,Birmingham,AL +484613,University of Phoenix-Arizona,Tempe,AZ +484622,University of Phoenix-Arkansas,Little Rock,AR +484631,University of Phoenix-California,Costa Mesa,CA +484640,University of Phoenix-Colorado,Lone Tree,CO +448822,University of Phoenix-Connecticut,Norwalk,CT +484668,University of Phoenix-Florida,Orlando,FL +484677,University of Phoenix-Georgia,Sandy Springs,GA +420042,University of Phoenix-Hawaii,Honolulu,HI +440466,University of Phoenix-Idaho,Meridian,ID +442161,University of Phoenix-Illinois,Schaumburg,IL +443544,University of Phoenix-Indiana,Indianapolis,IN +446729,University of Phoenix-Iowa,Des Moines,IA +445391,University of Phoenix-Kentucky,Louisville,KY +484686,University of Phoenix-Louisiana,Baton Rouge,LA +434973,University of Phoenix-Maryland,Columbia,MD +440420,University of Phoenix-Massachusetts,Braintree,MA +484695,University of Phoenix-Michigan,Southfield,MI +445319,University of Phoenix-Minnesota,Saint Louis Park,MN +462390,University of Phoenix-Mississippi,Flowood,MS +484701,University of Phoenix-Missouri,Saint Louis,MO +484710,University of Phoenix-Nevada,Las Vegas,NV +445300,University of Phoenix-New Jersey,Jersey City,NJ +405997,University of Phoenix-New Mexico,Albuquerque,NM +484729,University of Phoenix-North Carolina,Charlotte,NC +439297,University of Phoenix-Ohio,Beachwood,OH +484738,University of Phoenix-Oklahoma,Oklahoma City,OK +432241,University of Phoenix-Oregon,Tigard,OR +484783,University of Phoenix-Pennsylvania,Philadelphia,PA +382063,University of Phoenix-Puerto Rico,Guaynabo,PR +448567,University of Phoenix-South Carolina,Columbia,SC +484747,University of Phoenix-Tennessee,Nashville,TN +484756,University of Phoenix-Texas,Houston,TX +380465,University of Phoenix-Utah,Salt Lake City,UT +484765,University of Phoenix-Virginia,Glen Allen,VA +432223,University of Phoenix-Washington,Tukwila,WA +450483,University of Phoenix-Washington DC,Washington,DC +440457,University of Phoenix-Wisconsin,Milwaukee,WI +157535,University of Pikeville,Pikeville,KY +215266,University of Pittsburgh-Bradford,Bradford,PA +215275,University of Pittsburgh-Greensburg,Greensburg,PA +215284,University of Pittsburgh-Johnstown,Johnstown,PA +215293,University of Pittsburgh-Pittsburgh Campus,Pittsburgh,PA +215309,University of Pittsburgh-Titusville,Titusville,PA +209825,University of Portland,Portland,OR +243106,University of Puerto Rico-Aguadilla,Ramey,PR +243115,University of Puerto Rico-Arecibo,Arecibo,PR +243133,University of Puerto Rico-Bayamon,Bayamon,PR +243142,University of Puerto Rico-Carolina,Carolina,PR +243151,University of Puerto Rico-Cayey,Cayey,PR +243179,University of Puerto Rico-Humacao,Humacao,PR +243197,University of Puerto Rico-Mayaguez,Mayaguez,PR +243203,University of Puerto Rico-Medical Sciences,San Juan,PR +243212,University of Puerto Rico-Ponce,Ponce,PR +243221,University of Puerto Rico-Rio Piedras,San Juan,PR +243188,University of Puerto Rico-Utuado,Utuado,PR +236328,University of Puget Sound,Tacoma,WA +121691,University of Redlands,Redlands,CA +217484,University of Rhode Island,Kingston,RI +233374,University of Richmond,University of Richmond,VA +205203,University of Rio Grande,Rio Grande,OH +195030,University of Rochester,Rochester,NY +152336,University of Saint Francis-Fort Wayne,Fort Wayne,IN +130314,University of Saint Joseph,West Hartford,CT +155812,University of Saint Mary,Leavenworth,KS +148885,University of Saint Mary of the Lake,Mundelein,IL +122436,University of San Diego,San Diego,CA +122612,University of San Francisco,San Francisco,CA +207722,University of Science and Arts of Oklahoma,Chickasha,OK +215929,University of Scranton,Scranton,PA +219383,University of Sioux Falls,Sioux Falls,SD +102094,University of South Alabama,Mobile,AL +218645,University of South Carolina-Aiken,Aiken,SC +218654,University of South Carolina-Beaufort,Bluffton,SC +218663,University of South Carolina-Columbia,Columbia,SC +218672,University of South Carolina-Lancaster,Lancaster,SC +218681,University of South Carolina-Salkehatchie,Allendale,SC +218690,University of South Carolina-Sumter,Sumter,SC +218706,University of South Carolina-Union,Union,SC +218742,University of South Carolina-Upstate,Spartanburg,SC +219471,University of South Dakota,Vermillion,SD +137351,University of South Florida-Main Campus,Tampa,FL +451671,University of South Florida-Sarasota-Manatee,Sarasota,FL +448840,University of South Florida-St Petersburg,St. Petersburg,FL +123961,University of Southern California,Los Angeles,CA +151306,University of Southern Indiana,Evansville,IN +161554,University of Southern Maine,Portland,ME +176372,University of Southern Mississippi,Hattiesburg,MS +134121,University of Southernmost Florida,Jacksonville,FL +367954,University of St Augustine for Health Sciences,San Marcos,CA +148584,University of St Francis,Joliet,IL +227863,University of St Thomas-Houston,Houston,TX +174914,University of St Thomas-Saint Paul,Saint Paul,MN +228635,University of Texas Southwestern Medical Center,Dallas,TX +156541,University of the Cumberlands,Williamsburg,KY +131399,University of the District of Columbia,Washington,DC +363721,University of the District of Columbia-David A Clarke School of Law,Washington,DC +225627,University of the Incarnate Word,San Antonio,TX +107558,University of the Ozarks,Clarksville,AR +120883,University of the Pacific,Stockton,CA +442639,University of the Potomac-VA Campus,Vienna,VA +384412,University of the Potomac-Washington DC Campus,Washington,DC +441308,University of the Rockies,Colorado Springs,CO +215132,University of the Sciences,Philadelphia,PA +188182,University of the Southwest,Hobbs,NM +243665,University of the Virgin Islands,Charlotte Amalie,VI +449870,University of the West,Rosemead,CA +206084,University of Toledo,Toledo,OH +207971,University of Tulsa,Tulsa,OK +230764,University of Utah,Salt Lake City,UT +216542,University of Valley Forge,Phoenixville,PA +231174,University of Vermont,Burlington,VT +234076,University of Virginia-Main Campus,Charlottesville,VA +377555,University of Washington-Bothell Campus,Bothell,WA +236948,University of Washington-Seattle Campus,Seattle,WA +377564,University of Washington-Tacoma Campus,Tacoma,WA +101587,University of West Alabama,Livingston,AL +141334,University of West Georgia,Carrollton,GA +210438,University of Western States,Portland,OR +240055,University of Wisconsin Colleges,Madison,WI +240268,University of Wisconsin-Eau Claire,Eau Claire,WI +240277,University of Wisconsin-Green Bay,Green Bay,WI +240329,University of Wisconsin-La Crosse,La Crosse,WI +240444,University of Wisconsin-Madison,Madison,WI +240453,University of Wisconsin-Milwaukee,Milwaukee,WI +240365,University of Wisconsin-Oshkosh,Oshkosh,WI +240374,University of Wisconsin-Parkside,Kenosha,WI +240462,University of Wisconsin-Platteville,Platteville,WI +240471,University of Wisconsin-River Falls,River Falls,WI +240480,University of Wisconsin-Stevens Point,Stevens Point,WI +240417,University of Wisconsin-Stout,Menomonie,WI +240426,University of Wisconsin-Superior,Superior,WI +240189,University of Wisconsin-Whitewater,Whitewater,WI +240727,University of Wyoming,Laramie,WY +154493,Upper Iowa University,Fayette,IA +196307,Upstate Medical University,Syracuse,NY +429128,Urban College of Boston,Boston,MA +206330,Urbana University,Urbana,OH +455099,Urshan Graduate School of Theology,Florissant,MO +216524,Ursinus College,Collegeville,PA +206349,Ursuline College,Pepper Pike,OH +446604,Uta Mesivta of Kiryas Joel,Monroe,NY +230728,Utah State University,Logan,UT +230737,Utah Valley University,Orem,UT +197045,Utica College,Utica,NY +197081,Utica School of Commerce,Utica,NY +141264,Valdosta State University,Valdosta,GA +138187,Valencia College,Orlando,FL +200572,Valley City State University,Valley City,ND +377652,Valley College-Beckley,Beckley,WV +152600,Valparaiso University,Valparaiso,IN +199838,Vance-Granville Community College,Henderson,NC +221999,Vanderbilt University,Nashville,TN +149639,VanderCook College of Music,Chicago,IL +123651,Vanguard University of Southern California,Costa Mesa,CA +197133,Vassar College,Poughkeepsie,NY +455567,Vatterott College-Appling Farms,Memphis,TN +245342,Vatterott College-Berkeley,Berkeley,MO +442408,Vatterott College-Cleveland,Broadview Heights,OH +373058,Vatterott College-Des Moines,Des Moines,IA +440873,Vatterott College-Dividend,Memphis,TN +481988,Vatterott College-ex'treme Institute by Nelly-St Louis,St. Louis,MO +404374,Vatterott College-Joplin,Joplin,MO +404383,Vatterott College-Kansas City,Kansas City,MO +437060,Vatterott College-Oklahoma City,Warr Acres,OK +148140,Vatterott College-Quincy,Quincy,IL +181756,Vatterott College-Spring Valley,Omaha,NE +404365,Vatterott College-Springfield,Springfield,MO +445559,Vatterott College-St Charles,St Charles,MO +436182,Vatterott College-St Joseph,Saint Joseph,MO +436191,Vatterott College-Sunset Hills,Sunset Hills,MO +440882,Vatterott College-Tulsa,Tulsa,OK +440891,Vatterott College-Wichita,Wichita,KS +188340,Vaughn College of Aeronautics and Technology,Flushing,NY +125028,Ventura College,Ventura,CA +175157,Vermilion Community College,Ely,MN +455992,Vermont College of Fine Arts,Montpelier,VT +231147,Vermont Law School,South Royalton,VT +231165,Vermont Technical College,Randolph Center,VT +229504,Vernon College,Vernon,TX +213914,Vet Tech Institute,Pittsburgh,PA +223472,Vet Tech Institute of Houston,Houston,TX +125091,Victor Valley College,Victorville,CA +229540,Victoria College,Victoria,TX +197142,Villa Maria College,Buffalo,NY +216597,Villanova University,Villanova,PA +152637,Vincennes University,Vincennes,IN +482228,Virginia Baptist College,Fredericksburg,VA +458256,Virginia College-Augusta,Augusta,GA +441928,Virginia College-Austin,Austin,TX +460774,Virginia College-Baton Rouge,Baton Rouge,LA +450191,Virginia College-Biloxi,Biloxi,MS +420307,Virginia College-Birmingham,Birmingham,AL +456056,Virginia College-Charleston,North Charleston,SC +458593,Virginia College-Columbia,Columbia,SC +475370,Virginia College-Columbus,Columbus,GA +480107,Virginia College-Florence,Florence,SC +454625,Virginia College-Greenville,Greenville,SC +420316,Virginia College-Huntsville,Huntsville,AL +441919,Virginia College-Jackson,Jackson,MS +455716,Virginia College-Jacksonville,Jacksonville,FL +475617,Virginia College-Knoxville,Knoxville,TN +460844,Virginia College-Macon,Macon,GA +445090,Virginia College-Mobile,Mobile,AL +452115,Virginia College-Montgomery,Montgomery,AL +389727,Virginia College-Pensacola,Pensacola,FL +460923,Virginia College-Richmond,Richmond,VA +475352,Virginia College-Savannah,Savannah,GA +450289,Virginia College-School of Business and Health-Chattanooga,Chattanooga,TN +475866,Virginia College-Shreveport Bossier City,Bossier City,LA +460853,Virginia College-Spartanburg,Spartanburg,SC +475592,Virginia College-Tulsa,Tulsa,OK +234030,Virginia Commonwealth University,Richmond,VA +233903,Virginia Highlands Community College,Abingdon,VA +206394,Virginia Marti College of Art and Design,Lakewood,OH +234085,Virginia Military Institute,Lexington,VA +233921,Virginia Polytechnic Institute and State University,Blacksburg,VA +234155,Virginia State University,Petersburg,VA +459082,Virginia Tech Carilion School of Medicine,Roanoke,VA +234164,Virginia Union University,Richmond,VA +234137,Virginia University of Lynchburg,Lynchburg,VA +234173,Virginia Wesleyan College,Norfolk,VA +233949,Virginia Western Community College,Roanoke,VA +449764,Visible Music College,Memphis,TN +365204,Vista College,El Paso,TX +377342,Vista College-Online,Clearfield,UT +240107,Viterbo University,La Crosse,WI +222053,Volunteer State Community College,Gallatin,TN +218919,Voorhees College,Denmark,SC +152673,Wabash College,Crawfordsville,IN +403487,Wabash Valley College,Mount Carmel,IL +226879,Wade College,Dallas,TX +197197,Wagner College,Staten Island,NY +199847,Wake Forest University,Winston Salem,NC +199856,Wake Technical Community College,Raleigh,NC +125231,Walden University,Minneapolis,MN +154518,Waldorf College,Forest City,IA +236887,Walla Walla Community College,Walla Walla,WA +236896,Walla Walla University,College Place,WA +172608,Walsh College of Accountancy and Business Administration,Troy,MI +206437,Walsh University,North Canton,OH +222062,Walters State Community College,Morristown,TN +210304,Warner Pacific College,Portland,OR +480198,Warner Pacific College Adult Degree Program,Portland,OR +138275,Warner University,Lake Wales,FL +245625,Warren County Community College,Washington,NJ +199865,Warren Wilson College,Swannanoa,NC +154527,Wartburg College,Waverly,IA +154536,Wartburg Theological Seminary,Dubuque,IA +156082,Washburn University,Topeka,KS +216667,Washington & Jefferson College,Washington,PA +162210,Washington Adventist University,Takoma Park,MD +234207,Washington and Lee University,Lexington,VA +164216,Washington College,Chestertown,MD +161581,Washington County Community College,Calais,ME +206446,Washington State Community College,Marietta,OH +236939,Washington State University,Pullman,WA +179867,Washington University in St Louis,Saint Louis,MO +172617,Washtenaw Community College,Ann Arbor,MI +392840,Watkins College of Art Design & Film,Nashville,TN +149727,Waubonsee Community College,Sugar Grove,IL +240125,Waukesha County Technical College,Pewaukee,WI +229780,Wayland Baptist University,Plainview,TX +199892,Wayne Community College,Goldsboro,NC +172635,Wayne County Community College District,Detroit,MI +181783,Wayne State College,Wayne,NE +172644,Wayne State University,Detroit,MI +216694,Waynesburg University,Waynesburg,PA +229799,Weatherford College,Weatherford,TX +197221,Webb Institute,Glen Cove,NY +138293,Webber International University,Babson Park,FL +230782,Weber State University,Ogden,UT +179894,Webster University,Saint Louis,MO +190424,Weill Cornell Medicine,New York,NY +220206,Welch College,Nashville,TN +168218,Wellesley College,Wellesley,MA +197230,Wells College,Aurora,NY +447999,WellSpring School of Allied Health-Kansas City,Kansas City,MO +236975,Wenatchee Valley College,Wenatchee,WA +168227,Wentworth Institute of Technology,Boston,MA +179919,Wentworth Military Academy and College,Lexington,MO +176451,Wesley Biblical Seminary,Jackson,MS +131098,Wesley College,Dover,DE +131973,Wesley Theological Seminary,Washington,DC +141325,Wesleyan College,Macon,GA +130697,Wesleyan University,Middletown,CT +216764,West Chester University of Pennsylvania,West Chester,PA +441229,West Coast Ultrasound Institute,Beverly Hills,CA +477039,West Coast University-Dallas,Dallas,TX +443331,West Coast University-Los Angeles,North Hollywood,CA +458229,West Coast University-Ontario,Ontario,CA +458210,West Coast University-Orange County,Anaheim,CA +139278,West Georgia Technical College,Waco,GA +125462,West Hills College-Coalinga,Coalinga,CA +448594,West Hills College-Lemoore,Lemoore,CA +157483,West Kentucky Community and Technical College,Paducah,KY +237932,West Liberty University,West Liberty,WV +125471,West Los Angeles College,Culver City,CA +172671,West Shore Community College,Scottville,MI +222099,West Tennessee Business College,Jackson,TN +229814,West Texas A & M University,Canyon,TX +125499,West Valley College,Saratoga,CA +237978,West Virginia Business College-Wheeling,Wheeling,WV +442383,West Virginia Junior College-Bridgeport,Bridgeport,WV +237987,West Virginia Junior College-Charleston,Charleston,WV +237996,West Virginia Junior College-Morgantown,Morgantown,WV +238014,West Virginia Northern Community College,Wheeling,WV +237880,West Virginia School of Osteopathic Medicine,Lewisburg,WV +237899,West Virginia State University,Institute,WV +238032,West Virginia University,Morgantown,WV +237686,West Virginia University at Parkersburg,Parkersburg,WV +237950,West Virginia University Institute of Technology,Montgomery,WV +237969,West Virginia Wesleyan College,Buckhannon,WV +200004,Western Carolina University,Cullowhee,NC +130776,Western Connecticut State University,Danbury,CT +219480,Western Dakota Technical Institute,Rapid City,SD +433387,Western Governors University,Salt Lake City,UT +149772,Western Illinois University,Macomb,IL +106102,Western International University,Tempe,AZ +154572,Western Iowa Tech Community College,Sioux City,IA +157951,Western Kentucky University,Bowling Green,KY +172699,Western Michigan University,Kalamazoo,MI +172477,Western Michigan University-Thomas M. Cooley Law School,Lansing,MI +181817,Western Nebraska Community College,Scottsbluff,NE +182564,Western Nevada College,Carson City,NV +168254,Western New England University,Springfield,MA +188304,Western New Mexico University,Silver City,NM +208035,Western Oklahoma State College,Altus,OK +210429,Western Oregon University,Monmouth,OR +199908,Western Piedmont Community College,Morganton,NC +210368,Western Seminary,Portland,OR +126030,Western State College of Law at Argosy University,Fullerton,CA +128391,Western State Colorado University,Gunnison,CO +224660,Western Technical College-El Paso,El Paso,TX +224679,Western Technical College-El Paso,El Paso,TX +240170,Western Technical College-La Crosse,La Crosse,WI +229832,Western Texas College,Snyder,TX +172705,Western Theological Seminary,Holland,MI +112525,Western University of Health Sciences,Pomona,CA +237011,Western Washington University,Bellingham,WA +240693,Western Wyoming Community College,Rock Springs,WY +168263,Westfield State University,Westfield,MA +179946,Westminster College-Fulton,Fulton,MO +216807,Westminster College-New Wilmington,New Wilmington,PA +230807,Westminster College-Salt Lake City,Salt Lake City,UT +216816,Westminster Theological Seminary,Glenside,PA +125718,Westminster Theological Seminary in California,Escondido,CA +125727,Westmont College,Santa Barbara,CA +216825,Westmoreland County Community College,Youngwood,PA +437848,Westwood College-Anaheim,Anaheim,CA +448628,Westwood College-Annandale,Annandale,VA +447069,Westwood College-Arlington Ballston,Arlington,VA +445072,Westwood College-Atlanta Midtown,Atlanta,GA +443687,Westwood College-Chicago Loop,Chicago,IL +127024,Westwood College-Denver North,Denver,CO +381787,Westwood College-Denver South,Denver,CO +406194,Westwood College-Dupage,Woodridge,IL +440484,Westwood College-Inland Empire,Upland,CA +122843,Westwood College-Los Angeles,Los Angeles,CA +445276,Westwood College-Northlake,Atlanta,GA +178226,Westwood College-O'Hare Airport,Chicago,IL +440147,Westwood College-River Oaks,Calumet City,IL +121381,Westwood College-South Bay,Torrance,CA +229841,Wharton County Junior College,Wharton,TX +237039,Whatcom Community College,Bellingham,WA +168281,Wheaton College-Norton,Norton,MA +149781,Wheaton College-Wheaton,Wheaton,IL +238078,Wheeling Jesuit University,Wheeling,WV +168290,Wheelock College,Boston,MA +434751,White Earth Tribal and Community College,Mahnomen,MN +183105,White Mountains Community College,Berlin,NH +237057,Whitman College,Walla Walla,WA +125763,Whittier College,Whittier,CA +237066,Whitworth University,Spokane,WA +475200,Whitworth University-Adult Degree Programs,Spokane,WA +156107,Wichita Area Technical College,Wichita,KS +156125,Wichita State University,Wichita,KS +156134,Wichita Technical Institute,Wichita,KS +244190,Widener University-Delaware Campus,Wilmington,DE +402828,Widener University-Harrisburg Campus,Harrisburg,PA +216852,Widener University-Main Campus,Chester,PA +206491,Wilberforce University,Wilberforce,OH +229887,Wiley College,Marshall,TX +199926,Wilkes Community College,Wilkesboro,NC +216931,Wilkes University,Wilkes-Barre,PA +210401,Willamette University,Salem,OR +176479,William Carey University,Hattiesburg,MS +166717,William James College,Newton,MA +122728,William Jessup University,Rocklin,CA +179955,William Jewell College,Liberty,MO +175281,William Mitchell College of Law,Saint Paul,MN +222105,William Moore College of Technology,Memphis,TN +187444,William Paterson University of New Jersey,Wayne,NJ +199272,William Peace University,Raleigh,NC +154590,William Penn University,Oskaloosa,IA +149842,William Rainey Harper College,Palatine,IL +179964,William Woods University,Fulton,MO +107877,Williams Baptist College,Walnut Ridge,AR +168342,Williams College,Williamstown,MA +218955,Williamsburg Technical College,Kingstree,SC +443340,Williamson Christian College,Franklin,TN +200341,Williston State College,Williston,ND +206507,Wilmington College,Wilmington,OH +131113,Wilmington University,New Castle,DE +217013,Wilson College,Chambersburg,PA +199953,Wilson Community College,Wilson,NC +141990,Windward Community College,Kaneohe,HI +206516,Winebrenner Theological Seminary,Findlay,OH +199962,Wingate University,Wingate,NC +175272,Winona State University,Winona,MN +199999,Winston-Salem State University,Winston-Salem,NC +218964,Winthrop University,Rock Hill,SC +141255,Wiregrass Georgia Technical College,Valdosta,GA +240198,Wisconsin Indianhead Technical College,Shell Lake,WI +240338,Wisconsin Lutheran College,Milwaukee,WI +240213,Wisconsin School of Professional Psychology,Milwaukee,WI +206525,Wittenberg University,Springfield,OH +218973,Wofford College,Spartanburg,SC +451130,Wolford College,Naples,FL +442064,Won Institute of Graduate Studies,Glenside,PA +197522,Wood Tobe-Coburn School,New York,NY +125897,Woodbury University,Burbank,CA +455512,Woodland Community College,Woodland,CA +168421,Worcester Polytechnic Institute,Worcester,MA +168430,Worcester State University,Worcester,MA +141936,World Medicine Institute,Honolulu,HI +401223,World Mission University,Los Angeles,CA +369455,Worsham College of Mortuary Science,Wheeling,IL +164313,Wor-Wic Community College,Salisbury,MD +406200,Wright Career College,Overland Park,KS +206613,Wright State University-Lake Campus,Celina,OH +206604,Wright State University-Main Campus,Dayton,OH +441089,Wyo Tech-Blairsville,Blairsville,PA +132268,Wyotech-Daytona,Ormond Beach,FL +123208,Wyotech-Fremont,Fremont,CA +240718,Wyotech-Laramie,Laramie,WY +398574,Wyotech-Long Beach,Long Beach,CA +234377,Wytheville Community College,Wytheville,VA +206622,Xavier University,Cincinnati,OH +160904,Xavier University of Louisiana,New Orleans,LA +237109,Yakima Valley Community College,Yakima,WA +130794,Yale University,New Haven,CT +106148,Yavapai College,Prescott,AZ +245731,Yeshiva and Kollel Harbotzas Torah,Brooklyn,NY +434937,Yeshiva College of the Nations Capital,Silver Spring,MD +197647,Yeshiva Derech Chaim,Brooklyn,NY +420325,Yeshiva D'monsey Rabbinical College,Monsey,NY +375230,Yeshiva Gedolah Imrei Yosef D'spinka,Brooklyn,NY +481410,Yeshiva Gedolah Kesser Torah,Monsey,NY +247773,Yeshiva Gedolah of Greater Detroit,Oak Park,MI +476692,Yeshiva Gedolah Zichron Leyma,Linden,NJ +197601,Yeshiva Karlin Stolin,Brooklyn,NY +190752,Yeshiva of Far Rockaway Derech Ayson Rabbinical Seminary,Far Rockaway,NY +455257,Yeshiva of Machzikai Hadas,Brooklyn,NY +197674,Yeshiva of Nitra Rabbinical College,Mount Kisco,NY +431983,Yeshiva of the Telshe Alumni,Riverdale,NY +126076,Yeshiva Ohr Elchonon Chabad West Coast Talmudical Seminary,Los Angeles,CA +197692,Yeshiva Shaar Hatorah,Kew Gardens,NY +441609,Yeshiva Shaarei Torah of Rockland,Suffern,NY +451398,Yeshiva Toras Chaim,Lakewood,NJ +128425,Yeshiva Toras Chaim Talmudical Seminary,Denver,CO +197708,Yeshiva University,New York,NY +481438,Yeshiva Yesodei Hatorah,Lakewood,NJ +451370,Yeshivas Be'er Yitzchok,Elizabeth,NJ +405058,Yeshivas Novominsk,Brooklyn,NY +197610,Yeshivat Mikdash Melech,Brooklyn,NY +217040,Yeshivath Beth Moshe,Scranton,PA +197735,Yeshivath Viznitz,Monsey,NY +197744,Yeshivath Zichron Moshe,South Fallsburgh,NY +401250,Yo San University of Traditional Chinese Medicine,Los Angeles,CA +181853,York College,York,NE +217059,York College Pennsylvania,York,PA +420440,York County Community College,Wells,ME +218991,York Technical College,Rock Hill,SC +217086,Yorktowne Business Institute,York,PA +141361,Young Harris College,Young Harris,GA +206695,Youngstown State University,Youngstown,OH +375939,YTI Career Institute-Altoona,Altoona,PA +217077,YTI Career Institute-York,York,PA +126119,Yuba College,Marysville,CA +204255,Zane State College,Zanesville,OH \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/data/institutions.json b/vite-app/src/apps/Auth2/resources/data/institutions.json new file mode 100644 index 00000000..33e3d8a7 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/data/institutions.json @@ -0,0 +1 @@ +[{"value":"177834","label":"A T Still University of Health Sciences"},{"value":"180203","label":"Aaniiih Nakoda College"},{"value":"222178","label":"Abilene Christian University"},{"value":"138558","label":"Abraham Baldwin Agricultural College"},{"value":"172866","label":"Academy College"},{"value":"451079","label":"Academy for Five Element Acupuncture"},{"value":"457271","label":"Academy for Jewish Religion-California"},{"value":"412173","label":"Academy for Nursing and Health Occupations"},{"value":"108232","label":"Academy of Art University"},{"value":"108269","label":"Academy of Chinese Culture and Health Sciences"},{"value":"475635","label":"Academy of Couture Art"},{"value":"449454","label":"Academy of Natural Therapy Inc"},{"value":"384306","label":"Acupuncture and Integrative Medicine College-Berkeley"},{"value":"439969","label":"Acupuncture and Massage College"},{"value":"126182","label":"Adams State University"},{"value":"188429","label":"Adelphi University"},{"value":"188438","label":"Adirondack Community College"},{"value":"374024","label":"Adler Graduate School"},{"value":"142832","label":"Adler University"},{"value":"168528","label":"Adrian College"},{"value":"444343","label":"Advanced College"},{"value":"481234","label":"Advanced Computing Institute"},{"value":"231411","label":"Advanced Technology Institute"},{"value":"444361","label":"Advanced Training Associates"},{"value":"133872","label":"Adventist University of Health Sciences"},{"value":"205391","label":"Advertising Art Educational Services DBA School of Advertising Art"},{"value":"138600","label":"Agnes Scott College"},{"value":"134811","label":"AI Miami International University of Art and Design"},{"value":"152822","label":"AIB College of Business"},{"value":"217615","label":"Aiken Technical College"},{"value":"126207","label":"Aims Community College"},{"value":"200697","label":"Air Force Institute of Technology-Graduate School of Engineering & Management"},{"value":"200785","label":"Akron Institute of Herzing University"},{"value":"100654","label":"Alabama A & M University"},{"value":"101949","label":"Alabama Southern Community College"},{"value":"100724","label":"Alabama State University"},{"value":"199786","label":"Alamance Community College"},{"value":"102580","label":"Alaska Bible College"},{"value":"103501","label":"Alaska Career College"},{"value":"442523","label":"Alaska Christian College"},{"value":"102669","label":"Alaska Pacific University"},{"value":"188526","label":"Albany College of Pharmacy and Health Sciences"},{"value":"188535","label":"Albany Law School"},{"value":"188580","label":"Albany Medical College"},{"value":"138716","label":"Albany State University"},{"value":"138682","label":"Albany Technical College"},{"value":"128498","label":"Albertus Magnus College"},{"value":"168546","label":"Albion College"},{"value":"210571","label":"Albright College"},{"value":"175342","label":"Alcorn State University"},{"value":"237118","label":"Alderson Broaddus University"},{"value":"172918","label":"Alexandria Technical & Community College"},{"value":"188641","label":"Alfred University"},{"value":"156189","label":"Alice Lloyd College"},{"value":"108807","label":"Allan Hancock College"},{"value":"161688","label":"Allegany College of Maryland"},{"value":"210669","label":"Allegheny College"},{"value":"200873","label":"Allegheny Wesleyan College"},{"value":"152798","label":"Allen College"},{"value":"154642","label":"Allen County Community College"},{"value":"217624","label":"Allen University"},{"value":"110468","label":"Alliant International University-San Diego"},{"value":"460729","label":"Allied American University"},{"value":"168591","label":"Alma College"},{"value":"168607","label":"Alpena Community College"},{"value":"210775","label":"Alvernia University"},{"value":"238193","label":"Alverno College"},{"value":"222567","label":"Alvin Community College"},{"value":"222576","label":"Amarillo College"},{"value":"222628","label":"Amberton University"},{"value":"457527","label":"Ambria College of Nursing"},{"value":"188687","label":"American Academy McAllister Institute of Funeral Service"},{"value":"446002","label":"American Academy of Acupuncture and Oriental Medicine"},{"value":"142887","label":"American Academy of Art"},{"value":"108852","label":"American Academy of Dramatic Arts-Los Angeles"},{"value":"188678","label":"American Academy of Dramatic Arts-New York"},{"value":"219505","label":"American Baptist College"},{"value":"108861","label":"American Baptist Seminary of the West"},{"value":"457688","label":"American Business and Technology University"},{"value":"441052","label":"American Career College-Anaheim"},{"value":"109040","label":"American Career College-Los Angeles"},{"value":"447768","label":"American Career College-Ontario"},{"value":"461005","label":"American College for Medical Careers"},{"value":"429085","label":"American College of Acupuncture and Oriental Med"},{"value":"449889","label":"American College of Education"},{"value":"210809","label":"American College of Financial Services"},{"value":"443599","label":"American College of Healthcare Sciences"},{"value":"430591","label":"American College of Traditional Chinese Medicine"},{"value":"109086","label":"American Conservatory Theater"},{"value":"108870","label":"American Film Institute Conservatory"},{"value":"103787","label":"American Indian College Inc"},{"value":"441636","label":"American Institute of Alternative Medicine"},{"value":"438586","label":"American InterContinental University-Atlanta"},{"value":"445133","label":"American InterContinental University-Houston"},{"value":"445027","label":"American InterContinental University-Online"},{"value":"438601","label":"American InterContinental University-South Florida"},{"value":"164447","label":"American International College"},{"value":"116846","label":"American Jewish University"},{"value":"475714","label":"American Medical Academy"},{"value":"188854","label":"American Musical and Dramatic Academy"},{"value":"232797","label":"American National University"},{"value":"449339","label":"American Public University System"},{"value":"109208","label":"American River College"},{"value":"240736","label":"American Samoa Community College"},{"value":"460738","label":"American Sentinel University"},{"value":"131159","label":"American University"},{"value":"433004","label":"American University of Health Sciences"},{"value":"241100","label":"American University of Puerto Rico-Bayamon"},{"value":"241128","label":"American University of Puerto Rico-Manati"},{"value":"447263","label":"AmeriTech College-Draper"},{"value":"164465","label":"Amherst College"},{"value":"100690","label":"Amridge University"},{"value":"151865","label":"Anabaptist Mennonite Biblical Seminary"},{"value":"150048","label":"Ancilla College"},{"value":"150066","label":"Anderson University-Anderson"},{"value":"217633","label":"Anderson University-Anderson"},{"value":"164474","label":"Andover Newton Theological School"},{"value":"138761","label":"Andrew College"},{"value":"168740","label":"Andrews University"},{"value":"457299","label":"Angeles College"},{"value":"222822","label":"Angelina College"},{"value":"222831","label":"Angelo State University"},{"value":"164492","label":"Anna Maria College"},{"value":"161767","label":"Anne Arundel Community College"},{"value":"172954","label":"Anoka Technical College"},{"value":"172963","label":"Anoka-Ramsey Community College"},{"value":"109350","label":"Antelope Valley College"},{"value":"245838","label":"Antioch University-Los Angeles"},{"value":"245892","label":"Antioch University-Midwest"},{"value":"245865","label":"Antioch University-New England"},{"value":"442392","label":"Antioch University-PhD Program in Leadership and Change"},{"value":"245847","label":"Antioch University-Santa Barbara"},{"value":"245883","label":"Antioch University-Seattle"},{"value":"201016","label":"Antonelli College-Cincinnati"},{"value":"383950","label":"Antonelli College-Hattiesburg"},{"value":"175528","label":"Antonelli College-Jackson"},{"value":"210890","label":"Antonelli Institute"},{"value":"429094","label":"AOMA Graduate School of Integrative Medicine"},{"value":"441511","label":"Apex School of Theology"},{"value":"237136","label":"Appalachian Bible College"},{"value":"449922","label":"Appalachian College of Pharmacy"},{"value":"432348","label":"Appalachian School of Law"},{"value":"197869","label":"Appalachian State University"},{"value":"168786","label":"Aquinas College-Grand Rapids"},{"value":"219578","label":"Aquinas College-Nashville"},{"value":"176600","label":"Aquinas Institute of Theology"},{"value":"126289","label":"Arapahoe Community College"},{"value":"211088","label":"Arcadia University"},{"value":"367936","label":"Argosy University-Atlanta"},{"value":"145770","label":"Argosy University-Chicago"},{"value":"442222","label":"Argosy University-Dallas"},{"value":"448734","label":"Argosy University-Denver"},{"value":"366748","label":"Argosy University-Hawaii"},{"value":"450526","label":"Argosy University-Inland Empire"},{"value":"447272","label":"Argosy University-Los Angeles"},{"value":"450535","label":"Argosy University-Nashville"},{"value":"436438","label":"Argosy University-Orange County"},{"value":"436094","label":"Argosy University-Phoenix"},{"value":"456348","label":"Argosy University-Phoenix Online Division"},{"value":"452090","label":"Argosy University-Salt Lake City"},{"value":"450544","label":"Argosy University-San Diego"},{"value":"121983","label":"Argosy University-San Francisco Bay Area"},{"value":"137148","label":"Argosy University-Sarasota"},{"value":"420866","label":"Argosy University-Schaumburg"},{"value":"439057","label":"Argosy University-Seattle"},{"value":"428268","label":"Argosy University-Tampa"},{"value":"410502","label":"Argosy University-The Art Institute of California-Hollywood"},{"value":"448576","label":"Argosy University-The Art Institute of California-Inland Empire"},{"value":"432533","label":"Argosy University-The Art Institute of California-Los Angeles"},{"value":"441973","label":"Argosy University-The Art Institute of California-Orange County"},{"value":"450094","label":"Argosy University-The Art Institute of California-Sacramento"},{"value":"117113","label":"Argosy University-The Art Institute of California-San Diego"},{"value":"117928","label":"Argosy University-The Art Institute of California-San Francisco"},{"value":"451848","label":"Argosy University-The Art Institute of California-Silicon Valley"},{"value":"173984","label":"Argosy University-Twin Cities"},{"value":"419457","label":"Argosy University-Washington DC"},{"value":"105899","label":"Arizona Christian University"},{"value":"421708","label":"Arizona College-Glendale"},{"value":"482990","label":"Arizona College-Mesa"},{"value":"446039","label":"Arizona School of Acupuncture and Oriental Medicine"},{"value":"448886","label":"Arizona State University-Downtown Phoenix"},{"value":"420574","label":"Arizona State University-Polytechnic"},{"value":"483124","label":"Arizona State University-Skysong"},{"value":"104151","label":"Arizona State University-Tempe"},{"value":"407009","label":"Arizona State University-West"},{"value":"450942","label":"Arizona Summit Law School"},{"value":"104160","label":"Arizona Western College"},{"value":"106306","label":"Arkansas Baptist College"},{"value":"107327","label":"Arkansas Northeastern College"},{"value":"106449","label":"Arkansas State University-Beebe"},{"value":"106458","label":"Arkansas State University-Main Campus"},{"value":"107318","label":"Arkansas State University-Mid-South"},{"value":"420538","label":"Arkansas State University-Mountain Home"},{"value":"440402","label":"Arkansas State University-Newport"},{"value":"106467","label":"Arkansas Tech University"},{"value":"222877","label":"Arlington Baptist College"},{"value":"138789","label":"Armstrong State University"},{"value":"201061","label":"Art Academy of Cincinnati"},{"value":"109651","label":"Art Center College of Design"},{"value":"404994","label":"ASA College"},{"value":"156222","label":"Asbury Theological Seminary"},{"value":"156213","label":"Asbury University"},{"value":"461777","label":"Ashdown College of Health Sciences"},{"value":"447777","label":"Asher College"},{"value":"197887","label":"Asheville-Buncombe Technical Community College"},{"value":"154022","label":"Ashford University"},{"value":"156231","label":"Ashland Community and Technical College"},{"value":"201104","label":"Ashland University"},{"value":"128577","label":"Asnuntuck Community College"},{"value":"454829","label":"Aspen University"},{"value":"176619","label":"Assemblies of God Theological Seminary"},{"value":"164562","label":"Assumption College"},{"value":"183600","label":"Assumption College for Sisters"},{"value":"446127","label":"ATA Career Education"},{"value":"447935","label":"ATA College"},{"value":"440651","label":"Atenas College"},{"value":"201140","label":"Athenaeum of Ohio"},{"value":"100812","label":"Athens State University"},{"value":"246813","label":"Athens Technical College"},{"value":"138901","label":"Atlanta Metropolitan State College"},{"value":"138840","label":"Atlanta Technical College"},{"value":"138929","label":"Atlanta's John Marshall Law School"},{"value":"183655","label":"Atlantic Cape Community College"},{"value":"439446","label":"Atlantic Institute of Oriental Medicine"},{"value":"241216","label":"Atlantic University College"},{"value":"100858","label":"Auburn University"},{"value":"100830","label":"Auburn University at Montgomery"},{"value":"173045","label":"Augsburg College"},{"value":"138956","label":"Augusta Technical College"},{"value":"482149","label":"Augusta University"},{"value":"143084","label":"Augustana College-Rock Island"},{"value":"219000","label":"Augustana University"},{"value":"201177","label":"Aultman College of Nursing and Health Sciences"},{"value":"143118","label":"Aurora University"},{"value":"222983","label":"Austin College"},{"value":"222992","label":"Austin Community College District"},{"value":"247825","label":"Austin Graduate School of Theology"},{"value":"219602","label":"Austin Peay State University"},{"value":"223001","label":"Austin Presbyterian Theological Seminary"},{"value":"442295","label":"Ave Maria School of Law"},{"value":"446048","label":"Ave Maria University"},{"value":"231420","label":"Averett University"},{"value":"449931","label":"Averett University-Non-Traditional Programs"},{"value":"447847","label":"Aviator College of Aeronautical Science and Technology"},{"value":"176628","label":"Avila University"},{"value":"102711","label":"AVTEC-Alaska's Institute of Technology"},{"value":"483762","label":"Azure College"},{"value":"109785","label":"Azusa Pacific University"},{"value":"474863","label":"Azusa Pacific University College"},{"value":"164580","label":"Babson College"},{"value":"206817","label":"Bacone College"},{"value":"139010","label":"Bainbridge State College"},{"value":"476601","label":"Bais HaMedrash and Mesivta of Baltimore"},{"value":"245777","label":"Bais Medrash Elyon"},{"value":"449658","label":"Bais Medrash Toras Chesed"},{"value":"168847","label":"Baker College"},{"value":"414708","label":"Baker College Center for Graduate Studies"},{"value":"444167","label":"Baker College of Allen Park"},{"value":"404073","label":"Baker College of Auburn Hills"},{"value":"404648","label":"Baker College of Cadillac"},{"value":"404082","label":"Baker College of Clinton Township"},{"value":"414160","label":"Baker College of Jackson"},{"value":"171298","label":"Baker College of Muskegon"},{"value":"168838","label":"Baker College of Owosso"},{"value":"381617","label":"Baker College of Port Huron"},{"value":"154688","label":"Baker University"},{"value":"109819","label":"Bakersfield College"},{"value":"420705","label":"Bakke Graduate University"},{"value":"201195","label":"Baldwin Wallace University"},{"value":"150136","label":"Ball State University"},{"value":"161864","label":"Baltimore City Community College"},{"value":"189015","label":"Bank Street College of Education"},{"value":"176664","label":"Baptist Bible College"},{"value":"211024","label":"Clarks Summit University"},{"value":"223083","label":"Baptist Health System School of Health Professions"},{"value":"219639","label":"Baptist Memorial College of Health Sciences"},{"value":"223117","label":"Baptist Missionary Association Theological Seminary"},{"value":"366793","label":"Baptist Theological Seminary at Richmond"},{"value":"444398","label":"Baptist University of the Americas"},{"value":"155070","label":"Barclay College"},{"value":"189088","label":"Bard College"},{"value":"167792","label":"Bard College at Simon's Rock"},{"value":"189097","label":"Barnard College"},{"value":"177719","label":"Barnes-Jewish College Goldfarb School of Nursing"},{"value":"132471","label":"Barry University"},{"value":"109907","label":"Barstow Community College"},{"value":"197911","label":"Barton College"},{"value":"154697","label":"Barton County Community College"},{"value":"235547","label":"Bastyr University"},{"value":"160977","label":"Bates College"},{"value":"235671","label":"Bates Technical College"},{"value":"437103","label":"Baton Rouge Community College"},{"value":"158343","label":"Baton Rouge School of Computers"},{"value":"139074","label":"Bauder College"},{"value":"168883","label":"Bay de Noc Community College"},{"value":"380359","label":"Bay Mills Community College"},{"value":"164632","label":"Bay Path University"},{"value":"164641","label":"Bay State College"},{"value":"223223","label":"Baylor College of Medicine"},{"value":"223232","label":"Baylor University"},{"value":"384254","label":"Beacon College"},{"value":"160995","label":"Beal College"},{"value":"197966","label":"Beaufort County Community College"},{"value":"164720","label":"Becker College"},{"value":"247065","label":"Beckfield College-Florence"},{"value":"452373","label":"Beckfield College-Tri-County"},{"value":"476717","label":"Be'er Yaakov Talmudic Seminary"},{"value":"444413","label":"Beis Medrash Heichal Dovid"},{"value":"190956","label":"Belanger School of Nursing"},{"value":"175421","label":"Belhaven University"},{"value":"156286","label":"Bellarmine University"},{"value":"234669","label":"Bellevue College"},{"value":"180814","label":"Bellevue University"},{"value":"238324","label":"Bellin College"},{"value":"234696","label":"Bellingham Technical College"},{"value":"197984","label":"Belmont Abbey College"},{"value":"201283","label":"Belmont College"},{"value":"219709","label":"Belmont University"},{"value":"238333","label":"Beloit College"},{"value":"126359","label":"Bel-Rea Institute of Animal Technology"},{"value":"173124","label":"Bemidji State University"},{"value":"217721","label":"Benedict College"},{"value":"154712","label":"Benedictine College"},{"value":"145619","label":"Benedictine University"},{"value":"165884","label":"Benjamin Franklin Institute of Technology"},{"value":"197993","label":"Bennett College"},{"value":"230816","label":"Bennington College"},{"value":"164739","label":"Bentley University"},{"value":"156295","label":"Berea College"},{"value":"183743","label":"Bergen Community College"},{"value":"461643","label":"Bergin University of Canine Studies"},{"value":"125170","label":"Berkeley City College"},{"value":"189228","label":"Berkeley College-New York"},{"value":"183789","label":"Berkeley College-Woodland Park"},{"value":"164748","label":"Berklee College of Music"},{"value":"213534","label":"Berks Technical Institute"},{"value":"164775","label":"Berkshire Community College"},{"value":"139144","label":"Berry College"},{"value":"189273","label":"Beth Hamedrash Shaarei Yosher Institute"},{"value":"189264","label":"Beth Hatalmud Rabbinical College"},{"value":"183804","label":"Beth Medrash Govoha"},{"value":"237181","label":"Bethany College-Bethany"},{"value":"154721","label":"Bethany College-Lindsborg"},{"value":"173142","label":"Bethany Lutheran College"},{"value":"143233","label":"Bethany Theological Seminary"},{"value":"458113","label":"Bethel College"},{"value":"150145","label":"Bethel College-Indiana"},{"value":"154749","label":"Bethel College-North Newton"},{"value":"262022","label":"Bethel Seminary-San Diego"},{"value":"173179","label":"Bethel Seminary-St Paul"},{"value":"219718","label":"Bethel University-McKenzie"},{"value":"173160","label":"Bethel University-Saint Paul"},{"value":"110060","label":"Bethesda University"},{"value":"132602","label":"Bethune-Cookman University"},{"value":"139153","label":"Beulah Heights University"},{"value":"102429","label":"Bevill State Community College"},{"value":"148724","label":"Bexley Hall Seabury Western Theological Seminary Federation"},{"value":"443702","label":"Bexley Hall Seabury Western Theological Seminary Federation "},{"value":"211130","label":"Biblical Theological Seminary"},{"value":"211149","label":"Bidwell Training Center Inc"},{"value":"234711","label":"Big Bend Community College"},{"value":"157553","label":"Big Sandy Community and Technical College"},{"value":"110097","label":"Biola University"},{"value":"100937","label":"Birmingham Southern College"},{"value":"442949","label":"Birthingway College of Midwifery"},{"value":"102030","label":"Bishop State Community College"},{"value":"200022","label":"Bismarck State College"},{"value":"143279","label":"Black Hawk College"},{"value":"219046","label":"Black Hills State University"},{"value":"106625","label":"Black River Technical College"},{"value":"143288","label":"Blackburn College"},{"value":"180054","label":"Blackfeet Community College"},{"value":"238397","label":"Blackhawk Technical College"},{"value":"198011","label":"Bladen Community College"},{"value":"143297","label":"Blessing Rieman College of Nursing"},{"value":"223427","label":"Blinn College"},{"value":"183822","label":"Bloomfield College"},{"value":"211158","label":"Bloomsburg University of Pennsylvania"},{"value":"441502","label":"Blue Cliff College-Gulfport"},{"value":"175430","label":"Blue Mountain College"},{"value":"208275","label":"Blue Mountain Community College"},{"value":"446774","label":"Blue Ridge Community and Technical College"},{"value":"198039","label":"Blue Ridge Community College-Flat Rock"},{"value":"231536","label":"Blue Ridge Community College-Weyers Cave"},{"value":"231554","label":"Bluefield College"},{"value":"237215","label":"Bluefield State College"},{"value":"156392","label":"Bluegrass Community and Technical College"},{"value":"201371","label":"Bluffton University"},{"value":"217749","label":"Bob Jones University"},{"value":"142090","label":"Boise Bible College"},{"value":"142115","label":"Boise State University"},{"value":"233356","label":"Bon Secours Memorial College of Nursing"},{"value":"189413","label":"Boricua College"},{"value":"158431","label":"Bossier Parish Community College"},{"value":"164872","label":"Boston Architectural College"},{"value":"164614","label":"Boston Baptist College"},{"value":"164924","label":"Boston College"},{"value":"164915","label":"Boston Graduate School of Psychoanalysis Inc"},{"value":"164988","label":"Boston University"},{"value":"161004","label":"Bowdoin College"},{"value":"162007","label":"Bowie State University"},{"value":"201432","label":"Bowling Green State University-Firelands"},{"value":"201441","label":"Bowling Green State University-Main Campus"},{"value":"202161","label":"Bradford School-Columbus"},{"value":"211200","label":"Bradford School-Pittsburgh"},{"value":"143358","label":"Bradley University"},{"value":"189422","label":"Bramson ORT College"},{"value":"165015","label":"Brandeis University"},{"value":"262086","label":"Brandman University"},{"value":"223506","label":"Brazosport College"},{"value":"139199","label":"Brenau University"},{"value":"156356","label":"Brescia University"},{"value":"198066","label":"Brevard College"},{"value":"139205","label":"Brewton-Parker College"},{"value":"152992","label":"Briar Cliff University"},{"value":"189459","label":"Briarcliffe College"},{"value":"231581","label":"Bridgewater College"},{"value":"165024","label":"Bridgewater State University"},{"value":"230047","label":"Brigham Young University-Hawaii"},{"value":"142522","label":"Brigham Young University-Idaho"},{"value":"230038","label":"Brigham Young University-Provo"},{"value":"215646","label":"Brightwood Career Institute-Broomall"},{"value":"251075","label":"Brightwood Career Institute-Harrisburg"},{"value":"214254","label":"Brightwood Career Institute-Philadelphia"},{"value":"211617","label":"Brightwood Career Institute-Philadelphia Mills"},{"value":"213002","label":"Brightwood Career Institute-Pittsburgh"},{"value":"458690","label":"Brightwood College-Arlington"},{"value":"447102","label":"Brightwood College-Bakersfield"},{"value":"163736","label":"Brightwood College-Baltimore"},{"value":"440323","label":"Brightwood College-Beaumont"},{"value":"164058","label":"Brightwood College-Beltsville"},{"value":"443827","label":"Brightwood College-Brownsville"},{"value":"458706","label":"Brightwood College-Charlotte"},{"value":"458186","label":"Brightwood College-Chula Vista"},{"value":"443836","label":"Brightwood College-Corpus Christi"},{"value":"382896","label":"Brightwood College-Dallas"},{"value":"204626","label":"Brightwood College-Dayton"},{"value":"246266","label":"Brightwood College-El Paso"},{"value":"445328","label":"Brightwood College-Fort Worth"},{"value":"447120","label":"Brightwood College-Fresno"},{"value":"458283","label":"Brightwood College-Indianapolis"},{"value":"440332","label":"Brightwood College-Laredo"},{"value":"374875","label":"Brightwood College-Las Vegas"},{"value":"227836","label":"Brightwood College-McAllen"},{"value":"366960","label":"Brightwood College-Modesto"},{"value":"246202","label":"Brightwood College-Nashville"},{"value":"447634","label":"Brightwood College-Palm Springs"},{"value":"432302","label":"Brightwood College-Riverside"},{"value":"118259","label":"Brightwood College-Sacramento"},{"value":"431886","label":"Brightwood College-San Antonio-Ingram"},{"value":"364955","label":"Brightwood College-San Antonio-San Pedro"},{"value":"118277","label":"Brightwood College-San Diego"},{"value":"161776","label":"Brightwood College-Towson"},{"value":"118286","label":"Brightwood College-Vista"},{"value":"165033","label":"Bristol Community College"},{"value":"397270","label":"Bristol University"},{"value":"450304","label":"Brite Divinity School"},{"value":"459091","label":"Broadview Entertainment Arts University"},{"value":"467793","label":"Broadview University-Boise"},{"value":"450429","label":"Broadview University-Layton"},{"value":"454591","label":"Broadview University-Orem"},{"value":"230056","label":"Broadview University-West Jordan"},{"value":"183859","label":"Brookdale Community College"},{"value":"223524","label":"Brookhaven College"},{"value":"444088","label":"Brookline College-Albuquerque"},{"value":"104090","label":"Brookline College-Phoenix"},{"value":"404055","label":"Brookline College-Tempe"},{"value":"438179","label":"Brookline College-Tucson"},{"value":"189501","label":"Brooklyn Law School"},{"value":"110185","label":"Brooks Institute"},{"value":"132709","label":"Broward College"},{"value":"205647","label":"Brown Mackie College-Akron"},{"value":"460039","label":"Brown Mackie College-Albuquerque"},{"value":"410283","label":"Brown Mackie College-Atlanta"},{"value":"470162","label":"Brown Mackie College-Birmingham"},{"value":"455600","label":"Brown Mackie College-Boise"},{"value":"205610","label":"Brown Mackie College-Cincinnati"},{"value":"482954","label":"Brown Mackie College-Dallas"},{"value":"375489","label":"Brown Mackie College-Findlay"},{"value":"408039","label":"Brown Mackie College-Fort Wayne"},{"value":"456791","label":"Brown Mackie College-Greenville"},{"value":"421513","label":"Brown Mackie College-Hopkinsville"},{"value":"451699","label":"Brown Mackie College-Indianapolis"},{"value":"154767","label":"Brown Mackie College-Kansas City"},{"value":"157599","label":"Brown Mackie College-Louisville"},{"value":"151616","label":"Brown Mackie College-Merrillville"},{"value":"447290","label":"Brown Mackie College-Miami"},{"value":"151625","label":"Brown Mackie College-Michigan City"},{"value":"204316","label":"Brown Mackie College-North Canton"},{"value":"157696","label":"Brown Mackie College-Northern Kentucky"},{"value":"475042","label":"Brown Mackie College-Oklahoma City"},{"value":"456612","label":"Brown Mackie College-Phoenix"},{"value":"373085","label":"Brown Mackie College-Quad Cities"},{"value":"154776","label":"Brown Mackie College-Salina"},{"value":"460613","label":"Brown Mackie College-San Antonio"},{"value":"151944","label":"Brown Mackie College-South Bend"},{"value":"460048","label":"Brown Mackie College-St Louis"},{"value":"104364","label":"Brown Mackie College-Tucson"},{"value":"455619","label":"Brown Mackie College-Tulsa"},{"value":"217156","label":"Brown University"},{"value":"198084","label":"Brunswick Community College"},{"value":"180878","label":"Bryan College of Health Sciences"},{"value":"219790","label":"Bryan College-Dayton"},{"value":"439826","label":"Bryan College-Gold River"},{"value":"475583","label":"Bryan University-Columbia"},{"value":"110219","label":"Bryan University-Los Angeles"},{"value":"454458","label":"Bryan University-Rogers"},{"value":"369516","label":"Bryan University-Springfield"},{"value":"154794","label":"Bryan University-Topeka"},{"value":"475699","label":"Bryant & Stratton College-Akron"},{"value":"188517","label":"Bryant & Stratton College-Albany"},{"value":"189556","label":"Bryant & Stratton College-Amherst"},{"value":"458502","label":"Bryant & Stratton College-Bayshore"},{"value":"189583","label":"Bryant & Stratton College-Buffalo"},{"value":"202684","label":"Bryant & Stratton College-Cleveland"},{"value":"369905","label":"Bryant & Stratton College-Eastlake"},{"value":"189592","label":"Bryant & Stratton College-Greece"},{"value":"459107","label":"Bryant & Stratton College-Hampton"},{"value":"410496","label":"Bryant & Stratton College-Henrietta"},{"value":"239929","label":"Bryant & Stratton College-Milwaukee"},{"value":"480091","label":"Bryant & Stratton College-Online"},{"value":"201469","label":"Bryant & Stratton College-Parma"},{"value":"231828","label":"Bryant & Stratton College-Richmond"},{"value":"374972","label":"Bryant & Stratton College-Southtowns"},{"value":"189574","label":"Bryant & Stratton College-Syracuse"},{"value":"189565","label":"Bryant & Stratton College-Syracuse North"},{"value":"231785","label":"Bryant & Stratton College-Virginia Beach"},{"value":"451750","label":"Bryant & Stratton College-Wauwatosa"},{"value":"217165","label":"Bryant University"},{"value":"210492","label":"Bryn Athyn College of the New Church"},{"value":"211273","label":"Bryn Mawr College"},{"value":"211291","label":"Bucknell University"},{"value":"211307","label":"Bucks County Community College"},{"value":"211316","label":"Bucks County School of Beauty Culture Inc"},{"value":"153001","label":"Buena Vista University"},{"value":"165112","label":"Bunker Hill Community College"},{"value":"230825","label":"Burlington College"},{"value":"484181","label":"Burnett International College"},{"value":"189653","label":"Business Informatics Center Inc"},{"value":"154800","label":"Butler Community College"},{"value":"211343","label":"Butler County Community College"},{"value":"150163","label":"Butler University"},{"value":"110246","label":"Butte College"},{"value":"444103","label":"Byzantine Catholic Seminary of Saints Cyril and Methodius"},{"value":"198109","label":"Cabarrus College of Health Sciences"},{"value":"110334","label":"Cabrillo College"},{"value":"211352","label":"Cabrini University"},{"value":"215114","label":"Cairn University-Langhorne"},{"value":"198118","label":"Caldwell Community College and Technical Institute"},{"value":"183910","label":"Caldwell University"},{"value":"110361","label":"California Baptist University"},{"value":"110918","label":"California Christian College"},{"value":"110370","label":"California College of the Arts"},{"value":"485263","label":"California College San Diego-San Diego"},{"value":"478634","label":"California College San Diego-San Marcos"},{"value":"110316","label":"California Institute of Integral Studies"},{"value":"110404","label":"California Institute of Technology"},{"value":"111081","label":"California Institute of the Arts"},{"value":"110413","label":"California Lutheran University"},{"value":"480781","label":"California Miramar University"},{"value":"110422","label":"California Polytechnic State University-San Luis Obispo"},{"value":"110529","label":"California State Polytechnic University-Pomona"},{"value":"110486","label":"California State University-Bakersfield"},{"value":"441937","label":"California State University-Channel Islands"},{"value":"110538","label":"California State University-Chico"},{"value":"110547","label":"California State University-Dominguez Hills"},{"value":"110574","label":"California State University-East Bay"},{"value":"110556","label":"California State University-Fresno"},{"value":"110565","label":"California State University-Fullerton"},{"value":"110583","label":"California State University-Long Beach"},{"value":"110592","label":"California State University-Los Angeles"},{"value":"409698","label":"California State University-Monterey Bay"},{"value":"110608","label":"California State University-Northridge"},{"value":"110617","label":"California State University-Sacramento"},{"value":"110510","label":"California State University-San Bernardino"},{"value":"366711","label":"California State University-San Marcos"},{"value":"110495","label":"California State University-Stanislaus"},{"value":"460075","label":"California University of Management and Sciences"},{"value":"211361","label":"California University of Pennsylvania"},{"value":"111391","label":"California Western School of Law"},{"value":"150172","label":"Calumet College of Saint Joseph"},{"value":"176789","label":"Calvary Bible College and Theological Seminary"},{"value":"169080","label":"Calvin College"},{"value":"169099","label":"Calvin Theological Seminary"},{"value":"428329","label":"Cambria-Rowe Business College-Indiana"},{"value":"211398","label":"Cambria-Rowe Business College-Johnstown"},{"value":"165167","label":"Cambridge College"},{"value":"454865","label":"Cambridge College of Healthcare & Technology"},{"value":"446093","label":"Cambridge Junior College-Yuba City"},{"value":"183938","label":"Camden County College"},{"value":"158440","label":"Cameron College"},{"value":"206914","label":"Cameron University"},{"value":"198136","label":"Campbell University"},{"value":"156365","label":"Campbellsville University"},{"value":"111434","label":"Canada College"},{"value":"189705","label":"Canisius College"},{"value":"200208","label":"Cankdeska Cikana Community College"},{"value":"165194","label":"Cape Cod Community College"},{"value":"198154","label":"Cape Fear Community College"},{"value":"413413","label":"Capella University"},{"value":"158352","label":"Capital Area Technical College"},{"value":"129367","label":"Capital Community College"},{"value":"201548","label":"Capital University"},{"value":"162061","label":"Capitol Technology University"},{"value":"238430","label":"Cardinal Stritch University"},{"value":"181941","label":"Career College of Northern Nevada"},{"value":"224439","label":"Career Point College-San Antonio"},{"value":"246008","label":"Career Point College-Tulsa"},{"value":"454306","label":"Career Quest Learning Centers-Jackson"},{"value":"446136","label":"Career Quest Learning Centers-Lansing"},{"value":"367112","label":"Career Technical College-Monroe"},{"value":"446880","label":"Career Technical College-Shreveport"},{"value":"210951","label":"Career Training Academy-Lower Burrell"},{"value":"408312","label":"Career Training Academy-Monroeville"},{"value":"440174","label":"Career Training Academy-Pittsburgh"},{"value":"448239","label":"Careers Unlimited"},{"value":"241377","label":"Caribbean University-Bayamon"},{"value":"241386","label":"Caribbean University-Carolina"},{"value":"363907","label":"Caribbean University-Ponce"},{"value":"363916","label":"Caribbean University-Vega Baja"},{"value":"206923","label":"Carl Albert State College"},{"value":"143613","label":"Carl Sandburg College"},{"value":"173258","label":"Carleton College"},{"value":"132842","label":"Carlos Albizu University-Miami"},{"value":"241331","label":"Carlos Albizu University-San Juan"},{"value":"211431","label":"Carlow University"},{"value":"211440","label":"Carnegie Mellon University"},{"value":"199971","label":"Carolina Christian College"},{"value":"461032","label":"Carolina College of Biblical Studies"},{"value":"433174","label":"Carolinas College of Health Sciences"},{"value":"442602","label":"Carrington College-Albuquerque"},{"value":"142054","label":"Carrington College-Boise"},{"value":"450702","label":"Carrington College-Citrus Heights"},{"value":"457101","label":"Carrington College-Las Vegas"},{"value":"103909","label":"Carrington College-Mesa"},{"value":"103893","label":"Carrington College-Phoenix"},{"value":"438258","label":"Carrington College-Pleasant Hill"},{"value":"467368","label":"Carrington College-Pomona"},{"value":"246035","label":"Carrington College-Portland"},{"value":"457110","label":"Carrington College-Reno"},{"value":"125532","label":"Carrington College-Sacramento"},{"value":"437936","label":"Carrington College-San Jose"},{"value":"246974","label":"Carrington College-San Leandro"},{"value":"439118","label":"Carrington College-Spokane"},{"value":"450696","label":"Carrington College-Stockton"},{"value":"103927","label":"Carrington College-Tucson"},{"value":"250601","label":"Carrington College-Westside"},{"value":"180106","label":"Carroll College"},{"value":"405872","label":"Carroll Community College"},{"value":"238458","label":"Carroll University"},{"value":"219806","label":"Carson-Newman University"},{"value":"198206","label":"Carteret Community College"},{"value":"238476","label":"Carthage College"},{"value":"139287","label":"Carver Bible College"},{"value":"430795","label":"Carver Career Center"},{"value":"111638","label":"Casa Loma College-Van Nuys"},{"value":"439190","label":"Cascadia College"},{"value":"201645","label":"Case Western Reserve University"},{"value":"240505","label":"Casper College"},{"value":"230834","label":"Castleton State College"},{"value":"198215","label":"Catawba College"},{"value":"198233","label":"Catawba Valley Community College"},{"value":"475398","label":"Catholic Distance University"},{"value":"143659","label":"Catholic Theological Union at Chicago"},{"value":"131283","label":"Catholic University of America"},{"value":"189839","label":"Cayuga County Community College"},{"value":"189848","label":"Cazenovia College"},{"value":"162104","label":"Cecil College"},{"value":"211468","label":"Cedar Crest College"},{"value":"223773","label":"Cedar Valley College"},{"value":"201654","label":"Cedarville University"},{"value":"183974","label":"Centenary College"},{"value":"158477","label":"Centenary College of Louisiana"},{"value":"379782","label":"Center for Advanced Legal Studies"},{"value":"241793","label":"Center for Advanced Studies On Puerto Rico and the Caribbean"},{"value":"232618","label":"Centra College of Nursing"},{"value":"100760","label":"Central Alabama Community College"},{"value":"104346","label":"Central Arizona College"},{"value":"106713","label":"Central Baptist College"},{"value":"154837","label":"Central Baptist Theological Seminary"},{"value":"198251","label":"Central Carolina Community College"},{"value":"218858","label":"Central Carolina Technical College"},{"value":"154855","label":"Central Christian College of Kansas"},{"value":"176910","label":"Central Christian College of the Bible"},{"value":"153108","label":"Central College"},{"value":"180902","label":"Central Community College"},{"value":"128771","label":"Central Connecticut State University"},{"value":"439525","label":"Central Florida Institute"},{"value":"483045","label":"Central Georgia Technical College"},{"value":"173203","label":"Central Lakes College-Brainerd"},{"value":"158088","label":"Central Louisiana Technical Community College"},{"value":"161077","label":"Central Maine Community College"},{"value":"445267","label":"Central Methodist University-College of Graduate and Extended Studies"},{"value":"176947","label":"Central Methodist University-College of Liberal Arts and Sciences"},{"value":"169248","label":"Central Michigan University"},{"value":"187532","label":"Central New Mexico Community College"},{"value":"201672","label":"Central Ohio Technical College"},{"value":"208318","label":"Central Oregon Community College"},{"value":"211477","label":"Central Penn College"},{"value":"198260","label":"Central Piedmont Community College"},{"value":"201690","label":"Central State University"},{"value":"223816","label":"Central Texas College"},{"value":"231697","label":"Central Virginia Community College"},{"value":"234827","label":"Central Washington University"},{"value":"240514","label":"Central Wyoming College"},{"value":"189857","label":"Central Yeshiva Tomchei Tmimim Lubavitz"},{"value":"234845","label":"Centralia College"},{"value":"156408","label":"Centre College"},{"value":"451741","label":"Centro de Estudios Multidisciplinarios-Bayamon"},{"value":"376224","label":"Centro de Estudios Multidisciplinarios-Humacao"},{"value":"241517","label":"Centro de Estudios Multidisciplinarios-San Juan"},{"value":"420024","label":"Centura College-Chesapeake"},{"value":"444972","label":"Centura College-Columbia"},{"value":"377449","label":"Centura College-Newport News"},{"value":"377458","label":"Centura College-Norfolk"},{"value":"427982","label":"Centura College-Richmond Main"},{"value":"232016","label":"Centura College-Virginia Beach"},{"value":"175315","label":"Century College-White Bear Lake"},{"value":"111887","label":"Cerritos College"},{"value":"111896","label":"Cerro Coso Community College"},{"value":"111920","label":"Chabot College"},{"value":"180948","label":"Chadron State College"},{"value":"111939","label":"Chaffey College"},{"value":"454245","label":"Chamberlain College of Nursing-Arizona"},{"value":"457129","label":"Chamberlain College of Nursing-Florida"},{"value":"475732","label":"Chamberlain College of Nursing-Georgia"},{"value":"454227","label":"Chamberlain College of Nursing-Illinois"},{"value":"466921","label":"Chamberlain College of Nursing-Missouri"},{"value":"454236","label":"Chamberlain College of Nursing-Ohio"},{"value":"466930","label":"Chamberlain College of Nursing-Texas"},{"value":"460871","label":"Chamberlain College of Nursing-Virginia"},{"value":"141486","label":"Chaminade University of Honolulu"},{"value":"230852","label":"Champlain College"},{"value":"364025","label":"Chandler-Gilbert Community College"},{"value":"111948","label":"Chapman University"},{"value":"111966","label":"Charles R Drew University of Medicine and Science"},{"value":"451510","label":"Charleston School of Law"},{"value":"217688","label":"Charleston Southern University"},{"value":"444778","label":"Charlotte Christian College and Theological Seminary"},{"value":"455169","label":"Charlotte School of Law"},{"value":"102845","label":"Charter College-Anchorage"},{"value":"434317","label":"Charter College-Canyon Country"},{"value":"128780","label":"Charter Oak State College"},{"value":"201751","label":"Chatfield College"},{"value":"211556","label":"Chatham University"},{"value":"140331","label":"Chattahoochee Technical College"},{"value":"101028","label":"Chattahoochee Valley Community College"},{"value":"220118","label":"Chattanooga College Medical Dental and Technical Careers"},{"value":"219824","label":"Chattanooga State Community College"},{"value":"208390","label":"Chemeketa Community College"},{"value":"162168","label":"Chesapeake College"},{"value":"437769","label":"Chester Career College"},{"value":"211583","label":"Chestnut Hill College"},{"value":"211608","label":"Cheyney University of Pennsylvania"},{"value":"181145","label":"CHI Health School of Radiologic Technology"},{"value":"393180","label":"Chicago ORT Technical Institute"},{"value":"144005","label":"Chicago State University"},{"value":"144014","label":"Chicago Theological Seminary"},{"value":"180160","label":"Chief Dull Knife College"},{"value":"133021","label":"Chipola College"},{"value":"240116","label":"Chippewa Valley Technical College"},{"value":"198303","label":"Chowan University"},{"value":"189981","label":"Christ the King Seminary"},{"value":"219833","label":"Christian Brothers University"},{"value":"260947","label":"Christian Life College"},{"value":"150215","label":"Christian Theological Seminary"},{"value":"475510","label":"Christie's Education"},{"value":"231712","label":"Christopher Newport University"},{"value":"112127","label":"Church Divinity School of the Pacific"},{"value":"201858","label":"Cincinnati Christian University"},{"value":"201867","label":"Cincinnati College of Mortuary Science"},{"value":"201928","label":"Cincinnati State Technical and Community College"},{"value":"223898","label":"Cisco College"},{"value":"217864","label":"Citadel Military College of South Carolina"},{"value":"112172","label":"Citrus College"},{"value":"112190","label":"City College of San Francisco"},{"value":"417327","label":"City College-Altamonte Springs"},{"value":"244233","label":"City College-Fort Lauderdale"},{"value":"406547","label":"City College-Gainesville"},{"value":"475477","label":"City College-Hollywood"},{"value":"434539","label":"City College-Miami"},{"value":"144209","label":"City Colleges of Chicago-Harold Washington College"},{"value":"144184","label":"City Colleges of Chicago-Harry S Truman College"},{"value":"144157","label":"City Colleges of Chicago-Kennedy-King College"},{"value":"144166","label":"City Colleges of Chicago-Malcolm X College"},{"value":"144175","label":"City Colleges of Chicago-Olive-Harvey College"},{"value":"144193","label":"City Colleges of Chicago-Richard J Daley College"},{"value":"144218","label":"City Colleges of Chicago-Wilbur Wright College"},{"value":"234915","label":"City University of Seattle"},{"value":"457697","label":"City Vision University"},{"value":"208406","label":"Clackamas Community College"},{"value":"217873","label":"Claflin University"},{"value":"112251","label":"Claremont Graduate University"},{"value":"112260","label":"Claremont McKenna College"},{"value":"124283","label":"Claremont School of Theology"},{"value":"223922","label":"Clarendon College"},{"value":"211644","label":"Clarion University of Pennsylvania"},{"value":"138947","label":"Clark Atlanta University"},{"value":"234933","label":"Clark College"},{"value":"201973","label":"Clark State Community College"},{"value":"165334","label":"Clark University"},{"value":"153126","label":"Clarke University"},{"value":"180832","label":"Clarkson College"},{"value":"190044","label":"Clarkson University"},{"value":"450401","label":"Clary Sage College"},{"value":"208415","label":"Clatsop Community College"},{"value":"139311","label":"Clayton State University"},{"value":"156417","label":"Clear Creek Baptist Bible College"},{"value":"133085","label":"Clearwater Christian College"},{"value":"169327","label":"Cleary University"},{"value":"217882","label":"Clemson University"},{"value":"198321","label":"Cleveland Community College"},{"value":"202046","label":"Cleveland Institute of Art"},{"value":"202073","label":"Cleveland Institute of Music"},{"value":"219879","label":"Cleveland State Community College"},{"value":"202134","label":"Cleveland State University"},{"value":"177038","label":"Cleveland University-Kansas City"},{"value":"217891","label":"Clinton College"},{"value":"190053","label":"Clinton Community College"},{"value":"154907","label":"Cloud County Community College"},{"value":"234951","label":"Clover Park Technical College"},{"value":"187639","label":"Clovis Community College"},{"value":"175519","label":"Coahoma Community College"},{"value":"223320","label":"Coastal Bend College"},{"value":"198330","label":"Coastal Carolina Community College"},{"value":"218724","label":"Coastal Carolina University"},{"value":"485458","label":"Coastal Pines Technical College-Waycross"},{"value":"112385","label":"Coastline Community College"},{"value":"104425","label":"Cochise County Community College District"},{"value":"190071","label":"Cochran School of Nursing"},{"value":"404426","label":"Coconino Community College"},{"value":"153144","label":"Coe College"},{"value":"154925","label":"Coffeyville Community College"},{"value":"112394","label":"Cogswell College"},{"value":"217907","label":"Coker College"},{"value":"161086","label":"Colby College"},{"value":"154934","label":"Colby Community College"},{"value":"182634","label":"Colby-Sawyer College"},{"value":"430935","label":"Colegio de Cinematografía Artes y Television"},{"value":"241720","label":"Colegio Universitario de San Juan"},{"value":"112446","label":"Coleman University"},{"value":"190080","label":"Colgate Rochester Crozer Divinity School"},{"value":"190099","label":"Colgate University"},{"value":"169442","label":"College for Creative Studies"},{"value":"108667","label":"College of Alameda"},{"value":"388520","label":"College of Biblical Studies-Houston"},{"value":"456977","label":"College of Business and Technology-Cutler Bay"},{"value":"449083","label":"College of Business and Technology-Flagler"},{"value":"449092","label":"College of Business and Technology-Hialeah"},{"value":"417318","label":"College of Business and Technology-Kendall"},{"value":"482024","label":"College of Business and Technology-Miami Gardens"},{"value":"132851","label":"College of Central Florida"},{"value":"217819","label":"College of Charleston"},{"value":"139250","label":"College of Coastal Georgia"},{"value":"150251","label":"College of Court Reporting Inc"},{"value":"144865","label":"College of DuPage"},{"value":"392257","label":"College of Health Care Professions-Northwest"},{"value":"146472","label":"College of Lake County"},{"value":"118347","label":"College of Marin"},{"value":"413617","label":"College of Menominee Nation"},{"value":"243638","label":"College of Micronesia-FSM"},{"value":"193399","label":"College of Mount Saint Vincent"},{"value":"167394","label":"College of Our Lady of the Elms"},{"value":"174747","label":"College of Saint Benedict"},{"value":"186618","label":"College of Saint Elizabeth"},{"value":"181604","label":"College of Saint Mary"},{"value":"122791","label":"College of San Mateo"},{"value":"142559","label":"College of Southern Idaho"},{"value":"162122","label":"College of Southern Maryland"},{"value":"182005","label":"College of Southern Nevada"},{"value":"231077","label":"College of St Joseph"},{"value":"190558","label":"College of Staten Island CUNY"},{"value":"197814","label":"College of the Albemarle"},{"value":"160959","label":"College of the Atlantic"},{"value":"111461","label":"College of the Canyons"},{"value":"113573","label":"College of the Desert"},{"value":"166124","label":"College of the Holy Cross"},{"value":"226408","label":"College of the Mainland"},{"value":"376695","label":"College of the Marshall Islands"},{"value":"480967","label":"College of the Muscogee Nation"},{"value":"107521","label":"College of the Ouachitas"},{"value":"178697","label":"College of the Ozarks"},{"value":"121707","label":"College of the Redwoods"},{"value":"123217","label":"College of the Sequoias"},{"value":"123484","label":"College of the Siskiyous"},{"value":"455114","label":"College of Western Idaho"},{"value":"231624","label":"College of William and Mary"},{"value":"451705","label":"CollegeAmerica-Cheyenne"},{"value":"448752","label":"CollegeAmerica-Colorado Springs"},{"value":"126872","label":"CollegeAmerica-Denver"},{"value":"103945","label":"CollegeAmerica-Flagstaff"},{"value":"448761","label":"CollegeAmerica-Fort Collins"},{"value":"474890","label":"CollegeAmerica-Phoenix"},{"value":"247834","label":"Collin County Community College District"},{"value":"103723","label":"Collins College"},{"value":"461953","label":"Colorado Academy of Veterinary Technology"},{"value":"126669","label":"Colorado Christian University"},{"value":"126678","label":"Colorado College"},{"value":"367839","label":"Colorado Heights University"},{"value":"127556","label":"Colorado Mesa University"},{"value":"126711","label":"Colorado Mountain College"},{"value":"126748","label":"Colorado Northwestern Community College"},{"value":"381732","label":"Colorado School of Healing Arts"},{"value":"126775","label":"Colorado School of Mines"},{"value":"126784","label":"Colorado School of Trades"},{"value":"381352","label":"Colorado School of Traditional Chinese Medicine"},{"value":"126818","label":"Colorado State University-Fort Collins"},{"value":"476975","label":"Colorado State University-Global Campus"},{"value":"128106","label":"Colorado State University-Pueblo"},{"value":"126827","label":"Colorado Technical University-Colorado Springs"},{"value":"430087","label":"Colorado Technical University-Greenwood Village"},{"value":"444158","label":"Colorado Technical University-Online"},{"value":"402615","label":"Colorado Technical University-Sioux Falls"},{"value":"234979","label":"Columbia Basin College"},{"value":"241304","label":"Columbia Central University-Caguas"},{"value":"404806","label":"Columbia Central University-Yauco"},{"value":"238573","label":"Columbia College of Nursing"},{"value":"144281","label":"Columbia College-Chicago"},{"value":"177065","label":"Columbia College-Columbia"},{"value":"217934","label":"Columbia College-Columbia"},{"value":"455983","label":"Columbia College-Fairfax"},{"value":"112570","label":"Columbia College-Hollywood"},{"value":"112561","label":"Columbia College-Sonora"},{"value":"420556","label":"Columbia Gorge Community College"},{"value":"217925","label":"Columbia International University"},{"value":"450933","label":"Columbia Southern University"},{"value":"219888","label":"Columbia State Community College"},{"value":"139348","label":"Columbia Theological Seminary"},{"value":"190150","label":"Columbia University in the City of New York"},{"value":"190169","label":"Columbia-Greene Community College"},{"value":"202170","label":"Columbus College of Art and Design"},{"value":"202222","label":"Columbus State Community College"},{"value":"139366","label":"Columbus State University"},{"value":"139357","label":"Columbus Technical College"},{"value":"483522","label":"Comanche Nation College"},{"value":"366261","label":"Commonwealth Institute of Funeral Service"},{"value":"212975","label":"Commonwealth Technical Institute"},{"value":"439570","label":"Community Care College"},{"value":"446163","label":"Community Christian College"},{"value":"210605","label":"Community College of Allegheny County"},{"value":"126863","label":"Community College of Aurora"},{"value":"211079","label":"Community College of Beaver County"},{"value":"126942","label":"Community College of Denver"},{"value":"215239","label":"Community College of Philadelphia"},{"value":"217475","label":"Community College of Rhode Island"},{"value":"230861","label":"Community College of Vermont"},{"value":"459417","label":"Compass College of Cinematic Arts"},{"value":"177083","label":"Conception Seminary College"},{"value":"237330","label":"Concord University"},{"value":"126687","label":"Concorde Career College-Aurora"},{"value":"460181","label":"Concorde Career College-Dallas"},{"value":"123679","label":"Concorde Career College-Garden Grove"},{"value":"441742","label":"Concorde Career College-Grand Prairie"},{"value":"155283","label":"Concorde Career College-Kansas City"},{"value":"219903","label":"Concorde Career College-Memphis"},{"value":"124937","label":"Concorde Career College-North Hollywood"},{"value":"208479","label":"Concorde Career College-Portland"},{"value":"460206","label":"Concorde Career College-San Antonio"},{"value":"124706","label":"Concorde Career College-San Bernardino"},{"value":"120661","label":"Concorde Career College-San Diego"},{"value":"133845","label":"Concorde Career Institute-Jacksonville"},{"value":"133854","label":"Concorde Career Institute-Miramar"},{"value":"460190","label":"Concorde Career Institute-Orlando"},{"value":"133863","label":"Concorde Career Institute-Tampa"},{"value":"101073","label":"Concordia College Alabama"},{"value":"173300","label":"Concordia College at Moorhead"},{"value":"190248","label":"Concordia College-New York"},{"value":"177092","label":"Concordia Seminary"},{"value":"150288","label":"Concordia Theological Seminary"},{"value":"169363","label":"Concordia University-Ann Arbor"},{"value":"144351","label":"Concordia University-Chicago"},{"value":"112075","label":"Concordia University-Irvine"},{"value":"180984","label":"Concordia University-Nebraska"},{"value":"208488","label":"Concordia University-Portland"},{"value":"173328","label":"Concordia University-Saint Paul"},{"value":"224004","label":"Concordia University-Texas"},{"value":"238616","label":"Concordia University-Wisconsin"},{"value":"128902","label":"Connecticut College"},{"value":"206996","label":"Connors State College"},{"value":"260354","label":"Consolidated School of Business-Lancaster"},{"value":"211820","label":"Consolidated School of Business-York"},{"value":"112826","label":"Contra Costa College"},{"value":"217961","label":"Converse College"},{"value":"165495","label":"Conway School of Landscape Design"},{"value":"190372","label":"Cooper Union for the Advancement of Science and Art"},{"value":"175573","label":"Copiah-Lincoln Community College"},{"value":"395362","label":"Copper Mountain Community College"},{"value":"162283","label":"Coppin State University"},{"value":"210331","label":"Corban University"},{"value":"153162","label":"Cornell College"},{"value":"190415","label":"Cornell University"},{"value":"170037","label":"Cornerstone University"},{"value":"190442","label":"Corning Community College"},{"value":"235024","label":"Cornish College of the Arts"},{"value":"106795","label":"Cossatot Community College of the University of Arkansas"},{"value":"113096","label":"Cosumnes River College"},{"value":"177117","label":"Cottey College"},{"value":"184180","label":"County College of Morris"},{"value":"224183","label":"Court Reporting Institute of Dallas"},{"value":"139393","label":"Covenant College"},{"value":"177126","label":"Covenant Theological Seminary"},{"value":"154952","label":"Cowley County Community College"},{"value":"176770","label":"Cox College"},{"value":"144485","label":"Coyne College"},{"value":"113111","label":"Crafton Hills College"},{"value":"169424","label":"Cranbrook Academy of Art"},{"value":"198367","label":"Craven Community College"},{"value":"181002","label":"Creighton University"},{"value":"475608","label":"Criswell College"},{"value":"439613","label":"Crossroads Bible College"},{"value":"174206","label":"Crossroads College"},{"value":"177135","label":"Crowder College"},{"value":"106810","label":"Crowley's Ridge College"},{"value":"174862","label":"Crown College"},{"value":"113193","label":"Cuesta College"},{"value":"444565","label":"Culinary Institute Inc"},{"value":"190503","label":"Culinary Institute of America"},{"value":"177144","label":"Culver-Stockton College"},{"value":"184205","label":"Cumberland County College"},{"value":"219949","label":"Cumberland University"},{"value":"190512","label":"CUNY Bernard M Baruch College"},{"value":"190521","label":"CUNY Borough of Manhattan Community College"},{"value":"190530","label":"CUNY Bronx Community College"},{"value":"190549","label":"CUNY Brooklyn College"},{"value":"190567","label":"CUNY City College"},{"value":"190576","label":"CUNY Graduate School and University Center"},{"value":"190585","label":"CUNY Hostos Community College"},{"value":"190594","label":"CUNY Hunter College"},{"value":"190600","label":"CUNY John Jay College of Criminal Justice"},{"value":"190619","label":"CUNY Kingsborough Community College"},{"value":"190628","label":"CUNY LaGuardia Community College"},{"value":"190637","label":"CUNY Lehman College"},{"value":"190646","label":"CUNY Medgar Evers College"},{"value":"190655","label":"CUNY New York City College of Technology"},{"value":"190664","label":"CUNY Queens College"},{"value":"190673","label":"CUNY Queensborough Community College"},{"value":"190682","label":"CUNY School of Law"},{"value":"190691","label":"CUNY York College"},{"value":"165529","label":"Curry College"},{"value":"211893","label":"Curtis Institute of Music"},{"value":"202356","label":"Cuyahoga Community College District"},{"value":"113218","label":"Cuyamaca College"},{"value":"113236","label":"Cypress College"},{"value":"231873","label":"Dabney S Lancaster Community College"},{"value":"458797","label":"Dade Medical College-Hollywood"},{"value":"458247","label":"Dade Medical College-Homestead"},{"value":"476391","label":"Dade Medical College-Jacksonville"},{"value":"444574","label":"Dade Medical College-Miami"},{"value":"454175","label":"Dade Medical College-Miami Lakes"},{"value":"476382","label":"Dade Medical College-West Palm Beach"},{"value":"190725","label":"Daemen College"},{"value":"200314","label":"Dakota College at Bottineau"},{"value":"173416","label":"Dakota County Technical College"},{"value":"219082","label":"Dakota State University"},{"value":"219091","label":"Dakota Wesleyan University"},{"value":"224226","label":"Dallas Baptist University"},{"value":"224244","label":"Dallas Christian College"},{"value":"224271","label":"Dallas Institute of Funeral Service"},{"value":"437732","label":"Dallas Nursing Institute"},{"value":"224305","label":"Dallas Theological Seminary"},{"value":"139463","label":"Dalton State College"},{"value":"182661","label":"Daniel Webster College"},{"value":"144564","label":"Danville Area Community College"},{"value":"231882","label":"Danville Community College"},{"value":"455178","label":"Daoist Traditions College of Chinese Medical Arts"},{"value":"182670","label":"Dartmouth College"},{"value":"138691","label":"Darton State College"},{"value":"169479","label":"Davenport University"},{"value":"198385","label":"Davidson College"},{"value":"198376","label":"Davidson County Community College"},{"value":"237358","label":"Davis & Elkins College"},{"value":"194569","label":"Davis College-Johnson City"},{"value":"202435","label":"Davis College-Toledo"},{"value":"180151","label":"Dawson Community College"},{"value":"447476","label":"Daymar College-Bellevue"},{"value":"363439","label":"Daymar College-Bowling Green"},{"value":"205568","label":"Daymar College-Chillicothe"},{"value":"205531","label":"Daymar College-Jackson"},{"value":"205559","label":"Daymar College-Lancaster"},{"value":"406219","label":"Daymar College-Louisville-Louisville"},{"value":"449302","label":"Daymar College-Madisonville"},{"value":"205522","label":"Daymar College-New Boston"},{"value":"458557","label":"Daymar College-Online"},{"value":"157465","label":"Daymar College-Owensboro"},{"value":"156903","label":"Daymar College-Paducah Main"},{"value":"368443","label":"Daymar Institute-Clarksville"},{"value":"444255","label":"Daymar Institute-Murfreesboro"},{"value":"220002","label":"Daymar Institute-Nashville"},{"value":"447014","label":"Daytona College"},{"value":"133386","label":"Daytona State College"},{"value":"113333","label":"De Anza College"},{"value":"165574","label":"Dean College"},{"value":"211909","label":"Dean Institute of Technology"},{"value":"202514","label":"Defiance College"},{"value":"224350","label":"Del Mar College"},{"value":"432524","label":"Delaware College of Art and Design"},{"value":"211927","label":"Delaware County Community College"},{"value":"130934","label":"Delaware State University"},{"value":"130891","label":"Delaware Technical Community College-Owens"},{"value":"130916","label":"Delaware Technical Community College-Stanton/Wilmington"},{"value":"130907","label":"Delaware Technical Community College-Terry"},{"value":"211981","label":"Delaware Valley University"},{"value":"158662","label":"Delgado Community College"},{"value":"113537","label":"Dell'Arte International School of Physical Theatre"},{"value":"169521","label":"Delta College"},{"value":"366270","label":"Delta College of Arts & Technology"},{"value":"158723","label":"Delta School of Business and Technology"},{"value":"175616","label":"Delta State University"},{"value":"202523","label":"Denison University"},{"value":"217989","label":"Denmark Technical College"},{"value":"454856","label":"Denver School of Nursing"},{"value":"126979","label":"Denver Seminary"},{"value":"144740","label":"DePaul University"},{"value":"150400","label":"DePauw University"},{"value":"153214","label":"Des Moines Area Community College"},{"value":"154156","label":"Des Moines University-Osteopathic Medical Center"},{"value":"210739","label":"DeSales University"},{"value":"113582","label":"Design Institute of San Diego"},{"value":"482413","label":"DeVry College of New York"},{"value":"482422","label":"DeVry University-Arizona"},{"value":"482431","label":"DeVry University-California"},{"value":"482440","label":"DeVry University-Colorado"},{"value":"482459","label":"DeVry University-Florida"},{"value":"482468","label":"DeVry University-Georgia"},{"value":"482477","label":"DeVry University-Illinois"},{"value":"482486","label":"DeVry University-Indiana"},{"value":"482501","label":"DeVry University-Maryland"},{"value":"482510","label":"DeVry University-Michigan"},{"value":"482529","label":"DeVry University-Minnesota"},{"value":"482538","label":"DeVry University-Missouri"},{"value":"482547","label":"DeVry University-Nevada"},{"value":"482556","label":"DeVry University-New Jersey"},{"value":"482565","label":"DeVry University-North Carolina"},{"value":"482574","label":"DeVry University-Ohio"},{"value":"482583","label":"DeVry University-Oklahoma"},{"value":"482592","label":"DeVry University-Oregon"},{"value":"482608","label":"DeVry University-Pennsylvania"},{"value":"482617","label":"DeVry University-Tennessee"},{"value":"482635","label":"DeVry University-Texas"},{"value":"482644","label":"DeVry University-Utah"},{"value":"482653","label":"DeVry University-Virginia"},{"value":"482662","label":"DeVry University-Washington"},{"value":"482671","label":"DeVry University-Wisconsin"},{"value":"443562","label":"Dewey University-Hato Rey-Hato Rey"},{"value":"113634","label":"Diablo Valley College"},{"value":"212009","label":"Dickinson College"},{"value":"200059","label":"Dickinson State University"},{"value":"443410","label":"DigiPen Institute of Technology"},{"value":"451060","label":"Digital Media Arts College"},{"value":"158802","label":"Dillard University"},{"value":"105297","label":"Dine College"},{"value":"153241","label":"Divine Word College"},{"value":"230171","label":"Dixie State University"},{"value":"181020","label":"Doane University-Arts & Sciences"},{"value":"448284","label":"Doane University-Graduate and Professional Studies"},{"value":"154998","label":"Dodge City Community College"},{"value":"190761","label":"Dominican College of Blauvelt"},{"value":"113704","label":"Dominican School of Philosophy & Theology"},{"value":"148496","label":"Dominican University"},{"value":"113698","label":"Dominican University of California"},{"value":"122117","label":"Dongguk University-Los Angeles"},{"value":"155007","label":"Donnelly College"},{"value":"153250","label":"Dordt College"},{"value":"212045","label":"Douglas Education Center"},{"value":"190770","label":"Dowling College"},{"value":"153269","label":"Drake University"},{"value":"184348","label":"Drew University"},{"value":"212054","label":"Drexel University"},{"value":"177214","label":"Drury University"},{"value":"212072","label":"Du Bois Business College-Du Bois"},{"value":"439303","label":"Du Bois Business College-Huntingdon"},{"value":"439312","label":"Du Bois Business College-Oil City"},{"value":"198419","label":"Duke University"},{"value":"173489","label":"Duluth Business University"},{"value":"175227","label":"Dunwoody College of Technology"},{"value":"212106","label":"Duquesne University"},{"value":"198455","label":"Durham Technical Community College"},{"value":"190840","label":"Dutchess Community College"},{"value":"220057","label":"Dyersburg State Community College"},{"value":"190716","label":"D'Youville College"},{"value":"447421","label":"Eagle Gate College-Layton"},{"value":"230366","label":"Eagle Gate College-Murray"},{"value":"447625","label":"Eagle Gate College-Salt Lake City"},{"value":"150455","label":"Earlham College"},{"value":"106883","label":"East Arkansas Community College"},{"value":"198464","label":"East Carolina University"},{"value":"177250","label":"East Central College"},{"value":"175643","label":"East Central Community College"},{"value":"207041","label":"East Central University"},{"value":"139621","label":"East Georgia State College"},{"value":"113856","label":"East Los Angeles College"},{"value":"175652","label":"East Mississippi Community College"},{"value":"413802","label":"East San Gabriel Valley Regional Occupational Program"},{"value":"212115","label":"East Stroudsburg University of Pennsylvania"},{"value":"220075","label":"East Tennessee State University"},{"value":"224527","label":"East Texas Baptist University"},{"value":"439394","label":"East West College of Natural Medicine"},{"value":"104577","label":"Eastern Arizona College"},{"value":"129215","label":"Eastern Connecticut State University"},{"value":"132693","label":"Eastern Florida State College"},{"value":"203331","label":"Eastern Gateway Community College"},{"value":"142179","label":"Eastern Idaho Technical College"},{"value":"144892","label":"Eastern Illinois University"},{"value":"448354","label":"Eastern International College-Belleville"},{"value":"421878","label":"Eastern International College-Jersey City"},{"value":"153311","label":"Eastern Iowa Community College District"},{"value":"156620","label":"Eastern Kentucky University"},{"value":"161138","label":"Eastern Maine Community College"},{"value":"232043","label":"Eastern Mennonite University"},{"value":"169798","label":"Eastern Michigan University"},{"value":"165644","label":"Eastern Nazarene College"},{"value":"187648","label":"Eastern New Mexico University-Main Campus"},{"value":"187666","label":"Eastern New Mexico University-Roswell Campus"},{"value":"383996","label":"Eastern New Mexico University-Ruidoso Campus"},{"value":"207050","label":"Eastern Oklahoma State College"},{"value":"208646","label":"Eastern Oregon University"},{"value":"232052","label":"Eastern Shore Community College"},{"value":"212133","label":"Eastern University"},{"value":"441858","label":"Eastern Virginia Career College"},{"value":"231970","label":"Eastern Virginia Medical School"},{"value":"235097","label":"Eastern Washington University"},{"value":"438708","label":"Eastern West Virginia Community and Technical College"},{"value":"240596","label":"Eastern Wyoming College"},{"value":"224572","label":"Eastfield College"},{"value":"144883","label":"East-West University"},{"value":"183488","label":"Eastwick College-Hackensack"},{"value":"184959","label":"Eastwick College-Ramsey"},{"value":"446233","label":"Ecclesia College"},{"value":"133492","label":"Eckerd College"},{"value":"460215","label":"Ecotech Institute"},{"value":"248934","label":"ECPI University"},{"value":"247162","label":"Ecumenical Theological Seminary"},{"value":"177278","label":"Eden Theological Seminary"},{"value":"198491","label":"Edgecombe Community College"},{"value":"238661","label":"Edgewood College"},{"value":"376321","label":"EDIC College"},{"value":"212160","label":"Edinboro University of Pennsylvania"},{"value":"202648","label":"Edison State Community College"},{"value":"235103","label":"Edmonds Community College"},{"value":"243832","label":"EDP Univeristy of Puerto Rico Inc-San Juan"},{"value":"241836","label":"EDP University of Puerto Rico Inc-San Sebastian"},{"value":"442806","label":"Edward Via College of Osteopathic Medicine"},{"value":"133526","label":"Edward Waters College"},{"value":"112686","label":"El Camino College-Compton Center"},{"value":"113980","label":"El Camino Community College District"},{"value":"224615","label":"El Centro College"},{"value":"224642","label":"El Paso Community College"},{"value":"144944","label":"Elgin Community College"},{"value":"198507","label":"Elizabeth City State University"},{"value":"212197","label":"Elizabethtown College"},{"value":"480134","label":"Elizabethtown College School of Continuing and Professional Studies"},{"value":"156648","label":"Elizabethtown Community and Technical College"},{"value":"153296","label":"Ellsworth Community College"},{"value":"144962","label":"Elmhurst College"},{"value":"190974","label":"Elmira Business Institute"},{"value":"190983","label":"Elmira College"},{"value":"198516","label":"Elon University"},{"value":"133553","label":"Embry-Riddle Aeronautical University-Daytona Beach"},{"value":"104586","label":"Embry-Riddle Aeronautical University-Prescott"},{"value":"426314","label":"Embry-Riddle Aeronautical University-Worldwide"},{"value":"165662","label":"Emerson College"},{"value":"220136","label":"Emmanuel Christian Seminary"},{"value":"165671","label":"Emmanuel College-Boston"},{"value":"139630","label":"Emmanuel College-Franklin Springs"},{"value":"153302","label":"Emmaus Bible College"},{"value":"232025","label":"Emory & Henry College"},{"value":"139658","label":"Emory University"},{"value":"114114","label":"Emperor's College of Traditional Oriental Medicine"},{"value":"114123","label":"Empire College"},{"value":"155025","label":"Emporia State University"},{"value":"165699","label":"Endicott College"},{"value":"101143","label":"Enterprise State Community College"},{"value":"124487","label":"Epic Bible College"},{"value":"165705","label":"Episcopal Divinity School"},{"value":"224712","label":"Episcopal Theological Seminary of the Southwest"},{"value":"191083","label":"Erie Community College"},{"value":"212434","label":"Erie Institute of Technology Inc"},{"value":"409254","label":"Erikson Institute"},{"value":"217998","label":"Erskine College"},{"value":"241951","label":"Escuela de Artes Plasticas de Puerto Rico"},{"value":"184481","label":"Essex County College"},{"value":"384333","label":"Estrella Mountain Community College"},{"value":"200590","label":"ETI Technical College"},{"value":"144971","label":"Eureka College"},{"value":"177339","label":"Evangel University"},{"value":"212443","label":"Evangelical Theological Seminary"},{"value":"371982","label":"Everest College-Anaheim"},{"value":"443854","label":"Everest College-Arlington"},{"value":"366544","label":"Everest College-Aurora"},{"value":"234739","label":"Everest College-Bremerton"},{"value":"438647","label":"Everest College-Chesapeake"},{"value":"372037","label":"Everest College-City of Industry"},{"value":"126401","label":"Everest College-Colorado Springs"},{"value":"442790","label":"Everest College-Dallas"},{"value":"363590","label":"Everest College-Everett"},{"value":"445197","label":"Everest College-Fort Worth"},{"value":"460358","label":"Everest College-Fort Worth South"},{"value":"182148","label":"Everest College-Henderson"},{"value":"445470","label":"Everest College-McLean"},{"value":"447236","label":"Everest College-Mesa"},{"value":"232502","label":"Everest College-Newport News"},{"value":"440299","label":"Everest College-Ontario Metro"},{"value":"103644","label":"Everest College-Phoenix"},{"value":"210359","label":"Everest College-Portland"},{"value":"119359","label":"Everest College-Reseda"},{"value":"230472","label":"Everest College-Salt Lake City"},{"value":"119508","label":"Everest College-San Bernardino"},{"value":"179070","label":"Everest College-Springfield"},{"value":"444024","label":"Everest College-Tacoma"},{"value":"127787","label":"Everest College-Thornton"},{"value":"236993","label":"Everest College-Vancouver"},{"value":"368805","label":"Everest College-West Los Angeles"},{"value":"237604","label":"Everest Institute-Cross Lanes"},{"value":"409670","label":"Everest Institute-Kendall"},{"value":"443748","label":"Everest Institute-Norcross"},{"value":"135957","label":"Everest Institute-North Miami"},{"value":"212090","label":"Everest Institute-Pittsburgh"},{"value":"194967","label":"Everest Institute-Rochester"},{"value":"260293","label":"Everest University-Brandon"},{"value":"438902","label":"Everest University-Jacksonville"},{"value":"367909","label":"Everest University-Lakeland"},{"value":"137810","label":"Everest University-Largo"},{"value":"420006","label":"Everest University-Melbourne"},{"value":"136288","label":"Everest University-North Orlando"},{"value":"445434","label":"Everest University-Orange Park"},{"value":"134149","label":"Everest University-Pompano Beach"},{"value":"390701","label":"Everest University-South Orlando"},{"value":"137801","label":"Everest University-Tampa"},{"value":"235149","label":"Everett Community College"},{"value":"385619","label":"Everglades University"},{"value":"114266","label":"Evergreen Valley College"},{"value":"196680","label":"Excelsior College"},{"value":"447458","label":"Expression College for Digital Arts"},{"value":"129242","label":"Fairfield University"},{"value":"184694","label":"Fairleigh Dickinson University-College at Florham"},{"value":"184603","label":"Fairleigh Dickinson University-Metropolitan Campus"},{"value":"237367","label":"Fairmont State University"},{"value":"153320","label":"Faith Baptist Bible College and Theological Seminary"},{"value":"443049","label":"Faith Evangelical College & Seminary"},{"value":"212452","label":"Faith Theological Seminary"},{"value":"443058","label":"Family of Faith College"},{"value":"196042","label":"Farmingdale State College"},{"value":"114354","label":"Fashion Institute of Design & Merchandising-Los Angeles"},{"value":"248846","label":"Fashion Institute of Design & Merchandising-San Diego"},{"value":"114390","label":"Fashion Institute of Design & Merchandising-San Francisco"},{"value":"191126","label":"Fashion Institute of Technology"},{"value":"101189","label":"Faulkner University"},{"value":"198543","label":"Fayetteville State University"},{"value":"198534","label":"Fayetteville Technical Community College"},{"value":"114433","label":"Feather River Community College District"},{"value":"184612","label":"Felician University"},{"value":"169910","label":"Ferris State University"},{"value":"232089","label":"Ferrum College"},{"value":"114549","label":"Fielding Graduate University"},{"value":"436599","label":"FINE Mortuary College"},{"value":"191199","label":"Finger Lakes Community College"},{"value":"475422","label":"Finger Lakes Health College of Nursing"},{"value":"172440","label":"Finlandia University"},{"value":"165802","label":"Fisher College"},{"value":"220181","label":"Fisk University"},{"value":"165820","label":"Fitchburg State University"},{"value":"114585","label":"Five Branches University"},{"value":"191205","label":"Five Towns College"},{"value":"133711","label":"Flagler College-St Augustine"},{"value":"444990","label":"Flagler College-Tallahassee"},{"value":"180197","label":"Flathead Valley Community College"},{"value":"160481","label":"Fletcher Technical Community College"},{"value":"155052","label":"Flint Hills Technical College"},{"value":"218025","label":"Florence-Darlington Technical College"},{"value":"133650","label":"Florida Agricultural and Mechanical University"},{"value":"133669","label":"Florida Atlantic University"},{"value":"133997","label":"Florida Career College-Miami"},{"value":"434715","label":"Florida Coastal School of Law"},{"value":"133809","label":"Florida College"},{"value":"434441","label":"Florida College of Integrative Medicine"},{"value":"438294","label":"Florida College of Natural Health-Bradenton"},{"value":"438285","label":"Florida College of Natural Health-Maitland"},{"value":"420103","label":"Florida College of Natural Health-Miami"},{"value":"387925","label":"Florida College of Natural Health-Pompano Beach"},{"value":"135160","label":"Florida Gateway College"},{"value":"433660","label":"Florida Gulf Coast University"},{"value":"133881","label":"Florida Institute of Technology"},{"value":"480569","label":"Florida Institute of Technology-Online"},{"value":"133951","label":"Florida International University"},{"value":"133960","label":"Florida Keys Community College"},{"value":"133979","label":"Florida Memorial University"},{"value":"408844","label":"Florida National University-Main Campus"},{"value":"134079","label":"Florida Southern College"},{"value":"133508","label":"Florida SouthWestern State College"},{"value":"133702","label":"Florida State College at Jacksonville"},{"value":"134097","label":"Florida State University"},{"value":"134112","label":"Florida Technical College"},{"value":"444219","label":"Folsom Lake College"},{"value":"380368","label":"Fond du Lac Tribal and Community College"},{"value":"177418","label":"Fontbonne University"},{"value":"114716","label":"Foothill College"},{"value":"191241","label":"Fordham University"},{"value":"177427","label":"Forest Institute of Professional Psychology"},{"value":"218043","label":"Forrest College"},{"value":"198552","label":"Forsyth Technical Community College"},{"value":"155061","label":"Fort Hays State University"},{"value":"127185","label":"Fort Lewis College"},{"value":"180212","label":"Fort Peck Community College"},{"value":"155098","label":"Fort Scott Community College"},{"value":"139719","label":"Fort Valley State University"},{"value":"439738","label":"Fortis College-Baton Rouge"},{"value":"205179","label":"Fortis College-Centerville"},{"value":"450067","label":"Fortis College-Cincinnati"},{"value":"460020","label":"Fortis College-Columbia"},{"value":"450058","label":"Fortis College-Columbus"},{"value":"480143","label":"Fortis College-Cutler Bay"},{"value":"204307","label":"Fortis College-Cuyahoga Falls"},{"value":"458681","label":"Fortis College-Indianapolis"},{"value":"451909","label":"Fortis College-Landover"},{"value":"447360","label":"Fortis College-Largo"},{"value":"371052","label":"Fortis College-Mobile"},{"value":"455488","label":"Fortis College-Montgomery-Montgomery"},{"value":"233329","label":"Fortis College-Norfolk"},{"value":"439792","label":"Fortis College-Orange Park"},{"value":"456180","label":"Fortis College-Phoenix"},{"value":"201399","label":"Fortis College-Ravenna"},{"value":"382957","label":"Fortis College-Richmond"},{"value":"456454","label":"Fortis College-Salt Lake City"},{"value":"372921","label":"Fortis College-Smyrna"},{"value":"132806","label":"Fortis College-Winter Park"},{"value":"442745","label":"Fortis Institute"},{"value":"455628","label":"Fortis Institute-Birmingham"},{"value":"418870","label":"Fortis Institute-Cookeville"},{"value":"216418","label":"Fortis Institute-Erie"},{"value":"443438","label":"Fortis Institute-Fort Lauderdale"},{"value":"249609","label":"Fortis Institute-Forty Fort"},{"value":"445753","label":"Fortis Institute-Miami"},{"value":"452124","label":"Fortis Institute-Nashville"},{"value":"455479","label":"Fortis Institute-Pensacola"},{"value":"445744","label":"Fortis Institute-Port Saint Lucie"},{"value":"385503","label":"Fortis Institute-Scranton"},{"value":"221795","label":"Fountainhead College of Technology"},{"value":"415774","label":"Four-D College"},{"value":"145239","label":"Fox College"},{"value":"238722","label":"Fox Valley Technical College"},{"value":"165866","label":"Framingham State University"},{"value":"218061","label":"Francis Marion University"},{"value":"114734","label":"Franciscan School of Theology"},{"value":"205957","label":"Franciscan University of Steubenville"},{"value":"104665","label":"Frank Lloyd Wright School of Architecture"},{"value":"224891","label":"Frank Phillips College"},{"value":"212577","label":"Franklin and Marshall College"},{"value":"150604","label":"Franklin College"},{"value":"182795","label":"Franklin Pierce University"},{"value":"202806","label":"Franklin University"},{"value":"441982","label":"Franklin W Olin College of Engineering"},{"value":"162557","label":"Frederick Community College"},{"value":"220215","label":"Freed-Hardeman University"},{"value":"372073","label":"Fremont College"},{"value":"114789","label":"Fresno City College"},{"value":"114813","label":"Fresno Pacific University"},{"value":"155089","label":"Friends University"},{"value":"127200","label":"Front Range Community College"},{"value":"403469","label":"Frontier Community College"},{"value":"156727","label":"Frontier Nursing University"},{"value":"162584","label":"Frostburg State University"},{"value":"134237","label":"Full Sail University"},{"value":"114840","label":"Fuller Theological Seminary in California"},{"value":"114859","label":"Fullerton College"},{"value":"191302","label":"Fulton-Montgomery Community College"},{"value":"218070","label":"Furman University"},{"value":"481030","label":"Future Generations Graduate School"},{"value":"101240","label":"Gadsden State Community College"},{"value":"452948","label":"Galen College of Nursing-Cincinnati"},{"value":"156471","label":"Galen College of Nursing-Louisville"},{"value":"406033","label":"Galen College of Nursing-San Antonio"},{"value":"406024","label":"Galen College of Nursing-Tampa Bay"},{"value":"131450","label":"Gallaudet University"},{"value":"205513","label":"Gallipolis Career College"},{"value":"224961","label":"Galveston College"},{"value":"212601","label":"Gannon University"},{"value":"155104","label":"Garden City Community College"},{"value":"198561","label":"Gardner-Webb University"},{"value":"162609","label":"Garrett College"},{"value":"145275","label":"Garrett-Evangelical Theological Seminary"},{"value":"198570","label":"Gaston College"},{"value":"157438","label":"Gateway Community and Technical College"},{"value":"130396","label":"Gateway Community College-New Haven"},{"value":"105145","label":"GateWay Community College-Phoenix"},{"value":"238759","label":"Gateway Technical College"},{"value":"114938","label":"Gavilan College"},{"value":"191339","label":"Genesee Community College"},{"value":"212656","label":"Geneva College"},{"value":"101286","label":"George C Wallace State Community College-Dothan"},{"value":"101295","label":"George C Wallace State Community College-Hanceville"},{"value":"101301","label":"George C Wallace State Community College-Selma"},{"value":"208822","label":"George Fox University"},{"value":"232186","label":"George Mason University"},{"value":"131469","label":"George Washington University"},{"value":"156745","label":"Georgetown College"},{"value":"131496","label":"Georgetown University"},{"value":"461236","label":"Georgia Christian University"},{"value":"139861","label":"Georgia College and State University"},{"value":"447689","label":"Georgia Gwinnett College"},{"value":"139700","label":"Georgia Highlands College"},{"value":"139755","label":"Georgia Institute of Technology-Main Campus"},{"value":"485111","label":"Georgia Military College-Milledgeville"},{"value":"139384","label":"Georgia Northwestern Technical College"},{"value":"244437","label":"Georgia Perimeter College"},{"value":"244446","label":"Georgia Piedmont Technical College"},{"value":"139931","label":"Georgia Southern University"},{"value":"139764","label":"Georgia Southwestern State University"},{"value":"139940","label":"Georgia State University"},{"value":"184773","label":"Georgian Court University"},{"value":"232195","label":"Germanna Community College"},{"value":"212674","label":"Gettysburg College"},{"value":"169974","label":"Glen Oaks Community College"},{"value":"104708","label":"Glendale Community College-Glendale"},{"value":"115001","label":"Glendale Community College-Glendale"},{"value":"237385","label":"Glenville State College"},{"value":"455390","label":"Global Health College"},{"value":"188465","label":"Globe Institute of Technology"},{"value":"466514","label":"Globe University-Appleton"},{"value":"456816","label":"Globe University-Eau Claire"},{"value":"458751","label":"Globe University–Green Bay"},{"value":"458991","label":"Globe University-La Crosse"},{"value":"458733","label":"Globe University-Madison East"},{"value":"458760","label":"Globe University–Madison West"},{"value":"456834","label":"Globe University-Minneapolis"},{"value":"456807","label":"Globe University-Sioux Falls"},{"value":"458779","label":"Globe University–Wausau"},{"value":"173629","label":"Globe University-Woodbury"},{"value":"230889","label":"Goddard College"},{"value":"202903","label":"Gods Bible School and College"},{"value":"169992","label":"Gogebic Community College"},{"value":"115083","label":"Golden Gate University-San Francisco"},{"value":"115126","label":"Golden West College"},{"value":"130989","label":"Goldey-Beacom College"},{"value":"430157","label":"Golf Academy of America-Altamonte Springs"},{"value":"122366","label":"Golf Academy of America-Carlsbad"},{"value":"476337","label":"Golf Academy of America-Farmers Branch"},{"value":"434690","label":"Golf Academy of America-Myrtle Beach"},{"value":"430166","label":"Golf Academy of America-Phoenix"},{"value":"235316","label":"Gonzaga University"},{"value":"202912","label":"Good Samaritan College of Nursing and Health Science"},{"value":"132523","label":"Gooding Institute of Nurse Anesthesia"},{"value":"129154","label":"Goodwin College"},{"value":"165936","label":"Gordon College"},{"value":"139968","label":"Gordon State College"},{"value":"165945","label":"Gordon-Conwell Theological Seminary"},{"value":"150668","label":"Goshen College"},{"value":"162654","label":"Goucher College"},{"value":"145336","label":"Governors State University"},{"value":"170000","label":"Grace Bible College"},{"value":"150677","label":"Grace College and Theological Seminary"},{"value":"461528","label":"Grace College of Divinity"},{"value":"481058","label":"Grace Mission University"},{"value":"481401","label":"Grace School of Theology"},{"value":"181093","label":"Grace University"},{"value":"153366","label":"Graceland University-Lamoni"},{"value":"483285","label":"Graduate School USA"},{"value":"115214","label":"Graduate Theological Union"},{"value":"159009","label":"Grambling State University"},{"value":"104717","label":"Grand Canyon University"},{"value":"170055","label":"Grand Rapids Community College"},{"value":"170082","label":"Grand Valley State University"},{"value":"153375","label":"Grand View University"},{"value":"183257","label":"Granite State College"},{"value":"442569","label":"Grantham University"},{"value":"212771","label":"Gratz College"},{"value":"235334","label":"Grays Harbor College"},{"value":"225070","label":"Grayson College"},{"value":"182306","label":"Great Basin College"},{"value":"183150","label":"Great Bay Community College"},{"value":"180249","label":"Great Falls College Montana State University"},{"value":"170091","label":"Great Lakes Christian College"},{"value":"213181","label":"Great Lakes Institute of Technology"},{"value":"230898","label":"Green Mountain College"},{"value":"235343","label":"Green River College"},{"value":"165981","label":"Greenfield Community College"},{"value":"198598","label":"Greensboro College"},{"value":"145372","label":"Greenville College"},{"value":"218113","label":"Greenville Technical College"},{"value":"153384","label":"Grinnell College"},{"value":"115296","label":"Grossmont College"},{"value":"212805","label":"Grove City College"},{"value":"240745","label":"Guam Community College"},{"value":"198613","label":"Guilford College"},{"value":"198622","label":"Guilford Technical Community College"},{"value":"134343","label":"Gulf Coast State College"},{"value":"139995","label":"Gupton Jones College of Funeral Service"},{"value":"173647","label":"Gustavus Adolphus College"},{"value":"140003","label":"Gwinnett College-Lilburn"},{"value":"140012","label":"Gwinnett Technical College"},{"value":"212832","label":"Gwynedd Mercy University"},{"value":"102313","label":"H Councill Trenholm State Community College"},{"value":"162690","label":"Hagerstown Community College"},{"value":"198640","label":"Halifax Community College"},{"value":"225201","label":"Hallmark University"},{"value":"191515","label":"Hamilton College"},{"value":"153427","label":"Hamilton Technical College"},{"value":"173665","label":"Hamline University"},{"value":"232256","label":"Hampden-Sydney College"},{"value":"166018","label":"Hampshire College"},{"value":"232265","label":"Hampton University"},{"value":"177542","label":"Hannibal-LaGrange University"},{"value":"150756","label":"Hanover College"},{"value":"212869","label":"Harcum College"},{"value":"107044","label":"Harding University"},{"value":"225247","label":"Hardin-Simmons University"},{"value":"162706","label":"Harford Community College"},{"value":"145460","label":"Harrington College of Design"},{"value":"212878","label":"Harrisburg Area Community College-Harrisburg"},{"value":"446640","label":"Harrisburg University of Science and Technology"},{"value":"458432","label":"Harrison College-Grove City"},{"value":"151166","label":"Harrison College-Indianapolis"},{"value":"468398","label":"Harrison College-Morrisville"},{"value":"177551","label":"Harris-Stowe State University"},{"value":"129491","label":"Hartford Seminary"},{"value":"115393","label":"Hartnell College"},{"value":"191533","label":"Hartwick College"},{"value":"166027","label":"Harvard University"},{"value":"115409","label":"Harvey Mudd College"},{"value":"155140","label":"Haskell Indian Nations University"},{"value":"181127","label":"Hastings College"},{"value":"212911","label":"Haverford College"},{"value":"383190","label":"Hawaii Community College"},{"value":"141644","label":"Hawaii Pacific University"},{"value":"153445","label":"Hawkeye Community College"},{"value":"198668","label":"Haywood Community College"},{"value":"156790","label":"Hazard Community and Technical College"},{"value":"173683","label":"Hazelden Betty Ford Graduate School of Addiction Studies"},{"value":"115533","label":"Heald College-Concord"},{"value":"115472","label":"Heald College-Fresno"},{"value":"371779","label":"Heald College-Hayward"},{"value":"141468","label":"Heald College-Honolulu"},{"value":"459930","label":"Heald College-Modesto"},{"value":"430148","label":"Heald College-Portland"},{"value":"115454","label":"Heald College-Rancho Cordova"},{"value":"363387","label":"Heald College-Roseville"},{"value":"409874","label":"Heald College-Salinas"},{"value":"115515","label":"Heald College-San Francisco"},{"value":"115490","label":"Heald College-San Jose"},{"value":"371760","label":"Heald College-Stockton"},{"value":"384342","label":"Heartland Community College"},{"value":"166045","label":"Hebrew College"},{"value":"145497","label":"Hebrew Theological College"},{"value":"203067","label":"Hebrew Union College-Jewish Institute of Religion"},{"value":"203085","label":"Heidelberg University"},{"value":"180276","label":"Helena College University of Montana"},{"value":"191597","label":"Helene Fuld College of Nursing"},{"value":"166054","label":"Hellenic College-Holy Cross Greek Orthodox School of Theology"},{"value":"156851","label":"Henderson Community College"},{"value":"107071","label":"Henderson State University"},{"value":"107080","label":"Hendrix College"},{"value":"173708","label":"Hennepin Technical College"},{"value":"170240","label":"Henry Ford College"},{"value":"198677","label":"Heritage Bible College"},{"value":"101453","label":"Heritage Christian University"},{"value":"262509","label":"Heritage College-Denver"},{"value":"445814","label":"Heritage College-Kansas City"},{"value":"410070","label":"Heritage College-Oklahoma City"},{"value":"456320","label":"Heritage College-Wichita"},{"value":"135124","label":"Heritage Institute-Ft Myers"},{"value":"372772","label":"Heritage Institute-Jacksonville"},{"value":"235422","label":"Heritage University"},{"value":"191612","label":"Herkimer County Community College"},{"value":"140340","label":"Herzing University-Atlanta"},{"value":"101365","label":"Herzing University-Birmingham"},{"value":"459851","label":"Herzing University-Brookfield"},{"value":"433536","label":"Herzing University-Kenner"},{"value":"459842","label":"Herzing University-Kenosha"},{"value":"240392","label":"Herzing University-Madison"},{"value":"174154","label":"Herzing University-Minneapolis"},{"value":"457022","label":"Herzing University-Toledo"},{"value":"386472","label":"Herzing University-Winter Park"},{"value":"155177","label":"Hesston College"},{"value":"173735","label":"Hibbing Community College"},{"value":"177579","label":"Hickey College"},{"value":"198695","label":"High Point University"},{"value":"145521","label":"Highland Community College-Freeport"},{"value":"155186","label":"Highland Community College-Highland"},{"value":"180081","label":"Highlands College of Montana Tech"},{"value":"235431","label":"Highline College"},{"value":"191621","label":"Hilbert College"},{"value":"225371","label":"Hill College"},{"value":"134495","label":"Hillsborough Community College"},{"value":"170286","label":"Hillsdale College"},{"value":"207157","label":"Hillsdale Free Will Baptist College"},{"value":"175786","label":"Hinds Community College"},{"value":"203128","label":"Hiram College"},{"value":"220312","label":"Hiwassee College"},{"value":"191630","label":"Hobart William Smith Colleges"},{"value":"134510","label":"Hobe Sound Bible College"},{"value":"203155","label":"Hocking College"},{"value":"367884","label":"Hodges University"},{"value":"191649","label":"Hofstra University"},{"value":"232308","label":"Hollins University"},{"value":"175810","label":"Holmes Community College"},{"value":"129534","label":"Holy Apostles College and Seminary"},{"value":"150774","label":"Holy Cross College"},{"value":"212984","label":"Holy Family University"},{"value":"115728","label":"Holy Names University"},{"value":"166133","label":"Holyoke Community College"},{"value":"203386","label":"Hondros College"},{"value":"141680","label":"Honolulu Community College"},{"value":"162760","label":"Hood College"},{"value":"443076","label":"Hood Theological Seminary"},{"value":"170301","label":"Hope College"},{"value":"120537","label":"Hope International University"},{"value":"156860","label":"Hopkinsville Community College"},{"value":"457226","label":"Horizon University"},{"value":"218140","label":"Horry-Georgetown Technical College"},{"value":"191676","label":"Houghton College"},{"value":"129543","label":"Housatonic Community College"},{"value":"225399","label":"Houston Baptist University"},{"value":"225423","label":"Houston Community College"},{"value":"246345","label":"Houston Graduate School of Theology"},{"value":"225520","label":"Howard College"},{"value":"162779","label":"Howard Community College"},{"value":"225548","label":"Howard Payne University"},{"value":"131520","label":"Howard University"},{"value":"184995","label":"Hudson County Community College"},{"value":"191719","label":"Hudson Valley Community College"},{"value":"242112","label":"Huertas College"},{"value":"164368","label":"Hult International Business School"},{"value":"242121","label":"Humacao Community College"},{"value":"115755","label":"Humboldt State University"},{"value":"115773","label":"Humphreys College-Stockton and Modesto Campuses"},{"value":"101435","label":"Huntingdon College"},{"value":"237437","label":"Huntington Junior College"},{"value":"150941","label":"Huntington University"},{"value":"449348","label":"Huntsville Bible College"},{"value":"212993","label":"Hussian College School of Art"},{"value":"161165","label":"Husson University"},{"value":"225575","label":"Huston-Tillotson University"},{"value":"155195","label":"Hutchinson Community College"},{"value":"127839","label":"IBMC College"},{"value":"372329","label":"IBMC College"},{"value":"193405","label":"Icahn School of Medicine at Mount Sinai"},{"value":"437662","label":"ICDC College"},{"value":"242130","label":"ICPR Junior College-Arecibo"},{"value":"243841","label":"ICPR Junior College-General Institutional"},{"value":"460677","label":"ICPR Junior College-Manati"},{"value":"242149","label":"ICPR Junior College-Mayaguez"},{"value":"142276","label":"Idaho State University"},{"value":"483780","label":"IGlobal University"},{"value":"127273","label":"Iliff School of Theology"},{"value":"434584","label":"Ilisagvik College"},{"value":"145682","label":"Illinois Central College"},{"value":"145691","label":"Illinois College"},{"value":"145628","label":"Illinois College of Optometry"},{"value":"145725","label":"Illinois Institute of Technology"},{"value":"145813","label":"Illinois State University"},{"value":"145831","label":"Illinois Valley Community College"},{"value":"145646","label":"Illinois Wesleyan University"},{"value":"213011","label":"Immaculata University"},{"value":"115861","label":"Imperial Valley College"},{"value":"155201","label":"Independence Community College"},{"value":"465812","label":"Independence University"},{"value":"153472","label":"Indian Hills Community College"},{"value":"134608","label":"Indian River State College"},{"value":"151290","label":"Indiana Institute of Technology"},{"value":"151324","label":"Indiana State University"},{"value":"213020","label":"Indiana University of Pennsylvania-Main Campus"},{"value":"151351","label":"Indiana University-Bloomington"},{"value":"151388","label":"Indiana University-East"},{"value":"151333","label":"Indiana University-Kokomo"},{"value":"151360","label":"Indiana University-Northwest"},{"value":"151102","label":"Indiana University-Purdue University-Fort Wayne"},{"value":"151111","label":"Indiana University-Purdue University-Indianapolis"},{"value":"151342","label":"Indiana University-South Bend"},{"value":"151379","label":"Indiana University-Southeast"},{"value":"151801","label":"Indiana Wesleyan University"},{"value":"145886","label":"Institute for Clinical Social Work"},{"value":"462044","label":"Institute for Doctoral Studies in the Visual Arts"},{"value":"445869","label":"Institute for the Psychological Sciences"},{"value":"187745","label":"Institute of American Indian and Alaska Native Culture"},{"value":"444699","label":"Institute of Clinical Acupuncture & Oriental Med"},{"value":"191764","label":"Institute of Design and Construction"},{"value":"454616","label":"Institute of Production and Recording"},{"value":"454838","label":"Institute of Taoist Education and Acupuncture"},{"value":"431141","label":"Institute of Technology Inc-Clovis"},{"value":"455804","label":"Institute of World Politics"},{"value":"242422","label":"Instituto de Banca y Comercio Inc"},{"value":"242556","label":"Instituto Tecnologico de Puerto Rico-Recinto de Guayama"},{"value":"242042","label":"Instituto Tecnologico de Puerto Rico-Recinto de Manati"},{"value":"242565","label":"Instituto Tecnologico de Puerto Rico-Recinto de Ponce"},{"value":"242583","label":"Instituto Tecnologico de Puerto Rico-Recinto de San Juan"},{"value":"128179","label":"Intellitec College-Colorado Springs"},{"value":"128188","label":"Intellitec College-Grand Junction"},{"value":"242626","label":"Inter American University of Puerto Rico-Aguadilla"},{"value":"242635","label":"Inter American University of Puerto Rico-Arecibo"},{"value":"242644","label":"Inter American University of Puerto Rico-Barranquitas"},{"value":"242705","label":"Inter American University of Puerto Rico-Bayamon"},{"value":"242680","label":"Inter American University of Puerto Rico-Fajardo"},{"value":"242699","label":"Inter American University of Puerto Rico-Guayama"},{"value":"242653","label":"Inter American University of Puerto Rico-Metro"},{"value":"242662","label":"Inter American University of Puerto Rico-Ponce"},{"value":"242617","label":"Inter American University of Puerto Rico-San German"},{"value":"242723","label":"Inter American University of Puerto Rico-School of Law"},{"value":"404222","label":"Inter American University of Puerto Rico-School of Optometry"},{"value":"138655","label":"Interactive College of Technology-Chamblee"},{"value":"442435","label":"Interactive College of Technology-Gainesville"},{"value":"367361","label":"Interactive College of Technology-Houston"},{"value":"443696","label":"Interactive College of Technology-Houston"},{"value":"138664","label":"Interactive College of Technology-Morrow"},{"value":"367103","label":"Interactive College of Technology-Newport"},{"value":"440776","label":"Interactive College of Technology-Pasadena"},{"value":"366289","label":"InterCoast Colleges-Orange"},{"value":"140146","label":"Interdenominational Theological Center"},{"value":"235495","label":"Interface College-Spokane"},{"value":"116226","label":"Interior Designers Institute"},{"value":"446817","label":"International Academy of Design and Technology-Nashville"},{"value":"450447","label":"International Academy of Design and Technology-Sacramento"},{"value":"445124","label":"International Academy of Design and Technology-Troy"},{"value":"436614","label":"International Baptist College and Seminary"},{"value":"225779","label":"International Business College-El Paso-El Paso"},{"value":"225788","label":"International Business College-El Paso-El Paso"},{"value":"151458","label":"International Business College-Fort Wayne"},{"value":"151467","label":"International Business College-Indianapolis"},{"value":"203289","label":"International College of Broadcasting"},{"value":"448691","label":"International Institute for Restorative Practices"},{"value":"454740","label":"International Professional School of Bodywork"},{"value":"443128","label":"International Technological University"},{"value":"173799","label":"Inver Hills Community College"},{"value":"191931","label":"Iona College"},{"value":"153524","label":"Iowa Central Community College"},{"value":"153533","label":"Iowa Lakes Community College"},{"value":"153603","label":"Iowa State University"},{"value":"153621","label":"Iowa Wesleyan University"},{"value":"153630","label":"Iowa Western Community College"},{"value":"441238","label":"Irell & Manella Graduate School of Biological Sciences at City of Hope"},{"value":"116439","label":"Irvine Valley College"},{"value":"191959","label":"Island Drafting and Technical Institute"},{"value":"198710","label":"Isothermal Community College"},{"value":"173805","label":"Itasca Community College"},{"value":"175829","label":"Itawamba Community College"},{"value":"191968","label":"Ithaca College"},{"value":"159197","label":"ITI Technical College"},{"value":"459611","label":"ITT Technical Institute-Akron"},{"value":"434566","label":"ITT Technical Institute-Albany"},{"value":"369084","label":"ITT Technical Institute-Albuquerque"},{"value":"225849","label":"ITT Technical Institute-Arlington"},{"value":"260974","label":"ITT Technical Institute-Arlington Heights"},{"value":"434548","label":"ITT Technical Institute-Arnold"},{"value":"450243","label":"ITT Technical Institute-Atlanta"},{"value":"459675","label":"ITT Technical Institute-Aurora"},{"value":"366678","label":"ITT Technical Institute-Austin"},{"value":"450216","label":"ITT Technical Institute-Baton Rouge"},{"value":"414568","label":"ITT Technical Institute-Bessemer"},{"value":"142337","label":"ITT Technical Institute-Boise"},{"value":"470852","label":"ITT Technical Institute-Bradenton"},{"value":"470870","label":"ITT Technical Institute-Brooklyn Center"},{"value":"442338","label":"ITT Technical Institute-Canton"},{"value":"451936","label":"ITT Technical Institute-Cary"},{"value":"441964","label":"ITT Technical Institute-Chantilly"},{"value":"456445","label":"ITT Technical Institute-Charlotte North"},{"value":"448442","label":"ITT Technical Institute-Charlotte South"},{"value":"450261","label":"ITT Technical Institute-Chattanooga"},{"value":"451954","label":"ITT Technical Institute-Clive"},{"value":"448451","label":"ITT Technical Institute-Clovis"},{"value":"450225","label":"ITT Technical Institute-Columbia"},{"value":"451963","label":"ITT Technical Institute-Columbus"},{"value":"456427","label":"ITT Technical Institute-Concord"},{"value":"413884","label":"ITT Technical Institute-Cordova"},{"value":"459639","label":"ITT Technical Institute-Corona"},{"value":"459693","label":"ITT Technical Institute-Culver City"},{"value":"203313","label":"ITT Technical Institute-Dayton"},{"value":"459709","label":"ITT Technical Institute-Dearborn"},{"value":"479619","label":"ITT Technical Institute-Deerfield Beach"},{"value":"459657","label":"ITT Technical Institute-DeSoto"},{"value":"479637","label":"ITT Technical Institute-Douglasville"},{"value":"443526","label":"ITT Technical Institute-Duluth"},{"value":"448460","label":"ITT Technical Institute-Dunmore"},{"value":"462363","label":"ITT Technical Institute-Durham"},{"value":"176637","label":"ITT Technical Institute-Earth City"},{"value":"445081","label":"ITT Technical Institute-Eden Prairie"},{"value":"414531","label":"ITT Technical Institute-Everett"},{"value":"409069","label":"ITT Technical Institute-Fort Lauderdale"},{"value":"456436","label":"ITT Technical Institute-Fort Myers"},{"value":"151500","label":"ITT Technical Institute-Fort Wayne"},{"value":"479567","label":"ITT Technical Institute-Germantown"},{"value":"420404","label":"ITT Technical Institute-Getzville"},{"value":"440165","label":"ITT Technical Institute-Green Bay"},{"value":"238892","label":"ITT Technical Institute-Greenfield"},{"value":"413866","label":"ITT Technical Institute-Greenville"},{"value":"462372","label":"ITT Technical Institute-Hanover"},{"value":"430351","label":"ITT Technical Institute-Harrisburg"},{"value":"429599","label":"ITT Technical Institute-Henderson"},{"value":"430263","label":"ITT Technical Institute-Hialeah"},{"value":"451990","label":"ITT Technical Institute-High Point"},{"value":"443535","label":"ITT Technical Institute-Hilliard"},{"value":"366696","label":"ITT Technical Institute-Houston North"},{"value":"225858","label":"ITT Technical Institute-Houston West"},{"value":"456418","label":"ITT Technical Institute-Huntington"},{"value":"151519","label":"ITT Technical Institute-Indianapolis"},{"value":"479628","label":"ITT Technical Institute-Indianapolis East"},{"value":"407063","label":"ITT Technical Institute-Jacksonville"},{"value":"459648","label":"ITT Technical Institute-Johnson City"},{"value":"446899","label":"ITT Technical Institute-Kansas City"},{"value":"446905","label":"ITT Technical Institute-Kennesaw"},{"value":"366650","label":"ITT Technical Institute-Knoxville"},{"value":"372578","label":"ITT Technical Institute-Lake Mary"},{"value":"459718","label":"ITT Technical Institute-Las Vegas"},{"value":"437219","label":"ITT Technical Institute-Lathrop"},{"value":"440642","label":"ITT Technical Institute-Levittown"},{"value":"448488","label":"ITT Technical Institute-Lexington"},{"value":"413839","label":"ITT Technical Institute-Little Rock"},{"value":"434575","label":"ITT Technical Institute-Liverpool"},{"value":"413857","label":"ITT Technical Institute-Louisville"},{"value":"451945","label":"ITT Technical Institute-Madison-Madison"},{"value":"451981","label":"ITT Technical Institute-Madison-Madison"},{"value":"456393","label":"ITT Technical Institute-Madison-Madison"},{"value":"479558","label":"ITT Technical Institute-Marlton"},{"value":"448497","label":"ITT Technical Institute-Maumee"},{"value":"459587","label":"ITT Technical Institute-Merrillville"},{"value":"450252","label":"ITT Technical Institute-Mobile"},{"value":"230384","label":"ITT Technical Institute-Murray"},{"value":"470904","label":"ITT Technical Institute-Myrtle Beach"},{"value":"151494","label":"ITT Technical Institute-Nashville"},{"value":"116466","label":"ITT Technical Institute-National City"},{"value":"251251","label":"ITT Technical Institute-Newburgh"},{"value":"368601","label":"ITT Technical Institute-Norfolk"},{"value":"459666","label":"ITT Technical Institute-North Charleston"},{"value":"366580","label":"ITT Technical Institute-Norwood-Norwood"},{"value":"430379","label":"ITT Technical Institute-Norwood-Norwood"},{"value":"434557","label":"ITT Technical Institute-Oak Brook"},{"value":"467058","label":"ITT Technical Institute-Oakland"},{"value":"448503","label":"ITT Technical Institute-Oklahoma City"},{"value":"407319","label":"ITT Technical Institute-Omaha"},{"value":"116484","label":"ITT Technical Institute-Orange"},{"value":"414586","label":"ITT Technical Institute-Orland Park"},{"value":"470889","label":"ITT Technical Institute-Orlando"},{"value":"479646","label":"ITT Technical Institute-Overland Park"},{"value":"446914","label":"ITT Technical Institute-Owings Mills"},{"value":"413848","label":"ITT Technical Institute-Oxnard"},{"value":"479549","label":"ITT Technical Institute-Philadelphia"},{"value":"451972","label":"ITT Technical Institute-Phoenix"},{"value":"470861","label":"ITT Technical Institute-Phoenix West"},{"value":"414841","label":"ITT Technical Institute-Pittsburgh"},{"value":"442347","label":"ITT Technical Institute-Plymouth Meeting"},{"value":"208965","label":"ITT Technical Institute-Portland"},{"value":"108250","label":"ITT Technical Institute-Rancho Cordova"},{"value":"434052","label":"ITT Technical Institute-Richardson"},{"value":"437051","label":"ITT Technical Institute-Richmond"},{"value":"437042","label":"ITT Technical Institute-Saint Rose"},{"value":"459602","label":"ITT Technical Institute-Salem-Salem"},{"value":"479600","label":"ITT Technical Institute-Salem-Salem"},{"value":"377069","label":"ITT Technical Institute-San Antonio"},{"value":"481623","label":"ITT Technical Institute-San Antonio East"},{"value":"381909","label":"ITT Technical Institute-San Bernardino"},{"value":"116475","label":"ITT Technical Institute-San Dimas"},{"value":"235510","label":"ITT Technical Institute-Seattle"},{"value":"450270","label":"ITT Technical Institute-South Bend"},{"value":"479585","label":"ITT Technical Institute-Southfield"},{"value":"235529","label":"ITT Technical Institute-Spokane Valley"},{"value":"441955","label":"ITT Technical Institute-Springfield-Springfield"},{"value":"456409","label":"ITT Technical Institute-Springfield-Springfield"},{"value":"479655","label":"ITT Technical Institute-Springfield-Springfield"},{"value":"450207","label":"ITT Technical Institute-St Petersburg"},{"value":"430388","label":"ITT Technical Institute-Strongsville"},{"value":"448479","label":"ITT Technical Institute-Swartz Creek"},{"value":"244011","label":"ITT Technical Institute-Sylmar"},{"value":"459596","label":"ITT Technical Institute-Tallahassee"},{"value":"134909","label":"ITT Technical Institute-Tampa"},{"value":"430360","label":"ITT Technical Institute-Tarentum"},{"value":"105172","label":"ITT Technical Institute-Tempe"},{"value":"378406","label":"ITT Technical Institute-Torrance"},{"value":"261472","label":"ITT Technical Institute-Troy"},{"value":"105163","label":"ITT Technical Institute-Tucson"},{"value":"448512","label":"ITT Technical Institute-Tulsa"},{"value":"470898","label":"ITT Technical Institute-Waco"},{"value":"446923","label":"ITT Technical Institute-Warrensville Heights"},{"value":"427663","label":"ITT Technical Institute-Webster"},{"value":"479664","label":"ITT Technical Institute-West Chester"},{"value":"459684","label":"ITT Technical Institute-West Covina"},{"value":"479594","label":"ITT Technical Institute-West Palm Beach"},{"value":"244154","label":"ITT Technical Institute-Westminster"},{"value":"450234","label":"ITT Technical Institute-Wichita"},{"value":"439136","label":"ITT Technical Institute-Wilmington"},{"value":"170417","label":"ITT Technical Institute-Wyoming"},{"value":"206631","label":"ITT Technical Institute-Youngstown"},{"value":"150987","label":"Ivy Tech Community College"},{"value":"101462","label":"J F Drake State Community and Technical College"},{"value":"101471","label":"J F Ingram State Technical College"},{"value":"232414","label":"J Sargeant Reynolds Community College"},{"value":"170444","label":"Jackson College"},{"value":"220400","label":"Jackson State Community College"},{"value":"175856","label":"Jackson State University"},{"value":"225876","label":"Jacksonville College-Main Campus"},{"value":"101480","label":"Jacksonville State University"},{"value":"134945","label":"Jacksonville University"},{"value":"203678","label":"James A Rhodes State College"},{"value":"101161","label":"James H Faulkner State Community College"},{"value":"232423","label":"James Madison University"},{"value":"198729","label":"James Sprunt Community College"},{"value":"192004","label":"Jamestown Business College"},{"value":"191986","label":"Jamestown Community College"},{"value":"225885","label":"Jarvis Christian College"},{"value":"177676","label":"Jefferson College"},{"value":"231837","label":"Jefferson College of Health Sciences"},{"value":"156921","label":"Jefferson Community and Technical College"},{"value":"192022","label":"Jefferson Community College"},{"value":"101499","label":"Jefferson Davis Community College"},{"value":"101505","label":"Jefferson State Community College"},{"value":"455196","label":"Jersey College"},{"value":"192040","label":"Jewish Theological Seminary of America"},{"value":"419341","label":"Jna Institute of Culinary Arts"},{"value":"220464","label":"John A Gupton College"},{"value":"146205","label":"John A Logan College"},{"value":"107141","label":"John Brown University"},{"value":"101514","label":"John C Calhoun State Community College"},{"value":"203368","label":"John Carroll University"},{"value":"116712","label":"John F. Kennedy University"},{"value":"462354","label":"John Paul the Great Catholic University"},{"value":"232450","label":"John Tyler Community College"},{"value":"146278","label":"John Wood Community College"},{"value":"162928","label":"Johns Hopkins University"},{"value":"445708","label":"Johnson & Wales University-Charlotte"},{"value":"439288","label":"Johnson & Wales University-Denver"},{"value":"414823","label":"Johnson & Wales University-North Miami"},{"value":"460349","label":"Johnson & Wales University-Online"},{"value":"217235","label":"Johnson & Wales University-Providence"},{"value":"198756","label":"Johnson C Smith University"},{"value":"213233","label":"Johnson College"},{"value":"155210","label":"Johnson County Community College"},{"value":"230913","label":"Johnson State College"},{"value":"220473","label":"Johnson University"},{"value":"132879","label":"Johnson University Florida"},{"value":"198774","label":"Johnston Community College"},{"value":"146296","label":"Joliet Junior College"},{"value":"135063","label":"Jones College-Jacksonville"},{"value":"175883","label":"Jones County Junior College"},{"value":"444723","label":"Jones International University"},{"value":"461281","label":"Jose Maria Vargas University"},{"value":"101541","label":"Judson College"},{"value":"146339","label":"Judson University"},{"value":"461139","label":"Jung Tao School of Classical Chinese Medicine"},{"value":"213251","label":"Juniata College"},{"value":"170532","label":"Kalamazoo College"},{"value":"170541","label":"Kalamazoo Valley Community College"},{"value":"146348","label":"Kankakee Community College"},{"value":"177746","label":"Kansas City Art Institute"},{"value":"155308","label":"Kansas City College & Bible School"},{"value":"155292","label":"Kansas City Kansas Community College"},{"value":"179812","label":"Kansas City University of Medicine and Biosciences"},{"value":"155399","label":"Kansas State University"},{"value":"155414","label":"Kansas Wesleyan University"},{"value":"141796","label":"Kapiolani Community College"},{"value":"458715","label":"Kaplan College-Jacksonville"},{"value":"445346","label":"Kaplan College-Lubbock"},{"value":"480064","label":"Kaplan University-Augusta Campus"},{"value":"260910","label":"Kaplan University-Cedar Falls Campus"},{"value":"153418","label":"Kaplan University-Cedar Rapids Campus"},{"value":"260901","label":"Kaplan University-Davenport Campus"},{"value":"367024","label":"Kaplan University-Des Moines Campus"},{"value":"162681","label":"Kaplan University-Hagerstown Campus"},{"value":"181242","label":"Kaplan University-Lincoln Campus"},{"value":"160940","label":"Kaplan University-Maine Campus"},{"value":"153409","label":"Kaplan University-Mason City Campus"},{"value":"181400","label":"Kaplan University-Omaha Campus"},{"value":"146366","label":"Kaskaskia College"},{"value":"141802","label":"Kauai Community College"},{"value":"225991","label":"KD College Conservatory of Film and Dramatic Arts"},{"value":"185262","label":"Kean University"},{"value":"440031","label":"Keck Graduate Institute"},{"value":"183062","label":"Keene State College"},{"value":"192165","label":"Kehilath Yakov Rabbinical Seminary"},{"value":"135081","label":"Keiser University-Ft Lauderdale"},{"value":"170550","label":"Kellogg Community College"},{"value":"146393","label":"Kendall College"},{"value":"161192","label":"Kennebec Valley Community College"},{"value":"140164","label":"Kennesaw State University"},{"value":"177816","label":"Kenrick Glennon Seminary"},{"value":"203447","label":"Kent State University at Ashtabula"},{"value":"203456","label":"Kent State University at East Liverpool"},{"value":"203526","label":"Kent State University at Geauga"},{"value":"203517","label":"Kent State University at Kent"},{"value":"203492","label":"Kent State University at Salem"},{"value":"203465","label":"Kent State University at Stark"},{"value":"203474","label":"Kent State University at Trumbull"},{"value":"203483","label":"Kent State University at Tuscarawas"},{"value":"157100","label":"Kentucky Christian University"},{"value":"157030","label":"Kentucky Mountain Bible College"},{"value":"157058","label":"Kentucky State University"},{"value":"157076","label":"Kentucky Wesleyan College"},{"value":"203535","label":"Kenyon College"},{"value":"203544","label":"Kettering College"},{"value":"169983","label":"Kettering University"},{"value":"192192","label":"Keuka College"},{"value":"461315","label":"Keweenaw Bay Ojibwa Community College"},{"value":"134422","label":"Key College"},{"value":"213303","label":"Keystone College"},{"value":"210483","label":"Keystone Technical Institute"},{"value":"226019","label":"Kilgore College"},{"value":"219055","label":"Kilian Community College"},{"value":"220516","label":"King University"},{"value":"382504","label":"King's College-Charlotte"},{"value":"213321","label":"King's College-Wilkes-Barre"},{"value":"153737","label":"Kirkwood Community College"},{"value":"170587","label":"Kirtland Community College"},{"value":"146418","label":"Kishwaukee College"},{"value":"428392","label":"Klamath Community College"},{"value":"260956","label":"Knowledge Systems Institute"},{"value":"146427","label":"Knox College"},{"value":"484288","label":"Knox Theological Seminary"},{"value":"213349","label":"Kutztown University of Pennsylvania"},{"value":"171881","label":"Kuyper College"},{"value":"213358","label":"La Roche College"},{"value":"213367","label":"La Salle University"},{"value":"117627","label":"La Sierra University"},{"value":"155450","label":"Labette Community College"},{"value":"165264","label":"Laboure College"},{"value":"260372","label":"Lac Courte Oreilles Ojibwa Community College"},{"value":"213376","label":"Lackawanna College"},{"value":"213385","label":"Lafayette College"},{"value":"140234","label":"LaGrange College"},{"value":"117168","label":"Laguna College of Art and Design"},{"value":"219143","label":"Lake Area Technical Institute"},{"value":"203580","label":"Lake Erie College"},{"value":"407629","label":"Lake Erie College of Osteopathic Medicine"},{"value":"146481","label":"Lake Forest College"},{"value":"146490","label":"Lake Forest Graduate School of Management"},{"value":"146506","label":"Lake Land College"},{"value":"170620","label":"Lake Michigan College"},{"value":"200192","label":"Lake Region State College"},{"value":"173461","label":"Lake Superior College"},{"value":"170639","label":"Lake Superior State University"},{"value":"117195","label":"Lake Tahoe Community College"},{"value":"235699","label":"Lake Washington Institute of Technology"},{"value":"238980","label":"Lakeland College"},{"value":"203599","label":"Lakeland Community College"},{"value":"183123","label":"Lakes Region Community College"},{"value":"239008","label":"Lakeshore Technical College"},{"value":"135188","label":"Lake-Sumter State College"},{"value":"146533","label":"Lakeview College of Nursing"},{"value":"127389","label":"Lamar Community College"},{"value":"441760","label":"Lamar Institute of Technology"},{"value":"226107","label":"Lamar State College-Orange"},{"value":"226116","label":"Lamar State College-Port Arthur"},{"value":"226091","label":"Lamar University"},{"value":"213400","label":"Lancaster Bible College"},{"value":"418533","label":"Lancaster County Career and Technology Center"},{"value":"213446","label":"Lancaster Theological Seminary"},{"value":"218229","label":"Lander University"},{"value":"247649","label":"Landmark College"},{"value":"220598","label":"Lane College"},{"value":"209038","label":"Lane Community College"},{"value":"117247","label":"Laney College"},{"value":"207209","label":"Langston University"},{"value":"140243","label":"Lanier Technical College"},{"value":"213473","label":"Lansdale School of Business"},{"value":"170657","label":"Lansing Community College"},{"value":"240620","label":"Laramie County Community College"},{"value":"226134","label":"Laredo Community College"},{"value":"366401","label":"Las Positas College"},{"value":"166391","label":"Lasell College"},{"value":"117274","label":"Lassen Community College"},{"value":"230418","label":"Latter-day Saints Business College"},{"value":"250027","label":"Laurel Business Institute"},{"value":"408729","label":"Laurel Technical Institute-MEADVILLE"},{"value":"215992","label":"Laurel Technical Institute-Sharon"},{"value":"198747","label":"Laurel University"},{"value":"166407","label":"Lawrence Memorial Hospital School of Nursing"},{"value":"170675","label":"Lawrence Technological University"},{"value":"239017","label":"Lawrence University"},{"value":"101569","label":"Lawson State Community College-Birmingham Campus"},{"value":"443623","label":"Le Cordon Bleu College of Culinary Arts-Atlanta"},{"value":"364973","label":"Le Cordon Bleu College of Culinary Arts-Austin"},{"value":"452054","label":"Le Cordon Bleu College of Culinary Arts-Cambridge"},{"value":"144467","label":"Le Cordon Bleu College of Culinary Arts-Chicago"},{"value":"452063","label":"Le Cordon Bleu College of Culinary Arts-Dallas"},{"value":"445115","label":"Le Cordon Bleu College of Culinary Arts-Las Vegas"},{"value":"446835","label":"Le Cordon Bleu College of Culinary Arts-Miami"},{"value":"446844","label":"Le Cordon Bleu College of Culinary Arts-Minneapolis"},{"value":"442231","label":"Le Cordon Bleu College of Culinary Arts-Orlando"},{"value":"423980","label":"Le Cordon Bleu College of Culinary Arts-Pasadena"},{"value":"375841","label":"Le Cordon Bleu College of Culinary Arts-Portland"},{"value":"111009","label":"Le Cordon Bleu College of Culinary Arts-San Francisco"},{"value":"262332","label":"Le Cordon Bleu College of Culinary Arts-Scottsdale"},{"value":"192323","label":"Le Moyne College"},{"value":"220604","label":"Le Moyne-Owen College"},{"value":"213507","label":"Lebanon Valley College"},{"value":"456940","label":"L'Ecole Culinaire-Memphis"},{"value":"445726","label":"L'Ecole Culinaire-St Louis"},{"value":"226204","label":"Lee College"},{"value":"220613","label":"Lee University"},{"value":"413626","label":"Leech Lake Tribal College"},{"value":"198808","label":"Lees-McRae College"},{"value":"141811","label":"Leeward Community College"},{"value":"213525","label":"Lehigh Carbon Community College"},{"value":"213543","label":"Lehigh University"},{"value":"198817","label":"Lenoir Community College"},{"value":"198835","label":"Lenoir-Rhyne University"},{"value":"218265","label":"Lenoir-Rhyne University-Lutheran Theological Southern Seminary"},{"value":"166452","label":"Lesley University"},{"value":"226231","label":"LeTourneau University"},{"value":"209056","label":"Lewis & Clark College"},{"value":"146603","label":"Lewis and Clark Community College"},{"value":"146612","label":"Lewis University"},{"value":"142328","label":"Lewis-Clark State College"},{"value":"157207","label":"Lexington Theological Seminary"},{"value":"232557","label":"Liberty University"},{"value":"117520","label":"Life Chiropractic College West"},{"value":"117104","label":"Life Pacific College"},{"value":"140252","label":"Life University"},{"value":"192271","label":"LIM College"},{"value":"218238","label":"Limestone College"},{"value":"146667","label":"Lincoln Christian University"},{"value":"146676","label":"Lincoln College"},{"value":"128683","label":"Lincoln College of New England-Southington"},{"value":"163028","label":"Lincoln College of Technology-Columbia"},{"value":"126951","label":"Lincoln College of Technology-Denver"},{"value":"151661","label":"Lincoln College of Technology-Indianapolis"},{"value":"434159","label":"Lincoln College of Technology-Marietta"},{"value":"146700","label":"Lincoln College of Technology-Melrose Park"},{"value":"221148","label":"Lincoln College of Technology-Nashville"},{"value":"136066","label":"Lincoln College of Technology-West Palm Beach"},{"value":"146685","label":"Lincoln Land Community College"},{"value":"220631","label":"Lincoln Memorial University"},{"value":"213570","label":"Lincoln Technical Institute-Allentown"},{"value":"442037","label":"Lincoln Technical Institute-Northeast Philadelphia"},{"value":"213589","label":"Lincoln Technical Institute-Philadelphia"},{"value":"403478","label":"Lincoln Trail College"},{"value":"177940","label":"Lincoln University-Jefferson City"},{"value":"117557","label":"Lincoln University-Oakland"},{"value":"177968","label":"Lindenwood University"},{"value":"157216","label":"Lindsey Wilson College"},{"value":"437325","label":"Linfield College-Adult Degree Program"},{"value":"209065","label":"Linfield College-McMinnville Campus"},{"value":"437316","label":"Linfield College-School of Nursing"},{"value":"209074","label":"Linn-Benton Community College"},{"value":"219976","label":"Lipscomb University"},{"value":"180328","label":"Little Big Horn College"},{"value":"434016","label":"Little Priest Tribal College"},{"value":"192563","label":"LIU Brentwood"},{"value":"192439","label":"LIU Brooklyn"},{"value":"192554","label":"LIU Hudson at Rockland"},{"value":"432357","label":"LIU Hudson at Westchester"},{"value":"192448","label":"LIU Post"},{"value":"450766","label":"LIU Riverhead"},{"value":"421832","label":"Living Arts College"},{"value":"198862","label":"Livingstone College"},{"value":"213613","label":"Lock Haven University"},{"value":"177986","label":"Logan University"},{"value":"117636","label":"Loma Linda University"},{"value":"227182","label":"Lone Star College System"},{"value":"117645","label":"Long Beach City College"},{"value":"192509","label":"Long Island Business Institute"},{"value":"232566","label":"Longwood University"},{"value":"166489","label":"Longy School of Music of Bard College"},{"value":"203748","label":"Lorain County Community College"},{"value":"153825","label":"Loras College"},{"value":"232575","label":"Lord Fairfax Community College"},{"value":"117788","label":"Los Angeles City College"},{"value":"446385","label":"Los Angeles College of Music"},{"value":"117803","label":"Los Angeles County College of Nursing and Allied Health"},{"value":"436429","label":"Los Angeles Film School"},{"value":"117690","label":"Los Angeles Harbor College"},{"value":"117867","label":"Los Angeles Mission College"},{"value":"368780","label":"Los Angeles ORT College-Los Angeles Campus"},{"value":"381945","label":"Los Angeles ORT College-Van Nuys Campus"},{"value":"117706","label":"Los Angeles Pierce College"},{"value":"117715","label":"Los Angeles Southwest College"},{"value":"117724","label":"Los Angeles Trade Technical College"},{"value":"117733","label":"Los Angeles Valley College"},{"value":"117894","label":"Los Medanos College"},{"value":"198871","label":"Louisburg College"},{"value":"159568","label":"Louisiana College"},{"value":"449612","label":"Louisiana Culinary Institute"},{"value":"483212","label":"Louisiana Delta Community College"},{"value":"159391","label":"Louisiana State University and Agricultural & Mechanical College"},{"value":"159373","label":"Louisiana State University Health Sciences Center-New Orleans"},{"value":"435000","label":"Louisiana State University Health Sciences Center-Shreveport"},{"value":"159382","label":"Louisiana State University-Alexandria"},{"value":"159407","label":"Louisiana State University-Eunice"},{"value":"159416","label":"Louisiana State University-Shreveport"},{"value":"159647","label":"Louisiana Tech University"},{"value":"157298","label":"Louisville Presbyterian Theological Seminary"},{"value":"203757","label":"Lourdes University"},{"value":"235750","label":"Lower Columbia College"},{"value":"117946","label":"Loyola Marymount University"},{"value":"146719","label":"Loyola University Chicago"},{"value":"163046","label":"Loyola University Maryland"},{"value":"159656","label":"Loyola University New Orleans"},{"value":"226383","label":"Lubbock Christian University"},{"value":"363633","label":"Luna Community College"},{"value":"101602","label":"Lurleen B Wallace Community College"},{"value":"153834","label":"Luther College"},{"value":"135364","label":"Luther Rice University & Seminary"},{"value":"173896","label":"Luther Seminary"},{"value":"146728","label":"Lutheran School of Theology at Chicago"},{"value":"213631","label":"Lutheran Theological Seminary at Gettysburg"},{"value":"213640","label":"Lutheran Theological Seminary at Philadelphia"},{"value":"213659","label":"Luzerne County Community College"},{"value":"213668","label":"Lycoming College"},{"value":"232609","label":"Lynchburg College"},{"value":"230931","label":"Lyndon State College"},{"value":"132657","label":"Lynn University"},{"value":"106342","label":"Lyon College"},{"value":"173902","label":"Macalester College"},{"value":"146816","label":"MacCormac College"},{"value":"192624","label":"Machzikei Hadath Rabbinical College"},{"value":"146825","label":"MacMurray College"},{"value":"170790","label":"Macomb Community College"},{"value":"238263","label":"Madison Area Technical College"},{"value":"364168","label":"Madison Media Institute"},{"value":"148399","label":"Madison Media Institute-Rockford Career College"},{"value":"157304","label":"Madisonville Community College"},{"value":"170806","label":"Madonna University"},{"value":"153861","label":"Maharishi University of Management"},{"value":"161509","label":"Maine College of Art"},{"value":"161022","label":"Maine College of Health Professions"},{"value":"161299","label":"Maine Maritime Academy"},{"value":"203775","label":"Malone University"},{"value":"451103","label":"Management Resources College"},{"value":"129695","label":"Manchester Community College-Manchester"},{"value":"183132","label":"Manchester Community College-Manchester"},{"value":"151777","label":"Manchester University"},{"value":"192688","label":"Mandl School-The College of Allied Health"},{"value":"155487","label":"Manhattan Area Technical College"},{"value":"155496","label":"Manhattan Christian College"},{"value":"192703","label":"Manhattan College"},{"value":"192712","label":"Manhattan School of Music"},{"value":"192749","label":"Manhattanville College"},{"value":"213774","label":"Manor College"},{"value":"213783","label":"Mansfield University of Pennsylvania"},{"value":"446394","label":"Maple Springs Baptist Bible College and Seminary"},{"value":"239071","label":"Maranatha Baptist University"},{"value":"192785","label":"Maria College of Albany"},{"value":"166601","label":"Marian Court College"},{"value":"239080","label":"Marian University-Fond Du Lac"},{"value":"151786","label":"Marian University-Indianapolis"},{"value":"203845","label":"Marietta College"},{"value":"101648","label":"Marion Military Institute"},{"value":"203881","label":"Marion Technical College"},{"value":"192819","label":"Marist College"},{"value":"230940","label":"Marlboro College"},{"value":"440411","label":"Marlboro College Graduate & Professional Studies"},{"value":"239105","label":"Marquette University"},{"value":"198899","label":"Mars Hill University"},{"value":"123943","label":"Marshall B Ketchum University"},{"value":"237525","label":"Marshall University"},{"value":"153922","label":"Marshalltown Community College"},{"value":"198905","label":"Martin Community College"},{"value":"173452","label":"Martin Luther College"},{"value":"220701","label":"Martin Methodist College"},{"value":"151810","label":"Martin University"},{"value":"232672","label":"Mary Baldwin College"},{"value":"170842","label":"Marygrove College"},{"value":"163295","label":"Maryland Institute College of Art"},{"value":"164085","label":"Maryland University of Integrative Health"},{"value":"209108","label":"Marylhurst University"},{"value":"118541","label":"Marymount California University"},{"value":"192864","label":"Marymount Manhattan College"},{"value":"232706","label":"Marymount University"},{"value":"220710","label":"Maryville College"},{"value":"178059","label":"Maryville University of Saint Louis"},{"value":"213826","label":"Marywood University"},{"value":"166647","label":"Massachusetts Bay Community College"},{"value":"166674","label":"Massachusetts College of Art and Design"},{"value":"167288","label":"Massachusetts College of Liberal Arts"},{"value":"166683","label":"Massachusetts Institute of Technology"},{"value":"166692","label":"Massachusetts Maritime Academy"},{"value":"369002","label":"Massachusetts School of Law"},{"value":"166823","label":"Massasoit Community College"},{"value":"436702","label":"Mattia College"},{"value":"454698","label":"Mayfield College"},{"value":"198914","label":"Mayland Community College"},{"value":"365426","label":"Mayo Graduate School"},{"value":"173957","label":"Mayo Medical School"},{"value":"173966","label":"Mayo School of Health Sciences"},{"value":"157331","label":"Maysville Community and Technical College"},{"value":"200226","label":"Mayville State University"},{"value":"438212","label":"McCann School of Business & Technology"},{"value":"146977","label":"McCormick Theological Seminary"},{"value":"164270","label":"McDaniel College"},{"value":"198923","label":"McDowell Technical Community College"},{"value":"147004","label":"McHenry County College"},{"value":"147013","label":"McKendree University"},{"value":"226578","label":"McLennan Community College"},{"value":"226587","label":"McMurry University"},{"value":"367194","label":"McNally Smith College of Music"},{"value":"159717","label":"McNeese State University"},{"value":"155511","label":"McPherson College"},{"value":"166656","label":"MCPHS University"},{"value":"147031","label":"Meadville Lombard Theological School"},{"value":"414461","label":"Mech-Tech College"},{"value":"192925","label":"Medaille College"},{"value":"239169","label":"Medical College of Wisconsin"},{"value":"218335","label":"Medical University of South Carolina"},{"value":"448415","label":"MedTech College"},{"value":"456366","label":"MedTech College-Ft Wayne Campus"},{"value":"456357","label":"MedTech College-Greenwood Campus"},{"value":"456375","label":"MedTech College-Lexington Campus"},{"value":"131742","label":"Medtech Institute"},{"value":"444714","label":"MedTech Institute-Atlanta Campus"},{"value":"220792","label":"Meharry Medical College"},{"value":"192961","label":"Memorial School of Nursing"},{"value":"220808","label":"Memphis College of Art"},{"value":"220871","label":"Memphis Theological Seminary"},{"value":"118684","label":"Mendocino College"},{"value":"118693","label":"Menlo College"},{"value":"118718","label":"Merced College"},{"value":"185509","label":"Mercer County Community College"},{"value":"140447","label":"Mercer University"},{"value":"193016","label":"Mercy College"},{"value":"153977","label":"Mercy College of Health Sciences"},{"value":"203960","label":"Mercy College of Ohio"},{"value":"213987","label":"Mercyhurst University"},{"value":"480189","label":"Mercyhurst University-North East Campus"},{"value":"198950","label":"Meredith College"},{"value":"244279","label":"Meridian College"},{"value":"175935","label":"Meridian Community College"},{"value":"166850","label":"Merrimack College"},{"value":"118772","label":"Merritt College"},{"value":"105154","label":"Mesa Community College"},{"value":"173993","label":"Mesabi Range College"},{"value":"188261","label":"Mesalands Community College"},{"value":"461847","label":"Mesivta Keser Torah"},{"value":"193061","label":"Mesivta of Eastern Parkway-Yeshiva Zichron Meilech"},{"value":"193052","label":"Mesivta Torah Vodaath Rabbinical Seminary"},{"value":"193070","label":"Mesivtha Tifereth Jerusalem of America"},{"value":"417752","label":"Messenger College"},{"value":"213996","label":"Messiah College"},{"value":"147129","label":"Methodist College"},{"value":"203997","label":"Methodist Theological School in Ohio"},{"value":"198969","label":"Methodist University"},{"value":"455673","label":"Metro Business College-Arnold"},{"value":"178110","label":"Metro Business College-Cape Girardeau"},{"value":"245430","label":"Metro Business College-Jefferson City"},{"value":"245421","label":"Metro Business College-Rolla"},{"value":"214023","label":"Metropolitan Career Center Computer Technology Institute"},{"value":"190114","label":"Metropolitan College of New York"},{"value":"181303","label":"Metropolitan Community College Area"},{"value":"177995","label":"Metropolitan Community College-Kansas City-Kansas City"},{"value":"174020","label":"Metropolitan State University"},{"value":"127565","label":"Metropolitan State University of Denver"},{"value":"166869","label":"MGH Institute of Health Professions"},{"value":"135717","label":"Miami Dade College"},{"value":"204006","label":"Miami University-Hamilton"},{"value":"204015","label":"Miami University-Middletown"},{"value":"204024","label":"Miami University-Oxford"},{"value":"369862","label":"Miami-Jacobs Career College-Columbus"},{"value":"204060","label":"Miami-Jacobs Career College-Dayton"},{"value":"200633","label":"Miami-Jacobs Career College-Independence"},{"value":"441201","label":"Miami-Jacobs Career College-Sharonville"},{"value":"449126","label":"Miami-Jacobs Career College-Springboro"},{"value":"450003","label":"Miami-Jacobs Career College-Troy"},{"value":"169655","label":"MIAT College of Technology"},{"value":"434414","label":"Michigan Jewish Institute"},{"value":"169220","label":"Michigan School of Professional Psychology"},{"value":"171100","label":"Michigan State University"},{"value":"169628","label":"Michigan State University-College of Law"},{"value":"171128","label":"Michigan Technological University"},{"value":"171155","label":"Mid Michigan Community College"},{"value":"245953","label":"Mid-America Christian University"},{"value":"151962","label":"Mid-America College of Funeral Service"},{"value":"155520","label":"MidAmerica Nazarene University"},{"value":"199458","label":"Mid-Atlantic Christian University"},{"value":"482158","label":"Middle Georgia State College"},{"value":"220996","label":"Middle Tennessee School of Anesthesia Inc"},{"value":"220978","label":"Middle Tennessee State University"},{"value":"230959","label":"Middlebury College"},{"value":"166887","label":"Middlesex Community College-Bedford"},{"value":"129756","label":"Middlesex Community College-Middletown"},{"value":"185536","label":"Middlesex County College"},{"value":"226806","label":"Midland College"},{"value":"181330","label":"Midland University"},{"value":"218353","label":"Midlands Technical College"},{"value":"181312","label":"Mid-Plains Community College"},{"value":"481225","label":"Mid-South Christian College"},{"value":"147165","label":"Midstate College"},{"value":"239220","label":"Mid-State Technical College"},{"value":"157377","label":"Midway College"},{"value":"439020","label":"Midwest College of Oriental Medicine-Chicago"},{"value":"383020","label":"Midwest College of Oriental Medicine-Racine"},{"value":"178183","label":"Midwest Institute"},{"value":"178208","label":"Midwestern Baptist Theological Seminary"},{"value":"226833","label":"Midwestern State University"},{"value":"143853","label":"Midwestern University-Downers Grove"},{"value":"423643","label":"Midwestern University-Glendale"},{"value":"480985","label":"Midwives College of Utah"},{"value":"193201","label":"Mildred Elley School-Albany Campus"},{"value":"461014","label":"Mildred Elley-New York Campus"},{"value":"101675","label":"Miles College"},{"value":"180373","label":"Miles Community College"},{"value":"461883","label":"Millennia Atlantic University"},{"value":"449117","label":"Miller-Motte College-Cary"},{"value":"458405","label":"Miller-Motte College-Fayetteville"},{"value":"455655","label":"Miller-Motte College-Greenville"},{"value":"460817","label":"Miller-Motte College-Jacksonville"},{"value":"456205","label":"Miller-Motte College-Raleigh"},{"value":"198978","label":"Miller-Motte College-Wilmington"},{"value":"460826","label":"Miller-Motte Technical College-Augusta"},{"value":"441025","label":"Miller-Motte Technical College-Charleston"},{"value":"443650","label":"Miller-Motte Technical College-Chattanooga"},{"value":"382771","label":"Miller-Motte Technical College-Clarksville"},{"value":"458441","label":"Miller-Motte Technical College-Columbus"},{"value":"460835","label":"Miller-Motte Technical College-Conway"},{"value":"475079","label":"Miller-Motte Technical College-Gulfport"},{"value":"233091","label":"Miller-Motte Technical College-Lynchburg"},{"value":"475060","label":"Miller-Motte Technical College-Macon"},{"value":"448664","label":"Miller-Motte Technical College-Madison"},{"value":"475194","label":"Miller-Motte Technical College-Roanoke"},{"value":"214041","label":"Millersville University of Pennsylvania"},{"value":"221014","label":"Milligan College"},{"value":"147244","label":"Millikin University"},{"value":"118888","label":"Mills College"},{"value":"175980","label":"Millsaps College"},{"value":"239248","label":"Milwaukee Area Technical College"},{"value":"239309","label":"Milwaukee Institute of Art & Design"},{"value":"239318","label":"Milwaukee School of Engineering"},{"value":"178217","label":"Mineral Area College"},{"value":"174118","label":"Minneapolis Business College"},{"value":"174127","label":"Minneapolis College of Art and Design"},{"value":"174136","label":"Minneapolis Community and Technical College"},{"value":"474881","label":"Minneapolis Media Institute"},{"value":"451769","label":"Minnesota School of Business-Blaine"},{"value":"407285","label":"Minnesota School of Business-Brooklyn Center"},{"value":"456782","label":"Minnesota School of Business-Elk River"},{"value":"458742","label":"Minnesota School of Business-Lakeville"},{"value":"455585","label":"Minnesota School of Business-Moorhead"},{"value":"442578","label":"Minnesota School of Business-Plymouth"},{"value":"174279","label":"Minnesota School of Business-Richfield"},{"value":"447670","label":"Minnesota School of Business-Rochester"},{"value":"445920","label":"Minnesota School of Business-Waite Park"},{"value":"175263","label":"Minnesota State College-Southeast Technical"},{"value":"173559","label":"Minnesota State Community and Technical College"},{"value":"174358","label":"Minnesota State University Moorhead"},{"value":"173920","label":"Minnesota State University-Mankato"},{"value":"173638","label":"Minnesota West Community and Technical College"},{"value":"200253","label":"Minot State University"},{"value":"118912","label":"MiraCosta College"},{"value":"193247","label":"Mirrer Yeshiva Cent Institute"},{"value":"214069","label":"Misericordia University"},{"value":"118930","label":"Mission College"},{"value":"176053","label":"Mississippi College"},{"value":"176008","label":"Mississippi Delta Community College"},{"value":"176071","label":"Mississippi Gulf Coast Community College"},{"value":"176080","label":"Mississippi State University"},{"value":"176035","label":"Mississippi University for Women"},{"value":"176044","label":"Mississippi Valley State University"},{"value":"178244","label":"Missouri Baptist University"},{"value":"178305","label":"Missouri College"},{"value":"178341","label":"Missouri Southern State University"},{"value":"179566","label":"Missouri State University-Springfield"},{"value":"179344","label":"Missouri State University-West Plains"},{"value":"178350","label":"Missouri Tech"},{"value":"178411","label":"Missouri University of Science and Technology"},{"value":"178369","label":"Missouri Valley College"},{"value":"178387","label":"Missouri Western State University"},{"value":"129774","label":"Mitchell College"},{"value":"198987","label":"Mitchell Community College"},{"value":"219189","label":"Mitchell Technical Institute"},{"value":"178448","label":"Moberly Area Community College"},{"value":"118976","label":"Modesto Junior College"},{"value":"105206","label":"Mohave Community College"},{"value":"193283","label":"Mohawk Valley Community College"},{"value":"193292","label":"Molloy College"},{"value":"147341","label":"Monmouth College"},{"value":"185572","label":"Monmouth University"},{"value":"193308","label":"Monroe College"},{"value":"193326","label":"Monroe Community College"},{"value":"171225","label":"Monroe County Community College"},{"value":"262165","label":"Montana Bible College"},{"value":"180461","label":"Montana State University"},{"value":"180179","label":"Montana State University-Billings"},{"value":"180522","label":"Montana State University-Northern"},{"value":"180416","label":"Montana Tech of the University of Montana"},{"value":"171234","label":"Montcalm Community College"},{"value":"185590","label":"Montclair State University"},{"value":"119058","label":"Monterey Institute of International Studies"},{"value":"119067","label":"Monterey Peninsula College"},{"value":"163426","label":"Montgomery College"},{"value":"199023","label":"Montgomery Community College"},{"value":"214111","label":"Montgomery County Community College"},{"value":"199032","label":"Montreat College"},{"value":"166911","label":"Montserrat College of Art"},{"value":"147369","label":"Moody Bible Institute"},{"value":"214148","label":"Moore College of Art and Design"},{"value":"119137","label":"Moorpark College"},{"value":"239372","label":"Moraine Park Technical College"},{"value":"147378","label":"Moraine Valley Community College"},{"value":"214157","label":"Moravian College"},{"value":"157386","label":"Morehead State University"},{"value":"140553","label":"Morehouse College"},{"value":"140562","label":"Morehouse School of Medicine"},{"value":"460394","label":"Moreno Valley College"},{"value":"127617","label":"Morgan Community College"},{"value":"163453","label":"Morgan State University"},{"value":"154004","label":"Morningside College"},{"value":"218399","label":"Morris College"},{"value":"147396","label":"Morrison Institute of Technology"},{"value":"196051","label":"Morrisville State College"},{"value":"147411","label":"Morton College"},{"value":"221096","label":"Motlow State Community College"},{"value":"169275","label":"Mott Community College"},{"value":"140599","label":"Moultrie Technical College"},{"value":"214166","label":"Mount Aloysius College"},{"value":"209241","label":"Mount Angel Seminary"},{"value":"204176","label":"Mount Carmel College of Nursing"},{"value":"166939","label":"Mount Holyoke College"},{"value":"166948","label":"Mount Ida College"},{"value":"219198","label":"Mount Marty College"},{"value":"239390","label":"Mount Mary University"},{"value":"154013","label":"Mount Mercy University"},{"value":"204200","label":"Mount Saint Joseph University"},{"value":"193353","label":"Mount Saint Mary College"},{"value":"119173","label":"Mount Saint Mary's University"},{"value":"163462","label":"Mount St Mary's University"},{"value":"204194","label":"Mount Vernon Nazarene University"},{"value":"166957","label":"Mount Wachusett Community College"},{"value":"182865","label":"Mount Washington College"},{"value":"232788","label":"Mountain Empire Community College"},{"value":"237598","label":"Mountain State College"},{"value":"226930","label":"Mountain View College"},{"value":"444954","label":"Mountwest Community and Technical College"},{"value":"209250","label":"Mt Hood Community College"},{"value":"119164","label":"Mt San Antonio College"},{"value":"119216","label":"Mt San Jacinto Community College District"},{"value":"398130","label":"Mt Sierra College"},{"value":"118198","label":"MTI College"},{"value":"214175","label":"Muhlenberg College"},{"value":"209287","label":"Multnomah University"},{"value":"207236","label":"Murray State College"},{"value":"157401","label":"Murray State University"},{"value":"119270","label":"Musicians Institute"},{"value":"171304","label":"Muskegon Community College"},{"value":"204264","label":"Muskingum University"},{"value":"434432","label":"Myotherapy Institute"},{"value":"119331","label":"Napa Valley College"},{"value":"127653","label":"Naropa University"},{"value":"199087","label":"Nash Community College"},{"value":"239424","label":"Nashotah House"},{"value":"183141","label":"Nashua Community College"},{"value":"221184","label":"Nashville State Community College"},{"value":"193478","label":"Nassau Community College"},{"value":"248882","label":"National American University-Albuquerque"},{"value":"440758","label":"National American University-Albuquerque West"},{"value":"451875","label":"National American University-Austin"},{"value":"482307","label":"National American University-Austin South"},{"value":"477996","label":"National American University-Bellevue"},{"value":"436483","label":"National American University-Bloomington"},{"value":"440767","label":"National American University-Brooklyn Center"},{"value":"478005","label":"National American University-Burnsville"},{"value":"466161","label":"National American University-Centennial"},{"value":"127680","label":"National American University-Colorado Springs"},{"value":"466189","label":"National American University-Colorado Springs South"},{"value":"127699","label":"National American University-Denver"},{"value":"440749","label":"National American University-Ellsworth AFB Extension"},{"value":"482325","label":"National American University-Georgetown"},{"value":"485290","label":"National American University-Harold D. Buckingham Graduate School"},{"value":"247700","label":"National American University-Independence"},{"value":"482370","label":"National American University-Indianapolis"},{"value":"466170","label":"National American University-Lee's Summit"},{"value":"482316","label":"National American University-Lewisville"},{"value":"442718","label":"National American University-Overland Park"},{"value":"219204","label":"National American University-Rapid City"},{"value":"482343","label":"National American University-Rochester"},{"value":"174385","label":"National American University-Roseville"},{"value":"219213","label":"National American University-Sioux Falls"},{"value":"466152","label":"National American University-Tulsa"},{"value":"482352","label":"National American University-Weldon Spring"},{"value":"451884","label":"National American University-Wichita"},{"value":"482361","label":"National American University-Wichita West"},{"value":"448585","label":"National American University-Zona Rosa"},{"value":"209296","label":"National College of Natural Medicine"},{"value":"480480","label":"National College-Canton"},{"value":"453473","label":"National College-Cincinnati"},{"value":"457004","label":"National College-Columbus"},{"value":"453455","label":"National College-Dayton"},{"value":"157021","label":"National College-Lexington"},{"value":"388043","label":"National College-Nashville"},{"value":"453482","label":"National College-Stow"},{"value":"459833","label":"National College-Willoughby Hills"},{"value":"453464","label":"National College-Youngstown"},{"value":"441478","label":"National Graduate School of Quality Management"},{"value":"412003","label":"National Institute of Massotherapy"},{"value":"147536","label":"National Louis University"},{"value":"448114","label":"National Massage Therapy Institute"},{"value":"461023","label":"National Paralegal College"},{"value":"106980","label":"National Park Community College"},{"value":"119605","label":"National University"},{"value":"242981","label":"National University College-Arecibo"},{"value":"242972","label":"National University College-Bayamon"},{"value":"468723","label":"National University College-Caguas"},{"value":"458469","label":"National University College-Ponce"},{"value":"444042","label":"National University College-Rio Grande"},{"value":"147590","label":"National University of Health Sciences"},{"value":"129729","label":"Naugatuck Valley Community College"},{"value":"187596","label":"Navajo Technical University"},{"value":"119678","label":"Naval Postgraduate School"},{"value":"227146","label":"Navarro College"},{"value":"127714","label":"Nazarene Bible College"},{"value":"178518","label":"Nazarene Theological Seminary"},{"value":"193584","label":"Nazareth College"},{"value":"181376","label":"Nebraska Christian College"},{"value":"181765","label":"Nebraska College of Technical Agriculture"},{"value":"181419","label":"Nebraska Indian Community College"},{"value":"181297","label":"Nebraska Methodist College of Nursing & Allied Health"},{"value":"181446","label":"Nebraska Wesleyan University"},{"value":"155566","label":"Neosho County Community College"},{"value":"163532","label":"Ner Israel Rabbinical College"},{"value":"214272","label":"Neumann University"},{"value":"445692","label":"Neumont University"},{"value":"441900","label":"Nevada State College"},{"value":"185758","label":"New Brunswick Theological Seminary"},{"value":"214290","label":"New Castle School of Trades"},{"value":"262129","label":"New College of Florida"},{"value":"182980","label":"New England College"},{"value":"164438","label":"New England College of Business and Finance"},{"value":"167093","label":"New England College of Optometry"},{"value":"230977","label":"New England Culinary Institute"},{"value":"217305","label":"New England Institute of Technology"},{"value":"167215","label":"New England Law-Boston"},{"value":"167181","label":"New England School of Acupuncture"},{"value":"430810","label":"New Hampshire Institute of Art"},{"value":"208725","label":"New Hope Christian College-Eugene"},{"value":"185129","label":"New Jersey City University"},{"value":"185828","label":"New Jersey Institute of Technology"},{"value":"187897","label":"New Mexico Highlands University"},{"value":"187967","label":"New Mexico Institute of Mining and Technology"},{"value":"187903","label":"New Mexico Junior College"},{"value":"187912","label":"New Mexico Military Institute"},{"value":"187994","label":"New Mexico State University-Alamogordo"},{"value":"188003","label":"New Mexico State University-Carlsbad"},{"value":"187620","label":"New Mexico State University-Dona Ana"},{"value":"188021","label":"New Mexico State University-Grants"},{"value":"188030","label":"New Mexico State University-Main Campus"},{"value":"159948","label":"New Orleans Baptist Theological Seminary"},{"value":"447582","label":"New River Community and Technical College"},{"value":"232867","label":"New River Community College"},{"value":"366368","label":"New York Academy of Art"},{"value":"195845","label":"New York Career Institute"},{"value":"193751","label":"New York Chiropractic College"},{"value":"418126","label":"New York College of Health Professions"},{"value":"194073","label":"New York College of Podiatric Medicine"},{"value":"439783","label":"New York College of Traditional Chinese Medicine"},{"value":"421841","label":"New York Conservatory for Dramatic Arts"},{"value":"461148","label":"New York Film Academy"},{"value":"194091","label":"New York Institute of Technology"},{"value":"193821","label":"New York Law School"},{"value":"193830","label":"New York Medical College"},{"value":"194116","label":"New York School of Interior Design"},{"value":"193894","label":"New York Theological Seminary"},{"value":"193900","label":"New York University"},{"value":"218414","label":"Newberry College"},{"value":"167251","label":"Newbury College"},{"value":"155335","label":"Newman University"},{"value":"119775","label":"Newschool of Architecture and Design"},{"value":"183099","label":"NHTI-Concord's Community College"},{"value":"193946","label":"Niagara County Community College"},{"value":"193973","label":"Niagara University"},{"value":"159966","label":"Nicholls State University"},{"value":"167260","label":"Nichols College"},{"value":"239442","label":"Nicolet Area Technical College"},{"value":"444787","label":"Nightingale College"},{"value":"460464","label":"Norco College"},{"value":"232937","label":"Norfolk State University"},{"value":"174428","label":"Normandale Community College"},{"value":"461795","label":"North American University"},{"value":"107460","label":"North Arkansas College"},{"value":"199102","label":"North Carolina A & T State University"},{"value":"199157","label":"North Carolina Central University"},{"value":"199193","label":"North Carolina State University at Raleigh"},{"value":"199209","label":"North Carolina Wesleyan College"},{"value":"147660","label":"North Central College"},{"value":"418889","label":"North Central Institute"},{"value":"155593","label":"North Central Kansas Technical College"},{"value":"171395","label":"North Central Michigan College"},{"value":"179715","label":"North Central Missouri College"},{"value":"204422","label":"North Central State College"},{"value":"224110","label":"North Central Texas College"},{"value":"174437","label":"North Central University"},{"value":"194028","label":"North Country Community College"},{"value":"200305","label":"North Dakota State College of Science"},{"value":"200332","label":"North Dakota State University-Main Campus"},{"value":"136145","label":"North Florida Community College"},{"value":"140678","label":"North Georgia Technical College"},{"value":"218441","label":"North Greenville University"},{"value":"174376","label":"North Hennepin Community College"},{"value":"142443","label":"North Idaho College"},{"value":"154059","label":"North Iowa Area Community College"},{"value":"227191","label":"North Lake College"},{"value":"147679","label":"North Park University"},{"value":"236072","label":"North Seattle College"},{"value":"167312","label":"North Shore Community College"},{"value":"214379","label":"Northampton County Area Community College"},{"value":"239460","label":"Northcentral Technical College"},{"value":"444130","label":"Northcentral University"},{"value":"101897","label":"Northeast Alabama Community College"},{"value":"182917","label":"Northeast Catholic College"},{"value":"181491","label":"Northeast Community College"},{"value":"154110","label":"Northeast Iowa Community College"},{"value":"176169","label":"Northeast Mississippi Community College"},{"value":"204477","label":"Northeast Ohio Medical University"},{"value":"221908","label":"Northeast State Community College"},{"value":"227225","label":"Northeast Texas Community College"},{"value":"239488","label":"Northeast Wisconsin Technical College"},{"value":"147776","label":"Northeastern Illinois University"},{"value":"127732","label":"Northeastern Junior College"},{"value":"207290","label":"Northeastern Oklahoma A&M College"},{"value":"439817","label":"Northeastern Seminary"},{"value":"207263","label":"Northeastern State University"},{"value":"217837","label":"Northeastern Technical College"},{"value":"167358","label":"Northeastern University"},{"value":"482705","label":"Northeastern University Global Network"},{"value":"105330","label":"Northern Arizona University"},{"value":"147697","label":"Northern Baptist Theological Seminary"},{"value":"167376","label":"Northern Essex Community College"},{"value":"147703","label":"Northern Illinois University"},{"value":"157447","label":"Northern Kentucky University"},{"value":"161484","label":"Northern Maine Community College"},{"value":"240790","label":"Northern Marianas College"},{"value":"171456","label":"Northern Michigan University"},{"value":"188058","label":"Northern New Mexico College"},{"value":"207281","label":"Northern Oklahoma College"},{"value":"219259","label":"Northern State University"},{"value":"232946","label":"Northern Virginia Community College"},{"value":"239512","label":"Northland College"},{"value":"174473","label":"Northland Community and Technical College"},{"value":"239503","label":"Northland International University"},{"value":"105349","label":"Northland Pioneer College"},{"value":"217606","label":"Northpoint Bible College"},{"value":"160667","label":"Northshore Technical Community College"},{"value":"367459","label":"NorthWest Arkansas Community College"},{"value":"445948","label":"Northwest Career College"},{"value":"209409","label":"Northwest Christian University"},{"value":"240657","label":"Northwest College"},{"value":"377546","label":"Northwest College of Art & Design"},{"value":"136233","label":"Northwest Florida State College"},{"value":"380377","label":"Northwest Indian College"},{"value":"460941","label":"Northwest Institute of Literary Arts"},{"value":"154129","label":"Northwest Iowa Community College"},{"value":"155618","label":"Northwest Kansas Technical College"},{"value":"160010","label":"Northwest Louisiana Technical College"},{"value":"176178","label":"Northwest Mississippi Community College"},{"value":"178624","label":"Northwest Missouri State University"},{"value":"142461","label":"Northwest Nazarene University"},{"value":"458140","label":"Northwest School of Wooden Boat Building"},{"value":"204440","label":"Northwest State Community College"},{"value":"173115","label":"Northwest Technical College"},{"value":"236133","label":"Northwest University"},{"value":"420398","label":"Northwest Vista College"},{"value":"154101","label":"Northwestern College"},{"value":"147749","label":"Northwestern College-Chicago Campus"},{"value":"260992","label":"Northwestern College-Southwestern Campus"},{"value":"130040","label":"Northwestern Connecticut Community College"},{"value":"174507","label":"Northwestern Health Sciences University"},{"value":"171483","label":"Northwestern Michigan College"},{"value":"207306","label":"Northwestern Oklahoma State University"},{"value":"160038","label":"Northwestern State University of Louisiana"},{"value":"147767","label":"Northwestern University"},{"value":"101736","label":"Northwest-Shoals Community College"},{"value":"136206","label":"Northwood University-Florida"},{"value":"171492","label":"Northwood University-Michigan"},{"value":"227243","label":"Northwood University-Texas"},{"value":"130004","label":"Norwalk Community College"},{"value":"230995","label":"Norwich University"},{"value":"368452","label":"Nossi College of Art"},{"value":"204468","label":"Notre Dame College"},{"value":"120184","label":"Notre Dame de Namur University"},{"value":"163578","label":"Notre Dame of Maryland University"},{"value":"160029","label":"Notre Dame Seminary Graduate School of Theology"},{"value":"136215","label":"Nova Southeastern University"},{"value":"200086","label":"Nueta Hidatsa Sahnish College"},{"value":"158884","label":"Nunez Community College"},{"value":"194161","label":"Nyack College"},{"value":"174525","label":"Oak Hills Christian College"},{"value":"152099","label":"Oakland City University"},{"value":"171535","label":"Oakland Community College"},{"value":"171571","label":"Oakland University"},{"value":"147800","label":"Oakton Community College"},{"value":"101912","label":"Oakwood University"},{"value":"204501","label":"Oberlin College"},{"value":"227289","label":"Oblate School of Theology"},{"value":"120254","label":"Occidental College"},{"value":"185873","label":"Ocean County College"},{"value":"420431","label":"Oconee Fall Line Technical College"},{"value":"227304","label":"Odessa College"},{"value":"366465","label":"Ogeechee Technical College"},{"value":"219277","label":"Oglala Lakota College"},{"value":"140696","label":"Oglethorpe University"},{"value":"453747","label":"Ohio Business College-Hilliard"},{"value":"203739","label":"Ohio Business College-Sandusky"},{"value":"203720","label":"Ohio Business College-Sheffield"},{"value":"201964","label":"Ohio Christian University"},{"value":"204592","label":"Ohio College of Massotherapy Inc"},{"value":"204617","label":"Ohio Dominican University"},{"value":"206002","label":"Ohio Mid-Western College"},{"value":"204635","label":"Ohio Northern University"},{"value":"204662","label":"Ohio State University Agricultural Technical Institute"},{"value":"204671","label":"Ohio State University-Lima Campus"},{"value":"204796","label":"Ohio State University-Main Campus"},{"value":"204680","label":"Ohio State University-Mansfield Campus"},{"value":"204699","label":"Ohio State University-Marion Campus"},{"value":"204705","label":"Ohio State University-Newark Campus"},{"value":"204608","label":"Ohio Technical College"},{"value":"453817","label":"Ohio Technical College-PowerSport Institute"},{"value":"204820","label":"Ohio University-Chillicothe Campus"},{"value":"204802","label":"Ohio University-Eastern Campus"},{"value":"204848","label":"Ohio University-Lancaster Campus"},{"value":"204857","label":"Ohio University-Main Campus"},{"value":"204839","label":"Ohio University-Southern Campus"},{"value":"204866","label":"Ohio University-Zanesville Campus"},{"value":"204884","label":"Ohio Valley College of Technology"},{"value":"237640","label":"Ohio Valley University"},{"value":"204909","label":"Ohio Wesleyan University"},{"value":"120290","label":"Ohlone College"},{"value":"194189","label":"Ohr Hameir Theological Seminary"},{"value":"207403","label":"Oklahoma Baptist University"},{"value":"207324","label":"Oklahoma Christian University"},{"value":"207449","label":"Oklahoma City Community College"},{"value":"207458","label":"Oklahoma City University"},{"value":"207351","label":"Oklahoma Panhandle State University"},{"value":"207315","label":"Oklahoma State University Center for Health Sciences"},{"value":"207564","label":"Oklahoma State University Institute of Technology"},{"value":"207388","label":"Oklahoma State University-Main Campus"},{"value":"207397","label":"Oklahoma State University-Oklahoma City"},{"value":"469629","label":"Oklahoma Technical College"},{"value":"206835","label":"Oklahoma Wesleyan University"},{"value":"232982","label":"Old Dominion University"},{"value":"171599","label":"Olivet College"},{"value":"147828","label":"Olivet Nazarene University"},{"value":"145707","label":"Olney Central College"},{"value":"236188","label":"Olympic College"},{"value":"407328","label":"Omaha School of Massage and Healthcare of Herzing University"},{"value":"221254","label":"O'More College of Design"},{"value":"194222","label":"Onondaga Community College"},{"value":"207582","label":"Oral Roberts University"},{"value":"120342","label":"Orange Coast College"},{"value":"194240","label":"Orange County Community College"},{"value":"218487","label":"Orangeburg Calhoun Technical College"},{"value":"423652","label":"Oregon Coast Community College"},{"value":"209533","label":"Oregon College of Art and Craft"},{"value":"369659","label":"Oregon College of Oriental Medicine"},{"value":"209490","label":"Oregon Health & Science University"},{"value":"209506","label":"Oregon Institute of Technology"},{"value":"209542","label":"Oregon State University"},{"value":"454883","label":"Orion College"},{"value":"214528","label":"Orleans Technical Institute"},{"value":"127778","label":"Otero Junior College"},{"value":"120403","label":"Otis College of Art and Design"},{"value":"442897","label":"Ottawa University-Jeffersonville"},{"value":"155636","label":"Ottawa University-Kansas City"},{"value":"428259","label":"Ottawa University-Milwaukee"},{"value":"454582","label":"Ottawa University-Online"},{"value":"155627","label":"Ottawa University-Ottawa"},{"value":"105367","label":"Ottawa University-Phoenix"},{"value":"204936","label":"Otterbein University"},{"value":"107512","label":"Ouachita Baptist University"},{"value":"160074","label":"Our Lady of the Lake College"},{"value":"227331","label":"Our Lady of the Lake University"},{"value":"204945","label":"Owens Community College"},{"value":"247940","label":"Owensboro Community and Technical College"},{"value":"461120","label":"Oxford Graduate School"},{"value":"120421","label":"Oxnard College"},{"value":"178679","label":"Ozark Christian College"},{"value":"107549","label":"Ozarka College"},{"value":"177472","label":"Ozarks Technical Community College"},{"value":"214838","label":"Pace Institute"},{"value":"194310","label":"Pace University-New York"},{"value":"422695","label":"Pacific College"},{"value":"442842","label":"Pacific College of Oriental Medicine-Chicago"},{"value":"414595","label":"Pacific College of Oriental Medicine-New York"},{"value":"378576","label":"Pacific College of Oriental Medicine-San Diego"},{"value":"439862","label":"Pacific Islands University"},{"value":"120740","label":"Pacific Lutheran Theological Seminary"},{"value":"236230","label":"Pacific Lutheran University"},{"value":"209603","label":"Pacific Northwest College of Art"},{"value":"455406","label":"Pacific Northwest University of Health Sciences"},{"value":"120768","label":"Pacific Oaks College"},{"value":"457484","label":"Pacific Rim Christian University"},{"value":"120795","label":"Pacific School of Religion"},{"value":"120838","label":"Pacific States University"},{"value":"120865","label":"Pacific Union College"},{"value":"209612","label":"Pacific University"},{"value":"115746","label":"Pacifica Graduate Institute"},{"value":"130110","label":"Paier College of Art Inc"},{"value":"140720","label":"Paine College"},{"value":"243647","label":"Palau Community College"},{"value":"136330","label":"Palm Beach Atlantic University"},{"value":"136358","label":"Palm Beach State College"},{"value":"154174","label":"Palmer College of Chiropractic"},{"value":"246354","label":"Palo Alto College"},{"value":"120698","label":"Palo Alto University"},{"value":"120953","label":"Palo Verde College"},{"value":"120971","label":"Palomar College"},{"value":"199263","label":"Pamlico Community College"},{"value":"227386","label":"Panola College"},{"value":"364016","label":"Paradise Valley Community College"},{"value":"121628","label":"Pardee RAND Graduate School"},{"value":"227401","label":"Paris Junior College"},{"value":"178721","label":"Park University"},{"value":"243823","label":"Parker University"},{"value":"147916","label":"Parkland College"},{"value":"121044","label":"Pasadena City College"},{"value":"136400","label":"Pasco-Hernando State College"},{"value":"186034","label":"Passaic County Community College"},{"value":"666666","label":"Patrick Henry College"},{"value":"233019","label":"Patrick Henry Community College"},{"value":"233037","label":"Paul D Camp Community College"},{"value":"227429","label":"Paul Quinn College"},{"value":"194392","label":"Paul Smiths College of Arts and Science"},{"value":"204990","label":"Payne Theological Seminary"},{"value":"176239","label":"Pearl River Community College"},{"value":"214883","label":"Peirce College"},{"value":"221643","label":"Pellissippi State Community College"},{"value":"236258","label":"Peninsula College"},{"value":"214892","label":"Penn Commercial Business/Technical School"},{"value":"214944","label":"Pennco Tech-Bristol"},{"value":"214971","label":"Pennsylvania Academy of the Fine Arts"},{"value":"215053","label":"Pennsylvania College of Art and Design"},{"value":"442356","label":"Pennsylvania College of Health Sciences"},{"value":"366252","label":"Pennsylvania College of Technology"},{"value":"414911","label":"Pennsylvania Highlands Community College"},{"value":"261861","label":"Pennsylvania Institute of Health and Technology"},{"value":"214582","label":"Pennsylvania Institute of Technology"},{"value":"214616","label":"Pennsylvania State University-College of Medicine"},{"value":"212018","label":"Pennsylvania State University-Dickinson Law"},{"value":"214777","label":"Pennsylvania State University-Main Campus"},{"value":"214801","label":"Pennsylvania State University-Penn State Abington"},{"value":"214689","label":"Pennsylvania State University-Penn State Altoona"},{"value":"214698","label":"Pennsylvania State University-Penn State Beaver"},{"value":"214704","label":"Pennsylvania State University-Penn State Berks"},{"value":"214731","label":"Pennsylvania State University-Penn State Brandywine"},{"value":"214740","label":"Pennsylvania State University-Penn State DuBois"},{"value":"214591","label":"Pennsylvania State University-Penn State Erie-Behrend College"},{"value":"214759","label":"Pennsylvania State University-Penn State Fayette- Eberly"},{"value":"214607","label":"Pennsylvania State University-Penn State Great Valley"},{"value":"214786","label":"Pennsylvania State University-Penn State Greater Allegheny"},{"value":"214713","label":"Pennsylvania State University-Penn State Harrisburg"},{"value":"214768","label":"Pennsylvania State University-Penn State Hazleton"},{"value":"214670","label":"Pennsylvania State University-Penn State Lehigh Valley"},{"value":"214795","label":"Pennsylvania State University-Penn State Mont Alto"},{"value":"214625","label":"Pennsylvania State University-Penn State New Kensington"},{"value":"214810","label":"Pennsylvania State University-Penn State Schuylkill"},{"value":"214634","label":"Pennsylvania State University-Penn State Shenango"},{"value":"214643","label":"Pennsylvania State University-Penn State Wilkes-Barre"},{"value":"214652","label":"Pennsylvania State University-Penn State Worthington Scranton"},{"value":"214829","label":"Pennsylvania State University-Penn State York"},{"value":"479956","label":"Pennsylvania State University-World Campus"},{"value":"136473","label":"Pensacola State College"},{"value":"219842","label":"Pentecostal Theological Seminary"},{"value":"121150","label":"Pepperdine University"},{"value":"181534","label":"Peru State College"},{"value":"199306","label":"Pfeiffer University"},{"value":"215123","label":"Philadelphia College of Osteopathic Medicine"},{"value":"215099","label":"Philadelphia University"},{"value":"107600","label":"Philander Smith College"},{"value":"189282","label":"Phillips Beth Israel School of Nursing"},{"value":"107619","label":"Phillips Community College of the University of Arkansas"},{"value":"110307","label":"Phillips Graduate Institute"},{"value":"414966","label":"Phillips Theological Seminary"},{"value":"105428","label":"Phoenix College"},{"value":"447698","label":"Phoenix Institute of Herbal Medicine & Acupuncture"},{"value":"381459","label":"Phoenix Seminary"},{"value":"140818","label":"Piedmont College"},{"value":"199324","label":"Piedmont Community College"},{"value":"199315","label":"Piedmont International University"},{"value":"218520","label":"Piedmont Technical College"},{"value":"233116","label":"Piedmont Virginia Community College"},{"value":"235237","label":"Pierce College-Fort Steilacoom"},{"value":"439145","label":"Pierce College-Puyallup"},{"value":"443492","label":"Pierpont Community and Technical College"},{"value":"127820","label":"Pikes Peak Community College"},{"value":"440794","label":"Pillar College"},{"value":"105525","label":"Pima Community College"},{"value":"105543","label":"Pima Medical Institute-Albuquerque"},{"value":"461689","label":"Pima Medical Institute-Aurora"},{"value":"434140","label":"Pima Medical Institute-Chula Vista"},{"value":"442134","label":"Pima Medical Institute-Colorado Springs"},{"value":"404912","label":"Pima Medical Institute-Denver"},{"value":"456038","label":"Pima Medical Institute-East Valley"},{"value":"460136","label":"Pima Medical Institute-Houston"},{"value":"445230","label":"Pima Medical Institute-Las Vegas"},{"value":"260691","label":"Pima Medical Institute-Mesa"},{"value":"449074","label":"Pima Medical Institute-Renton"},{"value":"368629","label":"Pima Medical Institute-Seattle"},{"value":"105534","label":"Pima Medical Institute-Tucson"},{"value":"458159","label":"Pinchot University"},{"value":"167455","label":"Pine Manor College"},{"value":"174570","label":"Pine Technical & Community College"},{"value":"367097","label":"Pinnacle Career Institute-Lawrence"},{"value":"453109","label":"Pinnacle Career Institute-North Kansas City"},{"value":"177302","label":"Pinnacle Career Institute-South Kansas City"},{"value":"210076","label":"Pioneer Pacific College"},{"value":"199333","label":"Pitt Community College"},{"value":"155681","label":"Pittsburg State University"},{"value":"216782","label":"Pittsburgh Career Institute"},{"value":"215381","label":"Pittsburgh Institute of Aeronautics"},{"value":"215390","label":"Pittsburgh Institute of Mortuary Science Inc"},{"value":"215415","label":"Pittsburgh Technical Institute"},{"value":"215424","label":"Pittsburgh Theological Seminary"},{"value":"121257","label":"Pitzer College"},{"value":"260813","label":"Platt College-Aurora"},{"value":"207625","label":"Platt College-Central OKC"},{"value":"260789","label":"Platt College-Los Angeles"},{"value":"447379","label":"Platt College-Moore"},{"value":"445258","label":"Platt College-North OKC"},{"value":"432384","label":"Platt College-Ontario"},{"value":"480204","label":"Platt College-Riverside"},{"value":"121275","label":"Platt College-San Diego"},{"value":"245962","label":"Platt College-Tulsa"},{"value":"194499","label":"Plaza College"},{"value":"183080","label":"Plymouth State University"},{"value":"121309","label":"Point Loma Nazarene University"},{"value":"215442","label":"Point Park University"},{"value":"138868","label":"Point University"},{"value":"136516","label":"Polk State College"},{"value":"456481","label":"Polytechnic University of Puerto Rico-Miami"},{"value":"456490","label":"Polytechnic University of Puerto Rico-Orlando"},{"value":"190451","label":"Pomeroy College of Nursing at Crouse Hospital"},{"value":"121345","label":"Pomona College"},{"value":"243081","label":"Ponce Health Sciences University"},{"value":"243072","label":"Ponce Paramedical College Inc"},{"value":"241395","label":"Pontifical Catholic University of Puerto Rico-Arecibo"},{"value":"243586","label":"Pontifical Catholic University of Puerto Rico-Mayaguez"},{"value":"241410","label":"Pontifical Catholic University of Puerto Rico-Ponce"},{"value":"205027","label":"Pontifical College Josephinum"},{"value":"131405","label":"Pontifical Faculty of the Immaculate Conception at the Dominican House of Studies"},{"value":"455813","label":"Pontifical John Paul II Institute for Studies on Marriage and Family"},{"value":"167464","label":"Pope St John XXIII National Seminary"},{"value":"121363","label":"Porterville College"},{"value":"209746","label":"Portland Community College"},{"value":"209807","label":"Portland State University"},{"value":"130183","label":"Post University"},{"value":"237701","label":"Potomac State College of West Virginia University"},{"value":"148007","label":"Prairie State College"},{"value":"227526","label":"Prairie View A & M University"},{"value":"155715","label":"Pratt Community College"},{"value":"194578","label":"Pratt Institute-Main"},{"value":"218539","label":"Presbyterian College"},{"value":"105589","label":"Prescott College"},{"value":"219295","label":"Presentation College"},{"value":"163657","label":"Prince George's Community College"},{"value":"101958","label":"Prince Institute-Southeast"},{"value":"186122","label":"Princeton Theological Seminary"},{"value":"186131","label":"Princeton University"},{"value":"148016","label":"Principia College"},{"value":"215433","label":"Prism Career Institute-Upper Darby"},{"value":"437750","label":"Professional Golfers Career College"},{"value":"205054","label":"Professional Skills Institute"},{"value":"455770","label":"Providence Christian College"},{"value":"217402","label":"Providence College"},{"value":"380438","label":"Provo College"},{"value":"127884","label":"Pueblo Community College"},{"value":"241766","label":"Puerto Rico Conservatory of Music"},{"value":"107664","label":"Pulaski Technical College"},{"value":"152248","label":"Purdue University-Calumet Campus"},{"value":"243780","label":"Purdue University-Main Campus"},{"value":"152266","label":"Purdue University-North Central Campus"},{"value":"199412","label":"Queens University of Charlotte"},{"value":"167525","label":"Quincy College"},{"value":"148131","label":"Quincy University"},{"value":"130217","label":"Quinebaug Valley Community College"},{"value":"130226","label":"Quinnipiac University"},{"value":"167534","label":"Quinsigamond Community College"},{"value":"384421","label":"Rabbi Jacob Joseph School"},{"value":"194657","label":"Rabbinical Academy Mesivta Rabbi Chaim Berlin"},{"value":"194693","label":"Rabbinical College Beth Shraga"},{"value":"194666","label":"Rabbinical College Bobover Yeshiva Bnei Zion"},{"value":"186186","label":"Rabbinical College of America"},{"value":"194675","label":"Rabbinical College of Ch'san Sofer New York"},{"value":"194736","label":"Rabbinical College of Long Island"},{"value":"405854","label":"Rabbinical College of Ohr Shimon Yisroel"},{"value":"484871","label":"Rabbinical College Ohr Yisroel"},{"value":"205124","label":"Rabbinical College Telshe"},{"value":"194763","label":"Rabbinical Seminary of America"},{"value":"233277","label":"Radford University"},{"value":"481119","label":"Radians College"},{"value":"174604","label":"Rainy River Community College"},{"value":"186201","label":"Ramapo College of New Jersey"},{"value":"233301","label":"Randolph College"},{"value":"199421","label":"Randolph Community College"},{"value":"233295","label":"Randolph-Macon College"},{"value":"227687","label":"Ranger College"},{"value":"178891","label":"Ranken Technical College"},{"value":"233310","label":"Rappahannock Community College"},{"value":"186645","label":"Raritan Valley Community College"},{"value":"138309","label":"Rasmussen College-Florida"},{"value":"448673","label":"Rasmussen College-Illinois"},{"value":"175014","label":"Rasmussen College-Minnesota"},{"value":"200013","label":"Rasmussen College-North Dakota"},{"value":"450571","label":"Rasmussen College-Wisconsin"},{"value":"215585","label":"Reading Area Community College"},{"value":"215619","label":"Reconstructionist Rabbinical College"},{"value":"127909","label":"Red Rocks Community College"},{"value":"207069","label":"Redlands Community College"},{"value":"126605","label":"Redstone College"},{"value":"209922","label":"Reed College"},{"value":"117052","label":"Reedley College"},{"value":"215628","label":"Reformed Presbyterian Theological Seminary"},{"value":"105659","label":"Refrigeration School Inc"},{"value":"231651","label":"Regent University"},{"value":"167598","label":"Regis College"},{"value":"127918","label":"Regis University"},{"value":"101994","label":"Reid State Technical College"},{"value":"140872","label":"Reinhardt University"},{"value":"475033","label":"Relay Graduate School of Education"},{"value":"457183","label":"Remington College of Nursing Orlando"},{"value":"440271","label":"Remington College-Baton Rouge Campus"},{"value":"375416","label":"Remington College-Cleveland Campus"},{"value":"223463","label":"Remington College-Dallas Campus"},{"value":"377111","label":"Remington College-Fort Worth Campus"},{"value":"460783","label":"Remington College-Heathrow Campus"},{"value":"372958","label":"Remington College-Honolulu Campus"},{"value":"380094","label":"Remington College-Houston Campus"},{"value":"160524","label":"Remington College-Lafayette Campus"},{"value":"438869","label":"Remington College-Little Rock Campus"},{"value":"412599","label":"Remington College-Memphis Campus"},{"value":"366535","label":"Remington College-Mobile Campus"},{"value":"445249","label":"Remington College-Nashville Campus"},{"value":"445203","label":"Remington College-North Houston Campus"},{"value":"451866","label":"Remington College-Shreveport Campus"},{"value":"135939","label":"Remington College-Tampa Campus"},{"value":"148256","label":"Rend Lake College"},{"value":"129428","label":"Rensselaer Hartford Graduate Center Inc"},{"value":"194824","label":"Rensselaer Polytechnic Institute"},{"value":"236382","label":"Renton Technical College"},{"value":"178989","label":"Research College of Nursing"},{"value":"149763","label":"Resurrection University"},{"value":"217420","label":"Rhode Island College"},{"value":"217493","label":"Rhode Island School of Design"},{"value":"221351","label":"Rhodes College"},{"value":"227757","label":"Rice University"},{"value":"107743","label":"Rich Mountain Community College"},{"value":"233338","label":"Richard Bland College of the College of William and Mary"},{"value":"227766","label":"Richland College"},{"value":"148292","label":"Richland Community College"},{"value":"199449","label":"Richmond Community College"},{"value":"441104","label":"Richmont Graduate University"},{"value":"186283","label":"Rider University"},{"value":"175236","label":"Ridgewater College"},{"value":"136774","label":"Ringling College of Art and Design"},{"value":"475185","label":"Rio Grande Bible Institute"},{"value":"121886","label":"Rio Hondo College"},{"value":"105668","label":"Rio Salado College"},{"value":"239628","label":"Ripon College"},{"value":"436304","label":"River Parishes Community College"},{"value":"183114","label":"River Valley Community College"},{"value":"173063","label":"Riverland Community College"},{"value":"121901","label":"Riverside City College"},{"value":"233408","label":"Riverside College of Health Careers"},{"value":"183211","label":"Rivier University"},{"value":"221397","label":"Roane State Community College"},{"value":"233426","label":"Roanoke College"},{"value":"199467","label":"Roanoke-Chowan Community College"},{"value":"215655","label":"Robert Morris University"},{"value":"148335","label":"Robert Morris University Illinois"},{"value":"194958","label":"Roberts Wesleyan College"},{"value":"199476","label":"Robeson Community College"},{"value":"170967","label":"Rochester College"},{"value":"174738","label":"Rochester Community and Technical College"},{"value":"195003","label":"Rochester Institute of Technology"},{"value":"148380","label":"Rock Valley College"},{"value":"195049","label":"Rockefeller University"},{"value":"148405","label":"Rockford University"},{"value":"179043","label":"Rockhurst University"},{"value":"199485","label":"Rockingham Community College"},{"value":"195058","label":"Rockland Community College"},{"value":"180595","label":"Rocky Mountain College"},{"value":"127945","label":"Rocky Mountain College of Art and Design"},{"value":"475495","label":"Rocky Mountain University of Health Professions"},{"value":"480790","label":"Rocky Vista University"},{"value":"217518","label":"Roger Williams University"},{"value":"409616","label":"Roger Williams University School of Law"},{"value":"207661","label":"Rogers State University"},{"value":"209940","label":"Rogue Community College"},{"value":"136950","label":"Rollins College"},{"value":"148487","label":"Roosevelt University"},{"value":"145558","label":"Rosalind Franklin University of Medicine and Science"},{"value":"207670","label":"Rose State College"},{"value":"439899","label":"Rosedale Bible College"},{"value":"215682","label":"Rosedale Technical Institute"},{"value":"152318","label":"Rose-Hulman Institute of Technology"},{"value":"445735","label":"Roseman University of Health Sciences"},{"value":"215691","label":"Rosemont College"},{"value":"452081","label":"Ross College-Sylvania"},{"value":"183877","label":"Rowan College at Burlington County"},{"value":"184791","label":"Rowan College at Gloucester County"},{"value":"184782","label":"Rowan University"},{"value":"199494","label":"Rowan-Cabarrus Community College"},{"value":"167631","label":"Roxbury Community College"},{"value":"148511","label":"Rush University"},{"value":"176318","label":"Rust College"},{"value":"186371","label":"Rutgers University-Camden"},{"value":"186380","label":"Rutgers University-New Brunswick"},{"value":"186399","label":"Rutgers University-Newark"},{"value":"449506","label":"SABER College"},{"value":"122180","label":"Sacramento City College"},{"value":"172033","label":"Sacred Heart Major Seminary"},{"value":"239637","label":"Sacred Heart School of Theology"},{"value":"130253","label":"Sacred Heart University"},{"value":"122205","label":"Saddleback College"},{"value":"476948","label":"SAE Institute of Technology-Atlanta"},{"value":"446525","label":"SAE Institute of Technology-Nashville"},{"value":"410520","label":"Sage College"},{"value":"441070","label":"Saginaw Chippewa Tribal College"},{"value":"172051","label":"Saginaw Valley State University"},{"value":"154235","label":"Saint Ambrose University"},{"value":"183239","label":"Saint Anselm College"},{"value":"149028","label":"Saint Anthony College of Nursing"},{"value":"148876","label":"Saint Augustine College"},{"value":"199582","label":"Saint Augustine's University"},{"value":"157632","label":"Saint Catharine College"},{"value":"216047","label":"Saint Charles Borromeo Seminary-Overbrook"},{"value":"174783","label":"Saint Cloud State University"},{"value":"227845","label":"Saint Edward's University"},{"value":"195702","label":"Saint Elizabeth College of Nursing-Utica"},{"value":"148575","label":"Saint Francis Medical Center College of Nursing"},{"value":"215743","label":"Saint Francis University"},{"value":"195720","label":"Saint John Fisher College"},{"value":"137272","label":"Saint John Vianney College Seminary"},{"value":"137281","label":"Saint Johns River State College"},{"value":"167677","label":"Saint John's Seminary"},{"value":"174792","label":"Saint Johns University"},{"value":"160409","label":"Saint Joseph Seminary College"},{"value":"152363","label":"Saint Josephs College"},{"value":"161518","label":"Saint Joseph's College of Maine"},{"value":"195544","label":"Saint Joseph's College-New York"},{"value":"215770","label":"Saint Joseph's University"},{"value":"137032","label":"Saint Leo University"},{"value":"179256","label":"Saint Louis Christian College"},{"value":"179308","label":"Saint Louis Community College"},{"value":"179159","label":"Saint Louis University"},{"value":"179450","label":"Saint Luke's College of Health Sciences"},{"value":"236452","label":"Saint Martin's University"},{"value":"152381","label":"Saint Mary-of-the-Woods College"},{"value":"152390","label":"Saint Mary's College"},{"value":"123554","label":"Saint Mary's College of California"},{"value":"174817","label":"Saint Mary's University of Minnesota"},{"value":"152451","label":"Saint Meinrad School of Theology"},{"value":"231059","label":"Saint Michael's College"},{"value":"239716","label":"Saint Norbert College"},{"value":"175041","label":"Saint Paul College"},{"value":"179317","label":"Saint Paul School of Theology"},{"value":"186432","label":"Saint Peter's University"},{"value":"215798","label":"Saint Vincent College"},{"value":"136701","label":"Saint Vincent de Paul Regional Seminary"},{"value":"215813","label":"Saint Vincent Seminary"},{"value":"195580","label":"Saint Vladimirs Orthodox Theological Seminary"},{"value":"148627","label":"Saint Xavier University"},{"value":"199607","label":"Salem College"},{"value":"186469","label":"Salem Community College"},{"value":"237783","label":"Salem International University"},{"value":"167729","label":"Salem State University"},{"value":"155830","label":"Salina Area Technical College"},{"value":"163851","label":"Salisbury University"},{"value":"180647","label":"Salish Kootenai College"},{"value":"230746","label":"Salt Lake Community College"},{"value":"466523","label":"Salter College-Chicopee"},{"value":"167738","label":"Salter College-West Boylston"},{"value":"214564","label":"Salus University"},{"value":"217536","label":"Salve Regina University"},{"value":"227881","label":"Sam Houston State University"},{"value":"195289","label":"Samaritan Hospital School of Nursing"},{"value":"102049","label":"Samford University"},{"value":"199625","label":"Sampson Community College"},{"value":"122296","label":"Samuel Merritt University"},{"value":"227924","label":"San Antonio College"},{"value":"123527","label":"San Bernardino Valley College"},{"value":"112084","label":"San Diego Christian College"},{"value":"122339","label":"San Diego City College"},{"value":"122375","label":"San Diego Mesa College"},{"value":"122384","label":"San Diego Miramar College"},{"value":"122409","label":"San Diego State University"},{"value":"122454","label":"San Francisco Art Institute"},{"value":"122506","label":"San Francisco Conservatory of Music"},{"value":"122597","label":"San Francisco State University"},{"value":"122603","label":"San Francisco Theological Seminary"},{"value":"227979","label":"San Jacinto Community College"},{"value":"122649","label":"San Joaquin College of Law"},{"value":"122658","label":"San Joaquin Delta College"},{"value":"122685","label":"San Joaquin Valley College-Visalia"},{"value":"122746","label":"San Jose City College"},{"value":"122755","label":"San Jose State University"},{"value":"430670","label":"San Juan Bautista School of Medicine"},{"value":"188100","label":"San Juan College"},{"value":"199634","label":"Sandhills Community College"},{"value":"481535","label":"Sanford Burnham Prybis Medical Discovery Institute"},{"value":"420495","label":"Sanford-Brown College-Atlanta"},{"value":"475291","label":"Sanford-Brown College-Brooklyn Center"},{"value":"146010","label":"Sanford-Brown College-Chicago"},{"value":"404514","label":"Sanford-Brown College-Dallas"},{"value":"179201","label":"Sanford-Brown College-Fenton"},{"value":"404499","label":"Sanford-Brown College-Houston"},{"value":"446792","label":"Sanford-Brown College-Las Vegas"},{"value":"174394","label":"Sanford-Brown College-Mendota Heights"},{"value":"420501","label":"Sanford-Brown College-Middleburg Heights"},{"value":"456296","label":"Sanford-Brown College-Online"},{"value":"440925","label":"Sanford-Brown College-Orlando"},{"value":"450465","label":"Sanford-Brown College-San Antonio-San Antonio"},{"value":"446808","label":"Sanford-Brown College-Seattle"},{"value":"134680","label":"Sanford-Brown College-Tampa"},{"value":"234216","label":"Sanford-Brown College-Tysons Corner"},{"value":"385008","label":"Sanford-Brown Institute-Ft Lauderdale"},{"value":"404505","label":"Sanford-Brown Institute-Jacksonville"},{"value":"121619","label":"Santa Ana College"},{"value":"122834","label":"Santa Barbara Business College-Bakersfield"},{"value":"122852","label":"Santa Barbara Business College-Santa Maria"},{"value":"433420","label":"Santa Barbara Business College-Ventura"},{"value":"122889","label":"Santa Barbara City College"},{"value":"122931","label":"Santa Clara University"},{"value":"137096","label":"Santa Fe College"},{"value":"188137","label":"Santa Fe Community College"},{"value":"188146","label":"Santa Fe University of Art and Design"},{"value":"122977","label":"Santa Monica College"},{"value":"123013","label":"Santa Rosa Junior College"},{"value":"399212","label":"Santiago Canyon College"},{"value":"195304","label":"Sarah Lawrence College"},{"value":"148672","label":"Sauk Valley Community College"},{"value":"140951","label":"Savannah College of Art and Design"},{"value":"140960","label":"Savannah State University"},{"value":"140942","label":"Savannah Technical College"},{"value":"123095","label":"Saybrook University"},{"value":"192156","label":"SBI Campus-An Affiliate of Sanford-Brown"},{"value":"195322","label":"Schenectady County Community College"},{"value":"404338","label":"Schiller International University"},{"value":"143048","label":"School of the Art Institute of Chicago"},{"value":"166984","label":"School of the Museum of Fine Arts-Boston"},{"value":"197151","label":"School of Visual Arts"},{"value":"172200","label":"Schoolcraft College"},{"value":"228042","label":"Schreiner University"},{"value":"105747","label":"Scottsdale Community College"},{"value":"123165","label":"Scripps College"},{"value":"236513","label":"Seattle Central College"},{"value":"439914","label":"Seattle Institute of Oriental Medicine"},{"value":"236577","label":"Seattle Pacific University"},{"value":"236595","label":"Seattle University"},{"value":"102058","label":"Selma University"},{"value":"243498","label":"Seminario Evangelico de Puerto Rico"},{"value":"207740","label":"Seminole State College"},{"value":"137209","label":"Seminole State College of Florida"},{"value":"232885","label":"Sentara College of Health Sciences"},{"value":"475839","label":"Sessions College for Professional Design"},{"value":"186584","label":"Seton Hall University"},{"value":"215947","label":"Seton Hill University"},{"value":"221519","label":"Sewanee-The University of the South"},{"value":"155858","label":"Seward County Community College and Area Technical School"},{"value":"123280","label":"Shasta Bible College and Graduate School"},{"value":"123299","label":"Shasta College"},{"value":"199643","label":"Shaw University"},{"value":"148821","label":"Shawnee Community College"},{"value":"205443","label":"Shawnee State University"},{"value":"102067","label":"Shelton State Community College"},{"value":"233541","label":"Shenandoah University"},{"value":"237792","label":"Shepherd University"},{"value":"461485","label":"Shepherds Theological Seminary"},{"value":"240666","label":"Sheridan College"},{"value":"218751","label":"Sherman College of Straight Chiropractic"},{"value":"480499","label":"Shiloh University"},{"value":"148849","label":"Shimer College"},{"value":"216010","label":"Shippensburg University of Pennsylvania"},{"value":"195438","label":"Sh'or Yoshuv Rabbinical College"},{"value":"236610","label":"Shoreline Community College"},{"value":"107840","label":"Shorter College"},{"value":"140988","label":"Shorter University"},{"value":"448309","label":"Shorter University-College of Adult & Professional Programs"},{"value":"195474","label":"Siena College"},{"value":"172264","label":"Siena Heights University"},{"value":"123341","label":"Sierra College"},{"value":"182458","label":"Sierra Nevada College"},{"value":"239743","label":"Silver Lake College of the Holy Family"},{"value":"167783","label":"Simmons College"},{"value":"461759","label":"Simmons College of Kentucky"},{"value":"154350","label":"Simpson College"},{"value":"123457","label":"Simpson University"},{"value":"205470","label":"Sinclair Community College"},{"value":"219374","label":"Sinte Gleska University"},{"value":"219240","label":"Sioux Falls Seminary"},{"value":"219408","label":"Sisseton Wahpeton College"},{"value":"231068","label":"SIT Graduate Institute"},{"value":"200466","label":"Sitting Bull College"},{"value":"236638","label":"Skagit Valley College"},{"value":"195526","label":"Skidmore College"},{"value":"123509","label":"Skyline College"},{"value":"261931","label":"Skyline College-Roanoke"},{"value":"216038","label":"Slippery Rock University of Pennsylvania"},{"value":"167835","label":"Smith College"},{"value":"102076","label":"Snead State Community College"},{"value":"230597","label":"Snow College"},{"value":"110778","label":"Sofia University"},{"value":"163921","label":"Sojourner-Douglass College"},{"value":"399911","label":"Soka University of America"},{"value":"123563","label":"Solano Community College"},{"value":"459356","label":"SOLEX College"},{"value":"157711","label":"Somerset Community College"},{"value":"123572","label":"Sonoma State University"},{"value":"481094","label":"Sotheby's Institute of Art-NY"},{"value":"107974","label":"South Arkansas Community College"},{"value":"123633","label":"South Baylo University"},{"value":"218733","label":"South Carolina State University"},{"value":"173911","label":"South Central College"},{"value":"160913","label":"South Central Louisiana Technical College-Young Memorial Campus"},{"value":"123642","label":"South Coast College"},{"value":"220552","label":"South College"},{"value":"198242","label":"South College-Asheville"},{"value":"219347","label":"South Dakota School of Mines and Technology"},{"value":"219356","label":"South Dakota State University"},{"value":"366003","label":"South Florida Bible College and Theological Seminary"},{"value":"137315","label":"South Florida State College"},{"value":"482699","label":"South Georgia State College"},{"value":"141006","label":"South Georgia Technical College"},{"value":"216083","label":"South Hills School of Business & Technology"},{"value":"434061","label":"South Louisiana Community College"},{"value":"105792","label":"South Mountain Community College"},{"value":"197850","label":"South Piedmont Community College"},{"value":"228158","label":"South Plains College"},{"value":"236656","label":"South Puget Sound Community College"},{"value":"236504","label":"South Seattle College"},{"value":"149365","label":"South Suburban College"},{"value":"409315","label":"South Texas College"},{"value":"228194","label":"South Texas College of Law"},{"value":"468006","label":"South University-Accelerated Graduate Programs"},{"value":"480073","label":"South University-Austin"},{"value":"480082","label":"South University-Cleveland"},{"value":"251312","label":"South University-Columbia"},{"value":"481720","label":"South University-High Point"},{"value":"101116","label":"South University-Montgomery"},{"value":"468024","label":"South University-Novi"},{"value":"459259","label":"South University–Richmond"},{"value":"139579","label":"South University-Savannah"},{"value":"475121","label":"South University–Savannah Online"},{"value":"449898","label":"South University-Tampa"},{"value":"224776","label":"South University-The Art Institute of Dallas"},{"value":"468015","label":"South University-The Art Institute of Fort Worth"},{"value":"459268","label":"South University–Virginia Beach"},{"value":"133465","label":"South University-West Palm Beach"},{"value":"156338","label":"Southcentral Kentucky Community and Technical College"},{"value":"107637","label":"Southeast Arkansas College"},{"value":"181640","label":"Southeast Community College Area"},{"value":"157739","label":"Southeast Kentucky Community and Technical College"},{"value":"417734","label":"Southeast Missouri Hospital College of Nursing and Health Sciences"},{"value":"179557","label":"Southeast Missouri State University"},{"value":"219426","label":"Southeast Technical Institute"},{"value":"176336","label":"Southeastern Baptist College"},{"value":"199759","label":"Southeastern Baptist Theological Seminary"},{"value":"102261","label":"Southeastern Bible College"},{"value":"443270","label":"Southeastern College-Jacksonville"},{"value":"428170","label":"Southeastern College-West Palm Beach"},{"value":"154378","label":"Southeastern Community College-West Burlington"},{"value":"199722","label":"Southeastern Community College-Whiteville"},{"value":"148937","label":"Southeastern Illinois College"},{"value":"160612","label":"Southeastern Louisiana University"},{"value":"207847","label":"Southeastern Oklahoma State University"},{"value":"368911","label":"Southeastern Technical College"},{"value":"137564","label":"Southeastern University"},{"value":"221661","label":"Southern Adventist University"},{"value":"107983","label":"Southern Arkansas University Main Campus"},{"value":"107992","label":"Southern Arkansas University Tech"},{"value":"123952","label":"Southern California Institute of Architecture"},{"value":"399869","label":"Southern California Institute of Technology"},{"value":"117575","label":"Southern California Seminary"},{"value":"117672","label":"Southern California University of Health Sciences"},{"value":"459222","label":"Southern California University SOMA"},{"value":"221670","label":"Southern College of Optometry"},{"value":"130493","label":"Southern Connecticut State University"},{"value":"139986","label":"Southern Crescent Technical College"},{"value":"149222","label":"Southern Illinois University-Carbondale"},{"value":"149231","label":"Southern Illinois University-Edwardsville"},{"value":"161545","label":"Southern Maine Community College"},{"value":"228246","label":"Southern Methodist University"},{"value":"206862","label":"Southern Nazarene University"},{"value":"183026","label":"Southern New Hampshire University"},{"value":"210146","label":"Southern Oregon University"},{"value":"141097","label":"Southern Polytechnic State University"},{"value":"205966","label":"Southern State Community College"},{"value":"366553","label":"Southern Technical College-Fort Myers"},{"value":"446552","label":"Southern Technical College-Orlando"},{"value":"251260","label":"Southern Union State Community College"},{"value":"160621","label":"Southern University and A & M College"},{"value":"160630","label":"Southern University at New Orleans"},{"value":"160649","label":"Southern University at Shreveport"},{"value":"440916","label":"Southern University Law Center"},{"value":"230603","label":"Southern Utah University"},{"value":"231086","label":"Southern Vermont College"},{"value":"233611","label":"Southern Virginia University"},{"value":"217776","label":"Southern Wesleyan University"},{"value":"237817","label":"Southern West Virginia Community and Technical College"},{"value":"233082","label":"Southside Regional Medical Center Professional Schools"},{"value":"233639","label":"Southside Virginia Community College"},{"value":"413644","label":"Southwest Acupuncture College-Albuquerque"},{"value":"436261","label":"Southwest Acupuncture College-Boulder"},{"value":"366605","label":"Southwest Acupuncture College-Santa Fe"},{"value":"179326","label":"Southwest Baptist University"},{"value":"420246","label":"Southwest College of Naturopathic Medicine & Health Sciences"},{"value":"382911","label":"Southwest Collegiate Institute for the Deaf"},{"value":"141158","label":"Southwest Georgia Technical College"},{"value":"442879","label":"Southwest Institute of Healing Arts"},{"value":"175078","label":"Southwest Minnesota State University"},{"value":"176354","label":"Southwest Mississippi Community College"},{"value":"221485","label":"Southwest Tennessee Community College"},{"value":"228316","label":"Southwest Texas Junior College"},{"value":"451556","label":"Southwest University at El Paso"},{"value":"402776","label":"Southwest University of Visual Arts-Albuquerque"},{"value":"104188","label":"Southwest University of Visual Arts-Tucson"},{"value":"233648","label":"Southwest Virginia Community College"},{"value":"239910","label":"Southwest Wisconsin Technical College"},{"value":"228468","label":"Southwestern Adventist University"},{"value":"228325","label":"Southwestern Assemblies of God University"},{"value":"228486","label":"Southwestern Christian College"},{"value":"207856","label":"Southwestern Christian University"},{"value":"123800","label":"Southwestern College-Chula Vista"},{"value":"188207","label":"Southwestern College-Santa Fe"},{"value":"155900","label":"Southwestern College-Winfield"},{"value":"154396","label":"Southwestern Community College-Creston"},{"value":"199731","label":"Southwestern Community College-Sylva"},{"value":"143215","label":"Southwestern Illinois College"},{"value":"188216","label":"Southwestern Indian Polytechnic Institute"},{"value":"123970","label":"Southwestern Law School"},{"value":"172307","label":"Southwestern Michigan College"},{"value":"207865","label":"Southwestern Oklahoma State University"},{"value":"210155","label":"Southwestern Oregon Community College"},{"value":"228343","label":"Southwestern University"},{"value":"160579","label":"SOWELA Technical Community College"},{"value":"157757","label":"Spalding University"},{"value":"207254","label":"Spartan College of Aeronautics and Technology"},{"value":"218830","label":"Spartanburg Community College"},{"value":"218821","label":"Spartanburg Methodist College"},{"value":"141060","label":"Spelman College"},{"value":"433563","label":"Spencerian College-Lexington"},{"value":"157766","label":"Spencerian College-Louisville"},{"value":"148982","label":"Spertus College"},{"value":"236692","label":"Spokane Community College"},{"value":"236708","label":"Spokane Falls Community College"},{"value":"148991","label":"Spoon River College"},{"value":"172334","label":"Spring Arbor University"},{"value":"102234","label":"Spring Hill College"},{"value":"167899","label":"Springfield College"},{"value":"475273","label":"Springfield College-School of Professional and Continuing Studies"},{"value":"167905","label":"Springfield Technical Community College"},{"value":"199698","label":"St Andrews University"},{"value":"195155","label":"St Bernard's School of Theology and Ministry"},{"value":"195164","label":"St Bonaventure University"},{"value":"175005","label":"St Catherine University"},{"value":"262031","label":"St Charles Community College"},{"value":"172291","label":"St Clair County Community College"},{"value":"174756","label":"St Cloud Technical and Community College"},{"value":"195173","label":"St Francis College"},{"value":"163976","label":"St John's College"},{"value":"123855","label":"St John's Seminary"},{"value":"195809","label":"St John's University-New York"},{"value":"183248","label":"St Joseph School of Nursing-Nashua"},{"value":"195191","label":"St Joseph's College of Nursing at St Joseph's Hospital Health Center"},{"value":"195216","label":"St Lawrence University"},{"value":"442426","label":"St Louis College of Health Careers-Fenton"},{"value":"179511","label":"St Louis College of Health Careers-St Louis"},{"value":"179265","label":"St Louis College of Pharmacy"},{"value":"154262","label":"St Luke's College"},{"value":"163912","label":"St Mary's College of Maryland"},{"value":"228149","label":"St Mary's University"},{"value":"174844","label":"St Olaf College"},{"value":"189811","label":"St Paul's School of Nursing-Queens"},{"value":"195784","label":"St Paul's School of Nursing-Staten Island"},{"value":"137078","label":"St Petersburg College"},{"value":"227854","label":"St Philip's College"},{"value":"137476","label":"St Thomas University"},{"value":"130448","label":"St Vincent's College"},{"value":"207689","label":"St. Gregory's University"},{"value":"245652","label":"St. John's College"},{"value":"148593","label":"St. John's College-Department of Nursing"},{"value":"195243","label":"St. Thomas Aquinas College"},{"value":"446561","label":"Stanbridge College"},{"value":"483814","label":"Standard Healthcare Services-College of Nursing"},{"value":"243744","label":"Stanford University"},{"value":"199740","label":"Stanly Community College"},{"value":"205841","label":"Stark State College"},{"value":"123916","label":"Starr King School for Ministry"},{"value":"135391","label":"State College of Florida-Manatee-Sarasota"},{"value":"179539","label":"State Fair Community College"},{"value":"177977","label":"State Technical College of Missouri"},{"value":"196176","label":"State University of New York at New Paltz"},{"value":"448600","label":"Stautzenberger College-Brecksville"},{"value":"205887","label":"Stautzenberger College-Maumee"},{"value":"228431","label":"Stephen F Austin State University"},{"value":"179548","label":"Stephens College"},{"value":"231095","label":"Sterling College-Craftsbury Common"},{"value":"155937","label":"Sterling College-Sterling"},{"value":"137546","label":"Stetson University"},{"value":"186867","label":"Stevens Institute of Technology"},{"value":"460899","label":"Stevens-Henager College-Boise"},{"value":"474906","label":"Stevens-Henager College-Idaho Falls"},{"value":"446677","label":"Stevens-Henager College-Logan"},{"value":"438151","label":"Stevens-Henager College-Murray"},{"value":"230630","label":"Stevens-Henager College-Orem"},{"value":"477950","label":"Stevens-Henager College-St. George"},{"value":"230621","label":"Stevens-Henager College-West Haven"},{"value":"164173","label":"Stevenson University"},{"value":"178767","label":"Stevens-The Institute of Business & Arts"},{"value":"102270","label":"Stillman College"},{"value":"186876","label":"Stockton University"},{"value":"366340","label":"Stone Child College"},{"value":"167996","label":"Stonehill College"},{"value":"196097","label":"Stony Brook University"},{"value":"438498","label":"Stratford University"},{"value":"450377","label":"Strayer University-Alabama"},{"value":"458885","label":"Strayer University-Arkansas"},{"value":"450298","label":"Strayer University-Delaware"},{"value":"131803","label":"Strayer University-District of Columbia"},{"value":"449038","label":"Strayer University-Florida"},{"value":"458919","label":"Strayer University-Georgia"},{"value":"459994","label":"Strayer University-Global Region"},{"value":"458937","label":"Strayer University-Louisiana"},{"value":"430184","label":"Strayer University-Maryland"},{"value":"458955","label":"Strayer University-Mississippi"},{"value":"453215","label":"Strayer University-New Jersey"},{"value":"453163","label":"Strayer University-North Carolina"},{"value":"443784","label":"Strayer University-Pennsylvania"},{"value":"458964","label":"Strayer University-South Carolina"},{"value":"443766","label":"Strayer University-Tennessee"},{"value":"458973","label":"Strayer University-Texas"},{"value":"233684","label":"Strayer University-Virginia"},{"value":"456621","label":"Strayer University-West Virginia"},{"value":"366395","label":"Suffolk County Community College"},{"value":"168005","label":"Suffolk University"},{"value":"228501","label":"Sul Ross State University"},{"value":"157270","label":"Sullivan College of Technology and Design"},{"value":"195988","label":"Sullivan County Community College"},{"value":"157793","label":"Sullivan University"},{"value":"447953","label":"SUM Bible College and Theological Seminary"},{"value":"181543","label":"Summit Christian College"},{"value":"208512","label":"Sumner College"},{"value":"196060","label":"SUNY at Albany"},{"value":"196079","label":"SUNY at Binghamton"},{"value":"196158","label":"SUNY at Fredonia"},{"value":"196219","label":"SUNY at Purchase College"},{"value":"189547","label":"SUNY Broome Community College"},{"value":"196130","label":"SUNY Buffalo State"},{"value":"196121","label":"SUNY College at Brockport"},{"value":"196149","label":"SUNY College at Cortland"},{"value":"196167","label":"SUNY College at Geneseo"},{"value":"196237","label":"SUNY College at Old Westbury"},{"value":"196194","label":"SUNY College at Oswego"},{"value":"196246","label":"SUNY College at Plattsburgh"},{"value":"196200","label":"SUNY College at Potsdam"},{"value":"196033","label":"SUNY College of Agriculture and Technology at Cobleskill"},{"value":"196103","label":"SUNY College of Environmental Science and Forestry"},{"value":"196228","label":"SUNY College of Optometry"},{"value":"196006","label":"SUNY College of Technology at Alfred"},{"value":"196015","label":"SUNY College of Technology at Canton"},{"value":"196024","label":"SUNY College of Technology at Delhi"},{"value":"196255","label":"SUNY Downstate Medical Center"},{"value":"196264","label":"SUNY Empire State College"},{"value":"196291","label":"SUNY Maritime College"},{"value":"196185","label":"SUNY Oneonta"},{"value":"196112","label":"SUNY Polytechnic Institute"},{"value":"197294","label":"SUNY Westchester Community College"},{"value":"199768","label":"Surry Community College"},{"value":"216278","label":"Susquehanna University"},{"value":"247603","label":"Sussex County Community College"},{"value":"216287","label":"Swarthmore College"},{"value":"196389","label":"Swedish Institute a College of Health Sciences"},{"value":"233718","label":"Sweet Briar College"},{"value":"196413","label":"Syracuse University"},{"value":"155973","label":"Tabor College"},{"value":"236753","label":"Tacoma Community College"},{"value":"124113","label":"Taft College"},{"value":"454689","label":"Taft University System"},{"value":"102298","label":"Talladega College"},{"value":"137759","label":"Tallahassee Community College"},{"value":"137777","label":"Talmudic College of Florida"},{"value":"186900","label":"Talmudical Academy-New Jersey"},{"value":"196440","label":"Talmudical Institute of Upstate New York"},{"value":"451404","label":"Talmudical Seminary of Bobov"},{"value":"196431","label":"Talmudical Seminary Oholei Torah"},{"value":"216311","label":"Talmudical Yeshiva of Philadelphia"},{"value":"228529","label":"Tarleton State University"},{"value":"228547","label":"Tarrant County College District"},{"value":"149310","label":"Taylor Business Institute"},{"value":"449524","label":"Taylor College"},{"value":"152530","label":"Taylor University"},{"value":"196468","label":"Teachers College at Columbia University"},{"value":"196477","label":"Technical Career Institutes"},{"value":"217712","label":"Technical College of the Lowcountry"},{"value":"149329","label":"Telshe Yeshiva-Chicago"},{"value":"228608","label":"Temple College"},{"value":"216339","label":"Temple University"},{"value":"221838","label":"Tennessee State University"},{"value":"221847","label":"Tennessee Technological University"},{"value":"221856","label":"Tennessee Temple University"},{"value":"221731","label":"Tennessee Wesleyan College"},{"value":"206011","label":"Terra State Community College"},{"value":"228699","label":"Texarkana College"},{"value":"226152","label":"Texas A & M International University"},{"value":"483036","label":"Texas A & M University-Central Texas"},{"value":"228723","label":"Texas A & M University-College Station"},{"value":"224554","label":"Texas A & M University-Commerce"},{"value":"224147","label":"Texas A & M University-Corpus Christi"},{"value":"228705","label":"Texas A & M University-Kingsville"},{"value":"224545","label":"Texas A & M University-Texarkana"},{"value":"228866","label":"Texas Chiropractic College Foundation Inc"},{"value":"228875","label":"Texas Christian University"},{"value":"228884","label":"Texas College"},{"value":"441487","label":"Texas County Technical College"},{"value":"430704","label":"Texas Health and Science University"},{"value":"228981","label":"Texas Lutheran University"},{"value":"229063","label":"Texas Southern University"},{"value":"229319","label":"Texas State Technical College-Harlingen"},{"value":"408394","label":"Texas State Technical College-Marshall"},{"value":"228680","label":"Texas State Technical College-Waco"},{"value":"229328","label":"Texas State Technical College-West Texas"},{"value":"228459","label":"Texas State University"},{"value":"229115","label":"Texas Tech University"},{"value":"229337","label":"Texas Tech University Health Sciences Center"},{"value":"229160","label":"Texas Wesleyan University"},{"value":"229179","label":"Texas Woman's University"},{"value":"216296","label":"Thaddeus Stevens College of Technology"},{"value":"138813","label":"The Art Institute of Atlanta"},{"value":"451820","label":"The Art Institute of Austin"},{"value":"450085","label":"The Art Institute of Charleston"},{"value":"197832","label":"The Art Institute of Charlotte"},{"value":"200624","label":"The Art Institute of Cincinnati-AIC College of Design"},{"value":"126702","label":"The Art Institute of Colorado"},{"value":"132338","label":"The Art Institute of Fort Lauderdale"},{"value":"222938","label":"The Art Institute of Houston"},{"value":"448345","label":"The Art Institute of Indianapolis"},{"value":"182111","label":"The Art Institute of Las Vegas"},{"value":"451796","label":"The Art Institute of Michigan"},{"value":"365055","label":"The Art Institute of New York City"},{"value":"446668","label":"The Art Institute of Ohio-Cincinnati"},{"value":"210942","label":"The Art Institute of Philadelphia"},{"value":"428444","label":"The Art Institute of Phoenix"},{"value":"210960","label":"The Art Institute of Pittsburgh"},{"value":"451662","label":"The Art Institute of Pittsburgh-Online Division"},{"value":"208239","label":"The Art Institute of Portland"},{"value":"452027","label":"The Art Institute of Raleigh-Durham"},{"value":"450049","label":"The Art Institute of Salt Lake City"},{"value":"458982","label":"The Art Institute of San Antonio"},{"value":"234492","label":"The Art Institute of Seattle"},{"value":"482398","label":"The Art Institute of St Louis"},{"value":"449010","label":"The Art Institute of Tennessee-Nashville"},{"value":"444927","label":"The Art Institute of Tucson"},{"value":"458496","label":"The Art Institute of Virginia Beach"},{"value":"440341","label":"The Art Institute of Washington"},{"value":"456010","label":"The Art Institute of Washington-Dulles"},{"value":"470092","label":"The Art Institute of Wisconsin"},{"value":"452018","label":"The Art Institutes International–Kansas City"},{"value":"173887","label":"The Art Institutes International-Minnesota"},{"value":"210906","label":"The Art Institutes of York-PA"},{"value":"132408","label":"The Baptist College of Florida"},{"value":"164933","label":"The Boston Conservatory"},{"value":"111188","label":"The California Maritime Academy"},{"value":"143978","label":"The Chicago School of Professional Psychology at Chicago"},{"value":"455433","label":"The Chicago School of Professional Psychology at Irvine"},{"value":"455664","label":"The Chicago School of Professional Psychology at Los Angeles"},{"value":"459745","label":"The Chicago School of Professional Psychology at Washington DC"},{"value":"455682","label":"The Chicago School of Professional Psychology at Westwood"},{"value":"201821","label":"The Christ College of Nursing and Health Sciences"},{"value":"437635","label":"The College of Health Care Professions-Austin"},{"value":"480824","label":"The College of Health Care Professions-Dallas"},{"value":"480833","label":"The College of Health Care Professions-Fort Worth"},{"value":"142294","label":"The College of Idaho"},{"value":"187134","label":"The College of New Jersey"},{"value":"193645","label":"The College of New Rochelle"},{"value":"195234","label":"The College of Saint Rose"},{"value":"174899","label":"The College of Saint Scholastica"},{"value":"197285","label":"The College of Westchester"},{"value":"206589","label":"The College of Wooster"},{"value":"456542","label":"The Commonwealth Medical College"},{"value":"434672","label":"The Community College of Baltimore County"},{"value":"430485","label":"The Creative Center"},{"value":"235167","label":"The Evergreen State College"},{"value":"191320","label":"The General Theological Seminary"},{"value":"148177","label":"The Illinois Institute of Art-Chicago"},{"value":"428286","label":"The Illinois Institute of Art-Schaumburg"},{"value":"146241","label":"The John Marshall Law School"},{"value":"192110","label":"The Juilliard School"},{"value":"454184","label":"The King’s College"},{"value":"439701","label":"The King's University"},{"value":"161208","label":"The Landing School"},{"value":"213598","label":"The Lincoln University"},{"value":"117751","label":"The Master's College and Seminary"},{"value":"119544","label":"The National Hispanic University"},{"value":"167057","label":"The New England Conservatory of Music"},{"value":"167321","label":"The New England Institute of Art"},{"value":"193654","label":"The New School"},{"value":"215637","label":"The Restaurant School at Walnut Hill College"},{"value":"448804","label":"The Robert B Miller College"},{"value":"195128","label":"The Sage Colleges"},{"value":"475228","label":"The Santa Barbara and Ventura Colleges of Law–Santa Barbara"},{"value":"125037","label":"The Santa Barbara and Ventura Colleges of Law-Ventura"},{"value":"441131","label":"The Seattle School of Theology & Psychology"},{"value":"157748","label":"The Southern Baptist Theological Seminary"},{"value":"100751","label":"The University of Alabama"},{"value":"202763","label":"The University of Findlay"},{"value":"180489","label":"The University of Montana"},{"value":"180692","label":"The University of Montana-Western"},{"value":"137847","label":"The University of Tampa"},{"value":"221740","label":"The University of Tennessee-Chattanooga"},{"value":"221759","label":"The University of Tennessee-Knoxville"},{"value":"221768","label":"The University of Tennessee-Martin"},{"value":"227368","label":"The University of Texas - Rio Grande Valley"},{"value":"228769","label":"The University of Texas at Arlington"},{"value":"228778","label":"The University of Texas at Austin"},{"value":"228787","label":"The University of Texas at Dallas"},{"value":"228796","label":"The University of Texas at El Paso"},{"value":"229027","label":"The University of Texas at San Antonio"},{"value":"228802","label":"The University of Texas at Tyler"},{"value":"229300","label":"The University of Texas Health Science Center at Houston"},{"value":"228644","label":"The University of Texas Health Science Center at San Antonio"},{"value":"416801","label":"The University of Texas MD Anderson Cancer Center"},{"value":"228653","label":"The University of Texas Medical Branch"},{"value":"229018","label":"The University of Texas of the Permian Basin"},{"value":"215105","label":"The University of the Arts"},{"value":"233897","label":"The University of Virginia's College at Wise"},{"value":"138354","label":"The University of West Florida"},{"value":"126012","label":"The Wright Institute"},{"value":"216357","label":"Thiel College"},{"value":"124292","label":"Thomas Aquinas College"},{"value":"161563","label":"Thomas College"},{"value":"187046","label":"Thomas Edison State University"},{"value":"126049","label":"Thomas Jefferson School of Law"},{"value":"216366","label":"Thomas Jefferson University"},{"value":"157809","label":"Thomas More College"},{"value":"183275","label":"Thomas More College of Liberal Arts"},{"value":"233754","label":"Thomas Nelson Community College"},{"value":"141167","label":"Thomas University"},{"value":"129808","label":"Three Rivers Community College-Norwich"},{"value":"179645","label":"Three Rivers Community College-Poplar Bluff"},{"value":"103778","label":"Thunderbird School of Global Management"},{"value":"233772","label":"Tidewater Community College"},{"value":"206048","label":"Tiffin University"},{"value":"420723","label":"Tillamook Bay Community College"},{"value":"141185","label":"Toccoa Falls College"},{"value":"442781","label":"Tohono O'Odham Community College"},{"value":"196565","label":"Tompkins Cortland Community College"},{"value":"196583","label":"Torah Temimah Talmudical Seminary"},{"value":"176406","label":"Tougaloo College"},{"value":"196592","label":"Touro College"},{"value":"459736","label":"Touro University California"},{"value":"459824","label":"Touro University Nevada"},{"value":"459727","label":"Touro University Worldwide"},{"value":"164076","label":"Towson University"},{"value":"157818","label":"Transylvania University"},{"value":"210234","label":"Treasure Valley Community College"},{"value":"221892","label":"Trevecca Nazarene University"},{"value":"448859","label":"Triangle Tech Inc-Bethlehem"},{"value":"216454","label":"Triangle Tech Inc-Dubois"},{"value":"216427","label":"Triangle Tech Inc-Erie"},{"value":"216445","label":"Triangle Tech Inc-Greensburg"},{"value":"216436","label":"Triangle Tech Inc-Pittsburgh"},{"value":"443377","label":"Triangle Tech Inc-Sunbury"},{"value":"460747","label":"Tribeca Flashpoint College"},{"value":"199795","label":"Tri-County Community College"},{"value":"218885","label":"Tri-County Technical College"},{"value":"218894","label":"Trident Technical College"},{"value":"450979","label":"Trident University International"},{"value":"152567","label":"Trine University"},{"value":"414878","label":"Trine University-Regional/Non-Traditional Campuses"},{"value":"128258","label":"Trinidad State Junior College"},{"value":"137953","label":"Trinity Baptist College"},{"value":"200484","label":"Trinity Bible College"},{"value":"149505","label":"Trinity Christian College"},{"value":"130590","label":"Trinity College"},{"value":"137962","label":"Trinity College of Florida"},{"value":"146755","label":"Trinity College of Nursing & Health Sciences"},{"value":"216463","label":"Trinity Episcopal School for Ministry"},{"value":"135610","label":"Trinity International University-Florida"},{"value":"149514","label":"Trinity International University-Illinois"},{"value":"123448","label":"Trinity Law School"},{"value":"235769","label":"Trinity Lutheran College"},{"value":"206215","label":"Trinity Lutheran Seminary"},{"value":"229267","label":"Trinity University"},{"value":"225308","label":"Trinity Valley Community College"},{"value":"131876","label":"Trinity Washington University"},{"value":"206154","label":"Tri-State Bible College"},{"value":"130581","label":"Tri-State College of Acupuncture"},{"value":"149532","label":"Triton College"},{"value":"196653","label":"Trocaire College"},{"value":"102368","label":"Troy University"},{"value":"182500","label":"Truckee Meadows Community College"},{"value":"141237","label":"Truett-McConnell College"},{"value":"178615","label":"Truman State University"},{"value":"206224","label":"Trumbull Business College"},{"value":"168148","label":"Tufts University"},{"value":"160755","label":"Tulane University of Louisiana"},{"value":"207935","label":"Tulsa Community College"},{"value":"207962","label":"Tulsa Welding School-Tulsa-Tulsa"},{"value":"130606","label":"Tunxis Community College"},{"value":"200527","label":"Turtle Mountain Community College"},{"value":"221953","label":"Tusculum College"},{"value":"102377","label":"Tuskegee University"},{"value":"229355","label":"Tyler Junior College"},{"value":"196699","label":"Ulster County Community College"},{"value":"441371","label":"Ultimate Medical Academy-Clearwater"},{"value":"450173","label":"Ultimate Medical Academy-Tampa"},{"value":"481252","label":"Ultrasound Medical Institute"},{"value":"210270","label":"Umpqua Community College"},{"value":"246789","label":"Unification Theological Seminary"},{"value":"157863","label":"Union College-Barbourville"},{"value":"181738","label":"Union College-Lincoln"},{"value":"196866","label":"Union College-Schenectady"},{"value":"187198","label":"Union County College"},{"value":"446932","label":"Union Graduate College"},{"value":"206279","label":"Union Institute & University"},{"value":"233842","label":"Union Presbyterian Seminary"},{"value":"196884","label":"Union Theological Seminary in the City of New York"},{"value":"221971","label":"Union University"},{"value":"124681","label":"United Education Institute-Huntington Park Campus"},{"value":"128328","label":"United States Air Force Academy"},{"value":"130624","label":"United States Coast Guard Academy"},{"value":"197027","label":"United States Merchant Marine Academy"},{"value":"197036","label":"United States Military Academy"},{"value":"164155","label":"United States Naval Academy"},{"value":"102395","label":"United States Sports Academy"},{"value":"447050","label":"United States University"},{"value":"197018","label":"United Talmudical Seminary"},{"value":"206288","label":"United Theological Seminary"},{"value":"175139","label":"United Theological Seminary of the Twin Cities"},{"value":"200554","label":"United Tribes Technical College"},{"value":"459204","label":"Unitek College"},{"value":"161572","label":"Unity College"},{"value":"446598","label":"Universal College of Healing Arts"},{"value":"106041","label":"Universal Technical Institute of Arizona Inc"},{"value":"376385","label":"Universal Technology College of Puerto Rico"},{"value":"241191","label":"Universidad Adventista de las Antillas"},{"value":"241225","label":"Universidad Central de Bayamon"},{"value":"243568","label":"Universidad Central Del Caribe"},{"value":"243346","label":"Universidad Del Este"},{"value":"243443","label":"Universidad del Sagrado Corazon"},{"value":"243601","label":"Universidad Del Turabo"},{"value":"475811","label":"Universidad Internacional Iberoamericana"},{"value":"241739","label":"Universidad Metropolitana"},{"value":"441690","label":"Universidad Pentecostal Mizpa"},{"value":"243577","label":"Universidad Politecnica de Puerto Rico"},{"value":"241614","label":"Universidad Teologica del Caribe"},{"value":"196088","label":"University at Buffalo"},{"value":"363934","label":"University of Advancing Technology"},{"value":"200800","label":"University of Akron Main Campus"},{"value":"200846","label":"University of Akron Wayne College"},{"value":"100663","label":"University of Alabama at Birmingham"},{"value":"100706","label":"University of Alabama in Huntsville"},{"value":"102553","label":"University of Alaska Anchorage"},{"value":"102614","label":"University of Alaska Fairbanks"},{"value":"102632","label":"University of Alaska Southeast"},{"value":"442930","label":"University of Antelope Valley"},{"value":"104179","label":"University of Arizona"},{"value":"106397","label":"University of Arkansas"},{"value":"106245","label":"University of Arkansas at Little Rock"},{"value":"106485","label":"University of Arkansas at Monticello"},{"value":"106412","label":"University of Arkansas at Pine Bluff"},{"value":"106999","label":"University of Arkansas Community College-Batesville"},{"value":"107725","label":"University of Arkansas Community College-Hope"},{"value":"107585","label":"University of Arkansas Community College-Morrilton"},{"value":"106263","label":"University of Arkansas for Medical Sciences"},{"value":"108092","label":"University of Arkansas-Fort Smith"},{"value":"161873","label":"University of Baltimore"},{"value":"128744","label":"University of Bridgeport"},{"value":"110635","label":"University of California-Berkeley"},{"value":"110644","label":"University of California-Davis"},{"value":"110398","label":"University of California-Hastings College of Law"},{"value":"110653","label":"University of California-Irvine"},{"value":"110662","label":"University of California-Los Angeles"},{"value":"445188","label":"University of California-Merced"},{"value":"110671","label":"University of California-Riverside"},{"value":"110680","label":"University of California-San Diego"},{"value":"110699","label":"University of California-San Francisco"},{"value":"110705","label":"University of California-Santa Barbara"},{"value":"110714","label":"University of California-Santa Cruz"},{"value":"106704","label":"University of Central Arkansas"},{"value":"132903","label":"University of Central Florida"},{"value":"176965","label":"University of Central Missouri"},{"value":"206941","label":"University of Central Oklahoma"},{"value":"237312","label":"University of Charleston"},{"value":"144050","label":"University of Chicago"},{"value":"201955","label":"University of Cincinnati-Blue Ash College"},{"value":"201946","label":"University of Cincinnati-Clermont College"},{"value":"201885","label":"University of Cincinnati-Main Campus"},{"value":"126614","label":"University of Colorado Boulder"},{"value":"126580","label":"University of Colorado Colorado Springs"},{"value":"126562","label":"University of Colorado Denver"},{"value":"129020","label":"University of Connecticut"},{"value":"224323","label":"University of Dallas"},{"value":"202480","label":"University of Dayton"},{"value":"130943","label":"University of Delaware"},{"value":"127060","label":"University of Denver"},{"value":"169716","label":"University of Detroit Mercy"},{"value":"153278","label":"University of Dubuque"},{"value":"447801","label":"University of East-West Medicine"},{"value":"150534","label":"University of Evansville"},{"value":"134130","label":"University of Florida"},{"value":"457402","label":"University of Fort Lauderdale"},{"value":"139959","label":"University of Georgia"},{"value":"180258","label":"University of Great Falls"},{"value":"240754","label":"University of Guam"},{"value":"129525","label":"University of Hartford"},{"value":"141565","label":"University of Hawaii at Hilo"},{"value":"141574","label":"University of Hawaii at Manoa"},{"value":"141839","label":"University of Hawaii Maui College"},{"value":"141981","label":"University of Hawaii-West Oahu"},{"value":"160065","label":"University of Holy Cross"},{"value":"225511","label":"University of Houston"},{"value":"225414","label":"University of Houston-Clear Lake"},{"value":"225432","label":"University of Houston-Downtown"},{"value":"225502","label":"University of Houston-Victoria"},{"value":"142285","label":"University of Idaho"},{"value":"145600","label":"University of Illinois at Chicago"},{"value":"148654","label":"University of Illinois at Springfield"},{"value":"145637","label":"University of Illinois at Urbana-Champaign"},{"value":"151263","label":"University of Indianapolis"},{"value":"153658","label":"University of Iowa"},{"value":"200156","label":"University of Jamestown"},{"value":"155317","label":"University of Kansas"},{"value":"157085","label":"University of Kentucky"},{"value":"117140","label":"University of La Verne"},{"value":"160658","label":"University of Louisiana at Lafayette"},{"value":"159993","label":"University of Louisiana at Monroe"},{"value":"157289","label":"University of Louisville"},{"value":"161253","label":"University of Maine"},{"value":"161217","label":"University of Maine at Augusta"},{"value":"161226","label":"University of Maine at Farmington"},{"value":"161235","label":"University of Maine at Fort Kent"},{"value":"161244","label":"University of Maine at Machias"},{"value":"161341","label":"University of Maine at Presque Isle"},{"value":"437097","label":"University of Management and Technology"},{"value":"200217","label":"University of Mary"},{"value":"226471","label":"University of Mary Hardin-Baylor"},{"value":"232681","label":"University of Mary Washington"},{"value":"163338","label":"University of Maryland Eastern Shore"},{"value":"163259","label":"University of Maryland-Baltimore"},{"value":"163268","label":"University of Maryland-Baltimore County"},{"value":"163286","label":"University of Maryland-College Park"},{"value":"163204","label":"University of Maryland-University College"},{"value":"166708","label":"University of Massachusetts Medical School Worcester"},{"value":"166629","label":"University of Massachusetts-Amherst"},{"value":"166638","label":"University of Massachusetts-Boston"},{"value":"167987","label":"University of Massachusetts-Dartmouth"},{"value":"166513","label":"University of Massachusetts-Lowell"},{"value":"220862","label":"University of Memphis"},{"value":"135726","label":"University of Miami"},{"value":"170976","label":"University of Michigan-Ann Arbor"},{"value":"171137","label":"University of Michigan-Dearborn"},{"value":"171146","label":"University of Michigan-Flint"},{"value":"174075","label":"University of Minnesota-Crookston"},{"value":"174233","label":"University of Minnesota-Duluth"},{"value":"174251","label":"University of Minnesota-Morris"},{"value":"456959","label":"University of Minnesota-Rochester"},{"value":"174066","label":"University of Minnesota-Twin Cities"},{"value":"176017","label":"University of Mississippi"},{"value":"178396","label":"University of Missouri-Columbia"},{"value":"178402","label":"University of Missouri-Kansas City"},{"value":"178420","label":"University of Missouri-St Louis"},{"value":"101693","label":"University of Mobile"},{"value":"101709","label":"University of Montevallo"},{"value":"199069","label":"University of Mount Olive"},{"value":"204185","label":"University of Mount Union"},{"value":"181215","label":"University of Nebraska at Kearney"},{"value":"181394","label":"University of Nebraska at Omaha"},{"value":"181428","label":"University of Nebraska Medical Center"},{"value":"181464","label":"University of Nebraska-Lincoln"},{"value":"182281","label":"University of Nevada-Las Vegas"},{"value":"182290","label":"University of Nevada-Reno"},{"value":"161457","label":"University of New England"},{"value":"183071","label":"University of New Hampshire at Manchester"},{"value":"183044","label":"University of New Hampshire-Main Campus"},{"value":"182829","label":"University of New Hampshire-School of Law"},{"value":"129941","label":"University of New Haven"},{"value":"187958","label":"University of New Mexico-Gallup Campus"},{"value":"187976","label":"University of New Mexico-Los Alamos Campus"},{"value":"187985","label":"University of New Mexico-Main Campus"},{"value":"188225","label":"University of New Mexico-Taos Campus"},{"value":"188049","label":"University of New Mexico-Valencia County Campus"},{"value":"159939","label":"University of New Orleans"},{"value":"101879","label":"University of North Alabama"},{"value":"199111","label":"University of North Carolina at Asheville"},{"value":"199120","label":"University of North Carolina at Chapel Hill"},{"value":"199139","label":"University of North Carolina at Charlotte"},{"value":"199148","label":"University of North Carolina at Greensboro"},{"value":"199281","label":"University of North Carolina at Pembroke"},{"value":"199184","label":"University of North Carolina School of the Arts"},{"value":"199218","label":"University of North Carolina Wilmington"},{"value":"200280","label":"University of North Dakota"},{"value":"136172","label":"University of North Florida"},{"value":"482680","label":"University of North Georgia"},{"value":"227216","label":"University of North Texas"},{"value":"484905","label":"University of North Texas at Dallas"},{"value":"228909","label":"University of North Texas Health Science Center"},{"value":"127741","label":"University of Northern Colorado"},{"value":"154095","label":"University of Northern Iowa"},{"value":"204486","label":"University of Northwestern Ohio"},{"value":"174491","label":"University of Northwestern-St Paul"},{"value":"152080","label":"University of Notre Dame"},{"value":"207342","label":"University of Oklahoma-Health Sciences Center"},{"value":"207500","label":"University of Oklahoma-Norman Campus"},{"value":"209551","label":"University of Oregon"},{"value":"215062","label":"University of Pennsylvania"},{"value":"450456","label":"University of Phoenix-Alabama"},{"value":"484613","label":"University of Phoenix-Arizona"},{"value":"484622","label":"University of Phoenix-Arkansas"},{"value":"484631","label":"University of Phoenix-California"},{"value":"484640","label":"University of Phoenix-Colorado"},{"value":"448822","label":"University of Phoenix-Connecticut"},{"value":"484668","label":"University of Phoenix-Florida"},{"value":"484677","label":"University of Phoenix-Georgia"},{"value":"420042","label":"University of Phoenix-Hawaii"},{"value":"440466","label":"University of Phoenix-Idaho"},{"value":"442161","label":"University of Phoenix-Illinois"},{"value":"443544","label":"University of Phoenix-Indiana"},{"value":"446729","label":"University of Phoenix-Iowa"},{"value":"445391","label":"University of Phoenix-Kentucky"},{"value":"484686","label":"University of Phoenix-Louisiana"},{"value":"434973","label":"University of Phoenix-Maryland"},{"value":"440420","label":"University of Phoenix-Massachusetts"},{"value":"484695","label":"University of Phoenix-Michigan"},{"value":"445319","label":"University of Phoenix-Minnesota"},{"value":"462390","label":"University of Phoenix-Mississippi"},{"value":"484701","label":"University of Phoenix-Missouri"},{"value":"484710","label":"University of Phoenix-Nevada"},{"value":"445300","label":"University of Phoenix-New Jersey"},{"value":"405997","label":"University of Phoenix-New Mexico"},{"value":"484729","label":"University of Phoenix-North Carolina"},{"value":"439297","label":"University of Phoenix-Ohio"},{"value":"484738","label":"University of Phoenix-Oklahoma"},{"value":"432241","label":"University of Phoenix-Oregon"},{"value":"484783","label":"University of Phoenix-Pennsylvania"},{"value":"382063","label":"University of Phoenix-Puerto Rico"},{"value":"448567","label":"University of Phoenix-South Carolina"},{"value":"484747","label":"University of Phoenix-Tennessee"},{"value":"484756","label":"University of Phoenix-Texas"},{"value":"380465","label":"University of Phoenix-Utah"},{"value":"484765","label":"University of Phoenix-Virginia"},{"value":"432223","label":"University of Phoenix-Washington"},{"value":"450483","label":"University of Phoenix-Washington DC"},{"value":"440457","label":"University of Phoenix-Wisconsin"},{"value":"157535","label":"University of Pikeville"},{"value":"215266","label":"University of Pittsburgh-Bradford"},{"value":"215275","label":"University of Pittsburgh-Greensburg"},{"value":"215284","label":"University of Pittsburgh-Johnstown"},{"value":"215293","label":"University of Pittsburgh-Pittsburgh Campus"},{"value":"215309","label":"University of Pittsburgh-Titusville"},{"value":"209825","label":"University of Portland"},{"value":"243106","label":"University of Puerto Rico-Aguadilla"},{"value":"243115","label":"University of Puerto Rico-Arecibo"},{"value":"243133","label":"University of Puerto Rico-Bayamon"},{"value":"243142","label":"University of Puerto Rico-Carolina"},{"value":"243151","label":"University of Puerto Rico-Cayey"},{"value":"243179","label":"University of Puerto Rico-Humacao"},{"value":"243197","label":"University of Puerto Rico-Mayaguez"},{"value":"243203","label":"University of Puerto Rico-Medical Sciences"},{"value":"243212","label":"University of Puerto Rico-Ponce"},{"value":"243221","label":"University of Puerto Rico-Rio Piedras"},{"value":"243188","label":"University of Puerto Rico-Utuado"},{"value":"236328","label":"University of Puget Sound"},{"value":"121691","label":"University of Redlands"},{"value":"217484","label":"University of Rhode Island"},{"value":"233374","label":"University of Richmond"},{"value":"205203","label":"University of Rio Grande"},{"value":"195030","label":"University of Rochester"},{"value":"152336","label":"University of Saint Francis-Fort Wayne"},{"value":"130314","label":"University of Saint Joseph"},{"value":"155812","label":"University of Saint Mary"},{"value":"148885","label":"University of Saint Mary of the Lake"},{"value":"122436","label":"University of San Diego"},{"value":"122612","label":"University of San Francisco"},{"value":"207722","label":"University of Science and Arts of Oklahoma"},{"value":"215929","label":"University of Scranton"},{"value":"219383","label":"University of Sioux Falls"},{"value":"102094","label":"University of South Alabama"},{"value":"218645","label":"University of South Carolina-Aiken"},{"value":"218654","label":"University of South Carolina-Beaufort"},{"value":"218663","label":"University of South Carolina-Columbia"},{"value":"218672","label":"University of South Carolina-Lancaster"},{"value":"218681","label":"University of South Carolina-Salkehatchie"},{"value":"218690","label":"University of South Carolina-Sumter"},{"value":"218706","label":"University of South Carolina-Union"},{"value":"218742","label":"University of South Carolina-Upstate"},{"value":"219471","label":"University of South Dakota"},{"value":"137351","label":"University of South Florida-Main Campus"},{"value":"451671","label":"University of South Florida-Sarasota-Manatee"},{"value":"448840","label":"University of South Florida-St Petersburg"},{"value":"123961","label":"University of Southern California"},{"value":"151306","label":"University of Southern Indiana"},{"value":"161554","label":"University of Southern Maine"},{"value":"176372","label":"University of Southern Mississippi"},{"value":"134121","label":"University of Southernmost Florida"},{"value":"367954","label":"University of St Augustine for Health Sciences"},{"value":"148584","label":"University of St Francis"},{"value":"227863","label":"University of St Thomas-Houston"},{"value":"174914","label":"University of St Thomas-Saint Paul"},{"value":"228635","label":"University of Texas Southwestern Medical Center"},{"value":"156541","label":"University of the Cumberlands"},{"value":"131399","label":"University of the District of Columbia"},{"value":"363721","label":"University of the District of Columbia-David A Clarke School of Law"},{"value":"225627","label":"University of the Incarnate Word"},{"value":"107558","label":"University of the Ozarks"},{"value":"120883","label":"University of the Pacific"},{"value":"442639","label":"University of the Potomac-VA Campus"},{"value":"384412","label":"University of the Potomac-Washington DC Campus"},{"value":"441308","label":"University of the Rockies"},{"value":"215132","label":"University of the Sciences"},{"value":"188182","label":"University of the Southwest"},{"value":"243665","label":"University of the Virgin Islands"},{"value":"449870","label":"University of the West"},{"value":"206084","label":"University of Toledo"},{"value":"207971","label":"University of Tulsa"},{"value":"230764","label":"University of Utah"},{"value":"216542","label":"University of Valley Forge"},{"value":"231174","label":"University of Vermont"},{"value":"234076","label":"University of Virginia-Main Campus"},{"value":"377555","label":"University of Washington-Bothell Campus"},{"value":"236948","label":"University of Washington-Seattle Campus"},{"value":"377564","label":"University of Washington-Tacoma Campus"},{"value":"101587","label":"University of West Alabama"},{"value":"141334","label":"University of West Georgia"},{"value":"210438","label":"University of Western States"},{"value":"240055","label":"University of Wisconsin Colleges"},{"value":"240268","label":"University of Wisconsin-Eau Claire"},{"value":"240277","label":"University of Wisconsin-Green Bay"},{"value":"240329","label":"University of Wisconsin-La Crosse"},{"value":"240444","label":"University of Wisconsin-Madison"},{"value":"240453","label":"University of Wisconsin-Milwaukee"},{"value":"240365","label":"University of Wisconsin-Oshkosh"},{"value":"240374","label":"University of Wisconsin-Parkside"},{"value":"240462","label":"University of Wisconsin-Platteville"},{"value":"240471","label":"University of Wisconsin-River Falls"},{"value":"240480","label":"University of Wisconsin-Stevens Point"},{"value":"240417","label":"University of Wisconsin-Stout"},{"value":"240426","label":"University of Wisconsin-Superior"},{"value":"240189","label":"University of Wisconsin-Whitewater"},{"value":"240727","label":"University of Wyoming"},{"value":"154493","label":"Upper Iowa University"},{"value":"196307","label":"Upstate Medical University"},{"value":"429128","label":"Urban College of Boston"},{"value":"206330","label":"Urbana University"},{"value":"455099","label":"Urshan Graduate School of Theology"},{"value":"216524","label":"Ursinus College"},{"value":"206349","label":"Ursuline College"},{"value":"446604","label":"Uta Mesivta of Kiryas Joel"},{"value":"230728","label":"Utah State University"},{"value":"230737","label":"Utah Valley University"},{"value":"197045","label":"Utica College"},{"value":"197081","label":"Utica School of Commerce"},{"value":"141264","label":"Valdosta State University"},{"value":"138187","label":"Valencia College"},{"value":"200572","label":"Valley City State University"},{"value":"377652","label":"Valley College-Beckley"},{"value":"152600","label":"Valparaiso University"},{"value":"199838","label":"Vance-Granville Community College"},{"value":"221999","label":"Vanderbilt University"},{"value":"149639","label":"VanderCook College of Music"},{"value":"123651","label":"Vanguard University of Southern California"},{"value":"197133","label":"Vassar College"},{"value":"455567","label":"Vatterott College-Appling Farms"},{"value":"245342","label":"Vatterott College-Berkeley"},{"value":"442408","label":"Vatterott College-Cleveland"},{"value":"373058","label":"Vatterott College-Des Moines"},{"value":"440873","label":"Vatterott College-Dividend"},{"value":"481988","label":"Vatterott College-ex'treme Institute by Nelly-St Louis"},{"value":"404374","label":"Vatterott College-Joplin"},{"value":"404383","label":"Vatterott College-Kansas City"},{"value":"437060","label":"Vatterott College-Oklahoma City"},{"value":"148140","label":"Vatterott College-Quincy"},{"value":"181756","label":"Vatterott College-Spring Valley"},{"value":"404365","label":"Vatterott College-Springfield"},{"value":"445559","label":"Vatterott College-St Charles"},{"value":"436182","label":"Vatterott College-St Joseph"},{"value":"436191","label":"Vatterott College-Sunset Hills"},{"value":"440882","label":"Vatterott College-Tulsa"},{"value":"440891","label":"Vatterott College-Wichita"},{"value":"188340","label":"Vaughn College of Aeronautics and Technology"},{"value":"125028","label":"Ventura College"},{"value":"175157","label":"Vermilion Community College"},{"value":"455992","label":"Vermont College of Fine Arts"},{"value":"231147","label":"Vermont Law School"},{"value":"231165","label":"Vermont Technical College"},{"value":"229504","label":"Vernon College"},{"value":"213914","label":"Vet Tech Institute"},{"value":"223472","label":"Vet Tech Institute of Houston"},{"value":"125091","label":"Victor Valley College"},{"value":"229540","label":"Victoria College"},{"value":"197142","label":"Villa Maria College"},{"value":"216597","label":"Villanova University"},{"value":"152637","label":"Vincennes University"},{"value":"482228","label":"Virginia Baptist College"},{"value":"458256","label":"Virginia College-Augusta"},{"value":"441928","label":"Virginia College-Austin"},{"value":"460774","label":"Virginia College-Baton Rouge"},{"value":"450191","label":"Virginia College-Biloxi"},{"value":"420307","label":"Virginia College-Birmingham"},{"value":"456056","label":"Virginia College-Charleston"},{"value":"458593","label":"Virginia College-Columbia"},{"value":"475370","label":"Virginia College-Columbus"},{"value":"480107","label":"Virginia College-Florence"},{"value":"454625","label":"Virginia College-Greenville"},{"value":"420316","label":"Virginia College-Huntsville"},{"value":"441919","label":"Virginia College-Jackson"},{"value":"455716","label":"Virginia College-Jacksonville"},{"value":"475617","label":"Virginia College-Knoxville"},{"value":"460844","label":"Virginia College-Macon"},{"value":"445090","label":"Virginia College-Mobile"},{"value":"452115","label":"Virginia College-Montgomery"},{"value":"389727","label":"Virginia College-Pensacola"},{"value":"460923","label":"Virginia College-Richmond"},{"value":"475352","label":"Virginia College-Savannah"},{"value":"450289","label":"Virginia College-School of Business and Health-Chattanooga"},{"value":"475866","label":"Virginia College-Shreveport Bossier City"},{"value":"460853","label":"Virginia College-Spartanburg"},{"value":"475592","label":"Virginia College-Tulsa"},{"value":"234030","label":"Virginia Commonwealth University"},{"value":"233903","label":"Virginia Highlands Community College"},{"value":"206394","label":"Virginia Marti College of Art and Design"},{"value":"234085","label":"Virginia Military Institute"},{"value":"233921","label":"Virginia Polytechnic Institute and State University"},{"value":"234155","label":"Virginia State University"},{"value":"459082","label":"Virginia Tech Carilion School of Medicine"},{"value":"234164","label":"Virginia Union University"},{"value":"234137","label":"Virginia University of Lynchburg"},{"value":"234173","label":"Virginia Wesleyan College"},{"value":"233949","label":"Virginia Western Community College"},{"value":"449764","label":"Visible Music College"},{"value":"365204","label":"Vista College"},{"value":"377342","label":"Vista College-Online"},{"value":"240107","label":"Viterbo University"},{"value":"222053","label":"Volunteer State Community College"},{"value":"218919","label":"Voorhees College"},{"value":"152673","label":"Wabash College"},{"value":"403487","label":"Wabash Valley College"},{"value":"226879","label":"Wade College"},{"value":"197197","label":"Wagner College"},{"value":"199847","label":"Wake Forest University"},{"value":"199856","label":"Wake Technical Community College"},{"value":"125231","label":"Walden University"},{"value":"154518","label":"Waldorf College"},{"value":"236887","label":"Walla Walla Community College"},{"value":"236896","label":"Walla Walla University"},{"value":"172608","label":"Walsh College of Accountancy and Business Administration"},{"value":"206437","label":"Walsh University"},{"value":"222062","label":"Walters State Community College"},{"value":"210304","label":"Warner Pacific College"},{"value":"480198","label":"Warner Pacific College Adult Degree Program"},{"value":"138275","label":"Warner University"},{"value":"245625","label":"Warren County Community College"},{"value":"199865","label":"Warren Wilson College"},{"value":"154527","label":"Wartburg College"},{"value":"154536","label":"Wartburg Theological Seminary"},{"value":"156082","label":"Washburn University"},{"value":"216667","label":"Washington & Jefferson College"},{"value":"162210","label":"Washington Adventist University"},{"value":"234207","label":"Washington and Lee University"},{"value":"164216","label":"Washington College"},{"value":"161581","label":"Washington County Community College"},{"value":"206446","label":"Washington State Community College"},{"value":"236939","label":"Washington State University"},{"value":"179867","label":"Washington University in St Louis"},{"value":"172617","label":"Washtenaw Community College"},{"value":"392840","label":"Watkins College of Art Design & Film"},{"value":"149727","label":"Waubonsee Community College"},{"value":"240125","label":"Waukesha County Technical College"},{"value":"229780","label":"Wayland Baptist University"},{"value":"199892","label":"Wayne Community College"},{"value":"172635","label":"Wayne County Community College District"},{"value":"181783","label":"Wayne State College"},{"value":"172644","label":"Wayne State University"},{"value":"216694","label":"Waynesburg University"},{"value":"229799","label":"Weatherford College"},{"value":"197221","label":"Webb Institute"},{"value":"138293","label":"Webber International University"},{"value":"230782","label":"Weber State University"},{"value":"179894","label":"Webster University"},{"value":"190424","label":"Weill Cornell Medicine"},{"value":"220206","label":"Welch College"},{"value":"168218","label":"Wellesley College"},{"value":"197230","label":"Wells College"},{"value":"447999","label":"WellSpring School of Allied Health-Kansas City"},{"value":"236975","label":"Wenatchee Valley College"},{"value":"168227","label":"Wentworth Institute of Technology"},{"value":"179919","label":"Wentworth Military Academy and College"},{"value":"176451","label":"Wesley Biblical Seminary"},{"value":"131098","label":"Wesley College"},{"value":"131973","label":"Wesley Theological Seminary"},{"value":"141325","label":"Wesleyan College"},{"value":"130697","label":"Wesleyan University"},{"value":"216764","label":"West Chester University of Pennsylvania"},{"value":"441229","label":"West Coast Ultrasound Institute"},{"value":"477039","label":"West Coast University-Dallas"},{"value":"443331","label":"West Coast University-Los Angeles"},{"value":"458229","label":"West Coast University-Ontario"},{"value":"458210","label":"West Coast University-Orange County"},{"value":"139278","label":"West Georgia Technical College"},{"value":"125462","label":"West Hills College-Coalinga"},{"value":"448594","label":"West Hills College-Lemoore"},{"value":"157483","label":"West Kentucky Community and Technical College"},{"value":"237932","label":"West Liberty University"},{"value":"125471","label":"West Los Angeles College"},{"value":"172671","label":"West Shore Community College"},{"value":"222099","label":"West Tennessee Business College"},{"value":"229814","label":"West Texas A & M University"},{"value":"125499","label":"West Valley College"},{"value":"237978","label":"West Virginia Business College-Wheeling"},{"value":"442383","label":"West Virginia Junior College-Bridgeport"},{"value":"237987","label":"West Virginia Junior College-Charleston"},{"value":"237996","label":"West Virginia Junior College-Morgantown"},{"value":"238014","label":"West Virginia Northern Community College"},{"value":"237880","label":"West Virginia School of Osteopathic Medicine"},{"value":"237899","label":"West Virginia State University"},{"value":"238032","label":"West Virginia University"},{"value":"237686","label":"West Virginia University at Parkersburg"},{"value":"237950","label":"West Virginia University Institute of Technology"},{"value":"237969","label":"West Virginia Wesleyan College"},{"value":"200004","label":"Western Carolina University"},{"value":"130776","label":"Western Connecticut State University"},{"value":"219480","label":"Western Dakota Technical Institute"},{"value":"433387","label":"Western Governors University"},{"value":"149772","label":"Western Illinois University"},{"value":"106102","label":"Western International University"},{"value":"154572","label":"Western Iowa Tech Community College"},{"value":"157951","label":"Western Kentucky University"},{"value":"172699","label":"Western Michigan University"},{"value":"172477","label":"Western Michigan University-Thomas M. Cooley Law School"},{"value":"181817","label":"Western Nebraska Community College"},{"value":"182564","label":"Western Nevada College"},{"value":"168254","label":"Western New England University"},{"value":"188304","label":"Western New Mexico University"},{"value":"208035","label":"Western Oklahoma State College"},{"value":"210429","label":"Western Oregon University"},{"value":"199908","label":"Western Piedmont Community College"},{"value":"210368","label":"Western Seminary"},{"value":"126030","label":"Western State College of Law at Argosy University"},{"value":"128391","label":"Western State Colorado University"},{"value":"224660","label":"Western Technical College-El Paso"},{"value":"224679","label":"Western Technical College-El Paso"},{"value":"240170","label":"Western Technical College-La Crosse"},{"value":"229832","label":"Western Texas College"},{"value":"172705","label":"Western Theological Seminary"},{"value":"112525","label":"Western University of Health Sciences"},{"value":"237011","label":"Western Washington University"},{"value":"240693","label":"Western Wyoming Community College"},{"value":"168263","label":"Westfield State University"},{"value":"179946","label":"Westminster College-Fulton"},{"value":"216807","label":"Westminster College-New Wilmington"},{"value":"230807","label":"Westminster College-Salt Lake City"},{"value":"216816","label":"Westminster Theological Seminary"},{"value":"125718","label":"Westminster Theological Seminary in California"},{"value":"125727","label":"Westmont College"},{"value":"216825","label":"Westmoreland County Community College"},{"value":"437848","label":"Westwood College-Anaheim"},{"value":"448628","label":"Westwood College-Annandale"},{"value":"447069","label":"Westwood College-Arlington Ballston"},{"value":"445072","label":"Westwood College-Atlanta Midtown"},{"value":"443687","label":"Westwood College-Chicago Loop"},{"value":"127024","label":"Westwood College-Denver North"},{"value":"381787","label":"Westwood College-Denver South"},{"value":"406194","label":"Westwood College-Dupage"},{"value":"440484","label":"Westwood College-Inland Empire"},{"value":"122843","label":"Westwood College-Los Angeles"},{"value":"445276","label":"Westwood College-Northlake"},{"value":"178226","label":"Westwood College-O'Hare Airport"},{"value":"440147","label":"Westwood College-River Oaks"},{"value":"121381","label":"Westwood College-South Bay"},{"value":"229841","label":"Wharton County Junior College"},{"value":"237039","label":"Whatcom Community College"},{"value":"168281","label":"Wheaton College-Norton"},{"value":"149781","label":"Wheaton College-Wheaton"},{"value":"238078","label":"Wheeling Jesuit University"},{"value":"168290","label":"Wheelock College"},{"value":"434751","label":"White Earth Tribal and Community College"},{"value":"183105","label":"White Mountains Community College"},{"value":"237057","label":"Whitman College"},{"value":"125763","label":"Whittier College"},{"value":"237066","label":"Whitworth University"},{"value":"475200","label":"Whitworth University-Adult Degree Programs"},{"value":"156107","label":"Wichita Area Technical College"},{"value":"156125","label":"Wichita State University"},{"value":"156134","label":"Wichita Technical Institute"},{"value":"244190","label":"Widener University-Delaware Campus"},{"value":"402828","label":"Widener University-Harrisburg Campus"},{"value":"216852","label":"Widener University-Main Campus"},{"value":"206491","label":"Wilberforce University"},{"value":"229887","label":"Wiley College"},{"value":"199926","label":"Wilkes Community College"},{"value":"216931","label":"Wilkes University"},{"value":"210401","label":"Willamette University"},{"value":"176479","label":"William Carey University"},{"value":"166717","label":"William James College"},{"value":"122728","label":"William Jessup University"},{"value":"179955","label":"William Jewell College"},{"value":"175281","label":"William Mitchell College of Law"},{"value":"222105","label":"William Moore College of Technology"},{"value":"187444","label":"William Paterson University of New Jersey"},{"value":"199272","label":"William Peace University"},{"value":"154590","label":"William Penn University"},{"value":"149842","label":"William Rainey Harper College"},{"value":"179964","label":"William Woods University"},{"value":"107877","label":"Williams Baptist College"},{"value":"168342","label":"Williams College"},{"value":"218955","label":"Williamsburg Technical College"},{"value":"443340","label":"Williamson Christian College"},{"value":"200341","label":"Williston State College"},{"value":"206507","label":"Wilmington College"},{"value":"131113","label":"Wilmington University"},{"value":"217013","label":"Wilson College"},{"value":"199953","label":"Wilson Community College"},{"value":"141990","label":"Windward Community College"},{"value":"206516","label":"Winebrenner Theological Seminary"},{"value":"199962","label":"Wingate University"},{"value":"175272","label":"Winona State University"},{"value":"199999","label":"Winston-Salem State University"},{"value":"218964","label":"Winthrop University"},{"value":"141255","label":"Wiregrass Georgia Technical College"},{"value":"240198","label":"Wisconsin Indianhead Technical College"},{"value":"240338","label":"Wisconsin Lutheran College"},{"value":"240213","label":"Wisconsin School of Professional Psychology"},{"value":"206525","label":"Wittenberg University"},{"value":"218973","label":"Wofford College"},{"value":"451130","label":"Wolford College"},{"value":"442064","label":"Won Institute of Graduate Studies"},{"value":"197522","label":"Wood Tobe-Coburn School"},{"value":"125897","label":"Woodbury University"},{"value":"455512","label":"Woodland Community College"},{"value":"168421","label":"Worcester Polytechnic Institute"},{"value":"168430","label":"Worcester State University"},{"value":"141936","label":"World Medicine Institute"},{"value":"401223","label":"World Mission University"},{"value":"369455","label":"Worsham College of Mortuary Science"},{"value":"164313","label":"Wor-Wic Community College"},{"value":"406200","label":"Wright Career College"},{"value":"206613","label":"Wright State University-Lake Campus"},{"value":"206604","label":"Wright State University-Main Campus"},{"value":"441089","label":"Wyo Tech-Blairsville"},{"value":"132268","label":"Wyotech-Daytona"},{"value":"123208","label":"Wyotech-Fremont"},{"value":"240718","label":"Wyotech-Laramie"},{"value":"398574","label":"Wyotech-Long Beach"},{"value":"234377","label":"Wytheville Community College"},{"value":"206622","label":"Xavier University"},{"value":"160904","label":"Xavier University of Louisiana"},{"value":"237109","label":"Yakima Valley Community College"},{"value":"130794","label":"Yale University"},{"value":"106148","label":"Yavapai College"},{"value":"245731","label":"Yeshiva and Kollel Harbotzas Torah"},{"value":"434937","label":"Yeshiva College of the Nations Capital"},{"value":"197647","label":"Yeshiva Derech Chaim"},{"value":"420325","label":"Yeshiva D'monsey Rabbinical College"},{"value":"375230","label":"Yeshiva Gedolah Imrei Yosef D'spinka"},{"value":"481410","label":"Yeshiva Gedolah Kesser Torah"},{"value":"247773","label":"Yeshiva Gedolah of Greater Detroit"},{"value":"476692","label":"Yeshiva Gedolah Zichron Leyma"},{"value":"197601","label":"Yeshiva Karlin Stolin"},{"value":"190752","label":"Yeshiva of Far Rockaway Derech Ayson Rabbinical Seminary"},{"value":"455257","label":"Yeshiva of Machzikai Hadas"},{"value":"197674","label":"Yeshiva of Nitra Rabbinical College"},{"value":"431983","label":"Yeshiva of the Telshe Alumni"},{"value":"126076","label":"Yeshiva Ohr Elchonon Chabad West Coast Talmudical Seminary"},{"value":"197692","label":"Yeshiva Shaar Hatorah"},{"value":"441609","label":"Yeshiva Shaarei Torah of Rockland"},{"value":"451398","label":"Yeshiva Toras Chaim"},{"value":"128425","label":"Yeshiva Toras Chaim Talmudical Seminary"},{"value":"197708","label":"Yeshiva University"},{"value":"481438","label":"Yeshiva Yesodei Hatorah"},{"value":"451370","label":"Yeshivas Be'er Yitzchok"},{"value":"405058","label":"Yeshivas Novominsk"},{"value":"197610","label":"Yeshivat Mikdash Melech"},{"value":"217040","label":"Yeshivath Beth Moshe"},{"value":"197735","label":"Yeshivath Viznitz"},{"value":"197744","label":"Yeshivath Zichron Moshe"},{"value":"401250","label":"Yo San University of Traditional Chinese Medicine"},{"value":"181853","label":"York College"},{"value":"217059","label":"York College Pennsylvania"},{"value":"420440","label":"York County Community College"},{"value":"218991","label":"York Technical College"},{"value":"217086","label":"Yorktowne Business Institute"},{"value":"141361","label":"Young Harris College"},{"value":"206695","label":"Youngstown State University"},{"value":"375939","label":"YTI Career Institute-Altoona"},{"value":"217077","label":"YTI Career Institute-York"},{"value":"126119","label":"Yuba College"},{"value":"204255","label":"Zane State College"}] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/data/nationalLabs.yaml b/vite-app/src/apps/Auth2/resources/data/nationalLabs.yaml new file mode 100644 index 00000000..323226cf --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/data/nationalLabs.yaml @@ -0,0 +1,112 @@ +# National Labs +--- +- + name: Ames Laboratory + city: Ames + state: Iowa + initials: Ames + type: OSL +- + name: Argonne National Laboratory + city: Argonne + state: Illinois + initials: ANL + type: OSL +- + name: Brookhaven National Laboratory + city: Upton + state: New York + initials: BNL + type: OSL +- + name: Fermi National Accelerator Laboratory + city: Berkeley + state: California + initials: FERMILAB + type: OSL +- + name: Oak Ridge National Laboratory + city: Oak Ridge + state: Tennessee + initials: ORNL + type: OSL +- + name: Lawrence Berkeley National Laboratory + city: Berkeley + state: California + initials: LBNL + type: OSL +- + name: Pacific Northwest National Laboratory + city: Richland + state: Washington + initials: PNNL + type: OSL +- + name: Princeton Plasma Physics Laboratory + city: Princeton + state: New Jersey + initials: PPPL + type: OSL +- + name: SLAC National Accelerator Laboratory + city: Newport News + state: Virginia + initials: SLAC + type: OSL +- + name: Idaho National Laboratory + city: Idaho Falls + state: Idaho + initials: INL + type: OTHER +- + name: National Energy Technology Laboratory + locations: + - + city: Morgantown + state: West Virginia + - + city: Pittsburgh + state: Pennsylvania + - + city: Albany + state: Orgegon + initials: NETL + type: OTHER +- + name: National Renewabl Energy Laboratory + city: Golden + state: Colorado + initials: NREL + type: OTHER +- + name: Savannah River National Laboratory + city: Aiken + state: South Carolina + initials: SRNL + type: OTHER + +- + name: Lawrence Livermore National Laboratory + city: Livermore + state: California + initials: LLNL + type: NNSA +- + name: Los Alamos National Laboratory + city: Los Alamos + state: New Mexico + initials: LANL + type: NNSA +- + name: Sandia National Laboratory + locations: + - + city: Albequerque + state: New Mexico + - + city: Livermore + state: California + initials: SNL + type: NNSA diff --git a/vite-app/src/apps/Auth2/resources/data/organizations.json b/vite-app/src/apps/Auth2/resources/data/organizations.json new file mode 100644 index 00000000..906f6a10 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/data/organizations.json @@ -0,0 +1,14068 @@ +[ + { + "label": "A T Still University of Health Sciences" + }, + { + "label": "Aaniiih Nakoda College" + }, + { + "label": "Abilene Christian University" + }, + { + "label": "Abraham Baldwin Agricultural College" + }, + { + "label": "Academy College" + }, + { + "label": "Academy for Five Element Acupuncture" + }, + { + "label": "Academy for Jewish Religion-California" + }, + { + "label": "Academy for Nursing and Health Occupations" + }, + { + "label": "Academy of Art University" + }, + { + "label": "Academy of Chinese Culture and Health Sciences" + }, + { + "label": "Academy of Couture Art" + }, + { + "label": "Academy of Natural Therapy Inc" + }, + { + "label": "Acupuncture and Integrative Medicine College-Berkeley" + }, + { + "label": "Acupuncture and Massage College" + }, + { + "label": "Adams State University" + }, + { + "label": "Adelphi University" + }, + { + "label": "Adirondack Community College" + }, + { + "label": "Adler Graduate School" + }, + { + "label": "Adler University" + }, + { + "label": "Adrian College" + }, + { + "label": "Advanced College" + }, + { + "label": "Advanced Computing Institute" + }, + { + "label": "Advanced Technology Institute" + }, + { + "label": "Advanced Training Associates" + }, + { + "label": "Adventist University of Health Sciences" + }, + { + "label": "Advertising Art Educational Services DBA School of Advertising Art" + }, + { + "label": "Agnes Scott College" + }, + { + "label": "AI Miami International University of Art and Design" + }, + { + "label": "AIB College of Business" + }, + { + "label": "Aiken Technical College" + }, + { + "label": "Aims Community College" + }, + { + "label": "Air Force Institute of Technology-Graduate School of Engineering & Management" + }, + { + "label": "Akron Institute of Herzing University" + }, + { + "label": "Alabama A & M University" + }, + { + "label": "Alabama Southern Community College" + }, + { + "label": "Alabama State University" + }, + { + "label": "Alamance Community College" + }, + { + "label": "Alaska Bible College" + }, + { + "label": "Alaska Career College" + }, + { + "label": "Alaska Christian College" + }, + { + "label": "Alaska Pacific University" + }, + { + "label": "Albany College of Pharmacy and Health Sciences" + }, + { + "label": "Albany Law School" + }, + { + "label": "Albany Medical College" + }, + { + "label": "Albany State University" + }, + { + "label": "Albany Technical College" + }, + { + "label": "Albertus Magnus College" + }, + { + "label": "Albion College" + }, + { + "label": "Albright College" + }, + { + "label": "Alcorn State University" + }, + { + "label": "Alderson Broaddus University" + }, + { + "label": "Alexandria Technical & Community College" + }, + { + "label": "Alfred University" + }, + { + "label": "Alice Lloyd College" + }, + { + "label": "Allan Hancock College" + }, + { + "label": "Allegany College of Maryland" + }, + { + "label": "Allegheny College" + }, + { + "label": "Allegheny Wesleyan College" + }, + { + "label": "Allen College" + }, + { + "label": "Allen County Community College" + }, + { + "label": "Allen University" + }, + { + "label": "Alliant International University-San Diego" + }, + { + "label": "Allied American University" + }, + { + "label": "Alma College" + }, + { + "label": "Alpena Community College" + }, + { + "label": "Alvernia University" + }, + { + "label": "Alverno College" + }, + { + "label": "Alvin Community College" + }, + { + "label": "Amarillo College" + }, + { + "label": "Amberton University" + }, + { + "label": "Ambria College of Nursing" + }, + { + "label": "American Academy McAllister Institute of Funeral Service" + }, + { + "label": "American Academy of Acupuncture and Oriental Medicine" + }, + { + "label": "American Academy of Art" + }, + { + "label": "American Academy of Dramatic Arts-Los Angeles" + }, + { + "label": "American Academy of Dramatic Arts-New York" + }, + { + "label": "American Baptist College" + }, + { + "label": "American Baptist Seminary of the West" + }, + { + "label": "American Business and Technology University" + }, + { + "label": "American Career College-Anaheim" + }, + { + "label": "American Career College-Los Angeles" + }, + { + "label": "American Career College-Ontario" + }, + { + "label": "American College for Medical Careers" + }, + { + "label": "American College of Acupuncture and Oriental Med" + }, + { + "label": "American College of Education" + }, + { + "label": "American College of Financial Services" + }, + { + "label": "American College of Healthcare Sciences" + }, + { + "label": "American College of Traditional Chinese Medicine" + }, + { + "label": "American Conservatory Theater" + }, + { + "label": "American Film Institute Conservatory" + }, + { + "label": "American Indian College Inc" + }, + { + "label": "American Institute of Alternative Medicine" + }, + { + "label": "American InterContinental University-Atlanta" + }, + { + "label": "American InterContinental University-Houston" + }, + { + "label": "American InterContinental University-Online" + }, + { + "label": "American InterContinental University-South Florida" + }, + { + "label": "American International College" + }, + { + "label": "American Jewish University" + }, + { + "label": "American Medical Academy" + }, + { + "label": "American Musical and Dramatic Academy" + }, + { + "label": "American National University" + }, + { + "label": "American Public University System" + }, + { + "label": "American River College" + }, + { + "label": "American Samoa Community College" + }, + { + "label": "American Sentinel University" + }, + { + "label": "American University" + }, + { + "label": "American University of Health Sciences" + }, + { + "label": "American University of Puerto Rico-Bayamon" + }, + { + "label": "American University of Puerto Rico-Manati" + }, + { + "label": "AmeriTech College-Draper" + }, + { + "label": "Amherst College" + }, + { + "label": "Amridge University" + }, + { + "label": "Anabaptist Mennonite Biblical Seminary" + }, + { + "label": "Ancilla College" + }, + { + "label": "Anderson University-Anderson" + }, + { + "label": "Anderson University-Anderson" + }, + { + "label": "Andover Newton Theological School" + }, + { + "label": "Andrew College" + }, + { + "label": "Andrews University" + }, + { + "label": "Angeles College" + }, + { + "label": "Angelina College" + }, + { + "label": "Angelo State University" + }, + { + "label": "Anna Maria College" + }, + { + "label": "Anne Arundel Community College" + }, + { + "label": "Anoka Technical College" + }, + { + "label": "Anoka-Ramsey Community College" + }, + { + "label": "Antelope Valley College" + }, + { + "label": "Antioch University-Los Angeles" + }, + { + "label": "Antioch University-Midwest" + }, + { + "label": "Antioch University-New England" + }, + { + "label": "Antioch University-PhD Program in Leadership and Change" + }, + { + "label": "Antioch University-Santa Barbara" + }, + { + "label": "Antioch University-Seattle" + }, + { + "label": "Antonelli College-Cincinnati" + }, + { + "label": "Antonelli College-Hattiesburg" + }, + { + "label": "Antonelli College-Jackson" + }, + { + "label": "Antonelli Institute" + }, + { + "label": "AOMA Graduate School of Integrative Medicine" + }, + { + "label": "Apex School of Theology" + }, + { + "label": "Appalachian Bible College" + }, + { + "label": "Appalachian College of Pharmacy" + }, + { + "label": "Appalachian School of Law" + }, + { + "label": "Appalachian State University" + }, + { + "label": "Aquinas College-Grand Rapids" + }, + { + "label": "Aquinas College-Nashville" + }, + { + "label": "Aquinas Institute of Theology" + }, + { + "label": "Arapahoe Community College" + }, + { + "label": "Arcadia University" + }, + { + "label": "Argosy University-Atlanta" + }, + { + "label": "Argosy University-Chicago" + }, + { + "label": "Argosy University-Dallas" + }, + { + "label": "Argosy University-Denver" + }, + { + "label": "Argosy University-Hawaii" + }, + { + "label": "Argosy University-Inland Empire" + }, + { + "label": "Argosy University-Los Angeles" + }, + { + "label": "Argosy University-Nashville" + }, + { + "label": "Argosy University-Orange County" + }, + { + "label": "Argosy University-Phoenix" + }, + { + "label": "Argosy University-Phoenix Online Division" + }, + { + "label": "Argosy University-Salt Lake City" + }, + { + "label": "Argosy University-San Diego" + }, + { + "label": "Argosy University-San Francisco Bay Area" + }, + { + "label": "Argosy University-Sarasota" + }, + { + "label": "Argosy University-Schaumburg" + }, + { + "label": "Argosy University-Seattle" + }, + { + "label": "Argosy University-Tampa" + }, + { + "label": "Argosy University-The Art Institute of California-Hollywood" + }, + { + "label": "Argosy University-The Art Institute of California-Inland Empire" + }, + { + "label": "Argosy University-The Art Institute of California-Los Angeles" + }, + { + "label": "Argosy University-The Art Institute of California-Orange County" + }, + { + "label": "Argosy University-The Art Institute of California-Sacramento" + }, + { + "label": "Argosy University-The Art Institute of California-San Diego" + }, + { + "label": "Argosy University-The Art Institute of California-San Francisco" + }, + { + "label": "Argosy University-The Art Institute of California-Silicon Valley" + }, + { + "label": "Argosy University-Twin Cities" + }, + { + "label": "Argosy University-Washington DC" + }, + { + "label": "Arizona Christian University" + }, + { + "label": "Arizona College-Glendale" + }, + { + "label": "Arizona College-Mesa" + }, + { + "label": "Arizona School of Acupuncture and Oriental Medicine" + }, + { + "label": "Arizona State University-Downtown Phoenix" + }, + { + "label": "Arizona State University-Polytechnic" + }, + { + "label": "Arizona State University-Skysong" + }, + { + "label": "Arizona State University-Tempe" + }, + { + "label": "Arizona State University-West" + }, + { + "label": "Arizona Summit Law School" + }, + { + "label": "Arizona Western College" + }, + { + "label": "Arkansas Baptist College" + }, + { + "label": "Arkansas Northeastern College" + }, + { + "label": "Arkansas State University-Beebe" + }, + { + "label": "Arkansas State University-Main Campus" + }, + { + "label": "Arkansas State University-Mid-South" + }, + { + "label": "Arkansas State University-Mountain Home" + }, + { + "label": "Arkansas State University-Newport" + }, + { + "label": "Arkansas Tech University" + }, + { + "label": "Arlington Baptist College" + }, + { + "label": "Armstrong State University" + }, + { + "label": "Art Academy of Cincinnati" + }, + { + "label": "Art Center College of Design" + }, + { + "label": "ASA College" + }, + { + "label": "Asbury Theological Seminary" + }, + { + "label": "Asbury University" + }, + { + "label": "Ashdown College of Health Sciences" + }, + { + "label": "Asher College" + }, + { + "label": "Asheville-Buncombe Technical Community College" + }, + { + "label": "Ashford University" + }, + { + "label": "Ashland Community and Technical College" + }, + { + "label": "Ashland University" + }, + { + "label": "Asnuntuck Community College" + }, + { + "label": "Aspen University" + }, + { + "label": "Assemblies of God Theological Seminary" + }, + { + "label": "Assumption College" + }, + { + "label": "Assumption College for Sisters" + }, + { + "label": "ATA Career Education" + }, + { + "label": "ATA College" + }, + { + "label": "Atenas College" + }, + { + "label": "Athenaeum of Ohio" + }, + { + "label": "Athens State University" + }, + { + "label": "Athens Technical College" + }, + { + "label": "Atlanta Metropolitan State College" + }, + { + "label": "Atlanta Technical College" + }, + { + "label": "Atlanta's John Marshall Law School" + }, + { + "label": "Atlantic Cape Community College" + }, + { + "label": "Atlantic Institute of Oriental Medicine" + }, + { + "label": "Atlantic University College" + }, + { + "label": "Auburn University" + }, + { + "label": "Auburn University at Montgomery" + }, + { + "label": "Augsburg College" + }, + { + "label": "Augusta Technical College" + }, + { + "label": "Augusta University" + }, + { + "label": "Augustana College-Rock Island" + }, + { + "label": "Augustana University" + }, + { + "label": "Aultman College of Nursing and Health Sciences" + }, + { + "label": "Aurora University" + }, + { + "label": "Austin College" + }, + { + "label": "Austin Community College District" + }, + { + "label": "Austin Graduate School of Theology" + }, + { + "label": "Austin Peay State University" + }, + { + "label": "Austin Presbyterian Theological Seminary" + }, + { + "label": "Ave Maria School of Law" + }, + { + "label": "Ave Maria University" + }, + { + "label": "Averett University" + }, + { + "label": "Averett University-Non-Traditional Programs" + }, + { + "label": "Aviator College of Aeronautical Science and Technology" + }, + { + "label": "Avila University" + }, + { + "label": "AVTEC-Alaska's Institute of Technology" + }, + { + "label": "Azure College" + }, + { + "label": "Azusa Pacific University" + }, + { + "label": "Azusa Pacific University College" + }, + { + "label": "Babson College" + }, + { + "label": "Bacone College" + }, + { + "label": "Bainbridge State College" + }, + { + "label": "Bais HaMedrash and Mesivta of Baltimore" + }, + { + "label": "Bais Medrash Elyon" + }, + { + "label": "Bais Medrash Toras Chesed" + }, + { + "label": "Baker College" + }, + { + "label": "Baker College Center for Graduate Studies" + }, + { + "label": "Baker College of Allen Park" + }, + { + "label": "Baker College of Auburn Hills" + }, + { + "label": "Baker College of Cadillac" + }, + { + "label": "Baker College of Clinton Township" + }, + { + "label": "Baker College of Jackson" + }, + { + "label": "Baker College of Muskegon" + }, + { + "label": "Baker College of Owosso" + }, + { + "label": "Baker College of Port Huron" + }, + { + "label": "Baker University" + }, + { + "label": "Bakersfield College" + }, + { + "label": "Bakke Graduate University" + }, + { + "label": "Baldwin Wallace University" + }, + { + "label": "Ball State University" + }, + { + "label": "Baltimore City Community College" + }, + { + "label": "Bank Street College of Education" + }, + { + "label": "Baptist Bible College" + }, + { + "label": "Clarks Summit University" + }, + { + "label": "Baptist Health System School of Health Professions" + }, + { + "label": "Baptist Memorial College of Health Sciences" + }, + { + "label": "Baptist Missionary Association Theological Seminary" + }, + { + "label": "Baptist Theological Seminary at Richmond" + }, + { + "label": "Baptist University of the Americas" + }, + { + "label": "Barclay College" + }, + { + "label": "Bard College" + }, + { + "label": "Bard College at Simon's Rock" + }, + { + "label": "Barnard College" + }, + { + "label": "Barnes-Jewish College Goldfarb School of Nursing" + }, + { + "label": "Barry University" + }, + { + "label": "Barstow Community College" + }, + { + "label": "Barton College" + }, + { + "label": "Barton County Community College" + }, + { + "label": "Bastyr University" + }, + { + "label": "Bates College" + }, + { + "label": "Bates Technical College" + }, + { + "label": "Baton Rouge Community College" + }, + { + "label": "Baton Rouge School of Computers" + }, + { + "label": "Bauder College" + }, + { + "label": "Bay de Noc Community College" + }, + { + "label": "Bay Mills Community College" + }, + { + "label": "Bay Path University" + }, + { + "label": "Bay State College" + }, + { + "label": "Baylor College of Medicine" + }, + { + "label": "Baylor University" + }, + { + "label": "Beacon College" + }, + { + "label": "Beal College" + }, + { + "label": "Beaufort County Community College" + }, + { + "label": "Becker College" + }, + { + "label": "Beckfield College-Florence" + }, + { + "label": "Beckfield College-Tri-County" + }, + { + "label": "Be'er Yaakov Talmudic Seminary" + }, + { + "label": "Beis Medrash Heichal Dovid" + }, + { + "label": "Belanger School of Nursing" + }, + { + "label": "Belhaven University" + }, + { + "label": "Bellarmine University" + }, + { + "label": "Bellevue College" + }, + { + "label": "Bellevue University" + }, + { + "label": "Bellin College" + }, + { + "label": "Bellingham Technical College" + }, + { + "label": "Belmont Abbey College" + }, + { + "label": "Belmont College" + }, + { + "label": "Belmont University" + }, + { + "label": "Beloit College" + }, + { + "label": "Bel-Rea Institute of Animal Technology" + }, + { + "label": "Bemidji State University" + }, + { + "label": "Benedict College" + }, + { + "label": "Benedictine College" + }, + { + "label": "Benedictine University" + }, + { + "label": "Benjamin Franklin Institute of Technology" + }, + { + "label": "Bennett College" + }, + { + "label": "Bennington College" + }, + { + "label": "Bentley University" + }, + { + "label": "Berea College" + }, + { + "label": "Bergen Community College" + }, + { + "label": "Bergin University of Canine Studies" + }, + { + "label": "Berkeley City College" + }, + { + "label": "Berkeley College-New York" + }, + { + "label": "Berkeley College-Woodland Park" + }, + { + "label": "Berklee College of Music" + }, + { + "label": "Berks Technical Institute" + }, + { + "label": "Berkshire Community College" + }, + { + "label": "Berry College" + }, + { + "label": "Beth Hamedrash Shaarei Yosher Institute" + }, + { + "label": "Beth Hatalmud Rabbinical College" + }, + { + "label": "Beth Medrash Govoha" + }, + { + "label": "Bethany College-Bethany" + }, + { + "label": "Bethany College-Lindsborg" + }, + { + "label": "Bethany Lutheran College" + }, + { + "label": "Bethany Theological Seminary" + }, + { + "label": "Bethel College" + }, + { + "label": "Bethel College-Indiana" + }, + { + "label": "Bethel College-North Newton" + }, + { + "label": "Bethel Seminary-San Diego" + }, + { + "label": "Bethel Seminary-St Paul" + }, + { + "label": "Bethel University-McKenzie" + }, + { + "label": "Bethel University-Saint Paul" + }, + { + "label": "Bethesda University" + }, + { + "label": "Bethune-Cookman University" + }, + { + "label": "Beulah Heights University" + }, + { + "label": "Bevill State Community College" + }, + { + "label": "Bexley Hall Seabury Western Theological Seminary Federation" + }, + { + "label": "Bexley Hall Seabury Western Theological Seminary Federation " + }, + { + "label": "Biblical Theological Seminary" + }, + { + "label": "Bidwell Training Center Inc" + }, + { + "label": "Big Bend Community College" + }, + { + "label": "Big Sandy Community and Technical College" + }, + { + "label": "Biola University" + }, + { + "label": "Birmingham Southern College" + }, + { + "label": "Birthingway College of Midwifery" + }, + { + "label": "Bishop State Community College" + }, + { + "label": "Bismarck State College" + }, + { + "label": "Black Hawk College" + }, + { + "label": "Black Hills State University" + }, + { + "label": "Black River Technical College" + }, + { + "label": "Blackburn College" + }, + { + "label": "Blackfeet Community College" + }, + { + "label": "Blackhawk Technical College" + }, + { + "label": "Bladen Community College" + }, + { + "label": "Blessing Rieman College of Nursing" + }, + { + "label": "Blinn College" + }, + { + "label": "Bloomfield College" + }, + { + "label": "Bloomsburg University of Pennsylvania" + }, + { + "label": "Blue Cliff College-Gulfport" + }, + { + "label": "Blue Mountain College" + }, + { + "label": "Blue Mountain Community College" + }, + { + "label": "Blue Ridge Community and Technical College" + }, + { + "label": "Blue Ridge Community College-Flat Rock" + }, + { + "label": "Blue Ridge Community College-Weyers Cave" + }, + { + "label": "Bluefield College" + }, + { + "label": "Bluefield State College" + }, + { + "label": "Bluegrass Community and Technical College" + }, + { + "label": "Bluffton University" + }, + { + "label": "Bob Jones University" + }, + { + "label": "Boise Bible College" + }, + { + "label": "Boise State University" + }, + { + "label": "Bon Secours Memorial College of Nursing" + }, + { + "label": "Boricua College" + }, + { + "label": "Bossier Parish Community College" + }, + { + "label": "Boston Architectural College" + }, + { + "label": "Boston Baptist College" + }, + { + "label": "Boston College" + }, + { + "label": "Boston Graduate School of Psychoanalysis Inc" + }, + { + "label": "Boston University" + }, + { + "label": "Bowdoin College" + }, + { + "label": "Bowie State University" + }, + { + "label": "Bowling Green State University-Firelands" + }, + { + "label": "Bowling Green State University-Main Campus" + }, + { + "label": "Bradford School-Columbus" + }, + { + "label": "Bradford School-Pittsburgh" + }, + { + "label": "Bradley University" + }, + { + "label": "Bramson ORT College" + }, + { + "label": "Brandeis University" + }, + { + "label": "Brandman University" + }, + { + "label": "Brazosport College" + }, + { + "label": "Brenau University" + }, + { + "label": "Brescia University" + }, + { + "label": "Brevard College" + }, + { + "label": "Brewton-Parker College" + }, + { + "label": "Briar Cliff University" + }, + { + "label": "Briarcliffe College" + }, + { + "label": "Bridgewater College" + }, + { + "label": "Bridgewater State University" + }, + { + "label": "Brigham Young University-Hawaii" + }, + { + "label": "Brigham Young University-Idaho" + }, + { + "label": "Brigham Young University-Provo" + }, + { + "label": "Brightwood Career Institute-Broomall" + }, + { + "label": "Brightwood Career Institute-Harrisburg" + }, + { + "label": "Brightwood Career Institute-Philadelphia" + }, + { + "label": "Brightwood Career Institute-Philadelphia Mills" + }, + { + "label": "Brightwood Career Institute-Pittsburgh" + }, + { + "label": "Brightwood College-Arlington" + }, + { + "label": "Brightwood College-Bakersfield" + }, + { + "label": "Brightwood College-Baltimore" + }, + { + "label": "Brightwood College-Beaumont" + }, + { + "label": "Brightwood College-Beltsville" + }, + { + "label": "Brightwood College-Brownsville" + }, + { + "label": "Brightwood College-Charlotte" + }, + { + "label": "Brightwood College-Chula Vista" + }, + { + "label": "Brightwood College-Corpus Christi" + }, + { + "label": "Brightwood College-Dallas" + }, + { + "label": "Brightwood College-Dayton" + }, + { + "label": "Brightwood College-El Paso" + }, + { + "label": "Brightwood College-Fort Worth" + }, + { + "label": "Brightwood College-Fresno" + }, + { + "label": "Brightwood College-Indianapolis" + }, + { + "label": "Brightwood College-Laredo" + }, + { + "label": "Brightwood College-Las Vegas" + }, + { + "label": "Brightwood College-McAllen" + }, + { + "label": "Brightwood College-Modesto" + }, + { + "label": "Brightwood College-Nashville" + }, + { + "label": "Brightwood College-Palm Springs" + }, + { + "label": "Brightwood College-Riverside" + }, + { + "label": "Brightwood College-Sacramento" + }, + { + "label": "Brightwood College-San Antonio-Ingram" + }, + { + "label": "Brightwood College-San Antonio-San Pedro" + }, + { + "label": "Brightwood College-San Diego" + }, + { + "label": "Brightwood College-Towson" + }, + { + "label": "Brightwood College-Vista" + }, + { + "label": "Bristol Community College" + }, + { + "label": "Bristol University" + }, + { + "label": "Brite Divinity School" + }, + { + "label": "Broadview Entertainment Arts University" + }, + { + "label": "Broadview University-Boise" + }, + { + "label": "Broadview University-Layton" + }, + { + "label": "Broadview University-Orem" + }, + { + "label": "Broadview University-West Jordan" + }, + { + "label": "Brookdale Community College" + }, + { + "label": "Brookhaven College" + }, + { + "label": "Brookline College-Albuquerque" + }, + { + "label": "Brookline College-Phoenix" + }, + { + "label": "Brookline College-Tempe" + }, + { + "label": "Brookline College-Tucson" + }, + { + "label": "Brooklyn Law School" + }, + { + "label": "Brooks Institute" + }, + { + "label": "Broward College" + }, + { + "label": "Brown Mackie College-Akron" + }, + { + "label": "Brown Mackie College-Albuquerque" + }, + { + "label": "Brown Mackie College-Atlanta" + }, + { + "label": "Brown Mackie College-Birmingham" + }, + { + "label": "Brown Mackie College-Boise" + }, + { + "label": "Brown Mackie College-Cincinnati" + }, + { + "label": "Brown Mackie College-Dallas" + }, + { + "label": "Brown Mackie College-Findlay" + }, + { + "label": "Brown Mackie College-Fort Wayne" + }, + { + "label": "Brown Mackie College-Greenville" + }, + { + "label": "Brown Mackie College-Hopkinsville" + }, + { + "label": "Brown Mackie College-Indianapolis" + }, + { + "label": "Brown Mackie College-Kansas City" + }, + { + "label": "Brown Mackie College-Louisville" + }, + { + "label": "Brown Mackie College-Merrillville" + }, + { + "label": "Brown Mackie College-Miami" + }, + { + "label": "Brown Mackie College-Michigan City" + }, + { + "label": "Brown Mackie College-North Canton" + }, + { + "label": "Brown Mackie College-Northern Kentucky" + }, + { + "label": "Brown Mackie College-Oklahoma City" + }, + { + "label": "Brown Mackie College-Phoenix" + }, + { + "label": "Brown Mackie College-Quad Cities" + }, + { + "label": "Brown Mackie College-Salina" + }, + { + "label": "Brown Mackie College-San Antonio" + }, + { + "label": "Brown Mackie College-South Bend" + }, + { + "label": "Brown Mackie College-St Louis" + }, + { + "label": "Brown Mackie College-Tucson" + }, + { + "label": "Brown Mackie College-Tulsa" + }, + { + "label": "Brown University" + }, + { + "label": "Brunswick Community College" + }, + { + "label": "Bryan College of Health Sciences" + }, + { + "label": "Bryan College-Dayton" + }, + { + "label": "Bryan College-Gold River" + }, + { + "label": "Bryan University-Columbia" + }, + { + "label": "Bryan University-Los Angeles" + }, + { + "label": "Bryan University-Rogers" + }, + { + "label": "Bryan University-Springfield" + }, + { + "label": "Bryan University-Topeka" + }, + { + "label": "Bryant & Stratton College-Akron" + }, + { + "label": "Bryant & Stratton College-Albany" + }, + { + "label": "Bryant & Stratton College-Amherst" + }, + { + "label": "Bryant & Stratton College-Bayshore" + }, + { + "label": "Bryant & Stratton College-Buffalo" + }, + { + "label": "Bryant & Stratton College-Cleveland" + }, + { + "label": "Bryant & Stratton College-Eastlake" + }, + { + "label": "Bryant & Stratton College-Greece" + }, + { + "label": "Bryant & Stratton College-Hampton" + }, + { + "label": "Bryant & Stratton College-Henrietta" + }, + { + "label": "Bryant & Stratton College-Milwaukee" + }, + { + "label": "Bryant & Stratton College-Online" + }, + { + "label": "Bryant & Stratton College-Parma" + }, + { + "label": "Bryant & Stratton College-Richmond" + }, + { + "label": "Bryant & Stratton College-Southtowns" + }, + { + "label": "Bryant & Stratton College-Syracuse" + }, + { + "label": "Bryant & Stratton College-Syracuse North" + }, + { + "label": "Bryant & Stratton College-Virginia Beach" + }, + { + "label": "Bryant & Stratton College-Wauwatosa" + }, + { + "label": "Bryant University" + }, + { + "label": "Bryn Athyn College of the New Church" + }, + { + "label": "Bryn Mawr College" + }, + { + "label": "Bucknell University" + }, + { + "label": "Bucks County Community College" + }, + { + "label": "Bucks County School of Beauty Culture Inc" + }, + { + "label": "Buena Vista University" + }, + { + "label": "Bunker Hill Community College" + }, + { + "label": "Burlington College" + }, + { + "label": "Burnett International College" + }, + { + "label": "Business Informatics Center Inc" + }, + { + "label": "Butler Community College" + }, + { + "label": "Butler County Community College" + }, + { + "label": "Butler University" + }, + { + "label": "Butte College" + }, + { + "label": "Byzantine Catholic Seminary of Saints Cyril and Methodius" + }, + { + "label": "Cabarrus College of Health Sciences" + }, + { + "label": "Cabrillo College" + }, + { + "label": "Cabrini University" + }, + { + "label": "Cairn University-Langhorne" + }, + { + "label": "Caldwell Community College and Technical Institute" + }, + { + "label": "Caldwell University" + }, + { + "label": "California Baptist University" + }, + { + "label": "California Christian College" + }, + { + "label": "California College of the Arts" + }, + { + "label": "California College San Diego-San Diego" + }, + { + "label": "California College San Diego-San Marcos" + }, + { + "label": "California Institute of Integral Studies" + }, + { + "label": "California Institute of Technology" + }, + { + "label": "California Institute of the Arts" + }, + { + "label": "California Lutheran University" + }, + { + "label": "California Miramar University" + }, + { + "label": "California Polytechnic State University-San Luis Obispo" + }, + { + "label": "California State Polytechnic University-Pomona" + }, + { + "label": "California State University-Bakersfield" + }, + { + "label": "California State University-Channel Islands" + }, + { + "label": "California State University-Chico" + }, + { + "label": "California State University-Dominguez Hills" + }, + { + "label": "California State University-East Bay" + }, + { + "label": "California State University-Fresno" + }, + { + "label": "California State University-Fullerton" + }, + { + "label": "California State University-Long Beach" + }, + { + "label": "California State University-Los Angeles" + }, + { + "label": "California State University-Monterey Bay" + }, + { + "label": "California State University-Northridge" + }, + { + "label": "California State University-Sacramento" + }, + { + "label": "California State University-San Bernardino" + }, + { + "label": "California State University-San Marcos" + }, + { + "label": "California State University-Stanislaus" + }, + { + "label": "California University of Management and Sciences" + }, + { + "label": "California University of Pennsylvania" + }, + { + "label": "California Western School of Law" + }, + { + "label": "Calumet College of Saint Joseph" + }, + { + "label": "Calvary Bible College and Theological Seminary" + }, + { + "label": "Calvin College" + }, + { + "label": "Calvin Theological Seminary" + }, + { + "label": "Cambria-Rowe Business College-Indiana" + }, + { + "label": "Cambria-Rowe Business College-Johnstown" + }, + { + "label": "Cambridge College" + }, + { + "label": "Cambridge College of Healthcare & Technology" + }, + { + "label": "Cambridge Junior College-Yuba City" + }, + { + "label": "Camden County College" + }, + { + "label": "Cameron College" + }, + { + "label": "Cameron University" + }, + { + "label": "Campbell University" + }, + { + "label": "Campbellsville University" + }, + { + "label": "Canada College" + }, + { + "label": "Canisius College" + }, + { + "label": "Cankdeska Cikana Community College" + }, + { + "label": "Cape Cod Community College" + }, + { + "label": "Cape Fear Community College" + }, + { + "label": "Capella University" + }, + { + "label": "Capital Area Technical College" + }, + { + "label": "Capital Community College" + }, + { + "label": "Capital University" + }, + { + "label": "Capitol Technology University" + }, + { + "label": "Cardinal Stritch University" + }, + { + "label": "Career College of Northern Nevada" + }, + { + "label": "Career Point College-San Antonio" + }, + { + "label": "Career Point College-Tulsa" + }, + { + "label": "Career Quest Learning Centers-Jackson" + }, + { + "label": "Career Quest Learning Centers-Lansing" + }, + { + "label": "Career Technical College-Monroe" + }, + { + "label": "Career Technical College-Shreveport" + }, + { + "label": "Career Training Academy-Lower Burrell" + }, + { + "label": "Career Training Academy-Monroeville" + }, + { + "label": "Career Training Academy-Pittsburgh" + }, + { + "label": "Careers Unlimited" + }, + { + "label": "Caribbean University-Bayamon" + }, + { + "label": "Caribbean University-Carolina" + }, + { + "label": "Caribbean University-Ponce" + }, + { + "label": "Caribbean University-Vega Baja" + }, + { + "label": "Carl Albert State College" + }, + { + "label": "Carl Sandburg College" + }, + { + "label": "Carleton College" + }, + { + "label": "Carlos Albizu University-Miami" + }, + { + "label": "Carlos Albizu University-San Juan" + }, + { + "label": "Carlow University" + }, + { + "label": "Carnegie Mellon University" + }, + { + "label": "Carolina Christian College" + }, + { + "label": "Carolina College of Biblical Studies" + }, + { + "label": "Carolinas College of Health Sciences" + }, + { + "label": "Carrington College-Albuquerque" + }, + { + "label": "Carrington College-Boise" + }, + { + "label": "Carrington College-Citrus Heights" + }, + { + "label": "Carrington College-Las Vegas" + }, + { + "label": "Carrington College-Mesa" + }, + { + "label": "Carrington College-Phoenix" + }, + { + "label": "Carrington College-Pleasant Hill" + }, + { + "label": "Carrington College-Pomona" + }, + { + "label": "Carrington College-Portland" + }, + { + "label": "Carrington College-Reno" + }, + { + "label": "Carrington College-Sacramento" + }, + { + "label": "Carrington College-San Jose" + }, + { + "label": "Carrington College-San Leandro" + }, + { + "label": "Carrington College-Spokane" + }, + { + "label": "Carrington College-Stockton" + }, + { + "label": "Carrington College-Tucson" + }, + { + "label": "Carrington College-Westside" + }, + { + "label": "Carroll College" + }, + { + "label": "Carroll Community College" + }, + { + "label": "Carroll University" + }, + { + "label": "Carson-Newman University" + }, + { + "label": "Carteret Community College" + }, + { + "label": "Carthage College" + }, + { + "label": "Carver Bible College" + }, + { + "label": "Carver Career Center" + }, + { + "label": "Casa Loma College-Van Nuys" + }, + { + "label": "Cascadia College" + }, + { + "label": "Case Western Reserve University" + }, + { + "label": "Casper College" + }, + { + "label": "Castleton State College" + }, + { + "label": "Catawba College" + }, + { + "label": "Catawba Valley Community College" + }, + { + "label": "Catholic Distance University" + }, + { + "label": "Catholic Theological Union at Chicago" + }, + { + "label": "Catholic University of America" + }, + { + "label": "Cayuga County Community College" + }, + { + "label": "Cazenovia College" + }, + { + "label": "Cecil College" + }, + { + "label": "Cedar Crest College" + }, + { + "label": "Cedar Valley College" + }, + { + "label": "Cedarville University" + }, + { + "label": "Centenary College" + }, + { + "label": "Centenary College of Louisiana" + }, + { + "label": "Center for Advanced Legal Studies" + }, + { + "label": "Center for Advanced Studies On Puerto Rico and the Caribbean" + }, + { + "label": "Centra College of Nursing" + }, + { + "label": "Central Alabama Community College" + }, + { + "label": "Central Arizona College" + }, + { + "label": "Central Baptist College" + }, + { + "label": "Central Baptist Theological Seminary" + }, + { + "label": "Central Carolina Community College" + }, + { + "label": "Central Carolina Technical College" + }, + { + "label": "Central Christian College of Kansas" + }, + { + "label": "Central Christian College of the Bible" + }, + { + "label": "Central College" + }, + { + "label": "Central Community College" + }, + { + "label": "Central Connecticut State University" + }, + { + "label": "Central Florida Institute" + }, + { + "label": "Central Georgia Technical College" + }, + { + "label": "Central Lakes College-Brainerd" + }, + { + "label": "Central Louisiana Technical Community College" + }, + { + "label": "Central Maine Community College" + }, + { + "label": "Central Methodist University-College of Graduate and Extended Studies" + }, + { + "label": "Central Methodist University-College of Liberal Arts and Sciences" + }, + { + "label": "Central Michigan University" + }, + { + "label": "Central New Mexico Community College" + }, + { + "label": "Central Ohio Technical College" + }, + { + "label": "Central Oregon Community College" + }, + { + "label": "Central Penn College" + }, + { + "label": "Central Piedmont Community College" + }, + { + "label": "Central State University" + }, + { + "label": "Central Texas College" + }, + { + "label": "Central Virginia Community College" + }, + { + "label": "Central Washington University" + }, + { + "label": "Central Wyoming College" + }, + { + "label": "Central Yeshiva Tomchei Tmimim Lubavitz" + }, + { + "label": "Centralia College" + }, + { + "label": "Centre College" + }, + { + "label": "Centro de Estudios Multidisciplinarios-Bayamon" + }, + { + "label": "Centro de Estudios Multidisciplinarios-Humacao" + }, + { + "label": "Centro de Estudios Multidisciplinarios-San Juan" + }, + { + "label": "Centura College-Chesapeake" + }, + { + "label": "Centura College-Columbia" + }, + { + "label": "Centura College-Newport News" + }, + { + "label": "Centura College-Norfolk" + }, + { + "label": "Centura College-Richmond Main" + }, + { + "label": "Centura College-Virginia Beach" + }, + { + "label": "Century College-White Bear Lake" + }, + { + "label": "Cerritos College" + }, + { + "label": "Cerro Coso Community College" + }, + { + "label": "Chabot College" + }, + { + "label": "Chadron State College" + }, + { + "label": "Chaffey College" + }, + { + "label": "Chamberlain College of Nursing-Arizona" + }, + { + "label": "Chamberlain College of Nursing-Florida" + }, + { + "label": "Chamberlain College of Nursing-Georgia" + }, + { + "label": "Chamberlain College of Nursing-Illinois" + }, + { + "label": "Chamberlain College of Nursing-Missouri" + }, + { + "label": "Chamberlain College of Nursing-Ohio" + }, + { + "label": "Chamberlain College of Nursing-Texas" + }, + { + "label": "Chamberlain College of Nursing-Virginia" + }, + { + "label": "Chaminade University of Honolulu" + }, + { + "label": "Champlain College" + }, + { + "label": "Chandler-Gilbert Community College" + }, + { + "label": "Chapman University" + }, + { + "label": "Charles R Drew University of Medicine and Science" + }, + { + "label": "Charleston School of Law" + }, + { + "label": "Charleston Southern University" + }, + { + "label": "Charlotte Christian College and Theological Seminary" + }, + { + "label": "Charlotte School of Law" + }, + { + "label": "Charter College-Anchorage" + }, + { + "label": "Charter College-Canyon Country" + }, + { + "label": "Charter Oak State College" + }, + { + "label": "Chatfield College" + }, + { + "label": "Chatham University" + }, + { + "label": "Chattahoochee Technical College" + }, + { + "label": "Chattahoochee Valley Community College" + }, + { + "label": "Chattanooga College Medical Dental and Technical Careers" + }, + { + "label": "Chattanooga State Community College" + }, + { + "label": "Chemeketa Community College" + }, + { + "label": "Chesapeake College" + }, + { + "label": "Chester Career College" + }, + { + "label": "Chestnut Hill College" + }, + { + "label": "Cheyney University of Pennsylvania" + }, + { + "label": "CHI Health School of Radiologic Technology" + }, + { + "label": "Chicago ORT Technical Institute" + }, + { + "label": "Chicago State University" + }, + { + "label": "Chicago Theological Seminary" + }, + { + "label": "Chief Dull Knife College" + }, + { + "label": "Chipola College" + }, + { + "label": "Chippewa Valley Technical College" + }, + { + "label": "Chowan University" + }, + { + "label": "Christ the King Seminary" + }, + { + "label": "Christian Brothers University" + }, + { + "label": "Christian Life College" + }, + { + "label": "Christian Theological Seminary" + }, + { + "label": "Christie's Education" + }, + { + "label": "Christopher Newport University" + }, + { + "label": "Church Divinity School of the Pacific" + }, + { + "label": "Cincinnati Christian University" + }, + { + "label": "Cincinnati College of Mortuary Science" + }, + { + "label": "Cincinnati State Technical and Community College" + }, + { + "label": "Cisco College" + }, + { + "label": "Citadel Military College of South Carolina" + }, + { + "label": "Citrus College" + }, + { + "label": "City College of San Francisco" + }, + { + "label": "City College-Altamonte Springs" + }, + { + "label": "City College-Fort Lauderdale" + }, + { + "label": "City College-Gainesville" + }, + { + "label": "City College-Hollywood" + }, + { + "label": "City College-Miami" + }, + { + "label": "City Colleges of Chicago-Harold Washington College" + }, + { + "label": "City Colleges of Chicago-Harry S Truman College" + }, + { + "label": "City Colleges of Chicago-Kennedy-King College" + }, + { + "label": "City Colleges of Chicago-Malcolm X College" + }, + { + "label": "City Colleges of Chicago-Olive-Harvey College" + }, + { + "label": "City Colleges of Chicago-Richard J Daley College" + }, + { + "label": "City Colleges of Chicago-Wilbur Wright College" + }, + { + "label": "City University of Seattle" + }, + { + "label": "City Vision University" + }, + { + "label": "Clackamas Community College" + }, + { + "label": "Claflin University" + }, + { + "label": "Claremont Graduate University" + }, + { + "label": "Claremont McKenna College" + }, + { + "label": "Claremont School of Theology" + }, + { + "label": "Clarendon College" + }, + { + "label": "Clarion University of Pennsylvania" + }, + { + "label": "Clark Atlanta University" + }, + { + "label": "Clark College" + }, + { + "label": "Clark State Community College" + }, + { + "label": "Clark University" + }, + { + "label": "Clarke University" + }, + { + "label": "Clarkson College" + }, + { + "label": "Clarkson University" + }, + { + "label": "Clary Sage College" + }, + { + "label": "Clatsop Community College" + }, + { + "label": "Clayton State University" + }, + { + "label": "Clear Creek Baptist Bible College" + }, + { + "label": "Clearwater Christian College" + }, + { + "label": "Cleary University" + }, + { + "label": "Clemson University" + }, + { + "label": "Cleveland Community College" + }, + { + "label": "Cleveland Institute of Art" + }, + { + "label": "Cleveland Institute of Music" + }, + { + "label": "Cleveland State Community College" + }, + { + "label": "Cleveland State University" + }, + { + "label": "Cleveland University-Kansas City" + }, + { + "label": "Clinton College" + }, + { + "label": "Clinton Community College" + }, + { + "label": "Cloud County Community College" + }, + { + "label": "Clover Park Technical College" + }, + { + "label": "Clovis Community College" + }, + { + "label": "Coahoma Community College" + }, + { + "label": "Coastal Bend College" + }, + { + "label": "Coastal Carolina Community College" + }, + { + "label": "Coastal Carolina University" + }, + { + "label": "Coastal Pines Technical College-Waycross" + }, + { + "label": "Coastline Community College" + }, + { + "label": "Cochise County Community College District" + }, + { + "label": "Cochran School of Nursing" + }, + { + "label": "Coconino Community College" + }, + { + "label": "Coe College" + }, + { + "label": "Coffeyville Community College" + }, + { + "label": "Cogswell College" + }, + { + "label": "Coker College" + }, + { + "label": "Colby College" + }, + { + "label": "Colby Community College" + }, + { + "label": "Colby-Sawyer College" + }, + { + "label": "Colegio de Cinematografía Artes y Television" + }, + { + "label": "Colegio Universitario de San Juan" + }, + { + "label": "Coleman University" + }, + { + "label": "Colgate Rochester Crozer Divinity School" + }, + { + "label": "Colgate University" + }, + { + "label": "College for Creative Studies" + }, + { + "label": "College of Alameda" + }, + { + "label": "College of Biblical Studies-Houston" + }, + { + "label": "College of Business and Technology-Cutler Bay" + }, + { + "label": "College of Business and Technology-Flagler" + }, + { + "label": "College of Business and Technology-Hialeah" + }, + { + "label": "College of Business and Technology-Kendall" + }, + { + "label": "College of Business and Technology-Miami Gardens" + }, + { + "label": "College of Central Florida" + }, + { + "label": "College of Charleston" + }, + { + "label": "College of Coastal Georgia" + }, + { + "label": "College of Court Reporting Inc" + }, + { + "label": "College of DuPage" + }, + { + "label": "College of Health Care Professions-Northwest" + }, + { + "label": "College of Lake County" + }, + { + "label": "College of Marin" + }, + { + "label": "College of Menominee Nation" + }, + { + "label": "College of Micronesia-FSM" + }, + { + "label": "College of Mount Saint Vincent" + }, + { + "label": "College of Our Lady of the Elms" + }, + { + "label": "College of Saint Benedict" + }, + { + "label": "College of Saint Elizabeth" + }, + { + "label": "College of Saint Mary" + }, + { + "label": "College of San Mateo" + }, + { + "label": "College of Southern Idaho" + }, + { + "label": "College of Southern Maryland" + }, + { + "label": "College of Southern Nevada" + }, + { + "label": "College of St Joseph" + }, + { + "label": "College of Staten Island CUNY" + }, + { + "label": "College of the Albemarle" + }, + { + "label": "College of the Atlantic" + }, + { + "label": "College of the Canyons" + }, + { + "label": "College of the Desert" + }, + { + "label": "College of the Holy Cross" + }, + { + "label": "College of the Mainland" + }, + { + "label": "College of the Marshall Islands" + }, + { + "label": "College of the Muscogee Nation" + }, + { + "label": "College of the Ouachitas" + }, + { + "label": "College of the Ozarks" + }, + { + "label": "College of the Redwoods" + }, + { + "label": "College of the Sequoias" + }, + { + "label": "College of the Siskiyous" + }, + { + "label": "College of Western Idaho" + }, + { + "label": "College of William and Mary" + }, + { + "label": "CollegeAmerica-Cheyenne" + }, + { + "label": "CollegeAmerica-Colorado Springs" + }, + { + "label": "CollegeAmerica-Denver" + }, + { + "label": "CollegeAmerica-Flagstaff" + }, + { + "label": "CollegeAmerica-Fort Collins" + }, + { + "label": "CollegeAmerica-Phoenix" + }, + { + "label": "Collin County Community College District" + }, + { + "label": "Collins College" + }, + { + "label": "Colorado Academy of Veterinary Technology" + }, + { + "label": "Colorado Christian University" + }, + { + "label": "Colorado College" + }, + { + "label": "Colorado Heights University" + }, + { + "label": "Colorado Mesa University" + }, + { + "label": "Colorado Mountain College" + }, + { + "label": "Colorado Northwestern Community College" + }, + { + "label": "Colorado School of Healing Arts" + }, + { + "label": "Colorado School of Mines" + }, + { + "label": "Colorado School of Trades" + }, + { + "label": "Colorado School of Traditional Chinese Medicine" + }, + { + "label": "Colorado State University-Fort Collins" + }, + { + "label": "Colorado State University-Global Campus" + }, + { + "label": "Colorado State University-Pueblo" + }, + { + "label": "Colorado Technical University-Colorado Springs" + }, + { + "label": "Colorado Technical University-Greenwood Village" + }, + { + "label": "Colorado Technical University-Online" + }, + { + "label": "Colorado Technical University-Sioux Falls" + }, + { + "label": "Columbia Basin College" + }, + { + "label": "Columbia Central University-Caguas" + }, + { + "label": "Columbia Central University-Yauco" + }, + { + "label": "Columbia College of Nursing" + }, + { + "label": "Columbia College-Chicago" + }, + { + "label": "Columbia College-Columbia" + }, + { + "label": "Columbia College-Columbia" + }, + { + "label": "Columbia College-Fairfax" + }, + { + "label": "Columbia College-Hollywood" + }, + { + "label": "Columbia College-Sonora" + }, + { + "label": "Columbia Gorge Community College" + }, + { + "label": "Columbia International University" + }, + { + "label": "Columbia Southern University" + }, + { + "label": "Columbia State Community College" + }, + { + "label": "Columbia Theological Seminary" + }, + { + "label": "Columbia University in the City of New York" + }, + { + "label": "Columbia-Greene Community College" + }, + { + "label": "Columbus College of Art and Design" + }, + { + "label": "Columbus State Community College" + }, + { + "label": "Columbus State University" + }, + { + "label": "Columbus Technical College" + }, + { + "label": "Comanche Nation College" + }, + { + "label": "Commonwealth Institute of Funeral Service" + }, + { + "label": "Commonwealth Technical Institute" + }, + { + "label": "Community Care College" + }, + { + "label": "Community Christian College" + }, + { + "label": "Community College of Allegheny County" + }, + { + "label": "Community College of Aurora" + }, + { + "label": "Community College of Beaver County" + }, + { + "label": "Community College of Denver" + }, + { + "label": "Community College of Philadelphia" + }, + { + "label": "Community College of Rhode Island" + }, + { + "label": "Community College of Vermont" + }, + { + "label": "Compass College of Cinematic Arts" + }, + { + "label": "Conception Seminary College" + }, + { + "label": "Concord University" + }, + { + "label": "Concorde Career College-Aurora" + }, + { + "label": "Concorde Career College-Dallas" + }, + { + "label": "Concorde Career College-Garden Grove" + }, + { + "label": "Concorde Career College-Grand Prairie" + }, + { + "label": "Concorde Career College-Kansas City" + }, + { + "label": "Concorde Career College-Memphis" + }, + { + "label": "Concorde Career College-North Hollywood" + }, + { + "label": "Concorde Career College-Portland" + }, + { + "label": "Concorde Career College-San Antonio" + }, + { + "label": "Concorde Career College-San Bernardino" + }, + { + "label": "Concorde Career College-San Diego" + }, + { + "label": "Concorde Career Institute-Jacksonville" + }, + { + "label": "Concorde Career Institute-Miramar" + }, + { + "label": "Concorde Career Institute-Orlando" + }, + { + "label": "Concorde Career Institute-Tampa" + }, + { + "label": "Concordia College Alabama" + }, + { + "label": "Concordia College at Moorhead" + }, + { + "label": "Concordia College-New York" + }, + { + "label": "Concordia Seminary" + }, + { + "label": "Concordia Theological Seminary" + }, + { + "label": "Concordia University-Ann Arbor" + }, + { + "label": "Concordia University-Chicago" + }, + { + "label": "Concordia University-Irvine" + }, + { + "label": "Concordia University-Nebraska" + }, + { + "label": "Concordia University-Portland" + }, + { + "label": "Concordia University-Saint Paul" + }, + { + "label": "Concordia University-Texas" + }, + { + "label": "Concordia University-Wisconsin" + }, + { + "label": "Connecticut College" + }, + { + "label": "Connors State College" + }, + { + "label": "Consolidated School of Business-Lancaster" + }, + { + "label": "Consolidated School of Business-York" + }, + { + "label": "Contra Costa College" + }, + { + "label": "Converse College" + }, + { + "label": "Conway School of Landscape Design" + }, + { + "label": "Cooper Union for the Advancement of Science and Art" + }, + { + "label": "Copiah-Lincoln Community College" + }, + { + "label": "Copper Mountain Community College" + }, + { + "label": "Coppin State University" + }, + { + "label": "Corban University" + }, + { + "label": "Cornell College" + }, + { + "label": "Cornell University" + }, + { + "label": "Cornerstone University" + }, + { + "label": "Corning Community College" + }, + { + "label": "Cornish College of the Arts" + }, + { + "label": "Cossatot Community College of the University of Arkansas" + }, + { + "label": "Cosumnes River College" + }, + { + "label": "Cottey College" + }, + { + "label": "County College of Morris" + }, + { + "label": "Court Reporting Institute of Dallas" + }, + { + "label": "Covenant College" + }, + { + "label": "Covenant Theological Seminary" + }, + { + "label": "Cowley County Community College" + }, + { + "label": "Cox College" + }, + { + "label": "Coyne College" + }, + { + "label": "Crafton Hills College" + }, + { + "label": "Cranbrook Academy of Art" + }, + { + "label": "Craven Community College" + }, + { + "label": "Creighton University" + }, + { + "label": "Criswell College" + }, + { + "label": "Crossroads Bible College" + }, + { + "label": "Crossroads College" + }, + { + "label": "Crowder College" + }, + { + "label": "Crowley's Ridge College" + }, + { + "label": "Crown College" + }, + { + "label": "Cuesta College" + }, + { + "label": "Culinary Institute Inc" + }, + { + "label": "Culinary Institute of America" + }, + { + "label": "Culver-Stockton College" + }, + { + "label": "Cumberland County College" + }, + { + "label": "Cumberland University" + }, + { + "label": "CUNY Bernard M Baruch College" + }, + { + "label": "CUNY Borough of Manhattan Community College" + }, + { + "label": "CUNY Bronx Community College" + }, + { + "label": "CUNY Brooklyn College" + }, + { + "label": "CUNY City College" + }, + { + "label": "CUNY Graduate School and University Center" + }, + { + "label": "CUNY Hostos Community College" + }, + { + "label": "CUNY Hunter College" + }, + { + "label": "CUNY John Jay College of Criminal Justice" + }, + { + "label": "CUNY Kingsborough Community College" + }, + { + "label": "CUNY LaGuardia Community College" + }, + { + "label": "CUNY Lehman College" + }, + { + "label": "CUNY Medgar Evers College" + }, + { + "label": "CUNY New York City College of Technology" + }, + { + "label": "CUNY Queens College" + }, + { + "label": "CUNY Queensborough Community College" + }, + { + "label": "CUNY School of Law" + }, + { + "label": "CUNY York College" + }, + { + "label": "Curry College" + }, + { + "label": "Curtis Institute of Music" + }, + { + "label": "Cuyahoga Community College District" + }, + { + "label": "Cuyamaca College" + }, + { + "label": "Cypress College" + }, + { + "label": "Dabney S Lancaster Community College" + }, + { + "label": "Dade Medical College-Hollywood" + }, + { + "label": "Dade Medical College-Homestead" + }, + { + "label": "Dade Medical College-Jacksonville" + }, + { + "label": "Dade Medical College-Miami" + }, + { + "label": "Dade Medical College-Miami Lakes" + }, + { + "label": "Dade Medical College-West Palm Beach" + }, + { + "label": "Daemen College" + }, + { + "label": "Dakota College at Bottineau" + }, + { + "label": "Dakota County Technical College" + }, + { + "label": "Dakota State University" + }, + { + "label": "Dakota Wesleyan University" + }, + { + "label": "Dallas Baptist University" + }, + { + "label": "Dallas Christian College" + }, + { + "label": "Dallas Institute of Funeral Service" + }, + { + "label": "Dallas Nursing Institute" + }, + { + "label": "Dallas Theological Seminary" + }, + { + "label": "Dalton State College" + }, + { + "label": "Daniel Webster College" + }, + { + "label": "Danville Area Community College" + }, + { + "label": "Danville Community College" + }, + { + "label": "Daoist Traditions College of Chinese Medical Arts" + }, + { + "label": "Dartmouth College" + }, + { + "label": "Darton State College" + }, + { + "label": "Davenport University" + }, + { + "label": "Davidson College" + }, + { + "label": "Davidson County Community College" + }, + { + "label": "Davis & Elkins College" + }, + { + "label": "Davis College-Johnson City" + }, + { + "label": "Davis College-Toledo" + }, + { + "label": "Dawson Community College" + }, + { + "label": "Daymar College-Bellevue" + }, + { + "label": "Daymar College-Bowling Green" + }, + { + "label": "Daymar College-Chillicothe" + }, + { + "label": "Daymar College-Jackson" + }, + { + "label": "Daymar College-Lancaster" + }, + { + "label": "Daymar College-Louisville-Louisville" + }, + { + "label": "Daymar College-Madisonville" + }, + { + "label": "Daymar College-New Boston" + }, + { + "label": "Daymar College-Online" + }, + { + "label": "Daymar College-Owensboro" + }, + { + "label": "Daymar College-Paducah Main" + }, + { + "label": "Daymar Institute-Clarksville" + }, + { + "label": "Daymar Institute-Murfreesboro" + }, + { + "label": "Daymar Institute-Nashville" + }, + { + "label": "Daytona College" + }, + { + "label": "Daytona State College" + }, + { + "label": "De Anza College" + }, + { + "label": "Dean College" + }, + { + "label": "Dean Institute of Technology" + }, + { + "label": "Defiance College" + }, + { + "label": "Del Mar College" + }, + { + "label": "Delaware College of Art and Design" + }, + { + "label": "Delaware County Community College" + }, + { + "label": "Delaware State University" + }, + { + "label": "Delaware Technical Community College-Owens" + }, + { + "label": "Delaware Technical Community College-Stanton/Wilmington" + }, + { + "label": "Delaware Technical Community College-Terry" + }, + { + "label": "Delaware Valley University" + }, + { + "label": "Delgado Community College" + }, + { + "label": "Dell'Arte International School of Physical Theatre" + }, + { + "label": "Delta College" + }, + { + "label": "Delta College of Arts & Technology" + }, + { + "label": "Delta School of Business and Technology" + }, + { + "label": "Delta State University" + }, + { + "label": "Denison University" + }, + { + "label": "Denmark Technical College" + }, + { + "label": "Denver School of Nursing" + }, + { + "label": "Denver Seminary" + }, + { + "label": "DePaul University" + }, + { + "label": "DePauw University" + }, + { + "label": "Des Moines Area Community College" + }, + { + "label": "Des Moines University-Osteopathic Medical Center" + }, + { + "label": "DeSales University" + }, + { + "label": "Design Institute of San Diego" + }, + { + "label": "DeVry College of New York" + }, + { + "label": "DeVry University-Arizona" + }, + { + "label": "DeVry University-California" + }, + { + "label": "DeVry University-Colorado" + }, + { + "label": "DeVry University-Florida" + }, + { + "label": "DeVry University-Georgia" + }, + { + "label": "DeVry University-Illinois" + }, + { + "label": "DeVry University-Indiana" + }, + { + "label": "DeVry University-Maryland" + }, + { + "label": "DeVry University-Michigan" + }, + { + "label": "DeVry University-Minnesota" + }, + { + "label": "DeVry University-Missouri" + }, + { + "label": "DeVry University-Nevada" + }, + { + "label": "DeVry University-New Jersey" + }, + { + "label": "DeVry University-North Carolina" + }, + { + "label": "DeVry University-Ohio" + }, + { + "label": "DeVry University-Oklahoma" + }, + { + "label": "DeVry University-Oregon" + }, + { + "label": "DeVry University-Pennsylvania" + }, + { + "label": "DeVry University-Tennessee" + }, + { + "label": "DeVry University-Texas" + }, + { + "label": "DeVry University-Utah" + }, + { + "label": "DeVry University-Virginia" + }, + { + "label": "DeVry University-Washington" + }, + { + "label": "DeVry University-Wisconsin" + }, + { + "label": "Dewey University-Hato Rey-Hato Rey" + }, + { + "label": "Diablo Valley College" + }, + { + "label": "Dickinson College" + }, + { + "label": "Dickinson State University" + }, + { + "label": "DigiPen Institute of Technology" + }, + { + "label": "Digital Media Arts College" + }, + { + "label": "Dillard University" + }, + { + "label": "Dine College" + }, + { + "label": "Divine Word College" + }, + { + "label": "Dixie State University" + }, + { + "label": "Doane University-Arts & Sciences" + }, + { + "label": "Doane University-Graduate and Professional Studies" + }, + { + "label": "Dodge City Community College" + }, + { + "label": "Dominican College of Blauvelt" + }, + { + "label": "Dominican School of Philosophy & Theology" + }, + { + "label": "Dominican University" + }, + { + "label": "Dominican University of California" + }, + { + "label": "Dongguk University-Los Angeles" + }, + { + "label": "Donnelly College" + }, + { + "label": "Dordt College" + }, + { + "label": "Douglas Education Center" + }, + { + "label": "Dowling College" + }, + { + "label": "Drake University" + }, + { + "label": "Drew University" + }, + { + "label": "Drexel University" + }, + { + "label": "Drury University" + }, + { + "label": "Du Bois Business College-Du Bois" + }, + { + "label": "Du Bois Business College-Huntingdon" + }, + { + "label": "Du Bois Business College-Oil City" + }, + { + "label": "Duke University" + }, + { + "label": "Duluth Business University" + }, + { + "label": "Dunwoody College of Technology" + }, + { + "label": "Duquesne University" + }, + { + "label": "Durham Technical Community College" + }, + { + "label": "Dutchess Community College" + }, + { + "label": "Dyersburg State Community College" + }, + { + "label": "D'Youville College" + }, + { + "label": "Eagle Gate College-Layton" + }, + { + "label": "Eagle Gate College-Murray" + }, + { + "label": "Eagle Gate College-Salt Lake City" + }, + { + "label": "Earlham College" + }, + { + "label": "East Arkansas Community College" + }, + { + "label": "East Carolina University" + }, + { + "label": "East Central College" + }, + { + "label": "East Central Community College" + }, + { + "label": "East Central University" + }, + { + "label": "East Georgia State College" + }, + { + "label": "East Los Angeles College" + }, + { + "label": "East Mississippi Community College" + }, + { + "label": "East San Gabriel Valley Regional Occupational Program" + }, + { + "label": "East Stroudsburg University of Pennsylvania" + }, + { + "label": "East Tennessee State University" + }, + { + "label": "East Texas Baptist University" + }, + { + "label": "East West College of Natural Medicine" + }, + { + "label": "Eastern Arizona College" + }, + { + "label": "Eastern Connecticut State University" + }, + { + "label": "Eastern Florida State College" + }, + { + "label": "Eastern Gateway Community College" + }, + { + "label": "Eastern Idaho Technical College" + }, + { + "label": "Eastern Illinois University" + }, + { + "label": "Eastern International College-Belleville" + }, + { + "label": "Eastern International College-Jersey City" + }, + { + "label": "Eastern Iowa Community College District" + }, + { + "label": "Eastern Kentucky University" + }, + { + "label": "Eastern Maine Community College" + }, + { + "label": "Eastern Mennonite University" + }, + { + "label": "Eastern Michigan University" + }, + { + "label": "Eastern Nazarene College" + }, + { + "label": "Eastern New Mexico University-Main Campus" + }, + { + "label": "Eastern New Mexico University-Roswell Campus" + }, + { + "label": "Eastern New Mexico University-Ruidoso Campus" + }, + { + "label": "Eastern Oklahoma State College" + }, + { + "label": "Eastern Oregon University" + }, + { + "label": "Eastern Shore Community College" + }, + { + "label": "Eastern University" + }, + { + "label": "Eastern Virginia Career College" + }, + { + "label": "Eastern Virginia Medical School" + }, + { + "label": "Eastern Washington University" + }, + { + "label": "Eastern West Virginia Community and Technical College" + }, + { + "label": "Eastern Wyoming College" + }, + { + "label": "Eastfield College" + }, + { + "label": "East-West University" + }, + { + "label": "Eastwick College-Hackensack" + }, + { + "label": "Eastwick College-Ramsey" + }, + { + "label": "Ecclesia College" + }, + { + "label": "Eckerd College" + }, + { + "label": "Ecotech Institute" + }, + { + "label": "ECPI University" + }, + { + "label": "Ecumenical Theological Seminary" + }, + { + "label": "Eden Theological Seminary" + }, + { + "label": "Edgecombe Community College" + }, + { + "label": "Edgewood College" + }, + { + "label": "EDIC College" + }, + { + "label": "Edinboro University of Pennsylvania" + }, + { + "label": "Edison State Community College" + }, + { + "label": "Edmonds Community College" + }, + { + "label": "EDP Univeristy of Puerto Rico Inc-San Juan" + }, + { + "label": "EDP University of Puerto Rico Inc-San Sebastian" + }, + { + "label": "Edward Via College of Osteopathic Medicine" + }, + { + "label": "Edward Waters College" + }, + { + "label": "El Camino College-Compton Center" + }, + { + "label": "El Camino Community College District" + }, + { + "label": "El Centro College" + }, + { + "label": "El Paso Community College" + }, + { + "label": "Elgin Community College" + }, + { + "label": "Elizabeth City State University" + }, + { + "label": "Elizabethtown College" + }, + { + "label": "Elizabethtown College School of Continuing and Professional Studies" + }, + { + "label": "Elizabethtown Community and Technical College" + }, + { + "label": "Ellsworth Community College" + }, + { + "label": "Elmhurst College" + }, + { + "label": "Elmira Business Institute" + }, + { + "label": "Elmira College" + }, + { + "label": "Elon University" + }, + { + "label": "Embry-Riddle Aeronautical University-Daytona Beach" + }, + { + "label": "Embry-Riddle Aeronautical University-Prescott" + }, + { + "label": "Embry-Riddle Aeronautical University-Worldwide" + }, + { + "label": "Emerson College" + }, + { + "label": "Emmanuel Christian Seminary" + }, + { + "label": "Emmanuel College-Boston" + }, + { + "label": "Emmanuel College-Franklin Springs" + }, + { + "label": "Emmaus Bible College" + }, + { + "label": "Emory & Henry College" + }, + { + "label": "Emory University" + }, + { + "label": "Emperor's College of Traditional Oriental Medicine" + }, + { + "label": "Empire College" + }, + { + "label": "Emporia State University" + }, + { + "label": "Endicott College" + }, + { + "label": "Enterprise State Community College" + }, + { + "label": "Epic Bible College" + }, + { + "label": "Episcopal Divinity School" + }, + { + "label": "Episcopal Theological Seminary of the Southwest" + }, + { + "label": "Erie Community College" + }, + { + "label": "Erie Institute of Technology Inc" + }, + { + "label": "Erikson Institute" + }, + { + "label": "Erskine College" + }, + { + "label": "Escuela de Artes Plasticas de Puerto Rico" + }, + { + "label": "Essex County College" + }, + { + "label": "Estrella Mountain Community College" + }, + { + "label": "ETI Technical College" + }, + { + "label": "Eureka College" + }, + { + "label": "Evangel University" + }, + { + "label": "Evangelical Theological Seminary" + }, + { + "label": "Everest College-Anaheim" + }, + { + "label": "Everest College-Arlington" + }, + { + "label": "Everest College-Aurora" + }, + { + "label": "Everest College-Bremerton" + }, + { + "label": "Everest College-Chesapeake" + }, + { + "label": "Everest College-City of Industry" + }, + { + "label": "Everest College-Colorado Springs" + }, + { + "label": "Everest College-Dallas" + }, + { + "label": "Everest College-Everett" + }, + { + "label": "Everest College-Fort Worth" + }, + { + "label": "Everest College-Fort Worth South" + }, + { + "label": "Everest College-Henderson" + }, + { + "label": "Everest College-McLean" + }, + { + "label": "Everest College-Mesa" + }, + { + "label": "Everest College-Newport News" + }, + { + "label": "Everest College-Ontario Metro" + }, + { + "label": "Everest College-Phoenix" + }, + { + "label": "Everest College-Portland" + }, + { + "label": "Everest College-Reseda" + }, + { + "label": "Everest College-Salt Lake City" + }, + { + "label": "Everest College-San Bernardino" + }, + { + "label": "Everest College-Springfield" + }, + { + "label": "Everest College-Tacoma" + }, + { + "label": "Everest College-Thornton" + }, + { + "label": "Everest College-Vancouver" + }, + { + "label": "Everest College-West Los Angeles" + }, + { + "label": "Everest Institute-Cross Lanes" + }, + { + "label": "Everest Institute-Kendall" + }, + { + "label": "Everest Institute-Norcross" + }, + { + "label": "Everest Institute-North Miami" + }, + { + "label": "Everest Institute-Pittsburgh" + }, + { + "label": "Everest Institute-Rochester" + }, + { + "label": "Everest University-Brandon" + }, + { + "label": "Everest University-Jacksonville" + }, + { + "label": "Everest University-Lakeland" + }, + { + "label": "Everest University-Largo" + }, + { + "label": "Everest University-Melbourne" + }, + { + "label": "Everest University-North Orlando" + }, + { + "label": "Everest University-Orange Park" + }, + { + "label": "Everest University-Pompano Beach" + }, + { + "label": "Everest University-South Orlando" + }, + { + "label": "Everest University-Tampa" + }, + { + "label": "Everett Community College" + }, + { + "label": "Everglades University" + }, + { + "label": "Evergreen Valley College" + }, + { + "label": "Excelsior College" + }, + { + "label": "Expression College for Digital Arts" + }, + { + "label": "Fairfield University" + }, + { + "label": "Fairleigh Dickinson University-College at Florham" + }, + { + "label": "Fairleigh Dickinson University-Metropolitan Campus" + }, + { + "label": "Fairmont State University" + }, + { + "label": "Faith Baptist Bible College and Theological Seminary" + }, + { + "label": "Faith Evangelical College & Seminary" + }, + { + "label": "Faith Theological Seminary" + }, + { + "label": "Family of Faith College" + }, + { + "label": "Farmingdale State College" + }, + { + "label": "Fashion Institute of Design & Merchandising-Los Angeles" + }, + { + "label": "Fashion Institute of Design & Merchandising-San Diego" + }, + { + "label": "Fashion Institute of Design & Merchandising-San Francisco" + }, + { + "label": "Fashion Institute of Technology" + }, + { + "label": "Faulkner University" + }, + { + "label": "Fayetteville State University" + }, + { + "label": "Fayetteville Technical Community College" + }, + { + "label": "Feather River Community College District" + }, + { + "label": "Felician University" + }, + { + "label": "Ferris State University" + }, + { + "label": "Ferrum College" + }, + { + "label": "Fielding Graduate University" + }, + { + "label": "FINE Mortuary College" + }, + { + "label": "Finger Lakes Community College" + }, + { + "label": "Finger Lakes Health College of Nursing" + }, + { + "label": "Finlandia University" + }, + { + "label": "Fisher College" + }, + { + "label": "Fisk University" + }, + { + "label": "Fitchburg State University" + }, + { + "label": "Five Branches University" + }, + { + "label": "Five Towns College" + }, + { + "label": "Flagler College-St Augustine" + }, + { + "label": "Flagler College-Tallahassee" + }, + { + "label": "Flathead Valley Community College" + }, + { + "label": "Fletcher Technical Community College" + }, + { + "label": "Flint Hills Technical College" + }, + { + "label": "Florence-Darlington Technical College" + }, + { + "label": "Florida Agricultural and Mechanical University" + }, + { + "label": "Florida Atlantic University" + }, + { + "label": "Florida Career College-Miami" + }, + { + "label": "Florida Coastal School of Law" + }, + { + "label": "Florida College" + }, + { + "label": "Florida College of Integrative Medicine" + }, + { + "label": "Florida College of Natural Health-Bradenton" + }, + { + "label": "Florida College of Natural Health-Maitland" + }, + { + "label": "Florida College of Natural Health-Miami" + }, + { + "label": "Florida College of Natural Health-Pompano Beach" + }, + { + "label": "Florida Gateway College" + }, + { + "label": "Florida Gulf Coast University" + }, + { + "label": "Florida Institute of Technology" + }, + { + "label": "Florida Institute of Technology-Online" + }, + { + "label": "Florida International University" + }, + { + "label": "Florida Keys Community College" + }, + { + "label": "Florida Memorial University" + }, + { + "label": "Florida National University-Main Campus" + }, + { + "label": "Florida Southern College" + }, + { + "label": "Florida SouthWestern State College" + }, + { + "label": "Florida State College at Jacksonville" + }, + { + "label": "Florida State University" + }, + { + "label": "Florida Technical College" + }, + { + "label": "Folsom Lake College" + }, + { + "label": "Fond du Lac Tribal and Community College" + }, + { + "label": "Fontbonne University" + }, + { + "label": "Foothill College" + }, + { + "label": "Fordham University" + }, + { + "label": "Forest Institute of Professional Psychology" + }, + { + "label": "Forrest College" + }, + { + "label": "Forsyth Technical Community College" + }, + { + "label": "Fort Hays State University" + }, + { + "label": "Fort Lewis College" + }, + { + "label": "Fort Peck Community College" + }, + { + "label": "Fort Scott Community College" + }, + { + "label": "Fort Valley State University" + }, + { + "label": "Fortis College-Baton Rouge" + }, + { + "label": "Fortis College-Centerville" + }, + { + "label": "Fortis College-Cincinnati" + }, + { + "label": "Fortis College-Columbia" + }, + { + "label": "Fortis College-Columbus" + }, + { + "label": "Fortis College-Cutler Bay" + }, + { + "label": "Fortis College-Cuyahoga Falls" + }, + { + "label": "Fortis College-Indianapolis" + }, + { + "label": "Fortis College-Landover" + }, + { + "label": "Fortis College-Largo" + }, + { + "label": "Fortis College-Mobile" + }, + { + "label": "Fortis College-Montgomery-Montgomery" + }, + { + "label": "Fortis College-Norfolk" + }, + { + "label": "Fortis College-Orange Park" + }, + { + "label": "Fortis College-Phoenix" + }, + { + "label": "Fortis College-Ravenna" + }, + { + "label": "Fortis College-Richmond" + }, + { + "label": "Fortis College-Salt Lake City" + }, + { + "label": "Fortis College-Smyrna" + }, + { + "label": "Fortis College-Winter Park" + }, + { + "label": "Fortis Institute" + }, + { + "label": "Fortis Institute-Birmingham" + }, + { + "label": "Fortis Institute-Cookeville" + }, + { + "label": "Fortis Institute-Erie" + }, + { + "label": "Fortis Institute-Fort Lauderdale" + }, + { + "label": "Fortis Institute-Forty Fort" + }, + { + "label": "Fortis Institute-Miami" + }, + { + "label": "Fortis Institute-Nashville" + }, + { + "label": "Fortis Institute-Pensacola" + }, + { + "label": "Fortis Institute-Port Saint Lucie" + }, + { + "label": "Fortis Institute-Scranton" + }, + { + "label": "Fountainhead College of Technology" + }, + { + "label": "Four-D College" + }, + { + "label": "Fox College" + }, + { + "label": "Fox Valley Technical College" + }, + { + "label": "Framingham State University" + }, + { + "label": "Francis Marion University" + }, + { + "label": "Franciscan School of Theology" + }, + { + "label": "Franciscan University of Steubenville" + }, + { + "label": "Frank Lloyd Wright School of Architecture" + }, + { + "label": "Frank Phillips College" + }, + { + "label": "Franklin and Marshall College" + }, + { + "label": "Franklin College" + }, + { + "label": "Franklin Pierce University" + }, + { + "label": "Franklin University" + }, + { + "label": "Franklin W Olin College of Engineering" + }, + { + "label": "Frederick Community College" + }, + { + "label": "Freed-Hardeman University" + }, + { + "label": "Fremont College" + }, + { + "label": "Fresno City College" + }, + { + "label": "Fresno Pacific University" + }, + { + "label": "Friends University" + }, + { + "label": "Front Range Community College" + }, + { + "label": "Frontier Community College" + }, + { + "label": "Frontier Nursing University" + }, + { + "label": "Frostburg State University" + }, + { + "label": "Full Sail University" + }, + { + "label": "Fuller Theological Seminary in California" + }, + { + "label": "Fullerton College" + }, + { + "label": "Fulton-Montgomery Community College" + }, + { + "label": "Furman University" + }, + { + "label": "Future Generations Graduate School" + }, + { + "label": "Gadsden State Community College" + }, + { + "label": "Galen College of Nursing-Cincinnati" + }, + { + "label": "Galen College of Nursing-Louisville" + }, + { + "label": "Galen College of Nursing-San Antonio" + }, + { + "label": "Galen College of Nursing-Tampa Bay" + }, + { + "label": "Gallaudet University" + }, + { + "label": "Gallipolis Career College" + }, + { + "label": "Galveston College" + }, + { + "label": "Gannon University" + }, + { + "label": "Garden City Community College" + }, + { + "label": "Gardner-Webb University" + }, + { + "label": "Garrett College" + }, + { + "label": "Garrett-Evangelical Theological Seminary" + }, + { + "label": "Gaston College" + }, + { + "label": "Gateway Community and Technical College" + }, + { + "label": "Gateway Community College-New Haven" + }, + { + "label": "GateWay Community College-Phoenix" + }, + { + "label": "Gateway Technical College" + }, + { + "label": "Gavilan College" + }, + { + "label": "Genesee Community College" + }, + { + "label": "Geneva College" + }, + { + "label": "George C Wallace State Community College-Dothan" + }, + { + "label": "George C Wallace State Community College-Hanceville" + }, + { + "label": "George C Wallace State Community College-Selma" + }, + { + "label": "George Fox University" + }, + { + "label": "George Mason University" + }, + { + "label": "George Washington University" + }, + { + "label": "Georgetown College" + }, + { + "label": "Georgetown University" + }, + { + "label": "Georgia Christian University" + }, + { + "label": "Georgia College and State University" + }, + { + "label": "Georgia Gwinnett College" + }, + { + "label": "Georgia Highlands College" + }, + { + "label": "Georgia Institute of Technology-Main Campus" + }, + { + "label": "Georgia Military College-Milledgeville" + }, + { + "label": "Georgia Northwestern Technical College" + }, + { + "label": "Georgia Perimeter College" + }, + { + "label": "Georgia Piedmont Technical College" + }, + { + "label": "Georgia Southern University" + }, + { + "label": "Georgia Southwestern State University" + }, + { + "label": "Georgia State University" + }, + { + "label": "Georgian Court University" + }, + { + "label": "Germanna Community College" + }, + { + "label": "Gettysburg College" + }, + { + "label": "Glen Oaks Community College" + }, + { + "label": "Glendale Community College-Glendale" + }, + { + "label": "Glendale Community College-Glendale" + }, + { + "label": "Glenville State College" + }, + { + "label": "Global Health College" + }, + { + "label": "Globe Institute of Technology" + }, + { + "label": "Globe University-Appleton" + }, + { + "label": "Globe University-Eau Claire" + }, + { + "label": "Globe University–Green Bay" + }, + { + "label": "Globe University-La Crosse" + }, + { + "label": "Globe University-Madison East" + }, + { + "label": "Globe University–Madison West" + }, + { + "label": "Globe University-Minneapolis" + }, + { + "label": "Globe University-Sioux Falls" + }, + { + "label": "Globe University–Wausau" + }, + { + "label": "Globe University-Woodbury" + }, + { + "label": "Goddard College" + }, + { + "label": "Gods Bible School and College" + }, + { + "label": "Gogebic Community College" + }, + { + "label": "Golden Gate University-San Francisco" + }, + { + "label": "Golden West College" + }, + { + "label": "Goldey-Beacom College" + }, + { + "label": "Golf Academy of America-Altamonte Springs" + }, + { + "label": "Golf Academy of America-Carlsbad" + }, + { + "label": "Golf Academy of America-Farmers Branch" + }, + { + "label": "Golf Academy of America-Myrtle Beach" + }, + { + "label": "Golf Academy of America-Phoenix" + }, + { + "label": "Gonzaga University" + }, + { + "label": "Good Samaritan College of Nursing and Health Science" + }, + { + "label": "Gooding Institute of Nurse Anesthesia" + }, + { + "label": "Goodwin College" + }, + { + "label": "Gordon College" + }, + { + "label": "Gordon State College" + }, + { + "label": "Gordon-Conwell Theological Seminary" + }, + { + "label": "Goshen College" + }, + { + "label": "Goucher College" + }, + { + "label": "Governors State University" + }, + { + "label": "Grace Bible College" + }, + { + "label": "Grace College and Theological Seminary" + }, + { + "label": "Grace College of Divinity" + }, + { + "label": "Grace Mission University" + }, + { + "label": "Grace School of Theology" + }, + { + "label": "Grace University" + }, + { + "label": "Graceland University-Lamoni" + }, + { + "label": "Graduate School USA" + }, + { + "label": "Graduate Theological Union" + }, + { + "label": "Grambling State University" + }, + { + "label": "Grand Canyon University" + }, + { + "label": "Grand Rapids Community College" + }, + { + "label": "Grand Valley State University" + }, + { + "label": "Grand View University" + }, + { + "label": "Granite State College" + }, + { + "label": "Grantham University" + }, + { + "label": "Gratz College" + }, + { + "label": "Grays Harbor College" + }, + { + "label": "Grayson College" + }, + { + "label": "Great Basin College" + }, + { + "label": "Great Bay Community College" + }, + { + "label": "Great Falls College Montana State University" + }, + { + "label": "Great Lakes Christian College" + }, + { + "label": "Great Lakes Institute of Technology" + }, + { + "label": "Green Mountain College" + }, + { + "label": "Green River College" + }, + { + "label": "Greenfield Community College" + }, + { + "label": "Greensboro College" + }, + { + "label": "Greenville College" + }, + { + "label": "Greenville Technical College" + }, + { + "label": "Grinnell College" + }, + { + "label": "Grossmont College" + }, + { + "label": "Grove City College" + }, + { + "label": "Guam Community College" + }, + { + "label": "Guilford College" + }, + { + "label": "Guilford Technical Community College" + }, + { + "label": "Gulf Coast State College" + }, + { + "label": "Gupton Jones College of Funeral Service" + }, + { + "label": "Gustavus Adolphus College" + }, + { + "label": "Gwinnett College-Lilburn" + }, + { + "label": "Gwinnett Technical College" + }, + { + "label": "Gwynedd Mercy University" + }, + { + "label": "H Councill Trenholm State Community College" + }, + { + "label": "Hagerstown Community College" + }, + { + "label": "Halifax Community College" + }, + { + "label": "Hallmark University" + }, + { + "label": "Hamilton College" + }, + { + "label": "Hamilton Technical College" + }, + { + "label": "Hamline University" + }, + { + "label": "Hampden-Sydney College" + }, + { + "label": "Hampshire College" + }, + { + "label": "Hampton University" + }, + { + "label": "Hannibal-LaGrange University" + }, + { + "label": "Hanover College" + }, + { + "label": "Harcum College" + }, + { + "label": "Harding University" + }, + { + "label": "Hardin-Simmons University" + }, + { + "label": "Harford Community College" + }, + { + "label": "Harrington College of Design" + }, + { + "label": "Harrisburg Area Community College-Harrisburg" + }, + { + "label": "Harrisburg University of Science and Technology" + }, + { + "label": "Harrison College-Grove City" + }, + { + "label": "Harrison College-Indianapolis" + }, + { + "label": "Harrison College-Morrisville" + }, + { + "label": "Harris-Stowe State University" + }, + { + "label": "Hartford Seminary" + }, + { + "label": "Hartnell College" + }, + { + "label": "Hartwick College" + }, + { + "label": "Harvard University" + }, + { + "label": "Harvey Mudd College" + }, + { + "label": "Haskell Indian Nations University" + }, + { + "label": "Hastings College" + }, + { + "label": "Haverford College" + }, + { + "label": "Hawaii Community College" + }, + { + "label": "Hawaii Pacific University" + }, + { + "label": "Hawkeye Community College" + }, + { + "label": "Haywood Community College" + }, + { + "label": "Hazard Community and Technical College" + }, + { + "label": "Hazelden Betty Ford Graduate School of Addiction Studies" + }, + { + "label": "Heald College-Concord" + }, + { + "label": "Heald College-Fresno" + }, + { + "label": "Heald College-Hayward" + }, + { + "label": "Heald College-Honolulu" + }, + { + "label": "Heald College-Modesto" + }, + { + "label": "Heald College-Portland" + }, + { + "label": "Heald College-Rancho Cordova" + }, + { + "label": "Heald College-Roseville" + }, + { + "label": "Heald College-Salinas" + }, + { + "label": "Heald College-San Francisco" + }, + { + "label": "Heald College-San Jose" + }, + { + "label": "Heald College-Stockton" + }, + { + "label": "Heartland Community College" + }, + { + "label": "Hebrew College" + }, + { + "label": "Hebrew Theological College" + }, + { + "label": "Hebrew Union College-Jewish Institute of Religion" + }, + { + "label": "Heidelberg University" + }, + { + "label": "Helena College University of Montana" + }, + { + "label": "Helene Fuld College of Nursing" + }, + { + "label": "Hellenic College-Holy Cross Greek Orthodox School of Theology" + }, + { + "label": "Henderson Community College" + }, + { + "label": "Henderson State University" + }, + { + "label": "Hendrix College" + }, + { + "label": "Hennepin Technical College" + }, + { + "label": "Henry Ford College" + }, + { + "label": "Heritage Bible College" + }, + { + "label": "Heritage Christian University" + }, + { + "label": "Heritage College-Denver" + }, + { + "label": "Heritage College-Kansas City" + }, + { + "label": "Heritage College-Oklahoma City" + }, + { + "label": "Heritage College-Wichita" + }, + { + "label": "Heritage Institute-Ft Myers" + }, + { + "label": "Heritage Institute-Jacksonville" + }, + { + "label": "Heritage University" + }, + { + "label": "Herkimer County Community College" + }, + { + "label": "Herzing University-Atlanta" + }, + { + "label": "Herzing University-Birmingham" + }, + { + "label": "Herzing University-Brookfield" + }, + { + "label": "Herzing University-Kenner" + }, + { + "label": "Herzing University-Kenosha" + }, + { + "label": "Herzing University-Madison" + }, + { + "label": "Herzing University-Minneapolis" + }, + { + "label": "Herzing University-Toledo" + }, + { + "label": "Herzing University-Winter Park" + }, + { + "label": "Hesston College" + }, + { + "label": "Hibbing Community College" + }, + { + "label": "Hickey College" + }, + { + "label": "High Point University" + }, + { + "label": "Highland Community College-Freeport" + }, + { + "label": "Highland Community College-Highland" + }, + { + "label": "Highlands College of Montana Tech" + }, + { + "label": "Highline College" + }, + { + "label": "Hilbert College" + }, + { + "label": "Hill College" + }, + { + "label": "Hillsborough Community College" + }, + { + "label": "Hillsdale College" + }, + { + "label": "Hillsdale Free Will Baptist College" + }, + { + "label": "Hinds Community College" + }, + { + "label": "Hiram College" + }, + { + "label": "Hiwassee College" + }, + { + "label": "Hobart William Smith Colleges" + }, + { + "label": "Hobe Sound Bible College" + }, + { + "label": "Hocking College" + }, + { + "label": "Hodges University" + }, + { + "label": "Hofstra University" + }, + { + "label": "Hollins University" + }, + { + "label": "Holmes Community College" + }, + { + "label": "Holy Apostles College and Seminary" + }, + { + "label": "Holy Cross College" + }, + { + "label": "Holy Family University" + }, + { + "label": "Holy Names University" + }, + { + "label": "Holyoke Community College" + }, + { + "label": "Hondros College" + }, + { + "label": "Honolulu Community College" + }, + { + "label": "Hood College" + }, + { + "label": "Hood Theological Seminary" + }, + { + "label": "Hope College" + }, + { + "label": "Hope International University" + }, + { + "label": "Hopkinsville Community College" + }, + { + "label": "Horizon University" + }, + { + "label": "Horry-Georgetown Technical College" + }, + { + "label": "Houghton College" + }, + { + "label": "Housatonic Community College" + }, + { + "label": "Houston Baptist University" + }, + { + "label": "Houston Community College" + }, + { + "label": "Houston Graduate School of Theology" + }, + { + "label": "Howard College" + }, + { + "label": "Howard Community College" + }, + { + "label": "Howard Payne University" + }, + { + "label": "Howard University" + }, + { + "label": "Hudson County Community College" + }, + { + "label": "Hudson Valley Community College" + }, + { + "label": "Huertas College" + }, + { + "label": "Hult International Business School" + }, + { + "label": "Humacao Community College" + }, + { + "label": "Humboldt State University" + }, + { + "label": "Humphreys College-Stockton and Modesto Campuses" + }, + { + "label": "Huntingdon College" + }, + { + "label": "Huntington Junior College" + }, + { + "label": "Huntington University" + }, + { + "label": "Huntsville Bible College" + }, + { + "label": "Hussian College School of Art" + }, + { + "label": "Husson University" + }, + { + "label": "Huston-Tillotson University" + }, + { + "label": "Hutchinson Community College" + }, + { + "label": "IBMC College" + }, + { + "label": "IBMC College" + }, + { + "label": "Icahn School of Medicine at Mount Sinai" + }, + { + "label": "ICDC College" + }, + { + "label": "ICPR Junior College-Arecibo" + }, + { + "label": "ICPR Junior College-General Institutional" + }, + { + "label": "ICPR Junior College-Manati" + }, + { + "label": "ICPR Junior College-Mayaguez" + }, + { + "label": "Idaho State University" + }, + { + "label": "IGlobal University" + }, + { + "label": "Iliff School of Theology" + }, + { + "label": "Ilisagvik College" + }, + { + "label": "Illinois Central College" + }, + { + "label": "Illinois College" + }, + { + "label": "Illinois College of Optometry" + }, + { + "label": "Illinois Institute of Technology" + }, + { + "label": "Illinois State University" + }, + { + "label": "Illinois Valley Community College" + }, + { + "label": "Illinois Wesleyan University" + }, + { + "label": "Immaculata University" + }, + { + "label": "Imperial Valley College" + }, + { + "label": "Independence Community College" + }, + { + "label": "Independence University" + }, + { + "label": "Indian Hills Community College" + }, + { + "label": "Indian River State College" + }, + { + "label": "Indiana Institute of Technology" + }, + { + "label": "Indiana State University" + }, + { + "label": "Indiana University of Pennsylvania-Main Campus" + }, + { + "label": "Indiana University-Bloomington" + }, + { + "label": "Indiana University-East" + }, + { + "label": "Indiana University-Kokomo" + }, + { + "label": "Indiana University-Northwest" + }, + { + "label": "Indiana University-Purdue University-Fort Wayne" + }, + { + "label": "Indiana University-Purdue University-Indianapolis" + }, + { + "label": "Indiana University-South Bend" + }, + { + "label": "Indiana University-Southeast" + }, + { + "label": "Indiana Wesleyan University" + }, + { + "label": "Institute for Clinical Social Work" + }, + { + "label": "Institute for Doctoral Studies in the Visual Arts" + }, + { + "label": "Institute for the Psychological Sciences" + }, + { + "label": "Institute of American Indian and Alaska Native Culture" + }, + { + "label": "Institute of Clinical Acupuncture & Oriental Med" + }, + { + "label": "Institute of Design and Construction" + }, + { + "label": "Institute of Production and Recording" + }, + { + "label": "Institute of Taoist Education and Acupuncture" + }, + { + "label": "Institute of Technology Inc-Clovis" + }, + { + "label": "Institute of World Politics" + }, + { + "label": "Instituto de Banca y Comercio Inc" + }, + { + "label": "Instituto Tecnologico de Puerto Rico-Recinto de Guayama" + }, + { + "label": "Instituto Tecnologico de Puerto Rico-Recinto de Manati" + }, + { + "label": "Instituto Tecnologico de Puerto Rico-Recinto de Ponce" + }, + { + "label": "Instituto Tecnologico de Puerto Rico-Recinto de San Juan" + }, + { + "label": "Intellitec College-Colorado Springs" + }, + { + "label": "Intellitec College-Grand Junction" + }, + { + "label": "Inter American University of Puerto Rico-Aguadilla" + }, + { + "label": "Inter American University of Puerto Rico-Arecibo" + }, + { + "label": "Inter American University of Puerto Rico-Barranquitas" + }, + { + "label": "Inter American University of Puerto Rico-Bayamon" + }, + { + "label": "Inter American University of Puerto Rico-Fajardo" + }, + { + "label": "Inter American University of Puerto Rico-Guayama" + }, + { + "label": "Inter American University of Puerto Rico-Metro" + }, + { + "label": "Inter American University of Puerto Rico-Ponce" + }, + { + "label": "Inter American University of Puerto Rico-San German" + }, + { + "label": "Inter American University of Puerto Rico-School of Law" + }, + { + "label": "Inter American University of Puerto Rico-School of Optometry" + }, + { + "label": "Interactive College of Technology-Chamblee" + }, + { + "label": "Interactive College of Technology-Gainesville" + }, + { + "label": "Interactive College of Technology-Houston" + }, + { + "label": "Interactive College of Technology-Houston" + }, + { + "label": "Interactive College of Technology-Morrow" + }, + { + "label": "Interactive College of Technology-Newport" + }, + { + "label": "Interactive College of Technology-Pasadena" + }, + { + "label": "InterCoast Colleges-Orange" + }, + { + "label": "Interdenominational Theological Center" + }, + { + "label": "Interface College-Spokane" + }, + { + "label": "Interior Designers Institute" + }, + { + "label": "International Academy of Design and Technology-Nashville" + }, + { + "label": "International Academy of Design and Technology-Sacramento" + }, + { + "label": "International Academy of Design and Technology-Troy" + }, + { + "label": "International Baptist College and Seminary" + }, + { + "label": "International Business College-El Paso-El Paso" + }, + { + "label": "International Business College-El Paso-El Paso" + }, + { + "label": "International Business College-Fort Wayne" + }, + { + "label": "International Business College-Indianapolis" + }, + { + "label": "International College of Broadcasting" + }, + { + "label": "International Institute for Restorative Practices" + }, + { + "label": "International Professional School of Bodywork" + }, + { + "label": "International Technological University" + }, + { + "label": "Inver Hills Community College" + }, + { + "label": "Iona College" + }, + { + "label": "Iowa Central Community College" + }, + { + "label": "Iowa Lakes Community College" + }, + { + "label": "Iowa State University" + }, + { + "label": "Iowa Wesleyan University" + }, + { + "label": "Iowa Western Community College" + }, + { + "label": "Irell & Manella Graduate School of Biological Sciences at City of Hope" + }, + { + "label": "Irvine Valley College" + }, + { + "label": "Island Drafting and Technical Institute" + }, + { + "label": "Isothermal Community College" + }, + { + "label": "Itasca Community College" + }, + { + "label": "Itawamba Community College" + }, + { + "label": "Ithaca College" + }, + { + "label": "ITI Technical College" + }, + { + "label": "ITT Technical Institute-Akron" + }, + { + "label": "ITT Technical Institute-Albany" + }, + { + "label": "ITT Technical Institute-Albuquerque" + }, + { + "label": "ITT Technical Institute-Arlington" + }, + { + "label": "ITT Technical Institute-Arlington Heights" + }, + { + "label": "ITT Technical Institute-Arnold" + }, + { + "label": "ITT Technical Institute-Atlanta" + }, + { + "label": "ITT Technical Institute-Aurora" + }, + { + "label": "ITT Technical Institute-Austin" + }, + { + "label": "ITT Technical Institute-Baton Rouge" + }, + { + "label": "ITT Technical Institute-Bessemer" + }, + { + "label": "ITT Technical Institute-Boise" + }, + { + "label": "ITT Technical Institute-Bradenton" + }, + { + "label": "ITT Technical Institute-Brooklyn Center" + }, + { + "label": "ITT Technical Institute-Canton" + }, + { + "label": "ITT Technical Institute-Cary" + }, + { + "label": "ITT Technical Institute-Chantilly" + }, + { + "label": "ITT Technical Institute-Charlotte North" + }, + { + "label": "ITT Technical Institute-Charlotte South" + }, + { + "label": "ITT Technical Institute-Chattanooga" + }, + { + "label": "ITT Technical Institute-Clive" + }, + { + "label": "ITT Technical Institute-Clovis" + }, + { + "label": "ITT Technical Institute-Columbia" + }, + { + "label": "ITT Technical Institute-Columbus" + }, + { + "label": "ITT Technical Institute-Concord" + }, + { + "label": "ITT Technical Institute-Cordova" + }, + { + "label": "ITT Technical Institute-Corona" + }, + { + "label": "ITT Technical Institute-Culver City" + }, + { + "label": "ITT Technical Institute-Dayton" + }, + { + "label": "ITT Technical Institute-Dearborn" + }, + { + "label": "ITT Technical Institute-Deerfield Beach" + }, + { + "label": "ITT Technical Institute-DeSoto" + }, + { + "label": "ITT Technical Institute-Douglasville" + }, + { + "label": "ITT Technical Institute-Duluth" + }, + { + "label": "ITT Technical Institute-Dunmore" + }, + { + "label": "ITT Technical Institute-Durham" + }, + { + "label": "ITT Technical Institute-Earth City" + }, + { + "label": "ITT Technical Institute-Eden Prairie" + }, + { + "label": "ITT Technical Institute-Everett" + }, + { + "label": "ITT Technical Institute-Fort Lauderdale" + }, + { + "label": "ITT Technical Institute-Fort Myers" + }, + { + "label": "ITT Technical Institute-Fort Wayne" + }, + { + "label": "ITT Technical Institute-Germantown" + }, + { + "label": "ITT Technical Institute-Getzville" + }, + { + "label": "ITT Technical Institute-Green Bay" + }, + { + "label": "ITT Technical Institute-Greenfield" + }, + { + "label": "ITT Technical Institute-Greenville" + }, + { + "label": "ITT Technical Institute-Hanover" + }, + { + "label": "ITT Technical Institute-Harrisburg" + }, + { + "label": "ITT Technical Institute-Henderson" + }, + { + "label": "ITT Technical Institute-Hialeah" + }, + { + "label": "ITT Technical Institute-High Point" + }, + { + "label": "ITT Technical Institute-Hilliard" + }, + { + "label": "ITT Technical Institute-Houston North" + }, + { + "label": "ITT Technical Institute-Houston West" + }, + { + "label": "ITT Technical Institute-Huntington" + }, + { + "label": "ITT Technical Institute-Indianapolis" + }, + { + "label": "ITT Technical Institute-Indianapolis East" + }, + { + "label": "ITT Technical Institute-Jacksonville" + }, + { + "label": "ITT Technical Institute-Johnson City" + }, + { + "label": "ITT Technical Institute-Kansas City" + }, + { + "label": "ITT Technical Institute-Kennesaw" + }, + { + "label": "ITT Technical Institute-Knoxville" + }, + { + "label": "ITT Technical Institute-Lake Mary" + }, + { + "label": "ITT Technical Institute-Las Vegas" + }, + { + "label": "ITT Technical Institute-Lathrop" + }, + { + "label": "ITT Technical Institute-Levittown" + }, + { + "label": "ITT Technical Institute-Lexington" + }, + { + "label": "ITT Technical Institute-Little Rock" + }, + { + "label": "ITT Technical Institute-Liverpool" + }, + { + "label": "ITT Technical Institute-Louisville" + }, + { + "label": "ITT Technical Institute-Madison-Madison" + }, + { + "label": "ITT Technical Institute-Madison-Madison" + }, + { + "label": "ITT Technical Institute-Madison-Madison" + }, + { + "label": "ITT Technical Institute-Marlton" + }, + { + "label": "ITT Technical Institute-Maumee" + }, + { + "label": "ITT Technical Institute-Merrillville" + }, + { + "label": "ITT Technical Institute-Mobile" + }, + { + "label": "ITT Technical Institute-Murray" + }, + { + "label": "ITT Technical Institute-Myrtle Beach" + }, + { + "label": "ITT Technical Institute-Nashville" + }, + { + "label": "ITT Technical Institute-National City" + }, + { + "label": "ITT Technical Institute-Newburgh" + }, + { + "label": "ITT Technical Institute-Norfolk" + }, + { + "label": "ITT Technical Institute-North Charleston" + }, + { + "label": "ITT Technical Institute-Norwood-Norwood" + }, + { + "label": "ITT Technical Institute-Norwood-Norwood" + }, + { + "label": "ITT Technical Institute-Oak Brook" + }, + { + "label": "ITT Technical Institute-Oakland" + }, + { + "label": "ITT Technical Institute-Oklahoma City" + }, + { + "label": "ITT Technical Institute-Omaha" + }, + { + "label": "ITT Technical Institute-Orange" + }, + { + "label": "ITT Technical Institute-Orland Park" + }, + { + "label": "ITT Technical Institute-Orlando" + }, + { + "label": "ITT Technical Institute-Overland Park" + }, + { + "label": "ITT Technical Institute-Owings Mills" + }, + { + "label": "ITT Technical Institute-Oxnard" + }, + { + "label": "ITT Technical Institute-Philadelphia" + }, + { + "label": "ITT Technical Institute-Phoenix" + }, + { + "label": "ITT Technical Institute-Phoenix West" + }, + { + "label": "ITT Technical Institute-Pittsburgh" + }, + { + "label": "ITT Technical Institute-Plymouth Meeting" + }, + { + "label": "ITT Technical Institute-Portland" + }, + { + "label": "ITT Technical Institute-Rancho Cordova" + }, + { + "label": "ITT Technical Institute-Richardson" + }, + { + "label": "ITT Technical Institute-Richmond" + }, + { + "label": "ITT Technical Institute-Saint Rose" + }, + { + "label": "ITT Technical Institute-Salem-Salem" + }, + { + "label": "ITT Technical Institute-Salem-Salem" + }, + { + "label": "ITT Technical Institute-San Antonio" + }, + { + "label": "ITT Technical Institute-San Antonio East" + }, + { + "label": "ITT Technical Institute-San Bernardino" + }, + { + "label": "ITT Technical Institute-San Dimas" + }, + { + "label": "ITT Technical Institute-Seattle" + }, + { + "label": "ITT Technical Institute-South Bend" + }, + { + "label": "ITT Technical Institute-Southfield" + }, + { + "label": "ITT Technical Institute-Spokane Valley" + }, + { + "label": "ITT Technical Institute-Springfield-Springfield" + }, + { + "label": "ITT Technical Institute-Springfield-Springfield" + }, + { + "label": "ITT Technical Institute-Springfield-Springfield" + }, + { + "label": "ITT Technical Institute-St Petersburg" + }, + { + "label": "ITT Technical Institute-Strongsville" + }, + { + "label": "ITT Technical Institute-Swartz Creek" + }, + { + "label": "ITT Technical Institute-Sylmar" + }, + { + "label": "ITT Technical Institute-Tallahassee" + }, + { + "label": "ITT Technical Institute-Tampa" + }, + { + "label": "ITT Technical Institute-Tarentum" + }, + { + "label": "ITT Technical Institute-Tempe" + }, + { + "label": "ITT Technical Institute-Torrance" + }, + { + "label": "ITT Technical Institute-Troy" + }, + { + "label": "ITT Technical Institute-Tucson" + }, + { + "label": "ITT Technical Institute-Tulsa" + }, + { + "label": "ITT Technical Institute-Waco" + }, + { + "label": "ITT Technical Institute-Warrensville Heights" + }, + { + "label": "ITT Technical Institute-Webster" + }, + { + "label": "ITT Technical Institute-West Chester" + }, + { + "label": "ITT Technical Institute-West Covina" + }, + { + "label": "ITT Technical Institute-West Palm Beach" + }, + { + "label": "ITT Technical Institute-Westminster" + }, + { + "label": "ITT Technical Institute-Wichita" + }, + { + "label": "ITT Technical Institute-Wilmington" + }, + { + "label": "ITT Technical Institute-Wyoming" + }, + { + "label": "ITT Technical Institute-Youngstown" + }, + { + "label": "Ivy Tech Community College" + }, + { + "label": "J F Drake State Community and Technical College" + }, + { + "label": "J F Ingram State Technical College" + }, + { + "label": "J Sargeant Reynolds Community College" + }, + { + "label": "Jackson College" + }, + { + "label": "Jackson State Community College" + }, + { + "label": "Jackson State University" + }, + { + "label": "Jacksonville College-Main Campus" + }, + { + "label": "Jacksonville State University" + }, + { + "label": "Jacksonville University" + }, + { + "label": "James A Rhodes State College" + }, + { + "label": "James H Faulkner State Community College" + }, + { + "label": "James Madison University" + }, + { + "label": "James Sprunt Community College" + }, + { + "label": "Jamestown Business College" + }, + { + "label": "Jamestown Community College" + }, + { + "label": "Jarvis Christian College" + }, + { + "label": "Jefferson College" + }, + { + "label": "Jefferson College of Health Sciences" + }, + { + "label": "Jefferson Community and Technical College" + }, + { + "label": "Jefferson Community College" + }, + { + "label": "Jefferson Davis Community College" + }, + { + "label": "Jefferson State Community College" + }, + { + "label": "Jersey College" + }, + { + "label": "Jewish Theological Seminary of America" + }, + { + "label": "Jna Institute of Culinary Arts" + }, + { + "label": "John A Gupton College" + }, + { + "label": "John A Logan College" + }, + { + "label": "John Brown University" + }, + { + "label": "John C Calhoun State Community College" + }, + { + "label": "John Carroll University" + }, + { + "label": "John F. Kennedy University" + }, + { + "label": "John Paul the Great Catholic University" + }, + { + "label": "John Tyler Community College" + }, + { + "label": "John Wood Community College" + }, + { + "label": "Johns Hopkins University" + }, + { + "label": "Johnson & Wales University-Charlotte" + }, + { + "label": "Johnson & Wales University-Denver" + }, + { + "label": "Johnson & Wales University-North Miami" + }, + { + "label": "Johnson & Wales University-Online" + }, + { + "label": "Johnson & Wales University-Providence" + }, + { + "label": "Johnson C Smith University" + }, + { + "label": "Johnson College" + }, + { + "label": "Johnson County Community College" + }, + { + "label": "Johnson State College" + }, + { + "label": "Johnson University" + }, + { + "label": "Johnson University Florida" + }, + { + "label": "Johnston Community College" + }, + { + "label": "Joliet Junior College" + }, + { + "label": "Jones College-Jacksonville" + }, + { + "label": "Jones County Junior College" + }, + { + "label": "Jones International University" + }, + { + "label": "Jose Maria Vargas University" + }, + { + "label": "Judson College" + }, + { + "label": "Judson University" + }, + { + "label": "Jung Tao School of Classical Chinese Medicine" + }, + { + "label": "Juniata College" + }, + { + "label": "Kalamazoo College" + }, + { + "label": "Kalamazoo Valley Community College" + }, + { + "label": "Kankakee Community College" + }, + { + "label": "Kansas City Art Institute" + }, + { + "label": "Kansas City College & Bible School" + }, + { + "label": "Kansas City Kansas Community College" + }, + { + "label": "Kansas City University of Medicine and Biosciences" + }, + { + "label": "Kansas State University" + }, + { + "label": "Kansas Wesleyan University" + }, + { + "label": "Kapiolani Community College" + }, + { + "label": "Kaplan College-Jacksonville" + }, + { + "label": "Kaplan College-Lubbock" + }, + { + "label": "Kaplan University-Augusta Campus" + }, + { + "label": "Kaplan University-Cedar Falls Campus" + }, + { + "label": "Kaplan University-Cedar Rapids Campus" + }, + { + "label": "Kaplan University-Davenport Campus" + }, + { + "label": "Kaplan University-Des Moines Campus" + }, + { + "label": "Kaplan University-Hagerstown Campus" + }, + { + "label": "Kaplan University-Lincoln Campus" + }, + { + "label": "Kaplan University-Maine Campus" + }, + { + "label": "Kaplan University-Mason City Campus" + }, + { + "label": "Kaplan University-Omaha Campus" + }, + { + "label": "Kaskaskia College" + }, + { + "label": "Kauai Community College" + }, + { + "label": "KD College Conservatory of Film and Dramatic Arts" + }, + { + "label": "Kean University" + }, + { + "label": "Keck Graduate Institute" + }, + { + "label": "Keene State College" + }, + { + "label": "Kehilath Yakov Rabbinical Seminary" + }, + { + "label": "Keiser University-Ft Lauderdale" + }, + { + "label": "Kellogg Community College" + }, + { + "label": "Kendall College" + }, + { + "label": "Kennebec Valley Community College" + }, + { + "label": "Kennesaw State University" + }, + { + "label": "Kenrick Glennon Seminary" + }, + { + "label": "Kent State University at Ashtabula" + }, + { + "label": "Kent State University at East Liverpool" + }, + { + "label": "Kent State University at Geauga" + }, + { + "label": "Kent State University at Kent" + }, + { + "label": "Kent State University at Salem" + }, + { + "label": "Kent State University at Stark" + }, + { + "label": "Kent State University at Trumbull" + }, + { + "label": "Kent State University at Tuscarawas" + }, + { + "label": "Kentucky Christian University" + }, + { + "label": "Kentucky Mountain Bible College" + }, + { + "label": "Kentucky State University" + }, + { + "label": "Kentucky Wesleyan College" + }, + { + "label": "Kenyon College" + }, + { + "label": "Kettering College" + }, + { + "label": "Kettering University" + }, + { + "label": "Keuka College" + }, + { + "label": "Keweenaw Bay Ojibwa Community College" + }, + { + "label": "Key College" + }, + { + "label": "Keystone College" + }, + { + "label": "Keystone Technical Institute" + }, + { + "label": "Kilgore College" + }, + { + "label": "Kilian Community College" + }, + { + "label": "King University" + }, + { + "label": "King's College-Charlotte" + }, + { + "label": "King's College-Wilkes-Barre" + }, + { + "label": "Kirkwood Community College" + }, + { + "label": "Kirtland Community College" + }, + { + "label": "Kishwaukee College" + }, + { + "label": "Klamath Community College" + }, + { + "label": "Knowledge Systems Institute" + }, + { + "label": "Knox College" + }, + { + "label": "Knox Theological Seminary" + }, + { + "label": "Kutztown University of Pennsylvania" + }, + { + "label": "Kuyper College" + }, + { + "label": "La Roche College" + }, + { + "label": "La Salle University" + }, + { + "label": "La Sierra University" + }, + { + "label": "Labette Community College" + }, + { + "label": "Laboure College" + }, + { + "label": "Lac Courte Oreilles Ojibwa Community College" + }, + { + "label": "Lackawanna College" + }, + { + "label": "Lafayette College" + }, + { + "label": "LaGrange College" + }, + { + "label": "Laguna College of Art and Design" + }, + { + "label": "Lake Area Technical Institute" + }, + { + "label": "Lake Erie College" + }, + { + "label": "Lake Erie College of Osteopathic Medicine" + }, + { + "label": "Lake Forest College" + }, + { + "label": "Lake Forest Graduate School of Management" + }, + { + "label": "Lake Land College" + }, + { + "label": "Lake Michigan College" + }, + { + "label": "Lake Region State College" + }, + { + "label": "Lake Superior College" + }, + { + "label": "Lake Superior State University" + }, + { + "label": "Lake Tahoe Community College" + }, + { + "label": "Lake Washington Institute of Technology" + }, + { + "label": "Lakeland College" + }, + { + "label": "Lakeland Community College" + }, + { + "label": "Lakes Region Community College" + }, + { + "label": "Lakeshore Technical College" + }, + { + "label": "Lake-Sumter State College" + }, + { + "label": "Lakeview College of Nursing" + }, + { + "label": "Lamar Community College" + }, + { + "label": "Lamar Institute of Technology" + }, + { + "label": "Lamar State College-Orange" + }, + { + "label": "Lamar State College-Port Arthur" + }, + { + "label": "Lamar University" + }, + { + "label": "Lancaster Bible College" + }, + { + "label": "Lancaster County Career and Technology Center" + }, + { + "label": "Lancaster Theological Seminary" + }, + { + "label": "Lander University" + }, + { + "label": "Landmark College" + }, + { + "label": "Lane College" + }, + { + "label": "Lane Community College" + }, + { + "label": "Laney College" + }, + { + "label": "Langston University" + }, + { + "label": "Lanier Technical College" + }, + { + "label": "Lansdale School of Business" + }, + { + "label": "Lansing Community College" + }, + { + "label": "Laramie County Community College" + }, + { + "label": "Laredo Community College" + }, + { + "label": "Las Positas College" + }, + { + "label": "Lasell College" + }, + { + "label": "Lassen Community College" + }, + { + "label": "Latter-day Saints Business College" + }, + { + "label": "Laurel Business Institute" + }, + { + "label": "Laurel Technical Institute-MEADVILLE" + }, + { + "label": "Laurel Technical Institute-Sharon" + }, + { + "label": "Laurel University" + }, + { + "label": "Lawrence Memorial Hospital School of Nursing" + }, + { + "label": "Lawrence Technological University" + }, + { + "label": "Lawrence University" + }, + { + "label": "Lawson State Community College-Birmingham Campus" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Atlanta" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Austin" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Cambridge" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Chicago" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Dallas" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Las Vegas" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Miami" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Minneapolis" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Orlando" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Pasadena" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Portland" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-San Francisco" + }, + { + "label": "Le Cordon Bleu College of Culinary Arts-Scottsdale" + }, + { + "label": "Le Moyne College" + }, + { + "label": "Le Moyne-Owen College" + }, + { + "label": "Lebanon Valley College" + }, + { + "label": "L'Ecole Culinaire-Memphis" + }, + { + "label": "L'Ecole Culinaire-St Louis" + }, + { + "label": "Lee College" + }, + { + "label": "Lee University" + }, + { + "label": "Leech Lake Tribal College" + }, + { + "label": "Lees-McRae College" + }, + { + "label": "Leeward Community College" + }, + { + "label": "Lehigh Carbon Community College" + }, + { + "label": "Lehigh University" + }, + { + "label": "Lenoir Community College" + }, + { + "label": "Lenoir-Rhyne University" + }, + { + "label": "Lenoir-Rhyne University-Lutheran Theological Southern Seminary" + }, + { + "label": "Lesley University" + }, + { + "label": "LeTourneau University" + }, + { + "label": "Lewis & Clark College" + }, + { + "label": "Lewis and Clark Community College" + }, + { + "label": "Lewis University" + }, + { + "label": "Lewis-Clark State College" + }, + { + "label": "Lexington Theological Seminary" + }, + { + "label": "Liberty University" + }, + { + "label": "Life Chiropractic College West" + }, + { + "label": "Life Pacific College" + }, + { + "label": "Life University" + }, + { + "label": "LIM College" + }, + { + "label": "Limestone College" + }, + { + "label": "Lincoln Christian University" + }, + { + "label": "Lincoln College" + }, + { + "label": "Lincoln College of New England-Southington" + }, + { + "label": "Lincoln College of Technology-Columbia" + }, + { + "label": "Lincoln College of Technology-Denver" + }, + { + "label": "Lincoln College of Technology-Indianapolis" + }, + { + "label": "Lincoln College of Technology-Marietta" + }, + { + "label": "Lincoln College of Technology-Melrose Park" + }, + { + "label": "Lincoln College of Technology-Nashville" + }, + { + "label": "Lincoln College of Technology-West Palm Beach" + }, + { + "label": "Lincoln Land Community College" + }, + { + "label": "Lincoln Memorial University" + }, + { + "label": "Lincoln Technical Institute-Allentown" + }, + { + "label": "Lincoln Technical Institute-Northeast Philadelphia" + }, + { + "label": "Lincoln Technical Institute-Philadelphia" + }, + { + "label": "Lincoln Trail College" + }, + { + "label": "Lincoln University-Jefferson City" + }, + { + "label": "Lincoln University-Oakland" + }, + { + "label": "Lindenwood University" + }, + { + "label": "Lindsey Wilson College" + }, + { + "label": "Linfield College-Adult Degree Program" + }, + { + "label": "Linfield College-McMinnville Campus" + }, + { + "label": "Linfield College-School of Nursing" + }, + { + "label": "Linn-Benton Community College" + }, + { + "label": "Lipscomb University" + }, + { + "label": "Little Big Horn College" + }, + { + "label": "Little Priest Tribal College" + }, + { + "label": "LIU Brentwood" + }, + { + "label": "LIU Brooklyn" + }, + { + "label": "LIU Hudson at Rockland" + }, + { + "label": "LIU Hudson at Westchester" + }, + { + "label": "LIU Post" + }, + { + "label": "LIU Riverhead" + }, + { + "label": "Living Arts College" + }, + { + "label": "Livingstone College" + }, + { + "label": "Lock Haven University" + }, + { + "label": "Logan University" + }, + { + "label": "Loma Linda University" + }, + { + "label": "Lone Star College System" + }, + { + "label": "Long Beach City College" + }, + { + "label": "Long Island Business Institute" + }, + { + "label": "Longwood University" + }, + { + "label": "Longy School of Music of Bard College" + }, + { + "label": "Lorain County Community College" + }, + { + "label": "Loras College" + }, + { + "label": "Lord Fairfax Community College" + }, + { + "label": "Los Angeles City College" + }, + { + "label": "Los Angeles College of Music" + }, + { + "label": "Los Angeles County College of Nursing and Allied Health" + }, + { + "label": "Los Angeles Film School" + }, + { + "label": "Los Angeles Harbor College" + }, + { + "label": "Los Angeles Mission College" + }, + { + "label": "Los Angeles ORT College-Los Angeles Campus" + }, + { + "label": "Los Angeles ORT College-Van Nuys Campus" + }, + { + "label": "Los Angeles Pierce College" + }, + { + "label": "Los Angeles Southwest College" + }, + { + "label": "Los Angeles Trade Technical College" + }, + { + "label": "Los Angeles Valley College" + }, + { + "label": "Los Medanos College" + }, + { + "label": "Louisburg College" + }, + { + "label": "Louisiana College" + }, + { + "label": "Louisiana Culinary Institute" + }, + { + "label": "Louisiana Delta Community College" + }, + { + "label": "Louisiana State University and Agricultural & Mechanical College" + }, + { + "label": "Louisiana State University Health Sciences Center-New Orleans" + }, + { + "label": "Louisiana State University Health Sciences Center-Shreveport" + }, + { + "label": "Louisiana State University-Alexandria" + }, + { + "label": "Louisiana State University-Eunice" + }, + { + "label": "Louisiana State University-Shreveport" + }, + { + "label": "Louisiana Tech University" + }, + { + "label": "Louisville Presbyterian Theological Seminary" + }, + { + "label": "Lourdes University" + }, + { + "label": "Lower Columbia College" + }, + { + "label": "Loyola Marymount University" + }, + { + "label": "Loyola University Chicago" + }, + { + "label": "Loyola University Maryland" + }, + { + "label": "Loyola University New Orleans" + }, + { + "label": "Lubbock Christian University" + }, + { + "label": "Luna Community College" + }, + { + "label": "Lurleen B Wallace Community College" + }, + { + "label": "Luther College" + }, + { + "label": "Luther Rice University & Seminary" + }, + { + "label": "Luther Seminary" + }, + { + "label": "Lutheran School of Theology at Chicago" + }, + { + "label": "Lutheran Theological Seminary at Gettysburg" + }, + { + "label": "Lutheran Theological Seminary at Philadelphia" + }, + { + "label": "Luzerne County Community College" + }, + { + "label": "Lycoming College" + }, + { + "label": "Lynchburg College" + }, + { + "label": "Lyndon State College" + }, + { + "label": "Lynn University" + }, + { + "label": "Lyon College" + }, + { + "label": "Macalester College" + }, + { + "label": "MacCormac College" + }, + { + "label": "Machzikei Hadath Rabbinical College" + }, + { + "label": "MacMurray College" + }, + { + "label": "Macomb Community College" + }, + { + "label": "Madison Area Technical College" + }, + { + "label": "Madison Media Institute" + }, + { + "label": "Madison Media Institute-Rockford Career College" + }, + { + "label": "Madisonville Community College" + }, + { + "label": "Madonna University" + }, + { + "label": "Maharishi University of Management" + }, + { + "label": "Maine College of Art" + }, + { + "label": "Maine College of Health Professions" + }, + { + "label": "Maine Maritime Academy" + }, + { + "label": "Malone University" + }, + { + "label": "Management Resources College" + }, + { + "label": "Manchester Community College-Manchester" + }, + { + "label": "Manchester Community College-Manchester" + }, + { + "label": "Manchester University" + }, + { + "label": "Mandl School-The College of Allied Health" + }, + { + "label": "Manhattan Area Technical College" + }, + { + "label": "Manhattan Christian College" + }, + { + "label": "Manhattan College" + }, + { + "label": "Manhattan School of Music" + }, + { + "label": "Manhattanville College" + }, + { + "label": "Manor College" + }, + { + "label": "Mansfield University of Pennsylvania" + }, + { + "label": "Maple Springs Baptist Bible College and Seminary" + }, + { + "label": "Maranatha Baptist University" + }, + { + "label": "Maria College of Albany" + }, + { + "label": "Marian Court College" + }, + { + "label": "Marian University-Fond Du Lac" + }, + { + "label": "Marian University-Indianapolis" + }, + { + "label": "Marietta College" + }, + { + "label": "Marion Military Institute" + }, + { + "label": "Marion Technical College" + }, + { + "label": "Marist College" + }, + { + "label": "Marlboro College" + }, + { + "label": "Marlboro College Graduate & Professional Studies" + }, + { + "label": "Marquette University" + }, + { + "label": "Mars Hill University" + }, + { + "label": "Marshall B Ketchum University" + }, + { + "label": "Marshall University" + }, + { + "label": "Marshalltown Community College" + }, + { + "label": "Martin Community College" + }, + { + "label": "Martin Luther College" + }, + { + "label": "Martin Methodist College" + }, + { + "label": "Martin University" + }, + { + "label": "Mary Baldwin College" + }, + { + "label": "Marygrove College" + }, + { + "label": "Maryland Institute College of Art" + }, + { + "label": "Maryland University of Integrative Health" + }, + { + "label": "Marylhurst University" + }, + { + "label": "Marymount California University" + }, + { + "label": "Marymount Manhattan College" + }, + { + "label": "Marymount University" + }, + { + "label": "Maryville College" + }, + { + "label": "Maryville University of Saint Louis" + }, + { + "label": "Marywood University" + }, + { + "label": "Massachusetts Bay Community College" + }, + { + "label": "Massachusetts College of Art and Design" + }, + { + "label": "Massachusetts College of Liberal Arts" + }, + { + "label": "Massachusetts Institute of Technology" + }, + { + "label": "Massachusetts Maritime Academy" + }, + { + "label": "Massachusetts School of Law" + }, + { + "label": "Massasoit Community College" + }, + { + "label": "Mattia College" + }, + { + "label": "Mayfield College" + }, + { + "label": "Mayland Community College" + }, + { + "label": "Mayo Graduate School" + }, + { + "label": "Mayo Medical School" + }, + { + "label": "Mayo School of Health Sciences" + }, + { + "label": "Maysville Community and Technical College" + }, + { + "label": "Mayville State University" + }, + { + "label": "McCann School of Business & Technology" + }, + { + "label": "McCormick Theological Seminary" + }, + { + "label": "McDaniel College" + }, + { + "label": "McDowell Technical Community College" + }, + { + "label": "McHenry County College" + }, + { + "label": "McKendree University" + }, + { + "label": "McLennan Community College" + }, + { + "label": "McMurry University" + }, + { + "label": "McNally Smith College of Music" + }, + { + "label": "McNeese State University" + }, + { + "label": "McPherson College" + }, + { + "label": "MCPHS University" + }, + { + "label": "Meadville Lombard Theological School" + }, + { + "label": "Mech-Tech College" + }, + { + "label": "Medaille College" + }, + { + "label": "Medical College of Wisconsin" + }, + { + "label": "Medical University of South Carolina" + }, + { + "label": "MedTech College" + }, + { + "label": "MedTech College-Ft Wayne Campus" + }, + { + "label": "MedTech College-Greenwood Campus" + }, + { + "label": "MedTech College-Lexington Campus" + }, + { + "label": "Medtech Institute" + }, + { + "label": "MedTech Institute-Atlanta Campus" + }, + { + "label": "Meharry Medical College" + }, + { + "label": "Memorial School of Nursing" + }, + { + "label": "Memphis College of Art" + }, + { + "label": "Memphis Theological Seminary" + }, + { + "label": "Mendocino College" + }, + { + "label": "Menlo College" + }, + { + "label": "Merced College" + }, + { + "label": "Mercer County Community College" + }, + { + "label": "Mercer University" + }, + { + "label": "Mercy College" + }, + { + "label": "Mercy College of Health Sciences" + }, + { + "label": "Mercy College of Ohio" + }, + { + "label": "Mercyhurst University" + }, + { + "label": "Mercyhurst University-North East Campus" + }, + { + "label": "Meredith College" + }, + { + "label": "Meridian College" + }, + { + "label": "Meridian Community College" + }, + { + "label": "Merrimack College" + }, + { + "label": "Merritt College" + }, + { + "label": "Mesa Community College" + }, + { + "label": "Mesabi Range College" + }, + { + "label": "Mesalands Community College" + }, + { + "label": "Mesivta Keser Torah" + }, + { + "label": "Mesivta of Eastern Parkway-Yeshiva Zichron Meilech" + }, + { + "label": "Mesivta Torah Vodaath Rabbinical Seminary" + }, + { + "label": "Mesivtha Tifereth Jerusalem of America" + }, + { + "label": "Messenger College" + }, + { + "label": "Messiah College" + }, + { + "label": "Methodist College" + }, + { + "label": "Methodist Theological School in Ohio" + }, + { + "label": "Methodist University" + }, + { + "label": "Metro Business College-Arnold" + }, + { + "label": "Metro Business College-Cape Girardeau" + }, + { + "label": "Metro Business College-Jefferson City" + }, + { + "label": "Metro Business College-Rolla" + }, + { + "label": "Metropolitan Career Center Computer Technology Institute" + }, + { + "label": "Metropolitan College of New York" + }, + { + "label": "Metropolitan Community College Area" + }, + { + "label": "Metropolitan Community College-Kansas City-Kansas City" + }, + { + "label": "Metropolitan State University" + }, + { + "label": "Metropolitan State University of Denver" + }, + { + "label": "MGH Institute of Health Professions" + }, + { + "label": "Miami Dade College" + }, + { + "label": "Miami University-Hamilton" + }, + { + "label": "Miami University-Middletown" + }, + { + "label": "Miami University-Oxford" + }, + { + "label": "Miami-Jacobs Career College-Columbus" + }, + { + "label": "Miami-Jacobs Career College-Dayton" + }, + { + "label": "Miami-Jacobs Career College-Independence" + }, + { + "label": "Miami-Jacobs Career College-Sharonville" + }, + { + "label": "Miami-Jacobs Career College-Springboro" + }, + { + "label": "Miami-Jacobs Career College-Troy" + }, + { + "label": "MIAT College of Technology" + }, + { + "label": "Michigan Jewish Institute" + }, + { + "label": "Michigan School of Professional Psychology" + }, + { + "label": "Michigan State University" + }, + { + "label": "Michigan State University-College of Law" + }, + { + "label": "Michigan Technological University" + }, + { + "label": "Mid Michigan Community College" + }, + { + "label": "Mid-America Christian University" + }, + { + "label": "Mid-America College of Funeral Service" + }, + { + "label": "MidAmerica Nazarene University" + }, + { + "label": "Mid-Atlantic Christian University" + }, + { + "label": "Middle Georgia State College" + }, + { + "label": "Middle Tennessee School of Anesthesia Inc" + }, + { + "label": "Middle Tennessee State University" + }, + { + "label": "Middlebury College" + }, + { + "label": "Middlesex Community College-Bedford" + }, + { + "label": "Middlesex Community College-Middletown" + }, + { + "label": "Middlesex County College" + }, + { + "label": "Midland College" + }, + { + "label": "Midland University" + }, + { + "label": "Midlands Technical College" + }, + { + "label": "Mid-Plains Community College" + }, + { + "label": "Mid-South Christian College" + }, + { + "label": "Midstate College" + }, + { + "label": "Mid-State Technical College" + }, + { + "label": "Midway College" + }, + { + "label": "Midwest College of Oriental Medicine-Chicago" + }, + { + "label": "Midwest College of Oriental Medicine-Racine" + }, + { + "label": "Midwest Institute" + }, + { + "label": "Midwestern Baptist Theological Seminary" + }, + { + "label": "Midwestern State University" + }, + { + "label": "Midwestern University-Downers Grove" + }, + { + "label": "Midwestern University-Glendale" + }, + { + "label": "Midwives College of Utah" + }, + { + "label": "Mildred Elley School-Albany Campus" + }, + { + "label": "Mildred Elley-New York Campus" + }, + { + "label": "Miles College" + }, + { + "label": "Miles Community College" + }, + { + "label": "Millennia Atlantic University" + }, + { + "label": "Miller-Motte College-Cary" + }, + { + "label": "Miller-Motte College-Fayetteville" + }, + { + "label": "Miller-Motte College-Greenville" + }, + { + "label": "Miller-Motte College-Jacksonville" + }, + { + "label": "Miller-Motte College-Raleigh" + }, + { + "label": "Miller-Motte College-Wilmington" + }, + { + "label": "Miller-Motte Technical College-Augusta" + }, + { + "label": "Miller-Motte Technical College-Charleston" + }, + { + "label": "Miller-Motte Technical College-Chattanooga" + }, + { + "label": "Miller-Motte Technical College-Clarksville" + }, + { + "label": "Miller-Motte Technical College-Columbus" + }, + { + "label": "Miller-Motte Technical College-Conway" + }, + { + "label": "Miller-Motte Technical College-Gulfport" + }, + { + "label": "Miller-Motte Technical College-Lynchburg" + }, + { + "label": "Miller-Motte Technical College-Macon" + }, + { + "label": "Miller-Motte Technical College-Madison" + }, + { + "label": "Miller-Motte Technical College-Roanoke" + }, + { + "label": "Millersville University of Pennsylvania" + }, + { + "label": "Milligan College" + }, + { + "label": "Millikin University" + }, + { + "label": "Mills College" + }, + { + "label": "Millsaps College" + }, + { + "label": "Milwaukee Area Technical College" + }, + { + "label": "Milwaukee Institute of Art & Design" + }, + { + "label": "Milwaukee School of Engineering" + }, + { + "label": "Mineral Area College" + }, + { + "label": "Minneapolis Business College" + }, + { + "label": "Minneapolis College of Art and Design" + }, + { + "label": "Minneapolis Community and Technical College" + }, + { + "label": "Minneapolis Media Institute" + }, + { + "label": "Minnesota School of Business-Blaine" + }, + { + "label": "Minnesota School of Business-Brooklyn Center" + }, + { + "label": "Minnesota School of Business-Elk River" + }, + { + "label": "Minnesota School of Business-Lakeville" + }, + { + "label": "Minnesota School of Business-Moorhead" + }, + { + "label": "Minnesota School of Business-Plymouth" + }, + { + "label": "Minnesota School of Business-Richfield" + }, + { + "label": "Minnesota School of Business-Rochester" + }, + { + "label": "Minnesota School of Business-Waite Park" + }, + { + "label": "Minnesota State College-Southeast Technical" + }, + { + "label": "Minnesota State Community and Technical College" + }, + { + "label": "Minnesota State University Moorhead" + }, + { + "label": "Minnesota State University-Mankato" + }, + { + "label": "Minnesota West Community and Technical College" + }, + { + "label": "Minot State University" + }, + { + "label": "MiraCosta College" + }, + { + "label": "Mirrer Yeshiva Cent Institute" + }, + { + "label": "Misericordia University" + }, + { + "label": "Mission College" + }, + { + "label": "Mississippi College" + }, + { + "label": "Mississippi Delta Community College" + }, + { + "label": "Mississippi Gulf Coast Community College" + }, + { + "label": "Mississippi State University" + }, + { + "label": "Mississippi University for Women" + }, + { + "label": "Mississippi Valley State University" + }, + { + "label": "Missouri Baptist University" + }, + { + "label": "Missouri College" + }, + { + "label": "Missouri Southern State University" + }, + { + "label": "Missouri State University-Springfield" + }, + { + "label": "Missouri State University-West Plains" + }, + { + "label": "Missouri Tech" + }, + { + "label": "Missouri University of Science and Technology" + }, + { + "label": "Missouri Valley College" + }, + { + "label": "Missouri Western State University" + }, + { + "label": "Mitchell College" + }, + { + "label": "Mitchell Community College" + }, + { + "label": "Mitchell Technical Institute" + }, + { + "label": "Moberly Area Community College" + }, + { + "label": "Modesto Junior College" + }, + { + "label": "Mohave Community College" + }, + { + "label": "Mohawk Valley Community College" + }, + { + "label": "Molloy College" + }, + { + "label": "Monmouth College" + }, + { + "label": "Monmouth University" + }, + { + "label": "Monroe College" + }, + { + "label": "Monroe Community College" + }, + { + "label": "Monroe County Community College" + }, + { + "label": "Montana Bible College" + }, + { + "label": "Montana State University" + }, + { + "label": "Montana State University-Billings" + }, + { + "label": "Montana State University-Northern" + }, + { + "label": "Montana Tech of the University of Montana" + }, + { + "label": "Montcalm Community College" + }, + { + "label": "Montclair State University" + }, + { + "label": "Monterey Institute of International Studies" + }, + { + "label": "Monterey Peninsula College" + }, + { + "label": "Montgomery College" + }, + { + "label": "Montgomery Community College" + }, + { + "label": "Montgomery County Community College" + }, + { + "label": "Montreat College" + }, + { + "label": "Montserrat College of Art" + }, + { + "label": "Moody Bible Institute" + }, + { + "label": "Moore College of Art and Design" + }, + { + "label": "Moorpark College" + }, + { + "label": "Moraine Park Technical College" + }, + { + "label": "Moraine Valley Community College" + }, + { + "label": "Moravian College" + }, + { + "label": "Morehead State University" + }, + { + "label": "Morehouse College" + }, + { + "label": "Morehouse School of Medicine" + }, + { + "label": "Moreno Valley College" + }, + { + "label": "Morgan Community College" + }, + { + "label": "Morgan State University" + }, + { + "label": "Morningside College" + }, + { + "label": "Morris College" + }, + { + "label": "Morrison Institute of Technology" + }, + { + "label": "Morrisville State College" + }, + { + "label": "Morton College" + }, + { + "label": "Motlow State Community College" + }, + { + "label": "Mott Community College" + }, + { + "label": "Moultrie Technical College" + }, + { + "label": "Mount Aloysius College" + }, + { + "label": "Mount Angel Seminary" + }, + { + "label": "Mount Carmel College of Nursing" + }, + { + "label": "Mount Holyoke College" + }, + { + "label": "Mount Ida College" + }, + { + "label": "Mount Marty College" + }, + { + "label": "Mount Mary University" + }, + { + "label": "Mount Mercy University" + }, + { + "label": "Mount Saint Joseph University" + }, + { + "label": "Mount Saint Mary College" + }, + { + "label": "Mount Saint Mary's University" + }, + { + "label": "Mount St Mary's University" + }, + { + "label": "Mount Vernon Nazarene University" + }, + { + "label": "Mount Wachusett Community College" + }, + { + "label": "Mount Washington College" + }, + { + "label": "Mountain Empire Community College" + }, + { + "label": "Mountain State College" + }, + { + "label": "Mountain View College" + }, + { + "label": "Mountwest Community and Technical College" + }, + { + "label": "Mt Hood Community College" + }, + { + "label": "Mt San Antonio College" + }, + { + "label": "Mt San Jacinto Community College District" + }, + { + "label": "Mt Sierra College" + }, + { + "label": "MTI College" + }, + { + "label": "Muhlenberg College" + }, + { + "label": "Multnomah University" + }, + { + "label": "Murray State College" + }, + { + "label": "Murray State University" + }, + { + "label": "Musicians Institute" + }, + { + "label": "Muskegon Community College" + }, + { + "label": "Muskingum University" + }, + { + "label": "Myotherapy Institute" + }, + { + "label": "Napa Valley College" + }, + { + "label": "Naropa University" + }, + { + "label": "Nash Community College" + }, + { + "label": "Nashotah House" + }, + { + "label": "Nashua Community College" + }, + { + "label": "Nashville State Community College" + }, + { + "label": "Nassau Community College" + }, + { + "label": "National American University-Albuquerque" + }, + { + "label": "National American University-Albuquerque West" + }, + { + "label": "National American University-Austin" + }, + { + "label": "National American University-Austin South" + }, + { + "label": "National American University-Bellevue" + }, + { + "label": "National American University-Bloomington" + }, + { + "label": "National American University-Brooklyn Center" + }, + { + "label": "National American University-Burnsville" + }, + { + "label": "National American University-Centennial" + }, + { + "label": "National American University-Colorado Springs" + }, + { + "label": "National American University-Colorado Springs South" + }, + { + "label": "National American University-Denver" + }, + { + "label": "National American University-Ellsworth AFB Extension" + }, + { + "label": "National American University-Georgetown" + }, + { + "label": "National American University-Harold D. Buckingham Graduate School" + }, + { + "label": "National American University-Independence" + }, + { + "label": "National American University-Indianapolis" + }, + { + "label": "National American University-Lee's Summit" + }, + { + "label": "National American University-Lewisville" + }, + { + "label": "National American University-Overland Park" + }, + { + "label": "National American University-Rapid City" + }, + { + "label": "National American University-Rochester" + }, + { + "label": "National American University-Roseville" + }, + { + "label": "National American University-Sioux Falls" + }, + { + "label": "National American University-Tulsa" + }, + { + "label": "National American University-Weldon Spring" + }, + { + "label": "National American University-Wichita" + }, + { + "label": "National American University-Wichita West" + }, + { + "label": "National American University-Zona Rosa" + }, + { + "label": "National College of Natural Medicine" + }, + { + "label": "National College-Canton" + }, + { + "label": "National College-Cincinnati" + }, + { + "label": "National College-Columbus" + }, + { + "label": "National College-Dayton" + }, + { + "label": "National College-Lexington" + }, + { + "label": "National College-Nashville" + }, + { + "label": "National College-Stow" + }, + { + "label": "National College-Willoughby Hills" + }, + { + "label": "National College-Youngstown" + }, + { + "label": "National Graduate School of Quality Management" + }, + { + "label": "National Institute of Massotherapy" + }, + { + "label": "National Louis University" + }, + { + "label": "National Massage Therapy Institute" + }, + { + "label": "National Paralegal College" + }, + { + "label": "National Park Community College" + }, + { + "label": "National University" + }, + { + "label": "National University College-Arecibo" + }, + { + "label": "National University College-Bayamon" + }, + { + "label": "National University College-Caguas" + }, + { + "label": "National University College-Ponce" + }, + { + "label": "National University College-Rio Grande" + }, + { + "label": "National University of Health Sciences" + }, + { + "label": "Naugatuck Valley Community College" + }, + { + "label": "Navajo Technical University" + }, + { + "label": "Naval Postgraduate School" + }, + { + "label": "Navarro College" + }, + { + "label": "Nazarene Bible College" + }, + { + "label": "Nazarene Theological Seminary" + }, + { + "label": "Nazareth College" + }, + { + "label": "Nebraska Christian College" + }, + { + "label": "Nebraska College of Technical Agriculture" + }, + { + "label": "Nebraska Indian Community College" + }, + { + "label": "Nebraska Methodist College of Nursing & Allied Health" + }, + { + "label": "Nebraska Wesleyan University" + }, + { + "label": "Neosho County Community College" + }, + { + "label": "Ner Israel Rabbinical College" + }, + { + "label": "Neumann University" + }, + { + "label": "Neumont University" + }, + { + "label": "Nevada State College" + }, + { + "label": "New Brunswick Theological Seminary" + }, + { + "label": "New Castle School of Trades" + }, + { + "label": "New College of Florida" + }, + { + "label": "New England College" + }, + { + "label": "New England College of Business and Finance" + }, + { + "label": "New England College of Optometry" + }, + { + "label": "New England Culinary Institute" + }, + { + "label": "New England Institute of Technology" + }, + { + "label": "New England Law-Boston" + }, + { + "label": "New England School of Acupuncture" + }, + { + "label": "New Hampshire Institute of Art" + }, + { + "label": "New Hope Christian College-Eugene" + }, + { + "label": "New Jersey City University" + }, + { + "label": "New Jersey Institute of Technology" + }, + { + "label": "New Mexico Highlands University" + }, + { + "label": "New Mexico Institute of Mining and Technology" + }, + { + "label": "New Mexico Junior College" + }, + { + "label": "New Mexico Military Institute" + }, + { + "label": "New Mexico State University-Alamogordo" + }, + { + "label": "New Mexico State University-Carlsbad" + }, + { + "label": "New Mexico State University-Dona Ana" + }, + { + "label": "New Mexico State University-Grants" + }, + { + "label": "New Mexico State University-Main Campus" + }, + { + "label": "New Orleans Baptist Theological Seminary" + }, + { + "label": "New River Community and Technical College" + }, + { + "label": "New River Community College" + }, + { + "label": "New York Academy of Art" + }, + { + "label": "New York Career Institute" + }, + { + "label": "New York Chiropractic College" + }, + { + "label": "New York College of Health Professions" + }, + { + "label": "New York College of Podiatric Medicine" + }, + { + "label": "New York College of Traditional Chinese Medicine" + }, + { + "label": "New York Conservatory for Dramatic Arts" + }, + { + "label": "New York Film Academy" + }, + { + "label": "New York Institute of Technology" + }, + { + "label": "New York Law School" + }, + { + "label": "New York Medical College" + }, + { + "label": "New York School of Interior Design" + }, + { + "label": "New York Theological Seminary" + }, + { + "label": "New York University" + }, + { + "label": "Newberry College" + }, + { + "label": "Newbury College" + }, + { + "label": "Newman University" + }, + { + "label": "Newschool of Architecture and Design" + }, + { + "label": "NHTI-Concord's Community College" + }, + { + "label": "Niagara County Community College" + }, + { + "label": "Niagara University" + }, + { + "label": "Nicholls State University" + }, + { + "label": "Nichols College" + }, + { + "label": "Nicolet Area Technical College" + }, + { + "label": "Nightingale College" + }, + { + "label": "Norco College" + }, + { + "label": "Norfolk State University" + }, + { + "label": "Normandale Community College" + }, + { + "label": "North American University" + }, + { + "label": "North Arkansas College" + }, + { + "label": "North Carolina A & T State University" + }, + { + "label": "North Carolina Central University" + }, + { + "label": "North Carolina State University at Raleigh" + }, + { + "label": "North Carolina Wesleyan College" + }, + { + "label": "North Central College" + }, + { + "label": "North Central Institute" + }, + { + "label": "North Central Kansas Technical College" + }, + { + "label": "North Central Michigan College" + }, + { + "label": "North Central Missouri College" + }, + { + "label": "North Central State College" + }, + { + "label": "North Central Texas College" + }, + { + "label": "North Central University" + }, + { + "label": "North Country Community College" + }, + { + "label": "North Dakota State College of Science" + }, + { + "label": "North Dakota State University-Main Campus" + }, + { + "label": "North Florida Community College" + }, + { + "label": "North Georgia Technical College" + }, + { + "label": "North Greenville University" + }, + { + "label": "North Hennepin Community College" + }, + { + "label": "North Idaho College" + }, + { + "label": "North Iowa Area Community College" + }, + { + "label": "North Lake College" + }, + { + "label": "North Park University" + }, + { + "label": "North Seattle College" + }, + { + "label": "North Shore Community College" + }, + { + "label": "Northampton County Area Community College" + }, + { + "label": "Northcentral Technical College" + }, + { + "label": "Northcentral University" + }, + { + "label": "Northeast Alabama Community College" + }, + { + "label": "Northeast Catholic College" + }, + { + "label": "Northeast Community College" + }, + { + "label": "Northeast Iowa Community College" + }, + { + "label": "Northeast Mississippi Community College" + }, + { + "label": "Northeast Ohio Medical University" + }, + { + "label": "Northeast State Community College" + }, + { + "label": "Northeast Texas Community College" + }, + { + "label": "Northeast Wisconsin Technical College" + }, + { + "label": "Northeastern Illinois University" + }, + { + "label": "Northeastern Junior College" + }, + { + "label": "Northeastern Oklahoma A&M College" + }, + { + "label": "Northeastern Seminary" + }, + { + "label": "Northeastern State University" + }, + { + "label": "Northeastern Technical College" + }, + { + "label": "Northeastern University" + }, + { + "label": "Northeastern University Global Network" + }, + { + "label": "Northern Arizona University" + }, + { + "label": "Northern Baptist Theological Seminary" + }, + { + "label": "Northern Essex Community College" + }, + { + "label": "Northern Illinois University" + }, + { + "label": "Northern Kentucky University" + }, + { + "label": "Northern Maine Community College" + }, + { + "label": "Northern Marianas College" + }, + { + "label": "Northern Michigan University" + }, + { + "label": "Northern New Mexico College" + }, + { + "label": "Northern Oklahoma College" + }, + { + "label": "Northern State University" + }, + { + "label": "Northern Virginia Community College" + }, + { + "label": "Northland College" + }, + { + "label": "Northland Community and Technical College" + }, + { + "label": "Northland International University" + }, + { + "label": "Northland Pioneer College" + }, + { + "label": "Northpoint Bible College" + }, + { + "label": "Northshore Technical Community College" + }, + { + "label": "NorthWest Arkansas Community College" + }, + { + "label": "Northwest Career College" + }, + { + "label": "Northwest Christian University" + }, + { + "label": "Northwest College" + }, + { + "label": "Northwest College of Art & Design" + }, + { + "label": "Northwest Florida State College" + }, + { + "label": "Northwest Indian College" + }, + { + "label": "Northwest Institute of Literary Arts" + }, + { + "label": "Northwest Iowa Community College" + }, + { + "label": "Northwest Kansas Technical College" + }, + { + "label": "Northwest Louisiana Technical College" + }, + { + "label": "Northwest Mississippi Community College" + }, + { + "label": "Northwest Missouri State University" + }, + { + "label": "Northwest Nazarene University" + }, + { + "label": "Northwest School of Wooden Boat Building" + }, + { + "label": "Northwest State Community College" + }, + { + "label": "Northwest Technical College" + }, + { + "label": "Northwest University" + }, + { + "label": "Northwest Vista College" + }, + { + "label": "Northwestern College" + }, + { + "label": "Northwestern College-Chicago Campus" + }, + { + "label": "Northwestern College-Southwestern Campus" + }, + { + "label": "Northwestern Connecticut Community College" + }, + { + "label": "Northwestern Health Sciences University" + }, + { + "label": "Northwestern Michigan College" + }, + { + "label": "Northwestern Oklahoma State University" + }, + { + "label": "Northwestern State University of Louisiana" + }, + { + "label": "Northwestern University" + }, + { + "label": "Northwest-Shoals Community College" + }, + { + "label": "Northwood University-Florida" + }, + { + "label": "Northwood University-Michigan" + }, + { + "label": "Northwood University-Texas" + }, + { + "label": "Norwalk Community College" + }, + { + "label": "Norwich University" + }, + { + "label": "Nossi College of Art" + }, + { + "label": "Notre Dame College" + }, + { + "label": "Notre Dame de Namur University" + }, + { + "label": "Notre Dame of Maryland University" + }, + { + "label": "Notre Dame Seminary Graduate School of Theology" + }, + { + "label": "Nova Southeastern University" + }, + { + "label": "Nueta Hidatsa Sahnish College" + }, + { + "label": "Nunez Community College" + }, + { + "label": "Nyack College" + }, + { + "label": "Oak Hills Christian College" + }, + { + "label": "Oakland City University" + }, + { + "label": "Oakland Community College" + }, + { + "label": "Oakland University" + }, + { + "label": "Oakton Community College" + }, + { + "label": "Oakwood University" + }, + { + "label": "Oberlin College" + }, + { + "label": "Oblate School of Theology" + }, + { + "label": "Occidental College" + }, + { + "label": "Ocean County College" + }, + { + "label": "Oconee Fall Line Technical College" + }, + { + "label": "Odessa College" + }, + { + "label": "Ogeechee Technical College" + }, + { + "label": "Oglala Lakota College" + }, + { + "label": "Oglethorpe University" + }, + { + "label": "Ohio Business College-Hilliard" + }, + { + "label": "Ohio Business College-Sandusky" + }, + { + "label": "Ohio Business College-Sheffield" + }, + { + "label": "Ohio Christian University" + }, + { + "label": "Ohio College of Massotherapy Inc" + }, + { + "label": "Ohio Dominican University" + }, + { + "label": "Ohio Mid-Western College" + }, + { + "label": "Ohio Northern University" + }, + { + "label": "Ohio State University Agricultural Technical Institute" + }, + { + "label": "Ohio State University-Lima Campus" + }, + { + "label": "Ohio State University-Main Campus" + }, + { + "label": "Ohio State University-Mansfield Campus" + }, + { + "label": "Ohio State University-Marion Campus" + }, + { + "label": "Ohio State University-Newark Campus" + }, + { + "label": "Ohio Technical College" + }, + { + "label": "Ohio Technical College-PowerSport Institute" + }, + { + "label": "Ohio University-Chillicothe Campus" + }, + { + "label": "Ohio University-Eastern Campus" + }, + { + "label": "Ohio University-Lancaster Campus" + }, + { + "label": "Ohio University-Main Campus" + }, + { + "label": "Ohio University-Southern Campus" + }, + { + "label": "Ohio University-Zanesville Campus" + }, + { + "label": "Ohio Valley College of Technology" + }, + { + "label": "Ohio Valley University" + }, + { + "label": "Ohio Wesleyan University" + }, + { + "label": "Ohlone College" + }, + { + "label": "Ohr Hameir Theological Seminary" + }, + { + "label": "Oklahoma Baptist University" + }, + { + "label": "Oklahoma Christian University" + }, + { + "label": "Oklahoma City Community College" + }, + { + "label": "Oklahoma City University" + }, + { + "label": "Oklahoma Panhandle State University" + }, + { + "label": "Oklahoma State University Center for Health Sciences" + }, + { + "label": "Oklahoma State University Institute of Technology" + }, + { + "label": "Oklahoma State University-Main Campus" + }, + { + "label": "Oklahoma State University-Oklahoma City" + }, + { + "label": "Oklahoma Technical College" + }, + { + "label": "Oklahoma Wesleyan University" + }, + { + "label": "Old Dominion University" + }, + { + "label": "Olivet College" + }, + { + "label": "Olivet Nazarene University" + }, + { + "label": "Olney Central College" + }, + { + "label": "Olympic College" + }, + { + "label": "Omaha School of Massage and Healthcare of Herzing University" + }, + { + "label": "O'More College of Design" + }, + { + "label": "Onondaga Community College" + }, + { + "label": "Oral Roberts University" + }, + { + "label": "Orange Coast College" + }, + { + "label": "Orange County Community College" + }, + { + "label": "Orangeburg Calhoun Technical College" + }, + { + "label": "Oregon Coast Community College" + }, + { + "label": "Oregon College of Art and Craft" + }, + { + "label": "Oregon College of Oriental Medicine" + }, + { + "label": "Oregon Health & Science University" + }, + { + "label": "Oregon Institute of Technology" + }, + { + "label": "Oregon State University" + }, + { + "label": "Orion College" + }, + { + "label": "Orleans Technical Institute" + }, + { + "label": "Otero Junior College" + }, + { + "label": "Otis College of Art and Design" + }, + { + "label": "Ottawa University-Jeffersonville" + }, + { + "label": "Ottawa University-Kansas City" + }, + { + "label": "Ottawa University-Milwaukee" + }, + { + "label": "Ottawa University-Online" + }, + { + "label": "Ottawa University-Ottawa" + }, + { + "label": "Ottawa University-Phoenix" + }, + { + "label": "Otterbein University" + }, + { + "label": "Ouachita Baptist University" + }, + { + "label": "Our Lady of the Lake College" + }, + { + "label": "Our Lady of the Lake University" + }, + { + "label": "Owens Community College" + }, + { + "label": "Owensboro Community and Technical College" + }, + { + "label": "Oxford Graduate School" + }, + { + "label": "Oxnard College" + }, + { + "label": "Ozark Christian College" + }, + { + "label": "Ozarka College" + }, + { + "label": "Ozarks Technical Community College" + }, + { + "label": "Pace Institute" + }, + { + "label": "Pace University-New York" + }, + { + "label": "Pacific College" + }, + { + "label": "Pacific College of Oriental Medicine-Chicago" + }, + { + "label": "Pacific College of Oriental Medicine-New York" + }, + { + "label": "Pacific College of Oriental Medicine-San Diego" + }, + { + "label": "Pacific Islands University" + }, + { + "label": "Pacific Lutheran Theological Seminary" + }, + { + "label": "Pacific Lutheran University" + }, + { + "label": "Pacific Northwest College of Art" + }, + { + "label": "Pacific Northwest University of Health Sciences" + }, + { + "label": "Pacific Oaks College" + }, + { + "label": "Pacific Rim Christian University" + }, + { + "label": "Pacific School of Religion" + }, + { + "label": "Pacific States University" + }, + { + "label": "Pacific Union College" + }, + { + "label": "Pacific University" + }, + { + "label": "Pacifica Graduate Institute" + }, + { + "label": "Paier College of Art Inc" + }, + { + "label": "Paine College" + }, + { + "label": "Palau Community College" + }, + { + "label": "Palm Beach Atlantic University" + }, + { + "label": "Palm Beach State College" + }, + { + "label": "Palmer College of Chiropractic" + }, + { + "label": "Palo Alto College" + }, + { + "label": "Palo Alto University" + }, + { + "label": "Palo Verde College" + }, + { + "label": "Palomar College" + }, + { + "label": "Pamlico Community College" + }, + { + "label": "Panola College" + }, + { + "label": "Paradise Valley Community College" + }, + { + "label": "Pardee RAND Graduate School" + }, + { + "label": "Paris Junior College" + }, + { + "label": "Park University" + }, + { + "label": "Parker University" + }, + { + "label": "Parkland College" + }, + { + "label": "Pasadena City College" + }, + { + "label": "Pasco-Hernando State College" + }, + { + "label": "Passaic County Community College" + }, + { + "label": "Patrick Henry College" + }, + { + "label": "Patrick Henry Community College" + }, + { + "label": "Paul D Camp Community College" + }, + { + "label": "Paul Quinn College" + }, + { + "label": "Paul Smiths College of Arts and Science" + }, + { + "label": "Payne Theological Seminary" + }, + { + "label": "Pearl River Community College" + }, + { + "label": "Peirce College" + }, + { + "label": "Pellissippi State Community College" + }, + { + "label": "Peninsula College" + }, + { + "label": "Penn Commercial Business/Technical School" + }, + { + "label": "Pennco Tech-Bristol" + }, + { + "label": "Pennsylvania Academy of the Fine Arts" + }, + { + "label": "Pennsylvania College of Art and Design" + }, + { + "label": "Pennsylvania College of Health Sciences" + }, + { + "label": "Pennsylvania College of Technology" + }, + { + "label": "Pennsylvania Highlands Community College" + }, + { + "label": "Pennsylvania Institute of Health and Technology" + }, + { + "label": "Pennsylvania Institute of Technology" + }, + { + "label": "Pennsylvania State University-College of Medicine" + }, + { + "label": "Pennsylvania State University-Dickinson Law" + }, + { + "label": "Pennsylvania State University-Main Campus" + }, + { + "label": "Pennsylvania State University-Penn State Abington" + }, + { + "label": "Pennsylvania State University-Penn State Altoona" + }, + { + "label": "Pennsylvania State University-Penn State Beaver" + }, + { + "label": "Pennsylvania State University-Penn State Berks" + }, + { + "label": "Pennsylvania State University-Penn State Brandywine" + }, + { + "label": "Pennsylvania State University-Penn State DuBois" + }, + { + "label": "Pennsylvania State University-Penn State Erie-Behrend College" + }, + { + "label": "Pennsylvania State University-Penn State Fayette- Eberly" + }, + { + "label": "Pennsylvania State University-Penn State Great Valley" + }, + { + "label": "Pennsylvania State University-Penn State Greater Allegheny" + }, + { + "label": "Pennsylvania State University-Penn State Harrisburg" + }, + { + "label": "Pennsylvania State University-Penn State Hazleton" + }, + { + "label": "Pennsylvania State University-Penn State Lehigh Valley" + }, + { + "label": "Pennsylvania State University-Penn State Mont Alto" + }, + { + "label": "Pennsylvania State University-Penn State New Kensington" + }, + { + "label": "Pennsylvania State University-Penn State Schuylkill" + }, + { + "label": "Pennsylvania State University-Penn State Shenango" + }, + { + "label": "Pennsylvania State University-Penn State Wilkes-Barre" + }, + { + "label": "Pennsylvania State University-Penn State Worthington Scranton" + }, + { + "label": "Pennsylvania State University-Penn State York" + }, + { + "label": "Pennsylvania State University-World Campus" + }, + { + "label": "Pensacola State College" + }, + { + "label": "Pentecostal Theological Seminary" + }, + { + "label": "Pepperdine University" + }, + { + "label": "Peru State College" + }, + { + "label": "Pfeiffer University" + }, + { + "label": "Philadelphia College of Osteopathic Medicine" + }, + { + "label": "Philadelphia University" + }, + { + "label": "Philander Smith College" + }, + { + "label": "Phillips Beth Israel School of Nursing" + }, + { + "label": "Phillips Community College of the University of Arkansas" + }, + { + "label": "Phillips Graduate Institute" + }, + { + "label": "Phillips Theological Seminary" + }, + { + "label": "Phoenix College" + }, + { + "label": "Phoenix Institute of Herbal Medicine & Acupuncture" + }, + { + "label": "Phoenix Seminary" + }, + { + "label": "Piedmont College" + }, + { + "label": "Piedmont Community College" + }, + { + "label": "Piedmont International University" + }, + { + "label": "Piedmont Technical College" + }, + { + "label": "Piedmont Virginia Community College" + }, + { + "label": "Pierce College-Fort Steilacoom" + }, + { + "label": "Pierce College-Puyallup" + }, + { + "label": "Pierpont Community and Technical College" + }, + { + "label": "Pikes Peak Community College" + }, + { + "label": "Pillar College" + }, + { + "label": "Pima Community College" + }, + { + "label": "Pima Medical Institute-Albuquerque" + }, + { + "label": "Pima Medical Institute-Aurora" + }, + { + "label": "Pima Medical Institute-Chula Vista" + }, + { + "label": "Pima Medical Institute-Colorado Springs" + }, + { + "label": "Pima Medical Institute-Denver" + }, + { + "label": "Pima Medical Institute-East Valley" + }, + { + "label": "Pima Medical Institute-Houston" + }, + { + "label": "Pima Medical Institute-Las Vegas" + }, + { + "label": "Pima Medical Institute-Mesa" + }, + { + "label": "Pima Medical Institute-Renton" + }, + { + "label": "Pima Medical Institute-Seattle" + }, + { + "label": "Pima Medical Institute-Tucson" + }, + { + "label": "Pinchot University" + }, + { + "label": "Pine Manor College" + }, + { + "label": "Pine Technical & Community College" + }, + { + "label": "Pinnacle Career Institute-Lawrence" + }, + { + "label": "Pinnacle Career Institute-North Kansas City" + }, + { + "label": "Pinnacle Career Institute-South Kansas City" + }, + { + "label": "Pioneer Pacific College" + }, + { + "label": "Pitt Community College" + }, + { + "label": "Pittsburg State University" + }, + { + "label": "Pittsburgh Career Institute" + }, + { + "label": "Pittsburgh Institute of Aeronautics" + }, + { + "label": "Pittsburgh Institute of Mortuary Science Inc" + }, + { + "label": "Pittsburgh Technical Institute" + }, + { + "label": "Pittsburgh Theological Seminary" + }, + { + "label": "Pitzer College" + }, + { + "label": "Platt College-Aurora" + }, + { + "label": "Platt College-Central OKC" + }, + { + "label": "Platt College-Los Angeles" + }, + { + "label": "Platt College-Moore" + }, + { + "label": "Platt College-North OKC" + }, + { + "label": "Platt College-Ontario" + }, + { + "label": "Platt College-Riverside" + }, + { + "label": "Platt College-San Diego" + }, + { + "label": "Platt College-Tulsa" + }, + { + "label": "Plaza College" + }, + { + "label": "Plymouth State University" + }, + { + "label": "Point Loma Nazarene University" + }, + { + "label": "Point Park University" + }, + { + "label": "Point University" + }, + { + "label": "Polk State College" + }, + { + "label": "Polytechnic University of Puerto Rico-Miami" + }, + { + "label": "Polytechnic University of Puerto Rico-Orlando" + }, + { + "label": "Pomeroy College of Nursing at Crouse Hospital" + }, + { + "label": "Pomona College" + }, + { + "label": "Ponce Health Sciences University" + }, + { + "label": "Ponce Paramedical College Inc" + }, + { + "label": "Pontifical Catholic University of Puerto Rico-Arecibo" + }, + { + "label": "Pontifical Catholic University of Puerto Rico-Mayaguez" + }, + { + "label": "Pontifical Catholic University of Puerto Rico-Ponce" + }, + { + "label": "Pontifical College Josephinum" + }, + { + "label": "Pontifical Faculty of the Immaculate Conception at the Dominican House of Studies" + }, + { + "label": "Pontifical John Paul II Institute for Studies on Marriage and Family" + }, + { + "label": "Pope St John XXIII National Seminary" + }, + { + "label": "Porterville College" + }, + { + "label": "Portland Community College" + }, + { + "label": "Portland State University" + }, + { + "label": "Post University" + }, + { + "label": "Potomac State College of West Virginia University" + }, + { + "label": "Prairie State College" + }, + { + "label": "Prairie View A & M University" + }, + { + "label": "Pratt Community College" + }, + { + "label": "Pratt Institute-Main" + }, + { + "label": "Presbyterian College" + }, + { + "label": "Prescott College" + }, + { + "label": "Presentation College" + }, + { + "label": "Prince George's Community College" + }, + { + "label": "Prince Institute-Southeast" + }, + { + "label": "Princeton Theological Seminary" + }, + { + "label": "Princeton University" + }, + { + "label": "Principia College" + }, + { + "label": "Prism Career Institute-Upper Darby" + }, + { + "label": "Professional Golfers Career College" + }, + { + "label": "Professional Skills Institute" + }, + { + "label": "Providence Christian College" + }, + { + "label": "Providence College" + }, + { + "label": "Provo College" + }, + { + "label": "Pueblo Community College" + }, + { + "label": "Puerto Rico Conservatory of Music" + }, + { + "label": "Pulaski Technical College" + }, + { + "label": "Purdue University-Calumet Campus" + }, + { + "label": "Purdue University-Main Campus" + }, + { + "label": "Purdue University-North Central Campus" + }, + { + "label": "Queens University of Charlotte" + }, + { + "label": "Quincy College" + }, + { + "label": "Quincy University" + }, + { + "label": "Quinebaug Valley Community College" + }, + { + "label": "Quinnipiac University" + }, + { + "label": "Quinsigamond Community College" + }, + { + "label": "Rabbi Jacob Joseph School" + }, + { + "label": "Rabbinical Academy Mesivta Rabbi Chaim Berlin" + }, + { + "label": "Rabbinical College Beth Shraga" + }, + { + "label": "Rabbinical College Bobover Yeshiva Bnei Zion" + }, + { + "label": "Rabbinical College of America" + }, + { + "label": "Rabbinical College of Ch'san Sofer New York" + }, + { + "label": "Rabbinical College of Long Island" + }, + { + "label": "Rabbinical College of Ohr Shimon Yisroel" + }, + { + "label": "Rabbinical College Ohr Yisroel" + }, + { + "label": "Rabbinical College Telshe" + }, + { + "label": "Rabbinical Seminary of America" + }, + { + "label": "Radford University" + }, + { + "label": "Radians College" + }, + { + "label": "Rainy River Community College" + }, + { + "label": "Ramapo College of New Jersey" + }, + { + "label": "Randolph College" + }, + { + "label": "Randolph Community College" + }, + { + "label": "Randolph-Macon College" + }, + { + "label": "Ranger College" + }, + { + "label": "Ranken Technical College" + }, + { + "label": "Rappahannock Community College" + }, + { + "label": "Raritan Valley Community College" + }, + { + "label": "Rasmussen College-Florida" + }, + { + "label": "Rasmussen College-Illinois" + }, + { + "label": "Rasmussen College-Minnesota" + }, + { + "label": "Rasmussen College-North Dakota" + }, + { + "label": "Rasmussen College-Wisconsin" + }, + { + "label": "Reading Area Community College" + }, + { + "label": "Reconstructionist Rabbinical College" + }, + { + "label": "Red Rocks Community College" + }, + { + "label": "Redlands Community College" + }, + { + "label": "Redstone College" + }, + { + "label": "Reed College" + }, + { + "label": "Reedley College" + }, + { + "label": "Reformed Presbyterian Theological Seminary" + }, + { + "label": "Refrigeration School Inc" + }, + { + "label": "Regent University" + }, + { + "label": "Regis College" + }, + { + "label": "Regis University" + }, + { + "label": "Reid State Technical College" + }, + { + "label": "Reinhardt University" + }, + { + "label": "Relay Graduate School of Education" + }, + { + "label": "Remington College of Nursing Orlando" + }, + { + "label": "Remington College-Baton Rouge Campus" + }, + { + "label": "Remington College-Cleveland Campus" + }, + { + "label": "Remington College-Dallas Campus" + }, + { + "label": "Remington College-Fort Worth Campus" + }, + { + "label": "Remington College-Heathrow Campus" + }, + { + "label": "Remington College-Honolulu Campus" + }, + { + "label": "Remington College-Houston Campus" + }, + { + "label": "Remington College-Lafayette Campus" + }, + { + "label": "Remington College-Little Rock Campus" + }, + { + "label": "Remington College-Memphis Campus" + }, + { + "label": "Remington College-Mobile Campus" + }, + { + "label": "Remington College-Nashville Campus" + }, + { + "label": "Remington College-North Houston Campus" + }, + { + "label": "Remington College-Shreveport Campus" + }, + { + "label": "Remington College-Tampa Campus" + }, + { + "label": "Rend Lake College" + }, + { + "label": "Rensselaer Hartford Graduate Center Inc" + }, + { + "label": "Rensselaer Polytechnic Institute" + }, + { + "label": "Renton Technical College" + }, + { + "label": "Research College of Nursing" + }, + { + "label": "Resurrection University" + }, + { + "label": "Rhode Island College" + }, + { + "label": "Rhode Island School of Design" + }, + { + "label": "Rhodes College" + }, + { + "label": "Rice University" + }, + { + "label": "Rich Mountain Community College" + }, + { + "label": "Richard Bland College of the College of William and Mary" + }, + { + "label": "Richland College" + }, + { + "label": "Richland Community College" + }, + { + "label": "Richmond Community College" + }, + { + "label": "Richmont Graduate University" + }, + { + "label": "Rider University" + }, + { + "label": "Ridgewater College" + }, + { + "label": "Ringling College of Art and Design" + }, + { + "label": "Rio Grande Bible Institute" + }, + { + "label": "Rio Hondo College" + }, + { + "label": "Rio Salado College" + }, + { + "label": "Ripon College" + }, + { + "label": "River Parishes Community College" + }, + { + "label": "River Valley Community College" + }, + { + "label": "Riverland Community College" + }, + { + "label": "Riverside City College" + }, + { + "label": "Riverside College of Health Careers" + }, + { + "label": "Rivier University" + }, + { + "label": "Roane State Community College" + }, + { + "label": "Roanoke College" + }, + { + "label": "Roanoke-Chowan Community College" + }, + { + "label": "Robert Morris University" + }, + { + "label": "Robert Morris University Illinois" + }, + { + "label": "Roberts Wesleyan College" + }, + { + "label": "Robeson Community College" + }, + { + "label": "Rochester College" + }, + { + "label": "Rochester Community and Technical College" + }, + { + "label": "Rochester Institute of Technology" + }, + { + "label": "Rock Valley College" + }, + { + "label": "Rockefeller University" + }, + { + "label": "Rockford University" + }, + { + "label": "Rockhurst University" + }, + { + "label": "Rockingham Community College" + }, + { + "label": "Rockland Community College" + }, + { + "label": "Rocky Mountain College" + }, + { + "label": "Rocky Mountain College of Art and Design" + }, + { + "label": "Rocky Mountain University of Health Professions" + }, + { + "label": "Rocky Vista University" + }, + { + "label": "Roger Williams University" + }, + { + "label": "Roger Williams University School of Law" + }, + { + "label": "Rogers State University" + }, + { + "label": "Rogue Community College" + }, + { + "label": "Rollins College" + }, + { + "label": "Roosevelt University" + }, + { + "label": "Rosalind Franklin University of Medicine and Science" + }, + { + "label": "Rose State College" + }, + { + "label": "Rosedale Bible College" + }, + { + "label": "Rosedale Technical Institute" + }, + { + "label": "Rose-Hulman Institute of Technology" + }, + { + "label": "Roseman University of Health Sciences" + }, + { + "label": "Rosemont College" + }, + { + "label": "Ross College-Sylvania" + }, + { + "label": "Rowan College at Burlington County" + }, + { + "label": "Rowan College at Gloucester County" + }, + { + "label": "Rowan University" + }, + { + "label": "Rowan-Cabarrus Community College" + }, + { + "label": "Roxbury Community College" + }, + { + "label": "Rush University" + }, + { + "label": "Rust College" + }, + { + "label": "Rutgers University-Camden" + }, + { + "label": "Rutgers University-New Brunswick" + }, + { + "label": "Rutgers University-Newark" + }, + { + "label": "SABER College" + }, + { + "label": "Sacramento City College" + }, + { + "label": "Sacred Heart Major Seminary" + }, + { + "label": "Sacred Heart School of Theology" + }, + { + "label": "Sacred Heart University" + }, + { + "label": "Saddleback College" + }, + { + "label": "SAE Institute of Technology-Atlanta" + }, + { + "label": "SAE Institute of Technology-Nashville" + }, + { + "label": "Sage College" + }, + { + "label": "Saginaw Chippewa Tribal College" + }, + { + "label": "Saginaw Valley State University" + }, + { + "label": "Saint Ambrose University" + }, + { + "label": "Saint Anselm College" + }, + { + "label": "Saint Anthony College of Nursing" + }, + { + "label": "Saint Augustine College" + }, + { + "label": "Saint Augustine's University" + }, + { + "label": "Saint Catharine College" + }, + { + "label": "Saint Charles Borromeo Seminary-Overbrook" + }, + { + "label": "Saint Cloud State University" + }, + { + "label": "Saint Edward's University" + }, + { + "label": "Saint Elizabeth College of Nursing-Utica" + }, + { + "label": "Saint Francis Medical Center College of Nursing" + }, + { + "label": "Saint Francis University" + }, + { + "label": "Saint John Fisher College" + }, + { + "label": "Saint John Vianney College Seminary" + }, + { + "label": "Saint Johns River State College" + }, + { + "label": "Saint John's Seminary" + }, + { + "label": "Saint Johns University" + }, + { + "label": "Saint Joseph Seminary College" + }, + { + "label": "Saint Josephs College" + }, + { + "label": "Saint Joseph's College of Maine" + }, + { + "label": "Saint Joseph's College-New York" + }, + { + "label": "Saint Joseph's University" + }, + { + "label": "Saint Leo University" + }, + { + "label": "Saint Louis Christian College" + }, + { + "label": "Saint Louis Community College" + }, + { + "label": "Saint Louis University" + }, + { + "label": "Saint Luke's College of Health Sciences" + }, + { + "label": "Saint Martin's University" + }, + { + "label": "Saint Mary-of-the-Woods College" + }, + { + "label": "Saint Mary's College" + }, + { + "label": "Saint Mary's College of California" + }, + { + "label": "Saint Mary's University of Minnesota" + }, + { + "label": "Saint Meinrad School of Theology" + }, + { + "label": "Saint Michael's College" + }, + { + "label": "Saint Norbert College" + }, + { + "label": "Saint Paul College" + }, + { + "label": "Saint Paul School of Theology" + }, + { + "label": "Saint Peter's University" + }, + { + "label": "Saint Vincent College" + }, + { + "label": "Saint Vincent de Paul Regional Seminary" + }, + { + "label": "Saint Vincent Seminary" + }, + { + "label": "Saint Vladimirs Orthodox Theological Seminary" + }, + { + "label": "Saint Xavier University" + }, + { + "label": "Salem College" + }, + { + "label": "Salem Community College" + }, + { + "label": "Salem International University" + }, + { + "label": "Salem State University" + }, + { + "label": "Salina Area Technical College" + }, + { + "label": "Salisbury University" + }, + { + "label": "Salish Kootenai College" + }, + { + "label": "Salt Lake Community College" + }, + { + "label": "Salter College-Chicopee" + }, + { + "label": "Salter College-West Boylston" + }, + { + "label": "Salus University" + }, + { + "label": "Salve Regina University" + }, + { + "label": "Sam Houston State University" + }, + { + "label": "Samaritan Hospital School of Nursing" + }, + { + "label": "Samford University" + }, + { + "label": "Sampson Community College" + }, + { + "label": "Samuel Merritt University" + }, + { + "label": "San Antonio College" + }, + { + "label": "San Bernardino Valley College" + }, + { + "label": "San Diego Christian College" + }, + { + "label": "San Diego City College" + }, + { + "label": "San Diego Mesa College" + }, + { + "label": "San Diego Miramar College" + }, + { + "label": "San Diego State University" + }, + { + "label": "San Francisco Art Institute" + }, + { + "label": "San Francisco Conservatory of Music" + }, + { + "label": "San Francisco State University" + }, + { + "label": "San Francisco Theological Seminary" + }, + { + "label": "San Jacinto Community College" + }, + { + "label": "San Joaquin College of Law" + }, + { + "label": "San Joaquin Delta College" + }, + { + "label": "San Joaquin Valley College-Visalia" + }, + { + "label": "San Jose City College" + }, + { + "label": "San Jose State University" + }, + { + "label": "San Juan Bautista School of Medicine" + }, + { + "label": "San Juan College" + }, + { + "label": "Sandhills Community College" + }, + { + "label": "Sanford Burnham Prybis Medical Discovery Institute" + }, + { + "label": "Sanford-Brown College-Atlanta" + }, + { + "label": "Sanford-Brown College-Brooklyn Center" + }, + { + "label": "Sanford-Brown College-Chicago" + }, + { + "label": "Sanford-Brown College-Dallas" + }, + { + "label": "Sanford-Brown College-Fenton" + }, + { + "label": "Sanford-Brown College-Houston" + }, + { + "label": "Sanford-Brown College-Las Vegas" + }, + { + "label": "Sanford-Brown College-Mendota Heights" + }, + { + "label": "Sanford-Brown College-Middleburg Heights" + }, + { + "label": "Sanford-Brown College-Online" + }, + { + "label": "Sanford-Brown College-Orlando" + }, + { + "label": "Sanford-Brown College-San Antonio-San Antonio" + }, + { + "label": "Sanford-Brown College-Seattle" + }, + { + "label": "Sanford-Brown College-Tampa" + }, + { + "label": "Sanford-Brown College-Tysons Corner" + }, + { + "label": "Sanford-Brown Institute-Ft Lauderdale" + }, + { + "label": "Sanford-Brown Institute-Jacksonville" + }, + { + "label": "Santa Ana College" + }, + { + "label": "Santa Barbara Business College-Bakersfield" + }, + { + "label": "Santa Barbara Business College-Santa Maria" + }, + { + "label": "Santa Barbara Business College-Ventura" + }, + { + "label": "Santa Barbara City College" + }, + { + "label": "Santa Clara University" + }, + { + "label": "Santa Fe College" + }, + { + "label": "Santa Fe Community College" + }, + { + "label": "Santa Fe University of Art and Design" + }, + { + "label": "Santa Monica College" + }, + { + "label": "Santa Rosa Junior College" + }, + { + "label": "Santiago Canyon College" + }, + { + "label": "Sarah Lawrence College" + }, + { + "label": "Sauk Valley Community College" + }, + { + "label": "Savannah College of Art and Design" + }, + { + "label": "Savannah State University" + }, + { + "label": "Savannah Technical College" + }, + { + "label": "Saybrook University" + }, + { + "label": "SBI Campus-An Affiliate of Sanford-Brown" + }, + { + "label": "Schenectady County Community College" + }, + { + "label": "Schiller International University" + }, + { + "label": "School of the Art Institute of Chicago" + }, + { + "label": "School of the Museum of Fine Arts-Boston" + }, + { + "label": "School of Visual Arts" + }, + { + "label": "Schoolcraft College" + }, + { + "label": "Schreiner University" + }, + { + "label": "Scottsdale Community College" + }, + { + "label": "Scripps College" + }, + { + "label": "Seattle Central College" + }, + { + "label": "Seattle Institute of Oriental Medicine" + }, + { + "label": "Seattle Pacific University" + }, + { + "label": "Seattle University" + }, + { + "label": "Selma University" + }, + { + "label": "Seminario Evangelico de Puerto Rico" + }, + { + "label": "Seminole State College" + }, + { + "label": "Seminole State College of Florida" + }, + { + "label": "Sentara College of Health Sciences" + }, + { + "label": "Sessions College for Professional Design" + }, + { + "label": "Seton Hall University" + }, + { + "label": "Seton Hill University" + }, + { + "label": "Sewanee-The University of the South" + }, + { + "label": "Seward County Community College and Area Technical School" + }, + { + "label": "Shasta Bible College and Graduate School" + }, + { + "label": "Shasta College" + }, + { + "label": "Shaw University" + }, + { + "label": "Shawnee Community College" + }, + { + "label": "Shawnee State University" + }, + { + "label": "Shelton State Community College" + }, + { + "label": "Shenandoah University" + }, + { + "label": "Shepherd University" + }, + { + "label": "Shepherds Theological Seminary" + }, + { + "label": "Sheridan College" + }, + { + "label": "Sherman College of Straight Chiropractic" + }, + { + "label": "Shiloh University" + }, + { + "label": "Shimer College" + }, + { + "label": "Shippensburg University of Pennsylvania" + }, + { + "label": "Sh'or Yoshuv Rabbinical College" + }, + { + "label": "Shoreline Community College" + }, + { + "label": "Shorter College" + }, + { + "label": "Shorter University" + }, + { + "label": "Shorter University-College of Adult & Professional Programs" + }, + { + "label": "Siena College" + }, + { + "label": "Siena Heights University" + }, + { + "label": "Sierra College" + }, + { + "label": "Sierra Nevada College" + }, + { + "label": "Silver Lake College of the Holy Family" + }, + { + "label": "Simmons College" + }, + { + "label": "Simmons College of Kentucky" + }, + { + "label": "Simpson College" + }, + { + "label": "Simpson University" + }, + { + "label": "Sinclair Community College" + }, + { + "label": "Sinte Gleska University" + }, + { + "label": "Sioux Falls Seminary" + }, + { + "label": "Sisseton Wahpeton College" + }, + { + "label": "SIT Graduate Institute" + }, + { + "label": "Sitting Bull College" + }, + { + "label": "Skagit Valley College" + }, + { + "label": "Skidmore College" + }, + { + "label": "Skyline College" + }, + { + "label": "Skyline College-Roanoke" + }, + { + "label": "Slippery Rock University of Pennsylvania" + }, + { + "label": "Smith College" + }, + { + "label": "Snead State Community College" + }, + { + "label": "Snow College" + }, + { + "label": "Sofia University" + }, + { + "label": "Sojourner-Douglass College" + }, + { + "label": "Soka University of America" + }, + { + "label": "Solano Community College" + }, + { + "label": "SOLEX College" + }, + { + "label": "Somerset Community College" + }, + { + "label": "Sonoma State University" + }, + { + "label": "Sotheby's Institute of Art-NY" + }, + { + "label": "South Arkansas Community College" + }, + { + "label": "South Baylo University" + }, + { + "label": "South Carolina State University" + }, + { + "label": "South Central College" + }, + { + "label": "South Central Louisiana Technical College-Young Memorial Campus" + }, + { + "label": "South Coast College" + }, + { + "label": "South College" + }, + { + "label": "South College-Asheville" + }, + { + "label": "South Dakota School of Mines and Technology" + }, + { + "label": "South Dakota State University" + }, + { + "label": "South Florida Bible College and Theological Seminary" + }, + { + "label": "South Florida State College" + }, + { + "label": "South Georgia State College" + }, + { + "label": "South Georgia Technical College" + }, + { + "label": "South Hills School of Business & Technology" + }, + { + "label": "South Louisiana Community College" + }, + { + "label": "South Mountain Community College" + }, + { + "label": "South Piedmont Community College" + }, + { + "label": "South Plains College" + }, + { + "label": "South Puget Sound Community College" + }, + { + "label": "South Seattle College" + }, + { + "label": "South Suburban College" + }, + { + "label": "South Texas College" + }, + { + "label": "South Texas College of Law" + }, + { + "label": "South University-Accelerated Graduate Programs" + }, + { + "label": "South University-Austin" + }, + { + "label": "South University-Cleveland" + }, + { + "label": "South University-Columbia" + }, + { + "label": "South University-High Point" + }, + { + "label": "South University-Montgomery" + }, + { + "label": "South University-Novi" + }, + { + "label": "South University–Richmond" + }, + { + "label": "South University-Savannah" + }, + { + "label": "South University–Savannah Online" + }, + { + "label": "South University-Tampa" + }, + { + "label": "South University-The Art Institute of Dallas" + }, + { + "label": "South University-The Art Institute of Fort Worth" + }, + { + "label": "South University–Virginia Beach" + }, + { + "label": "South University-West Palm Beach" + }, + { + "label": "Southcentral Kentucky Community and Technical College" + }, + { + "label": "Southeast Arkansas College" + }, + { + "label": "Southeast Community College Area" + }, + { + "label": "Southeast Kentucky Community and Technical College" + }, + { + "label": "Southeast Missouri Hospital College of Nursing and Health Sciences" + }, + { + "label": "Southeast Missouri State University" + }, + { + "label": "Southeast Technical Institute" + }, + { + "label": "Southeastern Baptist College" + }, + { + "label": "Southeastern Baptist Theological Seminary" + }, + { + "label": "Southeastern Bible College" + }, + { + "label": "Southeastern College-Jacksonville" + }, + { + "label": "Southeastern College-West Palm Beach" + }, + { + "label": "Southeastern Community College-West Burlington" + }, + { + "label": "Southeastern Community College-Whiteville" + }, + { + "label": "Southeastern Illinois College" + }, + { + "label": "Southeastern Louisiana University" + }, + { + "label": "Southeastern Oklahoma State University" + }, + { + "label": "Southeastern Technical College" + }, + { + "label": "Southeastern University" + }, + { + "label": "Southern Adventist University" + }, + { + "label": "Southern Arkansas University Main Campus" + }, + { + "label": "Southern Arkansas University Tech" + }, + { + "label": "Southern California Institute of Architecture" + }, + { + "label": "Southern California Institute of Technology" + }, + { + "label": "Southern California Seminary" + }, + { + "label": "Southern California University of Health Sciences" + }, + { + "label": "Southern California University SOMA" + }, + { + "label": "Southern College of Optometry" + }, + { + "label": "Southern Connecticut State University" + }, + { + "label": "Southern Crescent Technical College" + }, + { + "label": "Southern Illinois University-Carbondale" + }, + { + "label": "Southern Illinois University-Edwardsville" + }, + { + "label": "Southern Maine Community College" + }, + { + "label": "Southern Methodist University" + }, + { + "label": "Southern Nazarene University" + }, + { + "label": "Southern New Hampshire University" + }, + { + "label": "Southern Oregon University" + }, + { + "label": "Southern Polytechnic State University" + }, + { + "label": "Southern State Community College" + }, + { + "label": "Southern Technical College-Fort Myers" + }, + { + "label": "Southern Technical College-Orlando" + }, + { + "label": "Southern Union State Community College" + }, + { + "label": "Southern University and A & M College" + }, + { + "label": "Southern University at New Orleans" + }, + { + "label": "Southern University at Shreveport" + }, + { + "label": "Southern University Law Center" + }, + { + "label": "Southern Utah University" + }, + { + "label": "Southern Vermont College" + }, + { + "label": "Southern Virginia University" + }, + { + "label": "Southern Wesleyan University" + }, + { + "label": "Southern West Virginia Community and Technical College" + }, + { + "label": "Southside Regional Medical Center Professional Schools" + }, + { + "label": "Southside Virginia Community College" + }, + { + "label": "Southwest Acupuncture College-Albuquerque" + }, + { + "label": "Southwest Acupuncture College-Boulder" + }, + { + "label": "Southwest Acupuncture College-Santa Fe" + }, + { + "label": "Southwest Baptist University" + }, + { + "label": "Southwest College of Naturopathic Medicine & Health Sciences" + }, + { + "label": "Southwest Collegiate Institute for the Deaf" + }, + { + "label": "Southwest Georgia Technical College" + }, + { + "label": "Southwest Institute of Healing Arts" + }, + { + "label": "Southwest Minnesota State University" + }, + { + "label": "Southwest Mississippi Community College" + }, + { + "label": "Southwest Tennessee Community College" + }, + { + "label": "Southwest Texas Junior College" + }, + { + "label": "Southwest University at El Paso" + }, + { + "label": "Southwest University of Visual Arts-Albuquerque" + }, + { + "label": "Southwest University of Visual Arts-Tucson" + }, + { + "label": "Southwest Virginia Community College" + }, + { + "label": "Southwest Wisconsin Technical College" + }, + { + "label": "Southwestern Adventist University" + }, + { + "label": "Southwestern Assemblies of God University" + }, + { + "label": "Southwestern Christian College" + }, + { + "label": "Southwestern Christian University" + }, + { + "label": "Southwestern College-Chula Vista" + }, + { + "label": "Southwestern College-Santa Fe" + }, + { + "label": "Southwestern College-Winfield" + }, + { + "label": "Southwestern Community College-Creston" + }, + { + "label": "Southwestern Community College-Sylva" + }, + { + "label": "Southwestern Illinois College" + }, + { + "label": "Southwestern Indian Polytechnic Institute" + }, + { + "label": "Southwestern Law School" + }, + { + "label": "Southwestern Michigan College" + }, + { + "label": "Southwestern Oklahoma State University" + }, + { + "label": "Southwestern Oregon Community College" + }, + { + "label": "Southwestern University" + }, + { + "label": "SOWELA Technical Community College" + }, + { + "label": "Spalding University" + }, + { + "label": "Spartan College of Aeronautics and Technology" + }, + { + "label": "Spartanburg Community College" + }, + { + "label": "Spartanburg Methodist College" + }, + { + "label": "Spelman College" + }, + { + "label": "Spencerian College-Lexington" + }, + { + "label": "Spencerian College-Louisville" + }, + { + "label": "Spertus College" + }, + { + "label": "Spokane Community College" + }, + { + "label": "Spokane Falls Community College" + }, + { + "label": "Spoon River College" + }, + { + "label": "Spring Arbor University" + }, + { + "label": "Spring Hill College" + }, + { + "label": "Springfield College" + }, + { + "label": "Springfield College-School of Professional and Continuing Studies" + }, + { + "label": "Springfield Technical Community College" + }, + { + "label": "St Andrews University" + }, + { + "label": "St Bernard's School of Theology and Ministry" + }, + { + "label": "St Bonaventure University" + }, + { + "label": "St Catherine University" + }, + { + "label": "St Charles Community College" + }, + { + "label": "St Clair County Community College" + }, + { + "label": "St Cloud Technical and Community College" + }, + { + "label": "St Francis College" + }, + { + "label": "St John's College" + }, + { + "label": "St John's Seminary" + }, + { + "label": "St John's University-New York" + }, + { + "label": "St Joseph School of Nursing-Nashua" + }, + { + "label": "St Joseph's College of Nursing at St Joseph's Hospital Health Center" + }, + { + "label": "St Lawrence University" + }, + { + "label": "St Louis College of Health Careers-Fenton" + }, + { + "label": "St Louis College of Health Careers-St Louis" + }, + { + "label": "St Louis College of Pharmacy" + }, + { + "label": "St Luke's College" + }, + { + "label": "St Mary's College of Maryland" + }, + { + "label": "St Mary's University" + }, + { + "label": "St Olaf College" + }, + { + "label": "St Paul's School of Nursing-Queens" + }, + { + "label": "St Paul's School of Nursing-Staten Island" + }, + { + "label": "St Petersburg College" + }, + { + "label": "St Philip's College" + }, + { + "label": "St Thomas University" + }, + { + "label": "St Vincent's College" + }, + { + "label": "St. Gregory's University" + }, + { + "label": "St. John's College" + }, + { + "label": "St. John's College-Department of Nursing" + }, + { + "label": "St. Thomas Aquinas College" + }, + { + "label": "Stanbridge College" + }, + { + "label": "Standard Healthcare Services-College of Nursing" + }, + { + "label": "Stanford University" + }, + { + "label": "Stanly Community College" + }, + { + "label": "Stark State College" + }, + { + "label": "Starr King School for Ministry" + }, + { + "label": "State College of Florida-Manatee-Sarasota" + }, + { + "label": "State Fair Community College" + }, + { + "label": "State Technical College of Missouri" + }, + { + "label": "State University of New York at New Paltz" + }, + { + "label": "Stautzenberger College-Brecksville" + }, + { + "label": "Stautzenberger College-Maumee" + }, + { + "label": "Stephen F Austin State University" + }, + { + "label": "Stephens College" + }, + { + "label": "Sterling College-Craftsbury Common" + }, + { + "label": "Sterling College-Sterling" + }, + { + "label": "Stetson University" + }, + { + "label": "Stevens Institute of Technology" + }, + { + "label": "Stevens-Henager College-Boise" + }, + { + "label": "Stevens-Henager College-Idaho Falls" + }, + { + "label": "Stevens-Henager College-Logan" + }, + { + "label": "Stevens-Henager College-Murray" + }, + { + "label": "Stevens-Henager College-Orem" + }, + { + "label": "Stevens-Henager College-St. George" + }, + { + "label": "Stevens-Henager College-West Haven" + }, + { + "label": "Stevenson University" + }, + { + "label": "Stevens-The Institute of Business & Arts" + }, + { + "label": "Stillman College" + }, + { + "label": "Stockton University" + }, + { + "label": "Stone Child College" + }, + { + "label": "Stonehill College" + }, + { + "label": "Stony Brook University" + }, + { + "label": "Stratford University" + }, + { + "label": "Strayer University-Alabama" + }, + { + "label": "Strayer University-Arkansas" + }, + { + "label": "Strayer University-Delaware" + }, + { + "label": "Strayer University-District of Columbia" + }, + { + "label": "Strayer University-Florida" + }, + { + "label": "Strayer University-Georgia" + }, + { + "label": "Strayer University-Global Region" + }, + { + "label": "Strayer University-Louisiana" + }, + { + "label": "Strayer University-Maryland" + }, + { + "label": "Strayer University-Mississippi" + }, + { + "label": "Strayer University-New Jersey" + }, + { + "label": "Strayer University-North Carolina" + }, + { + "label": "Strayer University-Pennsylvania" + }, + { + "label": "Strayer University-South Carolina" + }, + { + "label": "Strayer University-Tennessee" + }, + { + "label": "Strayer University-Texas" + }, + { + "label": "Strayer University-Virginia" + }, + { + "label": "Strayer University-West Virginia" + }, + { + "label": "Suffolk County Community College" + }, + { + "label": "Suffolk University" + }, + { + "label": "Sul Ross State University" + }, + { + "label": "Sullivan College of Technology and Design" + }, + { + "label": "Sullivan County Community College" + }, + { + "label": "Sullivan University" + }, + { + "label": "SUM Bible College and Theological Seminary" + }, + { + "label": "Summit Christian College" + }, + { + "label": "Sumner College" + }, + { + "label": "SUNY at Albany" + }, + { + "label": "SUNY at Binghamton" + }, + { + "label": "SUNY at Fredonia" + }, + { + "label": "SUNY at Purchase College" + }, + { + "label": "SUNY Broome Community College" + }, + { + "label": "SUNY Buffalo State" + }, + { + "label": "SUNY College at Brockport" + }, + { + "label": "SUNY College at Cortland" + }, + { + "label": "SUNY College at Geneseo" + }, + { + "label": "SUNY College at Old Westbury" + }, + { + "label": "SUNY College at Oswego" + }, + { + "label": "SUNY College at Plattsburgh" + }, + { + "label": "SUNY College at Potsdam" + }, + { + "label": "SUNY College of Agriculture and Technology at Cobleskill" + }, + { + "label": "SUNY College of Environmental Science and Forestry" + }, + { + "label": "SUNY College of Optometry" + }, + { + "label": "SUNY College of Technology at Alfred" + }, + { + "label": "SUNY College of Technology at Canton" + }, + { + "label": "SUNY College of Technology at Delhi" + }, + { + "label": "SUNY Downstate Medical Center" + }, + { + "label": "SUNY Empire State College" + }, + { + "label": "SUNY Maritime College" + }, + { + "label": "SUNY Oneonta" + }, + { + "label": "SUNY Polytechnic Institute" + }, + { + "label": "SUNY Westchester Community College" + }, + { + "label": "Surry Community College" + }, + { + "label": "Susquehanna University" + }, + { + "label": "Sussex County Community College" + }, + { + "label": "Swarthmore College" + }, + { + "label": "Swedish Institute a College of Health Sciences" + }, + { + "label": "Sweet Briar College" + }, + { + "label": "Syracuse University" + }, + { + "label": "Tabor College" + }, + { + "label": "Tacoma Community College" + }, + { + "label": "Taft College" + }, + { + "label": "Taft University System" + }, + { + "label": "Talladega College" + }, + { + "label": "Tallahassee Community College" + }, + { + "label": "Talmudic College of Florida" + }, + { + "label": "Talmudical Academy-New Jersey" + }, + { + "label": "Talmudical Institute of Upstate New York" + }, + { + "label": "Talmudical Seminary of Bobov" + }, + { + "label": "Talmudical Seminary Oholei Torah" + }, + { + "label": "Talmudical Yeshiva of Philadelphia" + }, + { + "label": "Tarleton State University" + }, + { + "label": "Tarrant County College District" + }, + { + "label": "Taylor Business Institute" + }, + { + "label": "Taylor College" + }, + { + "label": "Taylor University" + }, + { + "label": "Teachers College at Columbia University" + }, + { + "label": "Technical Career Institutes" + }, + { + "label": "Technical College of the Lowcountry" + }, + { + "label": "Telshe Yeshiva-Chicago" + }, + { + "label": "Temple College" + }, + { + "label": "Temple University" + }, + { + "label": "Tennessee State University" + }, + { + "label": "Tennessee Technological University" + }, + { + "label": "Tennessee Temple University" + }, + { + "label": "Tennessee Wesleyan College" + }, + { + "label": "Terra State Community College" + }, + { + "label": "Texarkana College" + }, + { + "label": "Texas A & M International University" + }, + { + "label": "Texas A & M University-Central Texas" + }, + { + "label": "Texas A & M University-College Station" + }, + { + "label": "Texas A & M University-Commerce" + }, + { + "label": "Texas A & M University-Corpus Christi" + }, + { + "label": "Texas A & M University-Kingsville" + }, + { + "label": "Texas A & M University-Texarkana" + }, + { + "label": "Texas Chiropractic College Foundation Inc" + }, + { + "label": "Texas Christian University" + }, + { + "label": "Texas College" + }, + { + "label": "Texas County Technical College" + }, + { + "label": "Texas Health and Science University" + }, + { + "label": "Texas Lutheran University" + }, + { + "label": "Texas Southern University" + }, + { + "label": "Texas State Technical College-Harlingen" + }, + { + "label": "Texas State Technical College-Marshall" + }, + { + "label": "Texas State Technical College-Waco" + }, + { + "label": "Texas State Technical College-West Texas" + }, + { + "label": "Texas State University" + }, + { + "label": "Texas Tech University" + }, + { + "label": "Texas Tech University Health Sciences Center" + }, + { + "label": "Texas Wesleyan University" + }, + { + "label": "Texas Woman's University" + }, + { + "label": "Thaddeus Stevens College of Technology" + }, + { + "label": "The Art Institute of Atlanta" + }, + { + "label": "The Art Institute of Austin" + }, + { + "label": "The Art Institute of Charleston" + }, + { + "label": "The Art Institute of Charlotte" + }, + { + "label": "The Art Institute of Cincinnati-AIC College of Design" + }, + { + "label": "The Art Institute of Colorado" + }, + { + "label": "The Art Institute of Fort Lauderdale" + }, + { + "label": "The Art Institute of Houston" + }, + { + "label": "The Art Institute of Indianapolis" + }, + { + "label": "The Art Institute of Las Vegas" + }, + { + "label": "The Art Institute of Michigan" + }, + { + "label": "The Art Institute of New York City" + }, + { + "label": "The Art Institute of Ohio-Cincinnati" + }, + { + "label": "The Art Institute of Philadelphia" + }, + { + "label": "The Art Institute of Phoenix" + }, + { + "label": "The Art Institute of Pittsburgh" + }, + { + "label": "The Art Institute of Pittsburgh-Online Division" + }, + { + "label": "The Art Institute of Portland" + }, + { + "label": "The Art Institute of Raleigh-Durham" + }, + { + "label": "The Art Institute of Salt Lake City" + }, + { + "label": "The Art Institute of San Antonio" + }, + { + "label": "The Art Institute of Seattle" + }, + { + "label": "The Art Institute of St Louis" + }, + { + "label": "The Art Institute of Tennessee-Nashville" + }, + { + "label": "The Art Institute of Tucson" + }, + { + "label": "The Art Institute of Virginia Beach" + }, + { + "label": "The Art Institute of Washington" + }, + { + "label": "The Art Institute of Washington-Dulles" + }, + { + "label": "The Art Institute of Wisconsin" + }, + { + "label": "The Art Institutes International–Kansas City" + }, + { + "label": "The Art Institutes International-Minnesota" + }, + { + "label": "The Art Institutes of York-PA" + }, + { + "label": "The Baptist College of Florida" + }, + { + "label": "The Boston Conservatory" + }, + { + "label": "The California Maritime Academy" + }, + { + "label": "The Chicago School of Professional Psychology at Chicago" + }, + { + "label": "The Chicago School of Professional Psychology at Irvine" + }, + { + "label": "The Chicago School of Professional Psychology at Los Angeles" + }, + { + "label": "The Chicago School of Professional Psychology at Washington DC" + }, + { + "label": "The Chicago School of Professional Psychology at Westwood" + }, + { + "label": "The Christ College of Nursing and Health Sciences" + }, + { + "label": "The College of Health Care Professions-Austin" + }, + { + "label": "The College of Health Care Professions-Dallas" + }, + { + "label": "The College of Health Care Professions-Fort Worth" + }, + { + "label": "The College of Idaho" + }, + { + "label": "The College of New Jersey" + }, + { + "label": "The College of New Rochelle" + }, + { + "label": "The College of Saint Rose" + }, + { + "label": "The College of Saint Scholastica" + }, + { + "label": "The College of Westchester" + }, + { + "label": "The College of Wooster" + }, + { + "label": "The Commonwealth Medical College" + }, + { + "label": "The Community College of Baltimore County" + }, + { + "label": "The Creative Center" + }, + { + "label": "The Evergreen State College" + }, + { + "label": "The General Theological Seminary" + }, + { + "label": "The Illinois Institute of Art-Chicago" + }, + { + "label": "The Illinois Institute of Art-Schaumburg" + }, + { + "label": "The John Marshall Law School" + }, + { + "label": "The Juilliard School" + }, + { + "label": "The King’s College" + }, + { + "label": "The King's University" + }, + { + "label": "The Landing School" + }, + { + "label": "The Lincoln University" + }, + { + "label": "The Master's College and Seminary" + }, + { + "label": "The National Hispanic University" + }, + { + "label": "The New England Conservatory of Music" + }, + { + "label": "The New England Institute of Art" + }, + { + "label": "The New School" + }, + { + "label": "The Restaurant School at Walnut Hill College" + }, + { + "label": "The Robert B Miller College" + }, + { + "label": "The Sage Colleges" + }, + { + "label": "The Santa Barbara and Ventura Colleges of Law–Santa Barbara" + }, + { + "label": "The Santa Barbara and Ventura Colleges of Law-Ventura" + }, + { + "label": "The Seattle School of Theology & Psychology" + }, + { + "label": "The Southern Baptist Theological Seminary" + }, + { + "label": "The University of Alabama" + }, + { + "label": "The University of Findlay" + }, + { + "label": "The University of Montana" + }, + { + "label": "The University of Montana-Western" + }, + { + "label": "The University of Tampa" + }, + { + "label": "The University of Tennessee-Chattanooga" + }, + { + "label": "The University of Tennessee-Knoxville" + }, + { + "label": "The University of Tennessee-Martin" + }, + { + "label": "The University of Texas - Rio Grande Valley" + }, + { + "label": "The University of Texas at Arlington" + }, + { + "label": "The University of Texas at Austin" + }, + { + "label": "The University of Texas at Dallas" + }, + { + "label": "The University of Texas at El Paso" + }, + { + "label": "The University of Texas at San Antonio" + }, + { + "label": "The University of Texas at Tyler" + }, + { + "label": "The University of Texas Health Science Center at Houston" + }, + { + "label": "The University of Texas Health Science Center at San Antonio" + }, + { + "label": "The University of Texas MD Anderson Cancer Center" + }, + { + "label": "The University of Texas Medical Branch" + }, + { + "label": "The University of Texas of the Permian Basin" + }, + { + "label": "The University of the Arts" + }, + { + "label": "The University of Virginia's College at Wise" + }, + { + "label": "The University of West Florida" + }, + { + "label": "The Wright Institute" + }, + { + "label": "Thiel College" + }, + { + "label": "Thomas Aquinas College" + }, + { + "label": "Thomas College" + }, + { + "label": "Thomas Edison State University" + }, + { + "label": "Thomas Jefferson School of Law" + }, + { + "label": "Thomas Jefferson University" + }, + { + "label": "Thomas More College" + }, + { + "label": "Thomas More College of Liberal Arts" + }, + { + "label": "Thomas Nelson Community College" + }, + { + "label": "Thomas University" + }, + { + "label": "Three Rivers Community College-Norwich" + }, + { + "label": "Three Rivers Community College-Poplar Bluff" + }, + { + "label": "Thunderbird School of Global Management" + }, + { + "label": "Tidewater Community College" + }, + { + "label": "Tiffin University" + }, + { + "label": "Tillamook Bay Community College" + }, + { + "label": "Toccoa Falls College" + }, + { + "label": "Tohono O'Odham Community College" + }, + { + "label": "Tompkins Cortland Community College" + }, + { + "label": "Torah Temimah Talmudical Seminary" + }, + { + "label": "Tougaloo College" + }, + { + "label": "Touro College" + }, + { + "label": "Touro University California" + }, + { + "label": "Touro University Nevada" + }, + { + "label": "Touro University Worldwide" + }, + { + "label": "Towson University" + }, + { + "label": "Transylvania University" + }, + { + "label": "Treasure Valley Community College" + }, + { + "label": "Trevecca Nazarene University" + }, + { + "label": "Triangle Tech Inc-Bethlehem" + }, + { + "label": "Triangle Tech Inc-Dubois" + }, + { + "label": "Triangle Tech Inc-Erie" + }, + { + "label": "Triangle Tech Inc-Greensburg" + }, + { + "label": "Triangle Tech Inc-Pittsburgh" + }, + { + "label": "Triangle Tech Inc-Sunbury" + }, + { + "label": "Tribeca Flashpoint College" + }, + { + "label": "Tri-County Community College" + }, + { + "label": "Tri-County Technical College" + }, + { + "label": "Trident Technical College" + }, + { + "label": "Trident University International" + }, + { + "label": "Trine University" + }, + { + "label": "Trine University-Regional/Non-Traditional Campuses" + }, + { + "label": "Trinidad State Junior College" + }, + { + "label": "Trinity Baptist College" + }, + { + "label": "Trinity Bible College" + }, + { + "label": "Trinity Christian College" + }, + { + "label": "Trinity College" + }, + { + "label": "Trinity College of Florida" + }, + { + "label": "Trinity College of Nursing & Health Sciences" + }, + { + "label": "Trinity Episcopal School for Ministry" + }, + { + "label": "Trinity International University-Florida" + }, + { + "label": "Trinity International University-Illinois" + }, + { + "label": "Trinity Law School" + }, + { + "label": "Trinity Lutheran College" + }, + { + "label": "Trinity Lutheran Seminary" + }, + { + "label": "Trinity University" + }, + { + "label": "Trinity Valley Community College" + }, + { + "label": "Trinity Washington University" + }, + { + "label": "Tri-State Bible College" + }, + { + "label": "Tri-State College of Acupuncture" + }, + { + "label": "Triton College" + }, + { + "label": "Trocaire College" + }, + { + "label": "Troy University" + }, + { + "label": "Truckee Meadows Community College" + }, + { + "label": "Truett-McConnell College" + }, + { + "label": "Truman State University" + }, + { + "label": "Trumbull Business College" + }, + { + "label": "Tufts University" + }, + { + "label": "Tulane University of Louisiana" + }, + { + "label": "Tulsa Community College" + }, + { + "label": "Tulsa Welding School-Tulsa-Tulsa" + }, + { + "label": "Tunxis Community College" + }, + { + "label": "Turtle Mountain Community College" + }, + { + "label": "Tusculum College" + }, + { + "label": "Tuskegee University" + }, + { + "label": "Tyler Junior College" + }, + { + "label": "Ulster County Community College" + }, + { + "label": "Ultimate Medical Academy-Clearwater" + }, + { + "label": "Ultimate Medical Academy-Tampa" + }, + { + "label": "Ultrasound Medical Institute" + }, + { + "label": "Umpqua Community College" + }, + { + "label": "Unification Theological Seminary" + }, + { + "label": "Union College-Barbourville" + }, + { + "label": "Union College-Lincoln" + }, + { + "label": "Union College-Schenectady" + }, + { + "label": "Union County College" + }, + { + "label": "Union Graduate College" + }, + { + "label": "Union Institute & University" + }, + { + "label": "Union Presbyterian Seminary" + }, + { + "label": "Union Theological Seminary in the City of New York" + }, + { + "label": "Union University" + }, + { + "label": "United Education Institute-Huntington Park Campus" + }, + { + "label": "United States Air Force Academy" + }, + { + "label": "United States Coast Guard Academy" + }, + { + "label": "United States Merchant Marine Academy" + }, + { + "label": "United States Military Academy" + }, + { + "label": "United States Naval Academy" + }, + { + "label": "United States Sports Academy" + }, + { + "label": "United States University" + }, + { + "label": "United Talmudical Seminary" + }, + { + "label": "United Theological Seminary" + }, + { + "label": "United Theological Seminary of the Twin Cities" + }, + { + "label": "United Tribes Technical College" + }, + { + "label": "Unitek College" + }, + { + "label": "Unity College" + }, + { + "label": "Universal College of Healing Arts" + }, + { + "label": "Universal Technical Institute of Arizona Inc" + }, + { + "label": "Universal Technology College of Puerto Rico" + }, + { + "label": "Universidad Adventista de las Antillas" + }, + { + "label": "Universidad Central de Bayamon" + }, + { + "label": "Universidad Central Del Caribe" + }, + { + "label": "Universidad Del Este" + }, + { + "label": "Universidad del Sagrado Corazon" + }, + { + "label": "Universidad Del Turabo" + }, + { + "label": "Universidad Internacional Iberoamericana" + }, + { + "label": "Universidad Metropolitana" + }, + { + "label": "Universidad Pentecostal Mizpa" + }, + { + "label": "Universidad Politecnica de Puerto Rico" + }, + { + "label": "Universidad Teologica del Caribe" + }, + { + "label": "University at Buffalo" + }, + { + "label": "University of Advancing Technology" + }, + { + "label": "University of Akron Main Campus" + }, + { + "label": "University of Akron Wayne College" + }, + { + "label": "University of Alabama at Birmingham" + }, + { + "label": "University of Alabama in Huntsville" + }, + { + "label": "University of Alaska Anchorage" + }, + { + "label": "University of Alaska Fairbanks" + }, + { + "label": "University of Alaska Southeast" + }, + { + "label": "University of Antelope Valley" + }, + { + "label": "University of Arizona" + }, + { + "label": "University of Arkansas" + }, + { + "label": "University of Arkansas at Little Rock" + }, + { + "label": "University of Arkansas at Monticello" + }, + { + "label": "University of Arkansas at Pine Bluff" + }, + { + "label": "University of Arkansas Community College-Batesville" + }, + { + "label": "University of Arkansas Community College-Hope" + }, + { + "label": "University of Arkansas Community College-Morrilton" + }, + { + "label": "University of Arkansas for Medical Sciences" + }, + { + "label": "University of Arkansas-Fort Smith" + }, + { + "label": "University of Baltimore" + }, + { + "label": "University of Bridgeport" + }, + { + "label": "University of California-Berkeley" + }, + { + "label": "University of California-Davis" + }, + { + "label": "University of California-Hastings College of Law" + }, + { + "label": "University of California-Irvine" + }, + { + "label": "University of California-Los Angeles" + }, + { + "label": "University of California-Merced" + }, + { + "label": "University of California-Riverside" + }, + { + "label": "University of California-San Diego" + }, + { + "label": "University of California-San Francisco" + }, + { + "label": "University of California-Santa Barbara" + }, + { + "label": "University of California-Santa Cruz" + }, + { + "label": "University of Central Arkansas" + }, + { + "label": "University of Central Florida" + }, + { + "label": "University of Central Missouri" + }, + { + "label": "University of Central Oklahoma" + }, + { + "label": "University of Charleston" + }, + { + "label": "University of Chicago" + }, + { + "label": "University of Cincinnati-Blue Ash College" + }, + { + "label": "University of Cincinnati-Clermont College" + }, + { + "label": "University of Cincinnati-Main Campus" + }, + { + "label": "University of Colorado Boulder" + }, + { + "label": "University of Colorado Colorado Springs" + }, + { + "label": "University of Colorado Denver" + }, + { + "label": "University of Connecticut" + }, + { + "label": "University of Dallas" + }, + { + "label": "University of Dayton" + }, + { + "label": "University of Delaware" + }, + { + "label": "University of Denver" + }, + { + "label": "University of Detroit Mercy" + }, + { + "label": "University of Dubuque" + }, + { + "label": "University of East-West Medicine" + }, + { + "label": "University of Evansville" + }, + { + "label": "University of Florida" + }, + { + "label": "University of Fort Lauderdale" + }, + { + "label": "University of Georgia" + }, + { + "label": "University of Great Falls" + }, + { + "label": "University of Guam" + }, + { + "label": "University of Hartford" + }, + { + "label": "University of Hawaii at Hilo" + }, + { + "label": "University of Hawaii at Manoa" + }, + { + "label": "University of Hawaii Maui College" + }, + { + "label": "University of Hawaii-West Oahu" + }, + { + "label": "University of Holy Cross" + }, + { + "label": "University of Houston" + }, + { + "label": "University of Houston-Clear Lake" + }, + { + "label": "University of Houston-Downtown" + }, + { + "label": "University of Houston-Victoria" + }, + { + "label": "University of Idaho" + }, + { + "label": "University of Illinois at Chicago" + }, + { + "label": "University of Illinois at Springfield" + }, + { + "label": "University of Illinois at Urbana-Champaign" + }, + { + "label": "University of Indianapolis" + }, + { + "label": "University of Iowa" + }, + { + "label": "University of Jamestown" + }, + { + "label": "University of Kansas" + }, + { + "label": "University of Kentucky" + }, + { + "label": "University of La Verne" + }, + { + "label": "University of Louisiana at Lafayette" + }, + { + "label": "University of Louisiana at Monroe" + }, + { + "label": "University of Louisville" + }, + { + "label": "University of Maine" + }, + { + "label": "University of Maine at Augusta" + }, + { + "label": "University of Maine at Farmington" + }, + { + "label": "University of Maine at Fort Kent" + }, + { + "label": "University of Maine at Machias" + }, + { + "label": "University of Maine at Presque Isle" + }, + { + "label": "University of Management and Technology" + }, + { + "label": "University of Mary" + }, + { + "label": "University of Mary Hardin-Baylor" + }, + { + "label": "University of Mary Washington" + }, + { + "label": "University of Maryland Eastern Shore" + }, + { + "label": "University of Maryland-Baltimore" + }, + { + "label": "University of Maryland-Baltimore County" + }, + { + "label": "University of Maryland-College Park" + }, + { + "label": "University of Maryland-University College" + }, + { + "label": "University of Massachusetts Medical School Worcester" + }, + { + "label": "University of Massachusetts-Amherst" + }, + { + "label": "University of Massachusetts-Boston" + }, + { + "label": "University of Massachusetts-Dartmouth" + }, + { + "label": "University of Massachusetts-Lowell" + }, + { + "label": "University of Memphis" + }, + { + "label": "University of Miami" + }, + { + "label": "University of Michigan-Ann Arbor" + }, + { + "label": "University of Michigan-Dearborn" + }, + { + "label": "University of Michigan-Flint" + }, + { + "label": "University of Minnesota-Crookston" + }, + { + "label": "University of Minnesota-Duluth" + }, + { + "label": "University of Minnesota-Morris" + }, + { + "label": "University of Minnesota-Rochester" + }, + { + "label": "University of Minnesota-Twin Cities" + }, + { + "label": "University of Mississippi" + }, + { + "label": "University of Missouri-Columbia" + }, + { + "label": "University of Missouri-Kansas City" + }, + { + "label": "University of Missouri-St Louis" + }, + { + "label": "University of Mobile" + }, + { + "label": "University of Montevallo" + }, + { + "label": "University of Mount Olive" + }, + { + "label": "University of Mount Union" + }, + { + "label": "University of Nebraska at Kearney" + }, + { + "label": "University of Nebraska at Omaha" + }, + { + "label": "University of Nebraska Medical Center" + }, + { + "label": "University of Nebraska-Lincoln" + }, + { + "label": "University of Nevada-Las Vegas" + }, + { + "label": "University of Nevada-Reno" + }, + { + "label": "University of New England" + }, + { + "label": "University of New Hampshire at Manchester" + }, + { + "label": "University of New Hampshire-Main Campus" + }, + { + "label": "University of New Hampshire-School of Law" + }, + { + "label": "University of New Haven" + }, + { + "label": "University of New Mexico-Gallup Campus" + }, + { + "label": "University of New Mexico-Los Alamos Campus" + }, + { + "label": "University of New Mexico-Main Campus" + }, + { + "label": "University of New Mexico-Taos Campus" + }, + { + "label": "University of New Mexico-Valencia County Campus" + }, + { + "label": "University of New Orleans" + }, + { + "label": "University of North Alabama" + }, + { + "label": "University of North Carolina at Asheville" + }, + { + "label": "University of North Carolina at Chapel Hill" + }, + { + "label": "University of North Carolina at Charlotte" + }, + { + "label": "University of North Carolina at Greensboro" + }, + { + "label": "University of North Carolina at Pembroke" + }, + { + "label": "University of North Carolina School of the Arts" + }, + { + "label": "University of North Carolina Wilmington" + }, + { + "label": "University of North Dakota" + }, + { + "label": "University of North Florida" + }, + { + "label": "University of North Georgia" + }, + { + "label": "University of North Texas" + }, + { + "label": "University of North Texas at Dallas" + }, + { + "label": "University of North Texas Health Science Center" + }, + { + "label": "University of Northern Colorado" + }, + { + "label": "University of Northern Iowa" + }, + { + "label": "University of Northwestern Ohio" + }, + { + "label": "University of Northwestern-St Paul" + }, + { + "label": "University of Notre Dame" + }, + { + "label": "University of Oklahoma-Health Sciences Center" + }, + { + "label": "University of Oklahoma-Norman Campus" + }, + { + "label": "University of Oregon" + }, + { + "label": "University of Pennsylvania" + }, + { + "label": "University of Phoenix-Alabama" + }, + { + "label": "University of Phoenix-Arizona" + }, + { + "label": "University of Phoenix-Arkansas" + }, + { + "label": "University of Phoenix-California" + }, + { + "label": "University of Phoenix-Colorado" + }, + { + "label": "University of Phoenix-Connecticut" + }, + { + "label": "University of Phoenix-Florida" + }, + { + "label": "University of Phoenix-Georgia" + }, + { + "label": "University of Phoenix-Hawaii" + }, + { + "label": "University of Phoenix-Idaho" + }, + { + "label": "University of Phoenix-Illinois" + }, + { + "label": "University of Phoenix-Indiana" + }, + { + "label": "University of Phoenix-Iowa" + }, + { + "label": "University of Phoenix-Kentucky" + }, + { + "label": "University of Phoenix-Louisiana" + }, + { + "label": "University of Phoenix-Maryland" + }, + { + "label": "University of Phoenix-Massachusetts" + }, + { + "label": "University of Phoenix-Michigan" + }, + { + "label": "University of Phoenix-Minnesota" + }, + { + "label": "University of Phoenix-Mississippi" + }, + { + "label": "University of Phoenix-Missouri" + }, + { + "label": "University of Phoenix-Nevada" + }, + { + "label": "University of Phoenix-New Jersey" + }, + { + "label": "University of Phoenix-New Mexico" + }, + { + "label": "University of Phoenix-North Carolina" + }, + { + "label": "University of Phoenix-Ohio" + }, + { + "label": "University of Phoenix-Oklahoma" + }, + { + "label": "University of Phoenix-Oregon" + }, + { + "label": "University of Phoenix-Pennsylvania" + }, + { + "label": "University of Phoenix-Puerto Rico" + }, + { + "label": "University of Phoenix-South Carolina" + }, + { + "label": "University of Phoenix-Tennessee" + }, + { + "label": "University of Phoenix-Texas" + }, + { + "label": "University of Phoenix-Utah" + }, + { + "label": "University of Phoenix-Virginia" + }, + { + "label": "University of Phoenix-Washington" + }, + { + "label": "University of Phoenix-Washington DC" + }, + { + "label": "University of Phoenix-Wisconsin" + }, + { + "label": "University of Pikeville" + }, + { + "label": "University of Pittsburgh-Bradford" + }, + { + "label": "University of Pittsburgh-Greensburg" + }, + { + "label": "University of Pittsburgh-Johnstown" + }, + { + "label": "University of Pittsburgh-Pittsburgh Campus" + }, + { + "label": "University of Pittsburgh-Titusville" + }, + { + "label": "University of Portland" + }, + { + "label": "University of Puerto Rico-Aguadilla" + }, + { + "label": "University of Puerto Rico-Arecibo" + }, + { + "label": "University of Puerto Rico-Bayamon" + }, + { + "label": "University of Puerto Rico-Carolina" + }, + { + "label": "University of Puerto Rico-Cayey" + }, + { + "label": "University of Puerto Rico-Humacao" + }, + { + "label": "University of Puerto Rico-Mayaguez" + }, + { + "label": "University of Puerto Rico-Medical Sciences" + }, + { + "label": "University of Puerto Rico-Ponce" + }, + { + "label": "University of Puerto Rico-Rio Piedras" + }, + { + "label": "University of Puerto Rico-Utuado" + }, + { + "label": "University of Puget Sound" + }, + { + "label": "University of Redlands" + }, + { + "label": "University of Rhode Island" + }, + { + "label": "University of Richmond" + }, + { + "label": "University of Rio Grande" + }, + { + "label": "University of Rochester" + }, + { + "label": "University of Saint Francis-Fort Wayne" + }, + { + "label": "University of Saint Joseph" + }, + { + "label": "University of Saint Mary" + }, + { + "label": "University of Saint Mary of the Lake" + }, + { + "label": "University of San Diego" + }, + { + "label": "University of San Francisco" + }, + { + "label": "University of Science and Arts of Oklahoma" + }, + { + "label": "University of Scranton" + }, + { + "label": "University of Sioux Falls" + }, + { + "label": "University of South Alabama" + }, + { + "label": "University of South Carolina-Aiken" + }, + { + "label": "University of South Carolina-Beaufort" + }, + { + "label": "University of South Carolina-Columbia" + }, + { + "label": "University of South Carolina-Lancaster" + }, + { + "label": "University of South Carolina-Salkehatchie" + }, + { + "label": "University of South Carolina-Sumter" + }, + { + "label": "University of South Carolina-Union" + }, + { + "label": "University of South Carolina-Upstate" + }, + { + "label": "University of South Dakota" + }, + { + "label": "University of South Florida-Main Campus" + }, + { + "label": "University of South Florida-Sarasota-Manatee" + }, + { + "label": "University of South Florida-St Petersburg" + }, + { + "label": "University of Southern California" + }, + { + "label": "University of Southern Indiana" + }, + { + "label": "University of Southern Maine" + }, + { + "label": "University of Southern Mississippi" + }, + { + "label": "University of Southernmost Florida" + }, + { + "label": "University of St Augustine for Health Sciences" + }, + { + "label": "University of St Francis" + }, + { + "label": "University of St Thomas-Houston" + }, + { + "label": "University of St Thomas-Saint Paul" + }, + { + "label": "University of Texas Southwestern Medical Center" + }, + { + "label": "University of the Cumberlands" + }, + { + "label": "University of the District of Columbia" + }, + { + "label": "University of the District of Columbia-David A Clarke School of Law" + }, + { + "label": "University of the Incarnate Word" + }, + { + "label": "University of the Ozarks" + }, + { + "label": "University of the Pacific" + }, + { + "label": "University of the Potomac-VA Campus" + }, + { + "label": "University of the Potomac-Washington DC Campus" + }, + { + "label": "University of the Rockies" + }, + { + "label": "University of the Sciences" + }, + { + "label": "University of the Southwest" + }, + { + "label": "University of the Virgin Islands" + }, + { + "label": "University of the West" + }, + { + "label": "University of Toledo" + }, + { + "label": "University of Tulsa" + }, + { + "label": "University of Utah" + }, + { + "label": "University of Valley Forge" + }, + { + "label": "University of Vermont" + }, + { + "label": "University of Virginia-Main Campus" + }, + { + "label": "University of Washington-Bothell Campus" + }, + { + "label": "University of Washington-Seattle Campus" + }, + { + "label": "University of Washington-Tacoma Campus" + }, + { + "label": "University of West Alabama" + }, + { + "label": "University of West Georgia" + }, + { + "label": "University of Western States" + }, + { + "label": "University of Wisconsin Colleges" + }, + { + "label": "University of Wisconsin-Eau Claire" + }, + { + "label": "University of Wisconsin-Green Bay" + }, + { + "label": "University of Wisconsin-La Crosse" + }, + { + "label": "University of Wisconsin-Madison" + }, + { + "label": "University of Wisconsin-Milwaukee" + }, + { + "label": "University of Wisconsin-Oshkosh" + }, + { + "label": "University of Wisconsin-Parkside" + }, + { + "label": "University of Wisconsin-Platteville" + }, + { + "label": "University of Wisconsin-River Falls" + }, + { + "label": "University of Wisconsin-Stevens Point" + }, + { + "label": "University of Wisconsin-Stout" + }, + { + "label": "University of Wisconsin-Superior" + }, + { + "label": "University of Wisconsin-Whitewater" + }, + { + "label": "University of Wyoming" + }, + { + "label": "Upper Iowa University" + }, + { + "label": "Upstate Medical University" + }, + { + "label": "Urban College of Boston" + }, + { + "label": "Urbana University" + }, + { + "label": "Urshan Graduate School of Theology" + }, + { + "label": "Ursinus College" + }, + { + "label": "Ursuline College" + }, + { + "label": "Uta Mesivta of Kiryas Joel" + }, + { + "label": "Utah State University" + }, + { + "label": "Utah Valley University" + }, + { + "label": "Utica College" + }, + { + "label": "Utica School of Commerce" + }, + { + "label": "Valdosta State University" + }, + { + "label": "Valencia College" + }, + { + "label": "Valley City State University" + }, + { + "label": "Valley College-Beckley" + }, + { + "label": "Valparaiso University" + }, + { + "label": "Vance-Granville Community College" + }, + { + "label": "Vanderbilt University" + }, + { + "label": "VanderCook College of Music" + }, + { + "label": "Vanguard University of Southern California" + }, + { + "label": "Vassar College" + }, + { + "label": "Vatterott College-Appling Farms" + }, + { + "label": "Vatterott College-Berkeley" + }, + { + "label": "Vatterott College-Cleveland" + }, + { + "label": "Vatterott College-Des Moines" + }, + { + "label": "Vatterott College-Dividend" + }, + { + "label": "Vatterott College-ex'treme Institute by Nelly-St Louis" + }, + { + "label": "Vatterott College-Joplin" + }, + { + "label": "Vatterott College-Kansas City" + }, + { + "label": "Vatterott College-Oklahoma City" + }, + { + "label": "Vatterott College-Quincy" + }, + { + "label": "Vatterott College-Spring Valley" + }, + { + "label": "Vatterott College-Springfield" + }, + { + "label": "Vatterott College-St Charles" + }, + { + "label": "Vatterott College-St Joseph" + }, + { + "label": "Vatterott College-Sunset Hills" + }, + { + "label": "Vatterott College-Tulsa" + }, + { + "label": "Vatterott College-Wichita" + }, + { + "label": "Vaughn College of Aeronautics and Technology" + }, + { + "label": "Ventura College" + }, + { + "label": "Vermilion Community College" + }, + { + "label": "Vermont College of Fine Arts" + }, + { + "label": "Vermont Law School" + }, + { + "label": "Vermont Technical College" + }, + { + "label": "Vernon College" + }, + { + "label": "Vet Tech Institute" + }, + { + "label": "Vet Tech Institute of Houston" + }, + { + "label": "Victor Valley College" + }, + { + "label": "Victoria College" + }, + { + "label": "Villa Maria College" + }, + { + "label": "Villanova University" + }, + { + "label": "Vincennes University" + }, + { + "label": "Virginia Baptist College" + }, + { + "label": "Virginia College-Augusta" + }, + { + "label": "Virginia College-Austin" + }, + { + "label": "Virginia College-Baton Rouge" + }, + { + "label": "Virginia College-Biloxi" + }, + { + "label": "Virginia College-Birmingham" + }, + { + "label": "Virginia College-Charleston" + }, + { + "label": "Virginia College-Columbia" + }, + { + "label": "Virginia College-Columbus" + }, + { + "label": "Virginia College-Florence" + }, + { + "label": "Virginia College-Greenville" + }, + { + "label": "Virginia College-Huntsville" + }, + { + "label": "Virginia College-Jackson" + }, + { + "label": "Virginia College-Jacksonville" + }, + { + "label": "Virginia College-Knoxville" + }, + { + "label": "Virginia College-Macon" + }, + { + "label": "Virginia College-Mobile" + }, + { + "label": "Virginia College-Montgomery" + }, + { + "label": "Virginia College-Pensacola" + }, + { + "label": "Virginia College-Richmond" + }, + { + "label": "Virginia College-Savannah" + }, + { + "label": "Virginia College-School of Business and Health-Chattanooga" + }, + { + "label": "Virginia College-Shreveport Bossier City" + }, + { + "label": "Virginia College-Spartanburg" + }, + { + "label": "Virginia College-Tulsa" + }, + { + "label": "Virginia Commonwealth University" + }, + { + "label": "Virginia Highlands Community College" + }, + { + "label": "Virginia Marti College of Art and Design" + }, + { + "label": "Virginia Military Institute" + }, + { + "label": "Virginia Polytechnic Institute and State University" + }, + { + "label": "Virginia State University" + }, + { + "label": "Virginia Tech Carilion School of Medicine" + }, + { + "label": "Virginia Union University" + }, + { + "label": "Virginia University of Lynchburg" + }, + { + "label": "Virginia Wesleyan College" + }, + { + "label": "Virginia Western Community College" + }, + { + "label": "Visible Music College" + }, + { + "label": "Vista College" + }, + { + "label": "Vista College-Online" + }, + { + "label": "Viterbo University" + }, + { + "label": "Volunteer State Community College" + }, + { + "label": "Voorhees College" + }, + { + "label": "Wabash College" + }, + { + "label": "Wabash Valley College" + }, + { + "label": "Wade College" + }, + { + "label": "Wagner College" + }, + { + "label": "Wake Forest University" + }, + { + "label": "Wake Technical Community College" + }, + { + "label": "Walden University" + }, + { + "label": "Waldorf College" + }, + { + "label": "Walla Walla Community College" + }, + { + "label": "Walla Walla University" + }, + { + "label": "Walsh College of Accountancy and Business Administration" + }, + { + "label": "Walsh University" + }, + { + "label": "Walters State Community College" + }, + { + "label": "Warner Pacific College" + }, + { + "label": "Warner Pacific College Adult Degree Program" + }, + { + "label": "Warner University" + }, + { + "label": "Warren County Community College" + }, + { + "label": "Warren Wilson College" + }, + { + "label": "Wartburg College" + }, + { + "label": "Wartburg Theological Seminary" + }, + { + "label": "Washburn University" + }, + { + "label": "Washington & Jefferson College" + }, + { + "label": "Washington Adventist University" + }, + { + "label": "Washington and Lee University" + }, + { + "label": "Washington College" + }, + { + "label": "Washington County Community College" + }, + { + "label": "Washington State Community College" + }, + { + "label": "Washington State University" + }, + { + "label": "Washington University in St Louis" + }, + { + "label": "Washtenaw Community College" + }, + { + "label": "Watkins College of Art Design & Film" + }, + { + "label": "Waubonsee Community College" + }, + { + "label": "Waukesha County Technical College" + }, + { + "label": "Wayland Baptist University" + }, + { + "label": "Wayne Community College" + }, + { + "label": "Wayne County Community College District" + }, + { + "label": "Wayne State College" + }, + { + "label": "Wayne State University" + }, + { + "label": "Waynesburg University" + }, + { + "label": "Weatherford College" + }, + { + "label": "Webb Institute" + }, + { + "label": "Webber International University" + }, + { + "label": "Weber State University" + }, + { + "label": "Webster University" + }, + { + "label": "Weill Cornell Medicine" + }, + { + "label": "Welch College" + }, + { + "label": "Wellesley College" + }, + { + "label": "Wells College" + }, + { + "label": "WellSpring School of Allied Health-Kansas City" + }, + { + "label": "Wenatchee Valley College" + }, + { + "label": "Wentworth Institute of Technology" + }, + { + "label": "Wentworth Military Academy and College" + }, + { + "label": "Wesley Biblical Seminary" + }, + { + "label": "Wesley College" + }, + { + "label": "Wesley Theological Seminary" + }, + { + "label": "Wesleyan College" + }, + { + "label": "Wesleyan University" + }, + { + "label": "West Chester University of Pennsylvania" + }, + { + "label": "West Coast Ultrasound Institute" + }, + { + "label": "West Coast University-Dallas" + }, + { + "label": "West Coast University-Los Angeles" + }, + { + "label": "West Coast University-Ontario" + }, + { + "label": "West Coast University-Orange County" + }, + { + "label": "West Georgia Technical College" + }, + { + "label": "West Hills College-Coalinga" + }, + { + "label": "West Hills College-Lemoore" + }, + { + "label": "West Kentucky Community and Technical College" + }, + { + "label": "West Liberty University" + }, + { + "label": "West Los Angeles College" + }, + { + "label": "West Shore Community College" + }, + { + "label": "West Tennessee Business College" + }, + { + "label": "West Texas A & M University" + }, + { + "label": "West Valley College" + }, + { + "label": "West Virginia Business College-Wheeling" + }, + { + "label": "West Virginia Junior College-Bridgeport" + }, + { + "label": "West Virginia Junior College-Charleston" + }, + { + "label": "West Virginia Junior College-Morgantown" + }, + { + "label": "West Virginia Northern Community College" + }, + { + "label": "West Virginia School of Osteopathic Medicine" + }, + { + "label": "West Virginia State University" + }, + { + "label": "West Virginia University" + }, + { + "label": "West Virginia University at Parkersburg" + }, + { + "label": "West Virginia University Institute of Technology" + }, + { + "label": "West Virginia Wesleyan College" + }, + { + "label": "Western Carolina University" + }, + { + "label": "Western Connecticut State University" + }, + { + "label": "Western Dakota Technical Institute" + }, + { + "label": "Western Governors University" + }, + { + "label": "Western Illinois University" + }, + { + "label": "Western International University" + }, + { + "label": "Western Iowa Tech Community College" + }, + { + "label": "Western Kentucky University" + }, + { + "label": "Western Michigan University" + }, + { + "label": "Western Michigan University-Thomas M. Cooley Law School" + }, + { + "label": "Western Nebraska Community College" + }, + { + "label": "Western Nevada College" + }, + { + "label": "Western New England University" + }, + { + "label": "Western New Mexico University" + }, + { + "label": "Western Oklahoma State College" + }, + { + "label": "Western Oregon University" + }, + { + "label": "Western Piedmont Community College" + }, + { + "label": "Western Seminary" + }, + { + "label": "Western State College of Law at Argosy University" + }, + { + "label": "Western State Colorado University" + }, + { + "label": "Western Technical College-El Paso" + }, + { + "label": "Western Technical College-El Paso" + }, + { + "label": "Western Technical College-La Crosse" + }, + { + "label": "Western Texas College" + }, + { + "label": "Western Theological Seminary" + }, + { + "label": "Western University of Health Sciences" + }, + { + "label": "Western Washington University" + }, + { + "label": "Western Wyoming Community College" + }, + { + "label": "Westfield State University" + }, + { + "label": "Westminster College-Fulton" + }, + { + "label": "Westminster College-New Wilmington" + }, + { + "label": "Westminster College-Salt Lake City" + }, + { + "label": "Westminster Theological Seminary" + }, + { + "label": "Westminster Theological Seminary in California" + }, + { + "label": "Westmont College" + }, + { + "label": "Westmoreland County Community College" + }, + { + "label": "Westwood College-Anaheim" + }, + { + "label": "Westwood College-Annandale" + }, + { + "label": "Westwood College-Arlington Ballston" + }, + { + "label": "Westwood College-Atlanta Midtown" + }, + { + "label": "Westwood College-Chicago Loop" + }, + { + "label": "Westwood College-Denver North" + }, + { + "label": "Westwood College-Denver South" + }, + { + "label": "Westwood College-Dupage" + }, + { + "label": "Westwood College-Inland Empire" + }, + { + "label": "Westwood College-Los Angeles" + }, + { + "label": "Westwood College-Northlake" + }, + { + "label": "Westwood College-O'Hare Airport" + }, + { + "label": "Westwood College-River Oaks" + }, + { + "label": "Westwood College-South Bay" + }, + { + "label": "Wharton County Junior College" + }, + { + "label": "Whatcom Community College" + }, + { + "label": "Wheaton College-Norton" + }, + { + "label": "Wheaton College-Wheaton" + }, + { + "label": "Wheeling Jesuit University" + }, + { + "label": "Wheelock College" + }, + { + "label": "White Earth Tribal and Community College" + }, + { + "label": "White Mountains Community College" + }, + { + "label": "Whitman College" + }, + { + "label": "Whittier College" + }, + { + "label": "Whitworth University" + }, + { + "label": "Whitworth University-Adult Degree Programs" + }, + { + "label": "Wichita Area Technical College" + }, + { + "label": "Wichita State University" + }, + { + "label": "Wichita Technical Institute" + }, + { + "label": "Widener University-Delaware Campus" + }, + { + "label": "Widener University-Harrisburg Campus" + }, + { + "label": "Widener University-Main Campus" + }, + { + "label": "Wilberforce University" + }, + { + "label": "Wiley College" + }, + { + "label": "Wilkes Community College" + }, + { + "label": "Wilkes University" + }, + { + "label": "Willamette University" + }, + { + "label": "William Carey University" + }, + { + "label": "William James College" + }, + { + "label": "William Jessup University" + }, + { + "label": "William Jewell College" + }, + { + "label": "William Mitchell College of Law" + }, + { + "label": "William Moore College of Technology" + }, + { + "label": "William Paterson University of New Jersey" + }, + { + "label": "William Peace University" + }, + { + "label": "William Penn University" + }, + { + "label": "William Rainey Harper College" + }, + { + "label": "William Woods University" + }, + { + "label": "Williams Baptist College" + }, + { + "label": "Williams College" + }, + { + "label": "Williamsburg Technical College" + }, + { + "label": "Williamson Christian College" + }, + { + "label": "Williston State College" + }, + { + "label": "Wilmington College" + }, + { + "label": "Wilmington University" + }, + { + "label": "Wilson College" + }, + { + "label": "Wilson Community College" + }, + { + "label": "Windward Community College" + }, + { + "label": "Winebrenner Theological Seminary" + }, + { + "label": "Wingate University" + }, + { + "label": "Winona State University" + }, + { + "label": "Winston-Salem State University" + }, + { + "label": "Winthrop University" + }, + { + "label": "Wiregrass Georgia Technical College" + }, + { + "label": "Wisconsin Indianhead Technical College" + }, + { + "label": "Wisconsin Lutheran College" + }, + { + "label": "Wisconsin School of Professional Psychology" + }, + { + "label": "Wittenberg University" + }, + { + "label": "Wofford College" + }, + { + "label": "Wolford College" + }, + { + "label": "Won Institute of Graduate Studies" + }, + { + "label": "Wood Tobe-Coburn School" + }, + { + "label": "Woodbury University" + }, + { + "label": "Woodland Community College" + }, + { + "label": "Worcester Polytechnic Institute" + }, + { + "label": "Worcester State University" + }, + { + "label": "World Medicine Institute" + }, + { + "label": "World Mission University" + }, + { + "label": "Worsham College of Mortuary Science" + }, + { + "label": "Wor-Wic Community College" + }, + { + "label": "Wright Career College" + }, + { + "label": "Wright State University-Lake Campus" + }, + { + "label": "Wright State University-Main Campus" + }, + { + "label": "Wyo Tech-Blairsville" + }, + { + "label": "Wyotech-Daytona" + }, + { + "label": "Wyotech-Fremont" + }, + { + "label": "Wyotech-Laramie" + }, + { + "label": "Wyotech-Long Beach" + }, + { + "label": "Wytheville Community College" + }, + { + "label": "Xavier University" + }, + { + "label": "Xavier University of Louisiana" + }, + { + "label": "Yakima Valley Community College" + }, + { + "label": "Yale University" + }, + { + "label": "Yavapai College" + }, + { + "label": "Yeshiva and Kollel Harbotzas Torah" + }, + { + "label": "Yeshiva College of the Nations Capital" + }, + { + "label": "Yeshiva Derech Chaim" + }, + { + "label": "Yeshiva D'monsey Rabbinical College" + }, + { + "label": "Yeshiva Gedolah Imrei Yosef D'spinka" + }, + { + "label": "Yeshiva Gedolah Kesser Torah" + }, + { + "label": "Yeshiva Gedolah of Greater Detroit" + }, + { + "label": "Yeshiva Gedolah Zichron Leyma" + }, + { + "label": "Yeshiva Karlin Stolin" + }, + { + "label": "Yeshiva of Far Rockaway Derech Ayson Rabbinical Seminary" + }, + { + "label": "Yeshiva of Machzikai Hadas" + }, + { + "label": "Yeshiva of Nitra Rabbinical College" + }, + { + "label": "Yeshiva of the Telshe Alumni" + }, + { + "label": "Yeshiva Ohr Elchonon Chabad West Coast Talmudical Seminary" + }, + { + "label": "Yeshiva Shaar Hatorah" + }, + { + "label": "Yeshiva Shaarei Torah of Rockland" + }, + { + "label": "Yeshiva Toras Chaim" + }, + { + "label": "Yeshiva Toras Chaim Talmudical Seminary" + }, + { + "label": "Yeshiva University" + }, + { + "label": "Yeshiva Yesodei Hatorah" + }, + { + "label": "Yeshivas Be'er Yitzchok" + }, + { + "label": "Yeshivas Novominsk" + }, + { + "label": "Yeshivat Mikdash Melech" + }, + { + "label": "Yeshivath Beth Moshe" + }, + { + "label": "Yeshivath Viznitz" + }, + { + "label": "Yeshivath Zichron Moshe" + }, + { + "label": "Yo San University of Traditional Chinese Medicine" + }, + { + "label": "York College" + }, + { + "label": "York College Pennsylvania" + }, + { + "label": "York County Community College" + }, + { + "label": "York Technical College" + }, + { + "label": "Yorktowne Business Institute" + }, + { + "label": "Young Harris College" + }, + { + "label": "Youngstown State University" + }, + { + "label": "YTI Career Institute-Altoona" + }, + { + "label": "YTI Career Institute-York" + }, + { + "label": "Yuba College" + }, + { + "label": "Zane State College" + }, + { + "label": "Ames Laboratory" + }, + { + "label": "Argonne National Laboratory", + "abbreviation": "ANL" + }, + { + "label": "Brookhaven National Laboratory", + "abbreviation": "BNL" + }, + { + "label": "Fermi National Accelerator Laboratory", + "abbreviation": "FERMILAB" + }, + { + "label": "Oak Ridge National Laboratory", + "abbreviation": "ORNL" + }, + { + "label": "Lawrence Berkeley National Laboratory", + "abbreviation": "LBNL" + }, + { + "label": "Pacific Northwest National Laboratory", + "abbreviation": "PNNL" + }, + { + "label": "Princeton Plasma Physics Laboratory", + "abbreviation": "PPPL" + }, + { + "label": "SLAC National Accelerator Laboratory", + "abbreviation": "SLAC" + }, + { + "label": "Idaho National Laboratory", + "abbreviation": "INL" + }, + { + "label": "National Energy Technology Laboratory", + "abbreviation": "NETL" + }, + { + "label": "National Renewable Energy Laboratory", + "abbreviation": "NREL" + }, + { + "label": "Savannah River National Laboratory", + "abbreviation": "SRNL" + }, + { + "label": "Lawrence Livermore National Laboratory", + "abbreviation": "LLNL" + }, + { + "label": "Los Alamos National Laboratory", + "abbreviation": "LANL" + }, + { + "label": "Sandia National Laboratory", + "abbreviation": "SNL" + }, + { + "label": "Cold Spring Harbor Laboratory", + "abbreviation": "CSHL" + }, + { + "label": "Joint Genome Institute", + "abbreviation": "JGI" + } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/data/providers.json b/vite-app/src/apps/Auth2/resources/data/providers.json new file mode 100644 index 00000000..bb61efdc --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/data/providers.json @@ -0,0 +1,26 @@ +[ + { + "id": "Google", + "label": "Google", + "logoutUrl": "https://accounts.google.com/Logout", + "priority": 1, + "confirmSignin": false, + "description": "Any Google account may be used to access KBase.\n" + }, + { + "id": "OrcID", + "label": "ORCID", + "logoutUrl": "https://www.orcid.org/signout", + "priority": 1, + "confirmSignin": true, + "description": "Use your ORCiD account to access KBase.\n" + }, + { + "id": "Globus", + "label": "Globus", + "logoutUrl": "https://app.globus.org/logout", + "priority": 2, + "confirmSignin": true, + "description": "Use your Globus ID to access KBase.\n" + } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/data/providers.yaml b/vite-app/src/apps/Auth2/resources/data/providers.yaml new file mode 100644 index 00000000..4e11e2bc --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/data/providers.yaml @@ -0,0 +1,27 @@ +# Auth Providers +--- +- + id: Google + label: Google + logoutUrl: https://accounts.google.com/Logout + priority: 1 + confirmSignin: false + description: > + Any Google account may be used to access KBase. +- + id: OrcID + label: ORCID + logoutUrl: https://www.orcid.org/signout + priority: 1 + confirmSignin: true + description: > + Use your ORCiD account to access KBase. +- + id: Globus + label: Globus + logoutUrl: https://app.globus.org/logout + priority: 2 + confirmSignin: true + description: | + Use your Globus ID to access KBase. + \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/data/referralSources.json b/vite-app/src/apps/Auth2/resources/data/referralSources.json new file mode 100644 index 00000000..7ce74592 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/data/referralSources.json @@ -0,0 +1,47 @@ +[ + { + "label": "Journal Publication", + "value": "journal-publication" + }, + { + "label": "Conference Presentation", + "value": "conference-presentation" + }, + { + "label": "Workshop/Webinar", + "value": "workshop-webinar" + }, + { + "label": "Colleague", + "value": "colleague" + }, + { + "label": "Course/Instructor", + "value": "course" + }, + { + "label": "Newsletter/Email", + "value": "newsletter-email" + }, + { + "label": "YouTube", + "value": "youtube" + }, + { + "label": "Twitter (X)", + "value": "twitter" + }, + { + "label": "Search Engine", + "value": "search-engine" + }, + { + "label": "Online Advertisement", + "value": "online-ad" + }, + { + "label": "Other...", + "value": "other", + "customText": true + } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/avatarOptions.json b/vite-app/src/apps/Auth2/resources/dataSources/avatarOptions.json new file mode 100644 index 00000000..409ffd71 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/avatarOptions.json @@ -0,0 +1,10 @@ +[ + { + "value": "gravatar", + "label": "Gravatar - Use your Gravatar image otherwise random generator selected below" + }, + { + "value": "silhouette", + "label": "silhouette - simple, anonymous, featureless, silhouette" + } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/countries.json b/vite-app/src/apps/Auth2/resources/dataSources/countries.json new file mode 100644 index 00000000..e97ea049 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/countries.json @@ -0,0 +1,248 @@ +[ + { "value": "United States", "label": "United States" }, + { "value": "Afghanistan", "label": "Afghanistan" }, + { "value": "Aland Islands", "label": "Aland Islands" }, + { "value": "Albania", "label": "Albania" }, + { "value": "Algeria", "label": "Algeria" }, + { "value": "American Samoa", "label": "American Samoa" }, + { "value": "Andorra", "label": "Andorra" }, + { "value": "Angola", "label": "Angola" }, + { "value": "Anguilla", "label": "Anguilla" }, + { "value": "Antarctica", "label": "Antarctica" }, + { "value": "Antigua And Barbuda", "label": "Antigua And Barbuda" }, + { "value": "Argentina", "label": "Argentina" }, + { "value": "Armenia", "label": "Armenia" }, + { "value": "Aruba", "label": "Aruba" }, + { "value": "Australia", "label": "Australia" }, + { "value": "Austria", "label": "Austria" }, + { "value": "Azerbaijan", "label": "Azerbaijan" }, + { "value": "Bahamas", "label": "Bahamas" }, + { "value": "Bahrain", "label": "Bahrain" }, + { "value": "Bangladesh", "label": "Bangladesh" }, + { "value": "Barbados", "label": "Barbados" }, + { "value": "Belarus", "label": "Belarus" }, + { "value": "Belgium", "label": "Belgium" }, + { "value": "Belize", "label": "Belize" }, + { "value": "Benin", "label": "Benin" }, + { "value": "Bermuda", "label": "Bermuda" }, + { "value": "Bhutan", "label": "Bhutan" }, + { "value": "Bolivia", "label": "Bolivia" }, + { "value": "Bosnia and Herzegovina", "label": "Bosnia and Herzegovina" }, + { "value": "Botswana", "label": "Botswana" }, + { "value": "Bouvet Island", "label": "Bouvet Island" }, + { "value": "Brazil", "label": "Brazil" }, + { "value": "British Indian Ocean Territory", "label": "British Indian Ocean Territory" }, + { "value": "Brunei Darussalam", "label": "Brunei Darussalam" }, + { "value": "Bulgaria", "label": "Bulgaria" }, + { "value": "Burkina Faso", "label": "Burkina Faso" }, + { "value": "Burundi", "label": "Burundi" }, + { "value": "Cambodia", "label": "Cambodia" }, + { "value": "Cameroon", "label": "Cameroon" }, + { "value": "Canada", "label": "Canada" }, + { "value": "Cape Verde", "label": "Cape Verde" }, + { "value": "Cayman Islands", "label": "Cayman Islands" }, + { "value": "Central African Republic", "label": "Central African Republic" }, + { "value": "Chad", "label": "Chad" }, + { "value": "Chile", "label": "Chile" }, + { "value": "China", "label": "China" }, + { "value": "Christmas Island", "label": "Christmas Island" }, + { "value": "Cocos (Keeling) Islands", "label": "Cocos (Keeling) Islands" }, + { "value": "Colombia", "label": "Colombia" }, + { "value": "Comoros", "label": "Comoros" }, + { "value": "Congo", "label": "Congo" }, + { "value": "Congo, the Democratic Republic of the", "label": "Congo, the Democratic Republic of the" }, + { "value": "Cook Islands", "label": "Cook Islands" }, + { "value": "Costa Rica", "label": "Costa Rica" }, + { "value": "Cote d'Ivoire", "label": "Cote d'Ivoire" }, + { "value": "Croatia", "label": "Croatia" }, + { "value": "Cuba", "label": "Cuba" }, + { "value": "Curacao", "label": "Curacao" }, + { "value": "Cyprus", "label": "Cyprus" }, + { "value": "Czech Republic", "label": "Czech Republic" }, + { "value": "Denmark", "label": "Denmark" }, + { "value": "Djibouti", "label": "Djibouti" }, + { "value": "Dominica", "label": "Dominica" }, + { "value": "Dominican Republic", "label": "Dominican Republic" }, + { "value": "Ecuador", "label": "Ecuador" }, + { "value": "Egypt", "label": "Egypt" }, + { "value": "El Salvador", "label": "El Salvador" }, + { "value": "Equatorial Guinea", "label": "Equatorial Guinea" }, + { "value": "Eritrea", "label": "Eritrea" }, + { "value": "Estonia", "label": "Estonia" }, + { "value": "Ethiopia", "label": "Ethiopia" }, + { "value": "Falkland Islands (Malvinas)", "label": "Falkland Islands (Malvinas)" }, + { "value": "Faroe Islands", "label": "Faroe Islands" }, + { "value": "Fiji", "label": "Fiji" }, + { "value": "Finland", "label": "Finland" }, + { "value": "France", "label": "France" }, + { "value": "French Guiana", "label": "French Guiana" }, + { "value": "French Polynesia", "label": "French Polynesia" }, + { "value": "French Southern Territories", "label": "French Southern Territories" }, + { "value": "Gabon", "label": "Gabon" }, + { "value": "Gambia", "label": "Gambia" }, + { "value": "Georgia", "label": "Georgia" }, + { "value": "Germany", "label": "Germany" }, + { "value": "Ghana", "label": "Ghana" }, + { "value": "Gibraltar", "label": "Gibraltar" }, + { "value": "Greece", "label": "Greece" }, + { "value": "Greenland", "label": "Greenland" }, + { "value": "Grenada", "label": "Grenada" }, + { "value": "Guadeloupe", "label": "Guadeloupe" }, + { "value": "Guam", "label": "Guam" }, + { "value": "Guatemala", "label": "Guatemala" }, + { "value": "Guernsey", "label": "Guernsey" }, + { "value": "Guinea", "label": "Guinea" }, + { "value": "Guinea-Bissau", "label": "Guinea-Bissau" }, + { "value": "Guyana", "label": "Guyana" }, + { "value": "Haiti", "label": "Haiti" }, + { "value": "Heard and McDonald Islands", "label": "Heard and McDonald Islands" }, + { "value": "Holy See (Vatican City State)", "label": "Holy See (Vatican City State)" }, + { "value": "Honduras", "label": "Honduras" }, + { "value": "Hong Kong", "label": "Hong Kong" }, + { "value": "Hungary", "label": "Hungary" }, + { "value": "Iceland", "label": "Iceland" }, + { "value": "India", "label": "India" }, + { "value": "Indonesia", "label": "Indonesia" }, + { "value": "Iran, Islamic Republic of", "label": "Iran, Islamic Republic of" }, + { "value": "Iraq", "label": "Iraq" }, + { "value": "Ireland", "label": "Ireland" }, + { "value": "Isle of Man", "label": "Isle of Man" }, + { "value": "Israel", "label": "Israel" }, + { "value": "Italy", "label": "Italy" }, + { "value": "Jamaica", "label": "Jamaica" }, + { "value": "Japan", "label": "Japan" }, + { "value": "Jersey", "label": "Jersey" }, + { "value": "Jordan", "label": "Jordan" }, + { "value": "Kazakhstan", "label": "Kazakhstan" }, + { "value": "Kenya", "label": "Kenya" }, + { "value": "Kiribati", "label": "Kiribati" }, + { "value": "Korea, Democratic People's Republic of", "label": "Korea, Democratic People's Republic of" }, + { "value": "Korea, Republic of", "label": "Korea, Republic of" }, + { "value": "Kuwait", "label": "Kuwait" }, + { "value": "Kyrgyzstan", "label": "Kyrgyzstan" }, + { "value": "Lao People's Democratic Republic", "label": "Lao People's Democratic Republic" }, + { "value": "Latvia", "label": "Latvia" }, + { "value": "Lebanon", "label": "Lebanon" }, + { "value": "Lesotho", "label": "Lesotho" }, + { "value": "Liberia", "label": "Liberia" }, + { "value": "Libyan Arab Jamahiriya", "label": "Libyan Arab Jamahiriya" }, + { "value": "Liechtenstein", "label": "Liechtenstein" }, + { "value": "Lithuania", "label": "Lithuania" }, + { "value": "Luxembourg", "label": "Luxembourg" }, + { "value": "Macao", "label": "Macao" }, + { "value": "Macedonia, The Former Yugoslav Republic Of", "label": "Macedonia, The Former Yugoslav Republic Of" }, + { "value": "Madagascar", "label": "Madagascar" }, + { "value": "Malawi", "label": "Malawi" }, + { "value": "Malaysia", "label": "Malaysia" }, + { "value": "Maldives", "label": "Maldives" }, + { "value": "Mali", "label": "Mali" }, + { "value": "Malta", "label": "Malta" }, + { "value": "Marshall Islands", "label": "Marshall Islands" }, + { "value": "Martinique", "label": "Martinique" }, + { "value": "Mauritania", "label": "Mauritania" }, + { "value": "Mauritius", "label": "Mauritius" }, + { "value": "Mayotte", "label": "Mayotte" }, + { "value": "Mexico", "label": "Mexico" }, + { "value": "Micronesia, Federated States of", "label": "Micronesia, Federated States of" }, + { "value": "Moldova, Republic of", "label": "Moldova, Republic of" }, + { "value": "Monaco", "label": "Monaco" }, + { "value": "Mongolia", "label": "Mongolia" }, + { "value": "Montenegro", "label": "Montenegro" }, + { "value": "Montserrat", "label": "Montserrat" }, + { "value": "Morocco", "label": "Morocco" }, + { "value": "Mozambique", "label": "Mozambique" }, + { "value": "Myanmar", "label": "Myanmar" }, + { "value": "Namibia", "label": "Namibia" }, + { "value": "Nauru", "label": "Nauru" }, + { "value": "Nepal", "label": "Nepal" }, + { "value": "Netherlands", "label": "Netherlands" }, + { "value": "New Caledonia", "label": "New Caledonia" }, + { "value": "New Zealand", "label": "New Zealand" }, + { "value": "Nicaragua", "label": "Nicaragua" }, + { "value": "Niger", "label": "Niger" }, + { "value": "Nigeria", "label": "Nigeria" }, + { "value": "Niue", "label": "Niue" }, + { "value": "Norfolk Island", "label": "Norfolk Island" }, + { "value": "Northern Mariana Islands", "label": "Northern Mariana Islands" }, + { "value": "Norway", "label": "Norway" }, + { "value": "Oman", "label": "Oman" }, + { "value": "Pakistan", "label": "Pakistan" }, + { "value": "Palau", "label": "Palau" }, + { "value": "Palestinian Territory, Occupied", "label": "Palestinian Territory, Occupied" }, + { "value": "Panama", "label": "Panama" }, + { "value": "Papua New Guinea", "label": "Papua New Guinea" }, + { "value": "Paraguay", "label": "Paraguay" }, + { "value": "Peru", "label": "Peru" }, + { "value": "Philippines", "label": "Philippines" }, + { "value": "Pitcairn", "label": "Pitcairn" }, + { "value": "Poland", "label": "Poland" }, + { "value": "Portugal", "label": "Portugal" }, + { "value": "Puerto Rico", "label": "Puerto Rico" }, + { "value": "Qatar", "label": "Qatar" }, + { "value": "Reunion", "label": "Reunion" }, + { "value": "Romania", "label": "Romania" }, + { "value": "Russian Federation", "label": "Russian Federation" }, + { "value": "Rwanda", "label": "Rwanda" }, + { "value": "Saint Barthelemy", "label": "Saint Barthelemy" }, + { "value": "Saint Helena", "label": "Saint Helena" }, + { "value": "Saint Kitts and Nevis", "label": "Saint Kitts and Nevis" }, + { "value": "Saint Lucia", "label": "Saint Lucia" }, + { "value": "Saint Pierre and Miquelon", "label": "Saint Pierre and Miquelon" }, + { "value": "Saint Vincent and the Grenadines", "label": "Saint Vincent and the Grenadines" }, + { "value": "Samoa", "label": "Samoa" }, + { "value": "San Marino", "label": "San Marino" }, + { "value": "Sao Tome and Principe", "label": "Sao Tome and Principe" }, + { "value": "Saudi Arabia", "label": "Saudi Arabia" }, + { "value": "Senegal", "label": "Senegal" }, + { "value": "Serbia", "label": "Serbia" }, + { "value": "Seychelles", "label": "Seychelles" }, + { "value": "Sierra Leone", "label": "Sierra Leone" }, + { "value": "Singapore", "label": "Singapore" }, + { "value": "Sint Maarten", "label": "Sint Maarten" }, + { "value": "Slovakia", "label": "Slovakia" }, + { "value": "Slovenia", "label": "Slovenia" }, + { "value": "Solomon Islands", "label": "Solomon Islands" }, + { "value": "Somalia", "label": "Somalia" }, + { "value": "South Africa", "label": "South Africa" }, + { "value": "South Georgia and the South Sandwich Islands", "label": "South Georgia and the South Sandwich Islands" }, + { "value": "Spain", "label": "Spain" }, + { "value": "Sri Lanka", "label": "Sri Lanka" }, + { "value": "Sudan", "label": "Sudan" }, + { "value": "Suriname", "label": "Suriname" }, + { "value": "Svalbard and Jan Mayen", "label": "Svalbard and Jan Mayen" }, + { "value": "Swaziland", "label": "Swaziland" }, + { "value": "Sweden", "label": "Sweden" }, + { "value": "Switzerland", "label": "Switzerland" }, + { "value": "Syrian Arab Republic", "label": "Syrian Arab Republic" }, + { "value": "Taiwan", "label": "Taiwan" }, + { "value": "Tajikistan", "label": "Tajikistan" }, + { "value": "Tanzania, United Republic of", "label": "Tanzania, United Republic of" }, + { "value": "Thailand", "label": "Thailand" }, + { "value": "Timor-Leste", "label": "Timor-Leste" }, + { "value": "Togo", "label": "Togo" }, + { "value": "Tokelau", "label": "Tokelau" }, + { "value": "Tonga", "label": "Tonga" }, + { "value": "Trinidad and Tobago", "label": "Trinidad and Tobago" }, + { "value": "Tunisia", "label": "Tunisia" }, + { "value": "Turkey", "label": "Turkey" }, + { "value": "Turkmenistan", "label": "Turkmenistan" }, + { "value": "Turks and Caicos Islands", "label": "Turks and Caicos Islands" }, + { "value": "Tuvalu", "label": "Tuvalu" }, + { "value": "Uganda", "label": "Uganda" }, + { "value": "Ukraine", "label": "Ukraine" }, + { "value": "United Arab Emirates", "label": "United Arab Emirates" }, + { "value": "United Kingdom", "label": "United Kingdom" }, + { "value": "United States Minor Outlying Islands", "label": "United States Minor Outlying Islands" }, + { "value": "Uruguay", "label": "Uruguay" }, + { "value": "Uzbekistan", "label": "Uzbekistan" }, + { "value": "Vanuatu", "label": "Vanuatu" }, + { "value": "Venezuela", "label": "Venezuela" }, + { "value": "Viet Nam", "label": "Viet Nam" }, + { "value": "Virgin Islands, British", "label": "Virgin Islands, British" }, + { "value": "Virgin Islands, U.S.", "label": "Virgin Islands, U.S." }, + { "value": "Wallis and Futuna", "label": "Wallis and Futuna" }, + { "value": "Western Sahara", "label": "Western Sahara" }, + { "value": "Yemen", "label": "Yemen" }, + { "value": "Zambia", "label": "Zambia" }, + { "value": "Zimbabwe", "label": "Zimbabwe" } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/fundingSources.json b/vite-app/src/apps/Auth2/resources/dataSources/fundingSources.json new file mode 100644 index 00000000..13f0b31c --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/fundingSources.json @@ -0,0 +1,40 @@ +[ + { "value": "DOE Office of Energy Efficiency and Renewable Energy (EERE)", "label": "DOE Office of Energy Efficiency and Renewable Energy (EERE)" }, + { "value": "DOE Office of Environmental Management (EM)", "label": "DOE Office of Environmental Management (EM)" }, + { "value": "DOE Office of Fossil Energy (FE)", "label": "DOE Office of Fossil Energy (FE)" }, + { "value": "DOE Office Nuclear Energy (NE)", "label": "DOE Office Nuclear Energy (NE)" }, + { "value": "DOE National Nuclear Security Administration (NNSA)", "label": "DOE National Nuclear Security Administration (NNSA)" }, + { "value": "DOE Small Business Innovation Research/Small Business Technology Transfer (SBIR/STTR)", "label": "DOE Small Business Innovation Research/Small Business Technology Transfer (SBIR/STTR)" }, + { "value": "DOE Office of Science Advenced Scientific Computing Research (ASCR)", "label": "DOE Office of Science Advenced Scientific Computing Research (ASCR)" }, + { "value": "DOE Office of Science Basic Energy Sciences (BES)", "label": "DOE Office of Science Basic Energy Sciences (BES)" }, + { "value": "DOE Office of Science BES Energy Frontier Science Center (EFRC)", "label": "DOE Office of Science BES Energy Frontier Science Center (EFRC)" }, + { "value": "DOE Office of Science Biological and Environmental Research (BER)", "label": "DOE Office of Science Biological and Environmental Research (BER)" }, + { "value": "DOE Office of Science Fusion Energy Sciences (FES)", "label": "DOE Office of Science Fusion Energy Sciences (FES)" }, + { "value": "DOE Office of Science High Energy Physics (HEP)", "label": "DOE Office of Science High Energy Physics (HEP)" }, + { "value": "DOE Office of Science Nuclear Physics (NP)", "label": "DOE Office of Science Nuclear Physics (NP)" }, + { "value": "DOE Office of Science Workforce Development for Teachers and Students (WDTS)", "label": "DOE Office of Science Workforce Development for Teachers and Students (WDTS)" }, + { "value": "DOE Laboratory Directed Research and Development (LDRD)", "label": "DOE Laboratory Directed Research and Development (LDRD)" }, + { "value": "USDA - Agricultural Research Service (ARS)", "label": "USDA - Agricultural Research Service (ARS)" }, + { "value": "USDA - Forest Service (FS)", "label": "USDA - Forest Service (FS)" }, + { "value": "DOC - National Institute of Standards and Technology (NIST)", "label": "DOC - National Institute of Standards and Technology (NIST)" }, + { "value": "DOC - National Oceanic and Atmospheric Administration (NOAA)", "label": "DOC - National Oceanic and Atmospheric Administration (NOAA)" }, + { "value": "DOD - Defense Advanced Research Projects Agency (DARPA)", "label": "DOD - Defense Advanced Research Projects Agency (DARPA)" }, + { "value": "U.S. Department of Education (DOEd)", "label": "U.S. Department of Education (DOEd)" }, + { "value": "U.S. Department of Health and Human Services (HHS) - Other (excl. NCI and NIH)", "label": "U.S. Department of Health and Human Services (HHS) - Other (excl. NCI and NIH)" }, + { "value": "HHS - Centers for Disease Control (CDC)", "label": "HHS - Centers for Disease Control (CDC)" }, + { "value": "HHS - National Institutes of Health (NIH)", "label": "HHS - National Institutes of Health (NIH)" }, + { "value": "HHS - NIH - National Cancer Institute (NCI)", "label": "HHS - NIH - National Cancer Institute (NCI)" }, + { "value": "HHS - U.S. United States Food and Drug Administration (FDA)", "label": "HHS - U.S. United States Food and Drug Administration (FDA)" }, + { "value": "U.S. Department of Homeland Security (DHS)", "label": "U.S. Department of Homeland Security (DHS)" }, + { "value": "DOI - U.S. Geological Survey (USGS)", "label": "DOI - U.S. Geological Survey (USGS)" }, + { "value": "DOI - U.S. Fish and Wildlife Service (FWS)", "label": "DOI - U.S. Fish and Wildlife Service (FWS)" }, + { "value": "U.S. Department of Transportation (DOT)", "label": "U.S. Department of Transportation (DOT)" }, + { "value": "Environmental Protection Agency (EPA)", "label": "Environmental Protection Agency (EPA)" }, + { "value": "National Aeronautics and Space Administration (NASA)", "label": "National Aeronautics and Space Administration (NASA)" }, + { "value": "National Science Foundation (NSF)", "label": "National Science Foundation (NSF)" }, + { "value": "Nuclear Regulatory Commission (NRC)", "label": "Nuclear Regulatory Commission (NRC)" }, + { "value": "Small Business Administration (SBA)", "label": "Small Business Administration (SBA)" }, + { "value": "U.S. Other Federal Agency", "label": "U.S. Other Federal Agency" }, + { "value": "Federally Funded Research and Development Center (FFRDC) - (Specify)", "label": "Federally Funded Research and Development Center (FFRDC) - (Specify)" }, + { "value": "other", "label": "Other" } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/gravatarDefaults.json b/vite-app/src/apps/Auth2/resources/dataSources/gravatarDefaults.json new file mode 100644 index 00000000..181fbe43 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/gravatarDefaults.json @@ -0,0 +1,16 @@ +[{ + "value": "mm", + "label": "Mystery Man - simple, cartoon-style silhouetted outline" +}, { + "value": "identicon", + "label": "Identicon - a geometric pattern based on an email hash" +}, { + "value": "monsterid", + "label": "MonsterID - generated \"monster\" with different colors, faces, etc" +}, { + "value": "wavatar", + "label": "Wavatar - generated faces with differing features and backgrounds" +}, { + "value": "retro", + "label": "Retro - 8-bit arcade-style pixelated faces" +}] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/institutions.json b/vite-app/src/apps/Auth2/resources/dataSources/institutions.json new file mode 100644 index 00000000..33e3d8a7 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/institutions.json @@ -0,0 +1 @@ +[{"value":"177834","label":"A T Still University of Health Sciences"},{"value":"180203","label":"Aaniiih Nakoda College"},{"value":"222178","label":"Abilene Christian University"},{"value":"138558","label":"Abraham Baldwin Agricultural College"},{"value":"172866","label":"Academy College"},{"value":"451079","label":"Academy for Five Element Acupuncture"},{"value":"457271","label":"Academy for Jewish Religion-California"},{"value":"412173","label":"Academy for Nursing and Health Occupations"},{"value":"108232","label":"Academy of Art University"},{"value":"108269","label":"Academy of Chinese Culture and Health Sciences"},{"value":"475635","label":"Academy of Couture Art"},{"value":"449454","label":"Academy of Natural Therapy Inc"},{"value":"384306","label":"Acupuncture and Integrative Medicine College-Berkeley"},{"value":"439969","label":"Acupuncture and Massage College"},{"value":"126182","label":"Adams State University"},{"value":"188429","label":"Adelphi University"},{"value":"188438","label":"Adirondack Community College"},{"value":"374024","label":"Adler Graduate School"},{"value":"142832","label":"Adler University"},{"value":"168528","label":"Adrian College"},{"value":"444343","label":"Advanced College"},{"value":"481234","label":"Advanced Computing Institute"},{"value":"231411","label":"Advanced Technology Institute"},{"value":"444361","label":"Advanced Training Associates"},{"value":"133872","label":"Adventist University of Health Sciences"},{"value":"205391","label":"Advertising Art Educational Services DBA School of Advertising Art"},{"value":"138600","label":"Agnes Scott College"},{"value":"134811","label":"AI Miami International University of Art and Design"},{"value":"152822","label":"AIB College of Business"},{"value":"217615","label":"Aiken Technical College"},{"value":"126207","label":"Aims Community College"},{"value":"200697","label":"Air Force Institute of Technology-Graduate School of Engineering & Management"},{"value":"200785","label":"Akron Institute of Herzing University"},{"value":"100654","label":"Alabama A & M University"},{"value":"101949","label":"Alabama Southern Community College"},{"value":"100724","label":"Alabama State University"},{"value":"199786","label":"Alamance Community College"},{"value":"102580","label":"Alaska Bible College"},{"value":"103501","label":"Alaska Career College"},{"value":"442523","label":"Alaska Christian College"},{"value":"102669","label":"Alaska Pacific University"},{"value":"188526","label":"Albany College of Pharmacy and Health Sciences"},{"value":"188535","label":"Albany Law School"},{"value":"188580","label":"Albany Medical College"},{"value":"138716","label":"Albany State University"},{"value":"138682","label":"Albany Technical College"},{"value":"128498","label":"Albertus Magnus College"},{"value":"168546","label":"Albion College"},{"value":"210571","label":"Albright College"},{"value":"175342","label":"Alcorn State University"},{"value":"237118","label":"Alderson Broaddus University"},{"value":"172918","label":"Alexandria Technical & Community College"},{"value":"188641","label":"Alfred University"},{"value":"156189","label":"Alice Lloyd College"},{"value":"108807","label":"Allan Hancock College"},{"value":"161688","label":"Allegany College of Maryland"},{"value":"210669","label":"Allegheny College"},{"value":"200873","label":"Allegheny Wesleyan College"},{"value":"152798","label":"Allen College"},{"value":"154642","label":"Allen County Community College"},{"value":"217624","label":"Allen University"},{"value":"110468","label":"Alliant International University-San Diego"},{"value":"460729","label":"Allied American University"},{"value":"168591","label":"Alma College"},{"value":"168607","label":"Alpena Community College"},{"value":"210775","label":"Alvernia University"},{"value":"238193","label":"Alverno College"},{"value":"222567","label":"Alvin Community College"},{"value":"222576","label":"Amarillo College"},{"value":"222628","label":"Amberton University"},{"value":"457527","label":"Ambria College of Nursing"},{"value":"188687","label":"American Academy McAllister Institute of Funeral Service"},{"value":"446002","label":"American Academy of Acupuncture and Oriental Medicine"},{"value":"142887","label":"American Academy of Art"},{"value":"108852","label":"American Academy of Dramatic Arts-Los Angeles"},{"value":"188678","label":"American Academy of Dramatic Arts-New York"},{"value":"219505","label":"American Baptist College"},{"value":"108861","label":"American Baptist Seminary of the West"},{"value":"457688","label":"American Business and Technology University"},{"value":"441052","label":"American Career College-Anaheim"},{"value":"109040","label":"American Career College-Los Angeles"},{"value":"447768","label":"American Career College-Ontario"},{"value":"461005","label":"American College for Medical Careers"},{"value":"429085","label":"American College of Acupuncture and Oriental Med"},{"value":"449889","label":"American College of Education"},{"value":"210809","label":"American College of Financial Services"},{"value":"443599","label":"American College of Healthcare Sciences"},{"value":"430591","label":"American College of Traditional Chinese Medicine"},{"value":"109086","label":"American Conservatory Theater"},{"value":"108870","label":"American Film Institute Conservatory"},{"value":"103787","label":"American Indian College Inc"},{"value":"441636","label":"American Institute of Alternative Medicine"},{"value":"438586","label":"American InterContinental University-Atlanta"},{"value":"445133","label":"American InterContinental University-Houston"},{"value":"445027","label":"American InterContinental University-Online"},{"value":"438601","label":"American InterContinental University-South Florida"},{"value":"164447","label":"American International College"},{"value":"116846","label":"American Jewish University"},{"value":"475714","label":"American Medical Academy"},{"value":"188854","label":"American Musical and Dramatic Academy"},{"value":"232797","label":"American National University"},{"value":"449339","label":"American Public University System"},{"value":"109208","label":"American River College"},{"value":"240736","label":"American Samoa Community College"},{"value":"460738","label":"American Sentinel University"},{"value":"131159","label":"American University"},{"value":"433004","label":"American University of Health Sciences"},{"value":"241100","label":"American University of Puerto Rico-Bayamon"},{"value":"241128","label":"American University of Puerto Rico-Manati"},{"value":"447263","label":"AmeriTech College-Draper"},{"value":"164465","label":"Amherst College"},{"value":"100690","label":"Amridge University"},{"value":"151865","label":"Anabaptist Mennonite Biblical Seminary"},{"value":"150048","label":"Ancilla College"},{"value":"150066","label":"Anderson University-Anderson"},{"value":"217633","label":"Anderson University-Anderson"},{"value":"164474","label":"Andover Newton Theological School"},{"value":"138761","label":"Andrew College"},{"value":"168740","label":"Andrews University"},{"value":"457299","label":"Angeles College"},{"value":"222822","label":"Angelina College"},{"value":"222831","label":"Angelo State University"},{"value":"164492","label":"Anna Maria College"},{"value":"161767","label":"Anne Arundel Community College"},{"value":"172954","label":"Anoka Technical College"},{"value":"172963","label":"Anoka-Ramsey Community College"},{"value":"109350","label":"Antelope Valley College"},{"value":"245838","label":"Antioch University-Los Angeles"},{"value":"245892","label":"Antioch University-Midwest"},{"value":"245865","label":"Antioch University-New England"},{"value":"442392","label":"Antioch University-PhD Program in Leadership and Change"},{"value":"245847","label":"Antioch University-Santa Barbara"},{"value":"245883","label":"Antioch University-Seattle"},{"value":"201016","label":"Antonelli College-Cincinnati"},{"value":"383950","label":"Antonelli College-Hattiesburg"},{"value":"175528","label":"Antonelli College-Jackson"},{"value":"210890","label":"Antonelli Institute"},{"value":"429094","label":"AOMA Graduate School of Integrative Medicine"},{"value":"441511","label":"Apex School of Theology"},{"value":"237136","label":"Appalachian Bible College"},{"value":"449922","label":"Appalachian College of Pharmacy"},{"value":"432348","label":"Appalachian School of Law"},{"value":"197869","label":"Appalachian State University"},{"value":"168786","label":"Aquinas College-Grand Rapids"},{"value":"219578","label":"Aquinas College-Nashville"},{"value":"176600","label":"Aquinas Institute of Theology"},{"value":"126289","label":"Arapahoe Community College"},{"value":"211088","label":"Arcadia University"},{"value":"367936","label":"Argosy University-Atlanta"},{"value":"145770","label":"Argosy University-Chicago"},{"value":"442222","label":"Argosy University-Dallas"},{"value":"448734","label":"Argosy University-Denver"},{"value":"366748","label":"Argosy University-Hawaii"},{"value":"450526","label":"Argosy University-Inland Empire"},{"value":"447272","label":"Argosy University-Los Angeles"},{"value":"450535","label":"Argosy University-Nashville"},{"value":"436438","label":"Argosy University-Orange County"},{"value":"436094","label":"Argosy University-Phoenix"},{"value":"456348","label":"Argosy University-Phoenix Online Division"},{"value":"452090","label":"Argosy University-Salt Lake City"},{"value":"450544","label":"Argosy University-San Diego"},{"value":"121983","label":"Argosy University-San Francisco Bay Area"},{"value":"137148","label":"Argosy University-Sarasota"},{"value":"420866","label":"Argosy University-Schaumburg"},{"value":"439057","label":"Argosy University-Seattle"},{"value":"428268","label":"Argosy University-Tampa"},{"value":"410502","label":"Argosy University-The Art Institute of California-Hollywood"},{"value":"448576","label":"Argosy University-The Art Institute of California-Inland Empire"},{"value":"432533","label":"Argosy University-The Art Institute of California-Los Angeles"},{"value":"441973","label":"Argosy University-The Art Institute of California-Orange County"},{"value":"450094","label":"Argosy University-The Art Institute of California-Sacramento"},{"value":"117113","label":"Argosy University-The Art Institute of California-San Diego"},{"value":"117928","label":"Argosy University-The Art Institute of California-San Francisco"},{"value":"451848","label":"Argosy University-The Art Institute of California-Silicon Valley"},{"value":"173984","label":"Argosy University-Twin Cities"},{"value":"419457","label":"Argosy University-Washington DC"},{"value":"105899","label":"Arizona Christian University"},{"value":"421708","label":"Arizona College-Glendale"},{"value":"482990","label":"Arizona College-Mesa"},{"value":"446039","label":"Arizona School of Acupuncture and Oriental Medicine"},{"value":"448886","label":"Arizona State University-Downtown Phoenix"},{"value":"420574","label":"Arizona State University-Polytechnic"},{"value":"483124","label":"Arizona State University-Skysong"},{"value":"104151","label":"Arizona State University-Tempe"},{"value":"407009","label":"Arizona State University-West"},{"value":"450942","label":"Arizona Summit Law School"},{"value":"104160","label":"Arizona Western College"},{"value":"106306","label":"Arkansas Baptist College"},{"value":"107327","label":"Arkansas Northeastern College"},{"value":"106449","label":"Arkansas State University-Beebe"},{"value":"106458","label":"Arkansas State University-Main Campus"},{"value":"107318","label":"Arkansas State University-Mid-South"},{"value":"420538","label":"Arkansas State University-Mountain Home"},{"value":"440402","label":"Arkansas State University-Newport"},{"value":"106467","label":"Arkansas Tech University"},{"value":"222877","label":"Arlington Baptist College"},{"value":"138789","label":"Armstrong State University"},{"value":"201061","label":"Art Academy of Cincinnati"},{"value":"109651","label":"Art Center College of Design"},{"value":"404994","label":"ASA College"},{"value":"156222","label":"Asbury Theological Seminary"},{"value":"156213","label":"Asbury University"},{"value":"461777","label":"Ashdown College of Health Sciences"},{"value":"447777","label":"Asher College"},{"value":"197887","label":"Asheville-Buncombe Technical Community College"},{"value":"154022","label":"Ashford University"},{"value":"156231","label":"Ashland Community and Technical College"},{"value":"201104","label":"Ashland University"},{"value":"128577","label":"Asnuntuck Community College"},{"value":"454829","label":"Aspen University"},{"value":"176619","label":"Assemblies of God Theological Seminary"},{"value":"164562","label":"Assumption College"},{"value":"183600","label":"Assumption College for Sisters"},{"value":"446127","label":"ATA Career Education"},{"value":"447935","label":"ATA College"},{"value":"440651","label":"Atenas College"},{"value":"201140","label":"Athenaeum of Ohio"},{"value":"100812","label":"Athens State University"},{"value":"246813","label":"Athens Technical College"},{"value":"138901","label":"Atlanta Metropolitan State College"},{"value":"138840","label":"Atlanta Technical College"},{"value":"138929","label":"Atlanta's John Marshall Law School"},{"value":"183655","label":"Atlantic Cape Community College"},{"value":"439446","label":"Atlantic Institute of Oriental Medicine"},{"value":"241216","label":"Atlantic University College"},{"value":"100858","label":"Auburn University"},{"value":"100830","label":"Auburn University at Montgomery"},{"value":"173045","label":"Augsburg College"},{"value":"138956","label":"Augusta Technical College"},{"value":"482149","label":"Augusta University"},{"value":"143084","label":"Augustana College-Rock Island"},{"value":"219000","label":"Augustana University"},{"value":"201177","label":"Aultman College of Nursing and Health Sciences"},{"value":"143118","label":"Aurora University"},{"value":"222983","label":"Austin College"},{"value":"222992","label":"Austin Community College District"},{"value":"247825","label":"Austin Graduate School of Theology"},{"value":"219602","label":"Austin Peay State University"},{"value":"223001","label":"Austin Presbyterian Theological Seminary"},{"value":"442295","label":"Ave Maria School of Law"},{"value":"446048","label":"Ave Maria University"},{"value":"231420","label":"Averett University"},{"value":"449931","label":"Averett University-Non-Traditional Programs"},{"value":"447847","label":"Aviator College of Aeronautical Science and Technology"},{"value":"176628","label":"Avila University"},{"value":"102711","label":"AVTEC-Alaska's Institute of Technology"},{"value":"483762","label":"Azure College"},{"value":"109785","label":"Azusa Pacific University"},{"value":"474863","label":"Azusa Pacific University College"},{"value":"164580","label":"Babson College"},{"value":"206817","label":"Bacone College"},{"value":"139010","label":"Bainbridge State College"},{"value":"476601","label":"Bais HaMedrash and Mesivta of Baltimore"},{"value":"245777","label":"Bais Medrash Elyon"},{"value":"449658","label":"Bais Medrash Toras Chesed"},{"value":"168847","label":"Baker College"},{"value":"414708","label":"Baker College Center for Graduate Studies"},{"value":"444167","label":"Baker College of Allen Park"},{"value":"404073","label":"Baker College of Auburn Hills"},{"value":"404648","label":"Baker College of Cadillac"},{"value":"404082","label":"Baker College of Clinton Township"},{"value":"414160","label":"Baker College of Jackson"},{"value":"171298","label":"Baker College of Muskegon"},{"value":"168838","label":"Baker College of Owosso"},{"value":"381617","label":"Baker College of Port Huron"},{"value":"154688","label":"Baker University"},{"value":"109819","label":"Bakersfield College"},{"value":"420705","label":"Bakke Graduate University"},{"value":"201195","label":"Baldwin Wallace University"},{"value":"150136","label":"Ball State University"},{"value":"161864","label":"Baltimore City Community College"},{"value":"189015","label":"Bank Street College of Education"},{"value":"176664","label":"Baptist Bible College"},{"value":"211024","label":"Clarks Summit University"},{"value":"223083","label":"Baptist Health System School of Health Professions"},{"value":"219639","label":"Baptist Memorial College of Health Sciences"},{"value":"223117","label":"Baptist Missionary Association Theological Seminary"},{"value":"366793","label":"Baptist Theological Seminary at Richmond"},{"value":"444398","label":"Baptist University of the Americas"},{"value":"155070","label":"Barclay College"},{"value":"189088","label":"Bard College"},{"value":"167792","label":"Bard College at Simon's Rock"},{"value":"189097","label":"Barnard College"},{"value":"177719","label":"Barnes-Jewish College Goldfarb School of Nursing"},{"value":"132471","label":"Barry University"},{"value":"109907","label":"Barstow Community College"},{"value":"197911","label":"Barton College"},{"value":"154697","label":"Barton County Community College"},{"value":"235547","label":"Bastyr University"},{"value":"160977","label":"Bates College"},{"value":"235671","label":"Bates Technical College"},{"value":"437103","label":"Baton Rouge Community College"},{"value":"158343","label":"Baton Rouge School of Computers"},{"value":"139074","label":"Bauder College"},{"value":"168883","label":"Bay de Noc Community College"},{"value":"380359","label":"Bay Mills Community College"},{"value":"164632","label":"Bay Path University"},{"value":"164641","label":"Bay State College"},{"value":"223223","label":"Baylor College of Medicine"},{"value":"223232","label":"Baylor University"},{"value":"384254","label":"Beacon College"},{"value":"160995","label":"Beal College"},{"value":"197966","label":"Beaufort County Community College"},{"value":"164720","label":"Becker College"},{"value":"247065","label":"Beckfield College-Florence"},{"value":"452373","label":"Beckfield College-Tri-County"},{"value":"476717","label":"Be'er Yaakov Talmudic Seminary"},{"value":"444413","label":"Beis Medrash Heichal Dovid"},{"value":"190956","label":"Belanger School of Nursing"},{"value":"175421","label":"Belhaven University"},{"value":"156286","label":"Bellarmine University"},{"value":"234669","label":"Bellevue College"},{"value":"180814","label":"Bellevue University"},{"value":"238324","label":"Bellin College"},{"value":"234696","label":"Bellingham Technical College"},{"value":"197984","label":"Belmont Abbey College"},{"value":"201283","label":"Belmont College"},{"value":"219709","label":"Belmont University"},{"value":"238333","label":"Beloit College"},{"value":"126359","label":"Bel-Rea Institute of Animal Technology"},{"value":"173124","label":"Bemidji State University"},{"value":"217721","label":"Benedict College"},{"value":"154712","label":"Benedictine College"},{"value":"145619","label":"Benedictine University"},{"value":"165884","label":"Benjamin Franklin Institute of Technology"},{"value":"197993","label":"Bennett College"},{"value":"230816","label":"Bennington College"},{"value":"164739","label":"Bentley University"},{"value":"156295","label":"Berea College"},{"value":"183743","label":"Bergen Community College"},{"value":"461643","label":"Bergin University of Canine Studies"},{"value":"125170","label":"Berkeley City College"},{"value":"189228","label":"Berkeley College-New York"},{"value":"183789","label":"Berkeley College-Woodland Park"},{"value":"164748","label":"Berklee College of Music"},{"value":"213534","label":"Berks Technical Institute"},{"value":"164775","label":"Berkshire Community College"},{"value":"139144","label":"Berry College"},{"value":"189273","label":"Beth Hamedrash Shaarei Yosher Institute"},{"value":"189264","label":"Beth Hatalmud Rabbinical College"},{"value":"183804","label":"Beth Medrash Govoha"},{"value":"237181","label":"Bethany College-Bethany"},{"value":"154721","label":"Bethany College-Lindsborg"},{"value":"173142","label":"Bethany Lutheran College"},{"value":"143233","label":"Bethany Theological Seminary"},{"value":"458113","label":"Bethel College"},{"value":"150145","label":"Bethel College-Indiana"},{"value":"154749","label":"Bethel College-North Newton"},{"value":"262022","label":"Bethel Seminary-San Diego"},{"value":"173179","label":"Bethel Seminary-St Paul"},{"value":"219718","label":"Bethel University-McKenzie"},{"value":"173160","label":"Bethel University-Saint Paul"},{"value":"110060","label":"Bethesda University"},{"value":"132602","label":"Bethune-Cookman University"},{"value":"139153","label":"Beulah Heights University"},{"value":"102429","label":"Bevill State Community College"},{"value":"148724","label":"Bexley Hall Seabury Western Theological Seminary Federation"},{"value":"443702","label":"Bexley Hall Seabury Western Theological Seminary Federation "},{"value":"211130","label":"Biblical Theological Seminary"},{"value":"211149","label":"Bidwell Training Center Inc"},{"value":"234711","label":"Big Bend Community College"},{"value":"157553","label":"Big Sandy Community and Technical College"},{"value":"110097","label":"Biola University"},{"value":"100937","label":"Birmingham Southern College"},{"value":"442949","label":"Birthingway College of Midwifery"},{"value":"102030","label":"Bishop State Community College"},{"value":"200022","label":"Bismarck State College"},{"value":"143279","label":"Black Hawk College"},{"value":"219046","label":"Black Hills State University"},{"value":"106625","label":"Black River Technical College"},{"value":"143288","label":"Blackburn College"},{"value":"180054","label":"Blackfeet Community College"},{"value":"238397","label":"Blackhawk Technical College"},{"value":"198011","label":"Bladen Community College"},{"value":"143297","label":"Blessing Rieman College of Nursing"},{"value":"223427","label":"Blinn College"},{"value":"183822","label":"Bloomfield College"},{"value":"211158","label":"Bloomsburg University of Pennsylvania"},{"value":"441502","label":"Blue Cliff College-Gulfport"},{"value":"175430","label":"Blue Mountain College"},{"value":"208275","label":"Blue Mountain Community College"},{"value":"446774","label":"Blue Ridge Community and Technical College"},{"value":"198039","label":"Blue Ridge Community College-Flat Rock"},{"value":"231536","label":"Blue Ridge Community College-Weyers Cave"},{"value":"231554","label":"Bluefield College"},{"value":"237215","label":"Bluefield State College"},{"value":"156392","label":"Bluegrass Community and Technical College"},{"value":"201371","label":"Bluffton University"},{"value":"217749","label":"Bob Jones University"},{"value":"142090","label":"Boise Bible College"},{"value":"142115","label":"Boise State University"},{"value":"233356","label":"Bon Secours Memorial College of Nursing"},{"value":"189413","label":"Boricua College"},{"value":"158431","label":"Bossier Parish Community College"},{"value":"164872","label":"Boston Architectural College"},{"value":"164614","label":"Boston Baptist College"},{"value":"164924","label":"Boston College"},{"value":"164915","label":"Boston Graduate School of Psychoanalysis Inc"},{"value":"164988","label":"Boston University"},{"value":"161004","label":"Bowdoin College"},{"value":"162007","label":"Bowie State University"},{"value":"201432","label":"Bowling Green State University-Firelands"},{"value":"201441","label":"Bowling Green State University-Main Campus"},{"value":"202161","label":"Bradford School-Columbus"},{"value":"211200","label":"Bradford School-Pittsburgh"},{"value":"143358","label":"Bradley University"},{"value":"189422","label":"Bramson ORT College"},{"value":"165015","label":"Brandeis University"},{"value":"262086","label":"Brandman University"},{"value":"223506","label":"Brazosport College"},{"value":"139199","label":"Brenau University"},{"value":"156356","label":"Brescia University"},{"value":"198066","label":"Brevard College"},{"value":"139205","label":"Brewton-Parker College"},{"value":"152992","label":"Briar Cliff University"},{"value":"189459","label":"Briarcliffe College"},{"value":"231581","label":"Bridgewater College"},{"value":"165024","label":"Bridgewater State University"},{"value":"230047","label":"Brigham Young University-Hawaii"},{"value":"142522","label":"Brigham Young University-Idaho"},{"value":"230038","label":"Brigham Young University-Provo"},{"value":"215646","label":"Brightwood Career Institute-Broomall"},{"value":"251075","label":"Brightwood Career Institute-Harrisburg"},{"value":"214254","label":"Brightwood Career Institute-Philadelphia"},{"value":"211617","label":"Brightwood Career Institute-Philadelphia Mills"},{"value":"213002","label":"Brightwood Career Institute-Pittsburgh"},{"value":"458690","label":"Brightwood College-Arlington"},{"value":"447102","label":"Brightwood College-Bakersfield"},{"value":"163736","label":"Brightwood College-Baltimore"},{"value":"440323","label":"Brightwood College-Beaumont"},{"value":"164058","label":"Brightwood College-Beltsville"},{"value":"443827","label":"Brightwood College-Brownsville"},{"value":"458706","label":"Brightwood College-Charlotte"},{"value":"458186","label":"Brightwood College-Chula Vista"},{"value":"443836","label":"Brightwood College-Corpus Christi"},{"value":"382896","label":"Brightwood College-Dallas"},{"value":"204626","label":"Brightwood College-Dayton"},{"value":"246266","label":"Brightwood College-El Paso"},{"value":"445328","label":"Brightwood College-Fort Worth"},{"value":"447120","label":"Brightwood College-Fresno"},{"value":"458283","label":"Brightwood College-Indianapolis"},{"value":"440332","label":"Brightwood College-Laredo"},{"value":"374875","label":"Brightwood College-Las Vegas"},{"value":"227836","label":"Brightwood College-McAllen"},{"value":"366960","label":"Brightwood College-Modesto"},{"value":"246202","label":"Brightwood College-Nashville"},{"value":"447634","label":"Brightwood College-Palm Springs"},{"value":"432302","label":"Brightwood College-Riverside"},{"value":"118259","label":"Brightwood College-Sacramento"},{"value":"431886","label":"Brightwood College-San Antonio-Ingram"},{"value":"364955","label":"Brightwood College-San Antonio-San Pedro"},{"value":"118277","label":"Brightwood College-San Diego"},{"value":"161776","label":"Brightwood College-Towson"},{"value":"118286","label":"Brightwood College-Vista"},{"value":"165033","label":"Bristol Community College"},{"value":"397270","label":"Bristol University"},{"value":"450304","label":"Brite Divinity School"},{"value":"459091","label":"Broadview Entertainment Arts University"},{"value":"467793","label":"Broadview University-Boise"},{"value":"450429","label":"Broadview University-Layton"},{"value":"454591","label":"Broadview University-Orem"},{"value":"230056","label":"Broadview University-West Jordan"},{"value":"183859","label":"Brookdale Community College"},{"value":"223524","label":"Brookhaven College"},{"value":"444088","label":"Brookline College-Albuquerque"},{"value":"104090","label":"Brookline College-Phoenix"},{"value":"404055","label":"Brookline College-Tempe"},{"value":"438179","label":"Brookline College-Tucson"},{"value":"189501","label":"Brooklyn Law School"},{"value":"110185","label":"Brooks Institute"},{"value":"132709","label":"Broward College"},{"value":"205647","label":"Brown Mackie College-Akron"},{"value":"460039","label":"Brown Mackie College-Albuquerque"},{"value":"410283","label":"Brown Mackie College-Atlanta"},{"value":"470162","label":"Brown Mackie College-Birmingham"},{"value":"455600","label":"Brown Mackie College-Boise"},{"value":"205610","label":"Brown Mackie College-Cincinnati"},{"value":"482954","label":"Brown Mackie College-Dallas"},{"value":"375489","label":"Brown Mackie College-Findlay"},{"value":"408039","label":"Brown Mackie College-Fort Wayne"},{"value":"456791","label":"Brown Mackie College-Greenville"},{"value":"421513","label":"Brown Mackie College-Hopkinsville"},{"value":"451699","label":"Brown Mackie College-Indianapolis"},{"value":"154767","label":"Brown Mackie College-Kansas City"},{"value":"157599","label":"Brown Mackie College-Louisville"},{"value":"151616","label":"Brown Mackie College-Merrillville"},{"value":"447290","label":"Brown Mackie College-Miami"},{"value":"151625","label":"Brown Mackie College-Michigan City"},{"value":"204316","label":"Brown Mackie College-North Canton"},{"value":"157696","label":"Brown Mackie College-Northern Kentucky"},{"value":"475042","label":"Brown Mackie College-Oklahoma City"},{"value":"456612","label":"Brown Mackie College-Phoenix"},{"value":"373085","label":"Brown Mackie College-Quad Cities"},{"value":"154776","label":"Brown Mackie College-Salina"},{"value":"460613","label":"Brown Mackie College-San Antonio"},{"value":"151944","label":"Brown Mackie College-South Bend"},{"value":"460048","label":"Brown Mackie College-St Louis"},{"value":"104364","label":"Brown Mackie College-Tucson"},{"value":"455619","label":"Brown Mackie College-Tulsa"},{"value":"217156","label":"Brown University"},{"value":"198084","label":"Brunswick Community College"},{"value":"180878","label":"Bryan College of Health Sciences"},{"value":"219790","label":"Bryan College-Dayton"},{"value":"439826","label":"Bryan College-Gold River"},{"value":"475583","label":"Bryan University-Columbia"},{"value":"110219","label":"Bryan University-Los Angeles"},{"value":"454458","label":"Bryan University-Rogers"},{"value":"369516","label":"Bryan University-Springfield"},{"value":"154794","label":"Bryan University-Topeka"},{"value":"475699","label":"Bryant & Stratton College-Akron"},{"value":"188517","label":"Bryant & Stratton College-Albany"},{"value":"189556","label":"Bryant & Stratton College-Amherst"},{"value":"458502","label":"Bryant & Stratton College-Bayshore"},{"value":"189583","label":"Bryant & Stratton College-Buffalo"},{"value":"202684","label":"Bryant & Stratton College-Cleveland"},{"value":"369905","label":"Bryant & Stratton College-Eastlake"},{"value":"189592","label":"Bryant & Stratton College-Greece"},{"value":"459107","label":"Bryant & Stratton College-Hampton"},{"value":"410496","label":"Bryant & Stratton College-Henrietta"},{"value":"239929","label":"Bryant & Stratton College-Milwaukee"},{"value":"480091","label":"Bryant & Stratton College-Online"},{"value":"201469","label":"Bryant & Stratton College-Parma"},{"value":"231828","label":"Bryant & Stratton College-Richmond"},{"value":"374972","label":"Bryant & Stratton College-Southtowns"},{"value":"189574","label":"Bryant & Stratton College-Syracuse"},{"value":"189565","label":"Bryant & Stratton College-Syracuse North"},{"value":"231785","label":"Bryant & Stratton College-Virginia Beach"},{"value":"451750","label":"Bryant & Stratton College-Wauwatosa"},{"value":"217165","label":"Bryant University"},{"value":"210492","label":"Bryn Athyn College of the New Church"},{"value":"211273","label":"Bryn Mawr College"},{"value":"211291","label":"Bucknell University"},{"value":"211307","label":"Bucks County Community College"},{"value":"211316","label":"Bucks County School of Beauty Culture Inc"},{"value":"153001","label":"Buena Vista University"},{"value":"165112","label":"Bunker Hill Community College"},{"value":"230825","label":"Burlington College"},{"value":"484181","label":"Burnett International College"},{"value":"189653","label":"Business Informatics Center Inc"},{"value":"154800","label":"Butler Community College"},{"value":"211343","label":"Butler County Community College"},{"value":"150163","label":"Butler University"},{"value":"110246","label":"Butte College"},{"value":"444103","label":"Byzantine Catholic Seminary of Saints Cyril and Methodius"},{"value":"198109","label":"Cabarrus College of Health Sciences"},{"value":"110334","label":"Cabrillo College"},{"value":"211352","label":"Cabrini University"},{"value":"215114","label":"Cairn University-Langhorne"},{"value":"198118","label":"Caldwell Community College and Technical Institute"},{"value":"183910","label":"Caldwell University"},{"value":"110361","label":"California Baptist University"},{"value":"110918","label":"California Christian College"},{"value":"110370","label":"California College of the Arts"},{"value":"485263","label":"California College San Diego-San Diego"},{"value":"478634","label":"California College San Diego-San Marcos"},{"value":"110316","label":"California Institute of Integral Studies"},{"value":"110404","label":"California Institute of Technology"},{"value":"111081","label":"California Institute of the Arts"},{"value":"110413","label":"California Lutheran University"},{"value":"480781","label":"California Miramar University"},{"value":"110422","label":"California Polytechnic State University-San Luis Obispo"},{"value":"110529","label":"California State Polytechnic University-Pomona"},{"value":"110486","label":"California State University-Bakersfield"},{"value":"441937","label":"California State University-Channel Islands"},{"value":"110538","label":"California State University-Chico"},{"value":"110547","label":"California State University-Dominguez Hills"},{"value":"110574","label":"California State University-East Bay"},{"value":"110556","label":"California State University-Fresno"},{"value":"110565","label":"California State University-Fullerton"},{"value":"110583","label":"California State University-Long Beach"},{"value":"110592","label":"California State University-Los Angeles"},{"value":"409698","label":"California State University-Monterey Bay"},{"value":"110608","label":"California State University-Northridge"},{"value":"110617","label":"California State University-Sacramento"},{"value":"110510","label":"California State University-San Bernardino"},{"value":"366711","label":"California State University-San Marcos"},{"value":"110495","label":"California State University-Stanislaus"},{"value":"460075","label":"California University of Management and Sciences"},{"value":"211361","label":"California University of Pennsylvania"},{"value":"111391","label":"California Western School of Law"},{"value":"150172","label":"Calumet College of Saint Joseph"},{"value":"176789","label":"Calvary Bible College and Theological Seminary"},{"value":"169080","label":"Calvin College"},{"value":"169099","label":"Calvin Theological Seminary"},{"value":"428329","label":"Cambria-Rowe Business College-Indiana"},{"value":"211398","label":"Cambria-Rowe Business College-Johnstown"},{"value":"165167","label":"Cambridge College"},{"value":"454865","label":"Cambridge College of Healthcare & Technology"},{"value":"446093","label":"Cambridge Junior College-Yuba City"},{"value":"183938","label":"Camden County College"},{"value":"158440","label":"Cameron College"},{"value":"206914","label":"Cameron University"},{"value":"198136","label":"Campbell University"},{"value":"156365","label":"Campbellsville University"},{"value":"111434","label":"Canada College"},{"value":"189705","label":"Canisius College"},{"value":"200208","label":"Cankdeska Cikana Community College"},{"value":"165194","label":"Cape Cod Community College"},{"value":"198154","label":"Cape Fear Community College"},{"value":"413413","label":"Capella University"},{"value":"158352","label":"Capital Area Technical College"},{"value":"129367","label":"Capital Community College"},{"value":"201548","label":"Capital University"},{"value":"162061","label":"Capitol Technology University"},{"value":"238430","label":"Cardinal Stritch University"},{"value":"181941","label":"Career College of Northern Nevada"},{"value":"224439","label":"Career Point College-San Antonio"},{"value":"246008","label":"Career Point College-Tulsa"},{"value":"454306","label":"Career Quest Learning Centers-Jackson"},{"value":"446136","label":"Career Quest Learning Centers-Lansing"},{"value":"367112","label":"Career Technical College-Monroe"},{"value":"446880","label":"Career Technical College-Shreveport"},{"value":"210951","label":"Career Training Academy-Lower Burrell"},{"value":"408312","label":"Career Training Academy-Monroeville"},{"value":"440174","label":"Career Training Academy-Pittsburgh"},{"value":"448239","label":"Careers Unlimited"},{"value":"241377","label":"Caribbean University-Bayamon"},{"value":"241386","label":"Caribbean University-Carolina"},{"value":"363907","label":"Caribbean University-Ponce"},{"value":"363916","label":"Caribbean University-Vega Baja"},{"value":"206923","label":"Carl Albert State College"},{"value":"143613","label":"Carl Sandburg College"},{"value":"173258","label":"Carleton College"},{"value":"132842","label":"Carlos Albizu University-Miami"},{"value":"241331","label":"Carlos Albizu University-San Juan"},{"value":"211431","label":"Carlow University"},{"value":"211440","label":"Carnegie Mellon University"},{"value":"199971","label":"Carolina Christian College"},{"value":"461032","label":"Carolina College of Biblical Studies"},{"value":"433174","label":"Carolinas College of Health Sciences"},{"value":"442602","label":"Carrington College-Albuquerque"},{"value":"142054","label":"Carrington College-Boise"},{"value":"450702","label":"Carrington College-Citrus Heights"},{"value":"457101","label":"Carrington College-Las Vegas"},{"value":"103909","label":"Carrington College-Mesa"},{"value":"103893","label":"Carrington College-Phoenix"},{"value":"438258","label":"Carrington College-Pleasant Hill"},{"value":"467368","label":"Carrington College-Pomona"},{"value":"246035","label":"Carrington College-Portland"},{"value":"457110","label":"Carrington College-Reno"},{"value":"125532","label":"Carrington College-Sacramento"},{"value":"437936","label":"Carrington College-San Jose"},{"value":"246974","label":"Carrington College-San Leandro"},{"value":"439118","label":"Carrington College-Spokane"},{"value":"450696","label":"Carrington College-Stockton"},{"value":"103927","label":"Carrington College-Tucson"},{"value":"250601","label":"Carrington College-Westside"},{"value":"180106","label":"Carroll College"},{"value":"405872","label":"Carroll Community College"},{"value":"238458","label":"Carroll University"},{"value":"219806","label":"Carson-Newman University"},{"value":"198206","label":"Carteret Community College"},{"value":"238476","label":"Carthage College"},{"value":"139287","label":"Carver Bible College"},{"value":"430795","label":"Carver Career Center"},{"value":"111638","label":"Casa Loma College-Van Nuys"},{"value":"439190","label":"Cascadia College"},{"value":"201645","label":"Case Western Reserve University"},{"value":"240505","label":"Casper College"},{"value":"230834","label":"Castleton State College"},{"value":"198215","label":"Catawba College"},{"value":"198233","label":"Catawba Valley Community College"},{"value":"475398","label":"Catholic Distance University"},{"value":"143659","label":"Catholic Theological Union at Chicago"},{"value":"131283","label":"Catholic University of America"},{"value":"189839","label":"Cayuga County Community College"},{"value":"189848","label":"Cazenovia College"},{"value":"162104","label":"Cecil College"},{"value":"211468","label":"Cedar Crest College"},{"value":"223773","label":"Cedar Valley College"},{"value":"201654","label":"Cedarville University"},{"value":"183974","label":"Centenary College"},{"value":"158477","label":"Centenary College of Louisiana"},{"value":"379782","label":"Center for Advanced Legal Studies"},{"value":"241793","label":"Center for Advanced Studies On Puerto Rico and the Caribbean"},{"value":"232618","label":"Centra College of Nursing"},{"value":"100760","label":"Central Alabama Community College"},{"value":"104346","label":"Central Arizona College"},{"value":"106713","label":"Central Baptist College"},{"value":"154837","label":"Central Baptist Theological Seminary"},{"value":"198251","label":"Central Carolina Community College"},{"value":"218858","label":"Central Carolina Technical College"},{"value":"154855","label":"Central Christian College of Kansas"},{"value":"176910","label":"Central Christian College of the Bible"},{"value":"153108","label":"Central College"},{"value":"180902","label":"Central Community College"},{"value":"128771","label":"Central Connecticut State University"},{"value":"439525","label":"Central Florida Institute"},{"value":"483045","label":"Central Georgia Technical College"},{"value":"173203","label":"Central Lakes College-Brainerd"},{"value":"158088","label":"Central Louisiana Technical Community College"},{"value":"161077","label":"Central Maine Community College"},{"value":"445267","label":"Central Methodist University-College of Graduate and Extended Studies"},{"value":"176947","label":"Central Methodist University-College of Liberal Arts and Sciences"},{"value":"169248","label":"Central Michigan University"},{"value":"187532","label":"Central New Mexico Community College"},{"value":"201672","label":"Central Ohio Technical College"},{"value":"208318","label":"Central Oregon Community College"},{"value":"211477","label":"Central Penn College"},{"value":"198260","label":"Central Piedmont Community College"},{"value":"201690","label":"Central State University"},{"value":"223816","label":"Central Texas College"},{"value":"231697","label":"Central Virginia Community College"},{"value":"234827","label":"Central Washington University"},{"value":"240514","label":"Central Wyoming College"},{"value":"189857","label":"Central Yeshiva Tomchei Tmimim Lubavitz"},{"value":"234845","label":"Centralia College"},{"value":"156408","label":"Centre College"},{"value":"451741","label":"Centro de Estudios Multidisciplinarios-Bayamon"},{"value":"376224","label":"Centro de Estudios Multidisciplinarios-Humacao"},{"value":"241517","label":"Centro de Estudios Multidisciplinarios-San Juan"},{"value":"420024","label":"Centura College-Chesapeake"},{"value":"444972","label":"Centura College-Columbia"},{"value":"377449","label":"Centura College-Newport News"},{"value":"377458","label":"Centura College-Norfolk"},{"value":"427982","label":"Centura College-Richmond Main"},{"value":"232016","label":"Centura College-Virginia Beach"},{"value":"175315","label":"Century College-White Bear Lake"},{"value":"111887","label":"Cerritos College"},{"value":"111896","label":"Cerro Coso Community College"},{"value":"111920","label":"Chabot College"},{"value":"180948","label":"Chadron State College"},{"value":"111939","label":"Chaffey College"},{"value":"454245","label":"Chamberlain College of Nursing-Arizona"},{"value":"457129","label":"Chamberlain College of Nursing-Florida"},{"value":"475732","label":"Chamberlain College of Nursing-Georgia"},{"value":"454227","label":"Chamberlain College of Nursing-Illinois"},{"value":"466921","label":"Chamberlain College of Nursing-Missouri"},{"value":"454236","label":"Chamberlain College of Nursing-Ohio"},{"value":"466930","label":"Chamberlain College of Nursing-Texas"},{"value":"460871","label":"Chamberlain College of Nursing-Virginia"},{"value":"141486","label":"Chaminade University of Honolulu"},{"value":"230852","label":"Champlain College"},{"value":"364025","label":"Chandler-Gilbert Community College"},{"value":"111948","label":"Chapman University"},{"value":"111966","label":"Charles R Drew University of Medicine and Science"},{"value":"451510","label":"Charleston School of Law"},{"value":"217688","label":"Charleston Southern University"},{"value":"444778","label":"Charlotte Christian College and Theological Seminary"},{"value":"455169","label":"Charlotte School of Law"},{"value":"102845","label":"Charter College-Anchorage"},{"value":"434317","label":"Charter College-Canyon Country"},{"value":"128780","label":"Charter Oak State College"},{"value":"201751","label":"Chatfield College"},{"value":"211556","label":"Chatham University"},{"value":"140331","label":"Chattahoochee Technical College"},{"value":"101028","label":"Chattahoochee Valley Community College"},{"value":"220118","label":"Chattanooga College Medical Dental and Technical Careers"},{"value":"219824","label":"Chattanooga State Community College"},{"value":"208390","label":"Chemeketa Community College"},{"value":"162168","label":"Chesapeake College"},{"value":"437769","label":"Chester Career College"},{"value":"211583","label":"Chestnut Hill College"},{"value":"211608","label":"Cheyney University of Pennsylvania"},{"value":"181145","label":"CHI Health School of Radiologic Technology"},{"value":"393180","label":"Chicago ORT Technical Institute"},{"value":"144005","label":"Chicago State University"},{"value":"144014","label":"Chicago Theological Seminary"},{"value":"180160","label":"Chief Dull Knife College"},{"value":"133021","label":"Chipola College"},{"value":"240116","label":"Chippewa Valley Technical College"},{"value":"198303","label":"Chowan University"},{"value":"189981","label":"Christ the King Seminary"},{"value":"219833","label":"Christian Brothers University"},{"value":"260947","label":"Christian Life College"},{"value":"150215","label":"Christian Theological Seminary"},{"value":"475510","label":"Christie's Education"},{"value":"231712","label":"Christopher Newport University"},{"value":"112127","label":"Church Divinity School of the Pacific"},{"value":"201858","label":"Cincinnati Christian University"},{"value":"201867","label":"Cincinnati College of Mortuary Science"},{"value":"201928","label":"Cincinnati State Technical and Community College"},{"value":"223898","label":"Cisco College"},{"value":"217864","label":"Citadel Military College of South Carolina"},{"value":"112172","label":"Citrus College"},{"value":"112190","label":"City College of San Francisco"},{"value":"417327","label":"City College-Altamonte Springs"},{"value":"244233","label":"City College-Fort Lauderdale"},{"value":"406547","label":"City College-Gainesville"},{"value":"475477","label":"City College-Hollywood"},{"value":"434539","label":"City College-Miami"},{"value":"144209","label":"City Colleges of Chicago-Harold Washington College"},{"value":"144184","label":"City Colleges of Chicago-Harry S Truman College"},{"value":"144157","label":"City Colleges of Chicago-Kennedy-King College"},{"value":"144166","label":"City Colleges of Chicago-Malcolm X College"},{"value":"144175","label":"City Colleges of Chicago-Olive-Harvey College"},{"value":"144193","label":"City Colleges of Chicago-Richard J Daley College"},{"value":"144218","label":"City Colleges of Chicago-Wilbur Wright College"},{"value":"234915","label":"City University of Seattle"},{"value":"457697","label":"City Vision University"},{"value":"208406","label":"Clackamas Community College"},{"value":"217873","label":"Claflin University"},{"value":"112251","label":"Claremont Graduate University"},{"value":"112260","label":"Claremont McKenna College"},{"value":"124283","label":"Claremont School of Theology"},{"value":"223922","label":"Clarendon College"},{"value":"211644","label":"Clarion University of Pennsylvania"},{"value":"138947","label":"Clark Atlanta University"},{"value":"234933","label":"Clark College"},{"value":"201973","label":"Clark State Community College"},{"value":"165334","label":"Clark University"},{"value":"153126","label":"Clarke University"},{"value":"180832","label":"Clarkson College"},{"value":"190044","label":"Clarkson University"},{"value":"450401","label":"Clary Sage College"},{"value":"208415","label":"Clatsop Community College"},{"value":"139311","label":"Clayton State University"},{"value":"156417","label":"Clear Creek Baptist Bible College"},{"value":"133085","label":"Clearwater Christian College"},{"value":"169327","label":"Cleary University"},{"value":"217882","label":"Clemson University"},{"value":"198321","label":"Cleveland Community College"},{"value":"202046","label":"Cleveland Institute of Art"},{"value":"202073","label":"Cleveland Institute of Music"},{"value":"219879","label":"Cleveland State Community College"},{"value":"202134","label":"Cleveland State University"},{"value":"177038","label":"Cleveland University-Kansas City"},{"value":"217891","label":"Clinton College"},{"value":"190053","label":"Clinton Community College"},{"value":"154907","label":"Cloud County Community College"},{"value":"234951","label":"Clover Park Technical College"},{"value":"187639","label":"Clovis Community College"},{"value":"175519","label":"Coahoma Community College"},{"value":"223320","label":"Coastal Bend College"},{"value":"198330","label":"Coastal Carolina Community College"},{"value":"218724","label":"Coastal Carolina University"},{"value":"485458","label":"Coastal Pines Technical College-Waycross"},{"value":"112385","label":"Coastline Community College"},{"value":"104425","label":"Cochise County Community College District"},{"value":"190071","label":"Cochran School of Nursing"},{"value":"404426","label":"Coconino Community College"},{"value":"153144","label":"Coe College"},{"value":"154925","label":"Coffeyville Community College"},{"value":"112394","label":"Cogswell College"},{"value":"217907","label":"Coker College"},{"value":"161086","label":"Colby College"},{"value":"154934","label":"Colby Community College"},{"value":"182634","label":"Colby-Sawyer College"},{"value":"430935","label":"Colegio de Cinematografía Artes y Television"},{"value":"241720","label":"Colegio Universitario de San Juan"},{"value":"112446","label":"Coleman University"},{"value":"190080","label":"Colgate Rochester Crozer Divinity School"},{"value":"190099","label":"Colgate University"},{"value":"169442","label":"College for Creative Studies"},{"value":"108667","label":"College of Alameda"},{"value":"388520","label":"College of Biblical Studies-Houston"},{"value":"456977","label":"College of Business and Technology-Cutler Bay"},{"value":"449083","label":"College of Business and Technology-Flagler"},{"value":"449092","label":"College of Business and Technology-Hialeah"},{"value":"417318","label":"College of Business and Technology-Kendall"},{"value":"482024","label":"College of Business and Technology-Miami Gardens"},{"value":"132851","label":"College of Central Florida"},{"value":"217819","label":"College of Charleston"},{"value":"139250","label":"College of Coastal Georgia"},{"value":"150251","label":"College of Court Reporting Inc"},{"value":"144865","label":"College of DuPage"},{"value":"392257","label":"College of Health Care Professions-Northwest"},{"value":"146472","label":"College of Lake County"},{"value":"118347","label":"College of Marin"},{"value":"413617","label":"College of Menominee Nation"},{"value":"243638","label":"College of Micronesia-FSM"},{"value":"193399","label":"College of Mount Saint Vincent"},{"value":"167394","label":"College of Our Lady of the Elms"},{"value":"174747","label":"College of Saint Benedict"},{"value":"186618","label":"College of Saint Elizabeth"},{"value":"181604","label":"College of Saint Mary"},{"value":"122791","label":"College of San Mateo"},{"value":"142559","label":"College of Southern Idaho"},{"value":"162122","label":"College of Southern Maryland"},{"value":"182005","label":"College of Southern Nevada"},{"value":"231077","label":"College of St Joseph"},{"value":"190558","label":"College of Staten Island CUNY"},{"value":"197814","label":"College of the Albemarle"},{"value":"160959","label":"College of the Atlantic"},{"value":"111461","label":"College of the Canyons"},{"value":"113573","label":"College of the Desert"},{"value":"166124","label":"College of the Holy Cross"},{"value":"226408","label":"College of the Mainland"},{"value":"376695","label":"College of the Marshall Islands"},{"value":"480967","label":"College of the Muscogee Nation"},{"value":"107521","label":"College of the Ouachitas"},{"value":"178697","label":"College of the Ozarks"},{"value":"121707","label":"College of the Redwoods"},{"value":"123217","label":"College of the Sequoias"},{"value":"123484","label":"College of the Siskiyous"},{"value":"455114","label":"College of Western Idaho"},{"value":"231624","label":"College of William and Mary"},{"value":"451705","label":"CollegeAmerica-Cheyenne"},{"value":"448752","label":"CollegeAmerica-Colorado Springs"},{"value":"126872","label":"CollegeAmerica-Denver"},{"value":"103945","label":"CollegeAmerica-Flagstaff"},{"value":"448761","label":"CollegeAmerica-Fort Collins"},{"value":"474890","label":"CollegeAmerica-Phoenix"},{"value":"247834","label":"Collin County Community College District"},{"value":"103723","label":"Collins College"},{"value":"461953","label":"Colorado Academy of Veterinary Technology"},{"value":"126669","label":"Colorado Christian University"},{"value":"126678","label":"Colorado College"},{"value":"367839","label":"Colorado Heights University"},{"value":"127556","label":"Colorado Mesa University"},{"value":"126711","label":"Colorado Mountain College"},{"value":"126748","label":"Colorado Northwestern Community College"},{"value":"381732","label":"Colorado School of Healing Arts"},{"value":"126775","label":"Colorado School of Mines"},{"value":"126784","label":"Colorado School of Trades"},{"value":"381352","label":"Colorado School of Traditional Chinese Medicine"},{"value":"126818","label":"Colorado State University-Fort Collins"},{"value":"476975","label":"Colorado State University-Global Campus"},{"value":"128106","label":"Colorado State University-Pueblo"},{"value":"126827","label":"Colorado Technical University-Colorado Springs"},{"value":"430087","label":"Colorado Technical University-Greenwood Village"},{"value":"444158","label":"Colorado Technical University-Online"},{"value":"402615","label":"Colorado Technical University-Sioux Falls"},{"value":"234979","label":"Columbia Basin College"},{"value":"241304","label":"Columbia Central University-Caguas"},{"value":"404806","label":"Columbia Central University-Yauco"},{"value":"238573","label":"Columbia College of Nursing"},{"value":"144281","label":"Columbia College-Chicago"},{"value":"177065","label":"Columbia College-Columbia"},{"value":"217934","label":"Columbia College-Columbia"},{"value":"455983","label":"Columbia College-Fairfax"},{"value":"112570","label":"Columbia College-Hollywood"},{"value":"112561","label":"Columbia College-Sonora"},{"value":"420556","label":"Columbia Gorge Community College"},{"value":"217925","label":"Columbia International University"},{"value":"450933","label":"Columbia Southern University"},{"value":"219888","label":"Columbia State Community College"},{"value":"139348","label":"Columbia Theological Seminary"},{"value":"190150","label":"Columbia University in the City of New York"},{"value":"190169","label":"Columbia-Greene Community College"},{"value":"202170","label":"Columbus College of Art and Design"},{"value":"202222","label":"Columbus State Community College"},{"value":"139366","label":"Columbus State University"},{"value":"139357","label":"Columbus Technical College"},{"value":"483522","label":"Comanche Nation College"},{"value":"366261","label":"Commonwealth Institute of Funeral Service"},{"value":"212975","label":"Commonwealth Technical Institute"},{"value":"439570","label":"Community Care College"},{"value":"446163","label":"Community Christian College"},{"value":"210605","label":"Community College of Allegheny County"},{"value":"126863","label":"Community College of Aurora"},{"value":"211079","label":"Community College of Beaver County"},{"value":"126942","label":"Community College of Denver"},{"value":"215239","label":"Community College of Philadelphia"},{"value":"217475","label":"Community College of Rhode Island"},{"value":"230861","label":"Community College of Vermont"},{"value":"459417","label":"Compass College of Cinematic Arts"},{"value":"177083","label":"Conception Seminary College"},{"value":"237330","label":"Concord University"},{"value":"126687","label":"Concorde Career College-Aurora"},{"value":"460181","label":"Concorde Career College-Dallas"},{"value":"123679","label":"Concorde Career College-Garden Grove"},{"value":"441742","label":"Concorde Career College-Grand Prairie"},{"value":"155283","label":"Concorde Career College-Kansas City"},{"value":"219903","label":"Concorde Career College-Memphis"},{"value":"124937","label":"Concorde Career College-North Hollywood"},{"value":"208479","label":"Concorde Career College-Portland"},{"value":"460206","label":"Concorde Career College-San Antonio"},{"value":"124706","label":"Concorde Career College-San Bernardino"},{"value":"120661","label":"Concorde Career College-San Diego"},{"value":"133845","label":"Concorde Career Institute-Jacksonville"},{"value":"133854","label":"Concorde Career Institute-Miramar"},{"value":"460190","label":"Concorde Career Institute-Orlando"},{"value":"133863","label":"Concorde Career Institute-Tampa"},{"value":"101073","label":"Concordia College Alabama"},{"value":"173300","label":"Concordia College at Moorhead"},{"value":"190248","label":"Concordia College-New York"},{"value":"177092","label":"Concordia Seminary"},{"value":"150288","label":"Concordia Theological Seminary"},{"value":"169363","label":"Concordia University-Ann Arbor"},{"value":"144351","label":"Concordia University-Chicago"},{"value":"112075","label":"Concordia University-Irvine"},{"value":"180984","label":"Concordia University-Nebraska"},{"value":"208488","label":"Concordia University-Portland"},{"value":"173328","label":"Concordia University-Saint Paul"},{"value":"224004","label":"Concordia University-Texas"},{"value":"238616","label":"Concordia University-Wisconsin"},{"value":"128902","label":"Connecticut College"},{"value":"206996","label":"Connors State College"},{"value":"260354","label":"Consolidated School of Business-Lancaster"},{"value":"211820","label":"Consolidated School of Business-York"},{"value":"112826","label":"Contra Costa College"},{"value":"217961","label":"Converse College"},{"value":"165495","label":"Conway School of Landscape Design"},{"value":"190372","label":"Cooper Union for the Advancement of Science and Art"},{"value":"175573","label":"Copiah-Lincoln Community College"},{"value":"395362","label":"Copper Mountain Community College"},{"value":"162283","label":"Coppin State University"},{"value":"210331","label":"Corban University"},{"value":"153162","label":"Cornell College"},{"value":"190415","label":"Cornell University"},{"value":"170037","label":"Cornerstone University"},{"value":"190442","label":"Corning Community College"},{"value":"235024","label":"Cornish College of the Arts"},{"value":"106795","label":"Cossatot Community College of the University of Arkansas"},{"value":"113096","label":"Cosumnes River College"},{"value":"177117","label":"Cottey College"},{"value":"184180","label":"County College of Morris"},{"value":"224183","label":"Court Reporting Institute of Dallas"},{"value":"139393","label":"Covenant College"},{"value":"177126","label":"Covenant Theological Seminary"},{"value":"154952","label":"Cowley County Community College"},{"value":"176770","label":"Cox College"},{"value":"144485","label":"Coyne College"},{"value":"113111","label":"Crafton Hills College"},{"value":"169424","label":"Cranbrook Academy of Art"},{"value":"198367","label":"Craven Community College"},{"value":"181002","label":"Creighton University"},{"value":"475608","label":"Criswell College"},{"value":"439613","label":"Crossroads Bible College"},{"value":"174206","label":"Crossroads College"},{"value":"177135","label":"Crowder College"},{"value":"106810","label":"Crowley's Ridge College"},{"value":"174862","label":"Crown College"},{"value":"113193","label":"Cuesta College"},{"value":"444565","label":"Culinary Institute Inc"},{"value":"190503","label":"Culinary Institute of America"},{"value":"177144","label":"Culver-Stockton College"},{"value":"184205","label":"Cumberland County College"},{"value":"219949","label":"Cumberland University"},{"value":"190512","label":"CUNY Bernard M Baruch College"},{"value":"190521","label":"CUNY Borough of Manhattan Community College"},{"value":"190530","label":"CUNY Bronx Community College"},{"value":"190549","label":"CUNY Brooklyn College"},{"value":"190567","label":"CUNY City College"},{"value":"190576","label":"CUNY Graduate School and University Center"},{"value":"190585","label":"CUNY Hostos Community College"},{"value":"190594","label":"CUNY Hunter College"},{"value":"190600","label":"CUNY John Jay College of Criminal Justice"},{"value":"190619","label":"CUNY Kingsborough Community College"},{"value":"190628","label":"CUNY LaGuardia Community College"},{"value":"190637","label":"CUNY Lehman College"},{"value":"190646","label":"CUNY Medgar Evers College"},{"value":"190655","label":"CUNY New York City College of Technology"},{"value":"190664","label":"CUNY Queens College"},{"value":"190673","label":"CUNY Queensborough Community College"},{"value":"190682","label":"CUNY School of Law"},{"value":"190691","label":"CUNY York College"},{"value":"165529","label":"Curry College"},{"value":"211893","label":"Curtis Institute of Music"},{"value":"202356","label":"Cuyahoga Community College District"},{"value":"113218","label":"Cuyamaca College"},{"value":"113236","label":"Cypress College"},{"value":"231873","label":"Dabney S Lancaster Community College"},{"value":"458797","label":"Dade Medical College-Hollywood"},{"value":"458247","label":"Dade Medical College-Homestead"},{"value":"476391","label":"Dade Medical College-Jacksonville"},{"value":"444574","label":"Dade Medical College-Miami"},{"value":"454175","label":"Dade Medical College-Miami Lakes"},{"value":"476382","label":"Dade Medical College-West Palm Beach"},{"value":"190725","label":"Daemen College"},{"value":"200314","label":"Dakota College at Bottineau"},{"value":"173416","label":"Dakota County Technical College"},{"value":"219082","label":"Dakota State University"},{"value":"219091","label":"Dakota Wesleyan University"},{"value":"224226","label":"Dallas Baptist University"},{"value":"224244","label":"Dallas Christian College"},{"value":"224271","label":"Dallas Institute of Funeral Service"},{"value":"437732","label":"Dallas Nursing Institute"},{"value":"224305","label":"Dallas Theological Seminary"},{"value":"139463","label":"Dalton State College"},{"value":"182661","label":"Daniel Webster College"},{"value":"144564","label":"Danville Area Community College"},{"value":"231882","label":"Danville Community College"},{"value":"455178","label":"Daoist Traditions College of Chinese Medical Arts"},{"value":"182670","label":"Dartmouth College"},{"value":"138691","label":"Darton State College"},{"value":"169479","label":"Davenport University"},{"value":"198385","label":"Davidson College"},{"value":"198376","label":"Davidson County Community College"},{"value":"237358","label":"Davis & Elkins College"},{"value":"194569","label":"Davis College-Johnson City"},{"value":"202435","label":"Davis College-Toledo"},{"value":"180151","label":"Dawson Community College"},{"value":"447476","label":"Daymar College-Bellevue"},{"value":"363439","label":"Daymar College-Bowling Green"},{"value":"205568","label":"Daymar College-Chillicothe"},{"value":"205531","label":"Daymar College-Jackson"},{"value":"205559","label":"Daymar College-Lancaster"},{"value":"406219","label":"Daymar College-Louisville-Louisville"},{"value":"449302","label":"Daymar College-Madisonville"},{"value":"205522","label":"Daymar College-New Boston"},{"value":"458557","label":"Daymar College-Online"},{"value":"157465","label":"Daymar College-Owensboro"},{"value":"156903","label":"Daymar College-Paducah Main"},{"value":"368443","label":"Daymar Institute-Clarksville"},{"value":"444255","label":"Daymar Institute-Murfreesboro"},{"value":"220002","label":"Daymar Institute-Nashville"},{"value":"447014","label":"Daytona College"},{"value":"133386","label":"Daytona State College"},{"value":"113333","label":"De Anza College"},{"value":"165574","label":"Dean College"},{"value":"211909","label":"Dean Institute of Technology"},{"value":"202514","label":"Defiance College"},{"value":"224350","label":"Del Mar College"},{"value":"432524","label":"Delaware College of Art and Design"},{"value":"211927","label":"Delaware County Community College"},{"value":"130934","label":"Delaware State University"},{"value":"130891","label":"Delaware Technical Community College-Owens"},{"value":"130916","label":"Delaware Technical Community College-Stanton/Wilmington"},{"value":"130907","label":"Delaware Technical Community College-Terry"},{"value":"211981","label":"Delaware Valley University"},{"value":"158662","label":"Delgado Community College"},{"value":"113537","label":"Dell'Arte International School of Physical Theatre"},{"value":"169521","label":"Delta College"},{"value":"366270","label":"Delta College of Arts & Technology"},{"value":"158723","label":"Delta School of Business and Technology"},{"value":"175616","label":"Delta State University"},{"value":"202523","label":"Denison University"},{"value":"217989","label":"Denmark Technical College"},{"value":"454856","label":"Denver School of Nursing"},{"value":"126979","label":"Denver Seminary"},{"value":"144740","label":"DePaul University"},{"value":"150400","label":"DePauw University"},{"value":"153214","label":"Des Moines Area Community College"},{"value":"154156","label":"Des Moines University-Osteopathic Medical Center"},{"value":"210739","label":"DeSales University"},{"value":"113582","label":"Design Institute of San Diego"},{"value":"482413","label":"DeVry College of New York"},{"value":"482422","label":"DeVry University-Arizona"},{"value":"482431","label":"DeVry University-California"},{"value":"482440","label":"DeVry University-Colorado"},{"value":"482459","label":"DeVry University-Florida"},{"value":"482468","label":"DeVry University-Georgia"},{"value":"482477","label":"DeVry University-Illinois"},{"value":"482486","label":"DeVry University-Indiana"},{"value":"482501","label":"DeVry University-Maryland"},{"value":"482510","label":"DeVry University-Michigan"},{"value":"482529","label":"DeVry University-Minnesota"},{"value":"482538","label":"DeVry University-Missouri"},{"value":"482547","label":"DeVry University-Nevada"},{"value":"482556","label":"DeVry University-New Jersey"},{"value":"482565","label":"DeVry University-North Carolina"},{"value":"482574","label":"DeVry University-Ohio"},{"value":"482583","label":"DeVry University-Oklahoma"},{"value":"482592","label":"DeVry University-Oregon"},{"value":"482608","label":"DeVry University-Pennsylvania"},{"value":"482617","label":"DeVry University-Tennessee"},{"value":"482635","label":"DeVry University-Texas"},{"value":"482644","label":"DeVry University-Utah"},{"value":"482653","label":"DeVry University-Virginia"},{"value":"482662","label":"DeVry University-Washington"},{"value":"482671","label":"DeVry University-Wisconsin"},{"value":"443562","label":"Dewey University-Hato Rey-Hato Rey"},{"value":"113634","label":"Diablo Valley College"},{"value":"212009","label":"Dickinson College"},{"value":"200059","label":"Dickinson State University"},{"value":"443410","label":"DigiPen Institute of Technology"},{"value":"451060","label":"Digital Media Arts College"},{"value":"158802","label":"Dillard University"},{"value":"105297","label":"Dine College"},{"value":"153241","label":"Divine Word College"},{"value":"230171","label":"Dixie State University"},{"value":"181020","label":"Doane University-Arts & Sciences"},{"value":"448284","label":"Doane University-Graduate and Professional Studies"},{"value":"154998","label":"Dodge City Community College"},{"value":"190761","label":"Dominican College of Blauvelt"},{"value":"113704","label":"Dominican School of Philosophy & Theology"},{"value":"148496","label":"Dominican University"},{"value":"113698","label":"Dominican University of California"},{"value":"122117","label":"Dongguk University-Los Angeles"},{"value":"155007","label":"Donnelly College"},{"value":"153250","label":"Dordt College"},{"value":"212045","label":"Douglas Education Center"},{"value":"190770","label":"Dowling College"},{"value":"153269","label":"Drake University"},{"value":"184348","label":"Drew University"},{"value":"212054","label":"Drexel University"},{"value":"177214","label":"Drury University"},{"value":"212072","label":"Du Bois Business College-Du Bois"},{"value":"439303","label":"Du Bois Business College-Huntingdon"},{"value":"439312","label":"Du Bois Business College-Oil City"},{"value":"198419","label":"Duke University"},{"value":"173489","label":"Duluth Business University"},{"value":"175227","label":"Dunwoody College of Technology"},{"value":"212106","label":"Duquesne University"},{"value":"198455","label":"Durham Technical Community College"},{"value":"190840","label":"Dutchess Community College"},{"value":"220057","label":"Dyersburg State Community College"},{"value":"190716","label":"D'Youville College"},{"value":"447421","label":"Eagle Gate College-Layton"},{"value":"230366","label":"Eagle Gate College-Murray"},{"value":"447625","label":"Eagle Gate College-Salt Lake City"},{"value":"150455","label":"Earlham College"},{"value":"106883","label":"East Arkansas Community College"},{"value":"198464","label":"East Carolina University"},{"value":"177250","label":"East Central College"},{"value":"175643","label":"East Central Community College"},{"value":"207041","label":"East Central University"},{"value":"139621","label":"East Georgia State College"},{"value":"113856","label":"East Los Angeles College"},{"value":"175652","label":"East Mississippi Community College"},{"value":"413802","label":"East San Gabriel Valley Regional Occupational Program"},{"value":"212115","label":"East Stroudsburg University of Pennsylvania"},{"value":"220075","label":"East Tennessee State University"},{"value":"224527","label":"East Texas Baptist University"},{"value":"439394","label":"East West College of Natural Medicine"},{"value":"104577","label":"Eastern Arizona College"},{"value":"129215","label":"Eastern Connecticut State University"},{"value":"132693","label":"Eastern Florida State College"},{"value":"203331","label":"Eastern Gateway Community College"},{"value":"142179","label":"Eastern Idaho Technical College"},{"value":"144892","label":"Eastern Illinois University"},{"value":"448354","label":"Eastern International College-Belleville"},{"value":"421878","label":"Eastern International College-Jersey City"},{"value":"153311","label":"Eastern Iowa Community College District"},{"value":"156620","label":"Eastern Kentucky University"},{"value":"161138","label":"Eastern Maine Community College"},{"value":"232043","label":"Eastern Mennonite University"},{"value":"169798","label":"Eastern Michigan University"},{"value":"165644","label":"Eastern Nazarene College"},{"value":"187648","label":"Eastern New Mexico University-Main Campus"},{"value":"187666","label":"Eastern New Mexico University-Roswell Campus"},{"value":"383996","label":"Eastern New Mexico University-Ruidoso Campus"},{"value":"207050","label":"Eastern Oklahoma State College"},{"value":"208646","label":"Eastern Oregon University"},{"value":"232052","label":"Eastern Shore Community College"},{"value":"212133","label":"Eastern University"},{"value":"441858","label":"Eastern Virginia Career College"},{"value":"231970","label":"Eastern Virginia Medical School"},{"value":"235097","label":"Eastern Washington University"},{"value":"438708","label":"Eastern West Virginia Community and Technical College"},{"value":"240596","label":"Eastern Wyoming College"},{"value":"224572","label":"Eastfield College"},{"value":"144883","label":"East-West University"},{"value":"183488","label":"Eastwick College-Hackensack"},{"value":"184959","label":"Eastwick College-Ramsey"},{"value":"446233","label":"Ecclesia College"},{"value":"133492","label":"Eckerd College"},{"value":"460215","label":"Ecotech Institute"},{"value":"248934","label":"ECPI University"},{"value":"247162","label":"Ecumenical Theological Seminary"},{"value":"177278","label":"Eden Theological Seminary"},{"value":"198491","label":"Edgecombe Community College"},{"value":"238661","label":"Edgewood College"},{"value":"376321","label":"EDIC College"},{"value":"212160","label":"Edinboro University of Pennsylvania"},{"value":"202648","label":"Edison State Community College"},{"value":"235103","label":"Edmonds Community College"},{"value":"243832","label":"EDP Univeristy of Puerto Rico Inc-San Juan"},{"value":"241836","label":"EDP University of Puerto Rico Inc-San Sebastian"},{"value":"442806","label":"Edward Via College of Osteopathic Medicine"},{"value":"133526","label":"Edward Waters College"},{"value":"112686","label":"El Camino College-Compton Center"},{"value":"113980","label":"El Camino Community College District"},{"value":"224615","label":"El Centro College"},{"value":"224642","label":"El Paso Community College"},{"value":"144944","label":"Elgin Community College"},{"value":"198507","label":"Elizabeth City State University"},{"value":"212197","label":"Elizabethtown College"},{"value":"480134","label":"Elizabethtown College School of Continuing and Professional Studies"},{"value":"156648","label":"Elizabethtown Community and Technical College"},{"value":"153296","label":"Ellsworth Community College"},{"value":"144962","label":"Elmhurst College"},{"value":"190974","label":"Elmira Business Institute"},{"value":"190983","label":"Elmira College"},{"value":"198516","label":"Elon University"},{"value":"133553","label":"Embry-Riddle Aeronautical University-Daytona Beach"},{"value":"104586","label":"Embry-Riddle Aeronautical University-Prescott"},{"value":"426314","label":"Embry-Riddle Aeronautical University-Worldwide"},{"value":"165662","label":"Emerson College"},{"value":"220136","label":"Emmanuel Christian Seminary"},{"value":"165671","label":"Emmanuel College-Boston"},{"value":"139630","label":"Emmanuel College-Franklin Springs"},{"value":"153302","label":"Emmaus Bible College"},{"value":"232025","label":"Emory & Henry College"},{"value":"139658","label":"Emory University"},{"value":"114114","label":"Emperor's College of Traditional Oriental Medicine"},{"value":"114123","label":"Empire College"},{"value":"155025","label":"Emporia State University"},{"value":"165699","label":"Endicott College"},{"value":"101143","label":"Enterprise State Community College"},{"value":"124487","label":"Epic Bible College"},{"value":"165705","label":"Episcopal Divinity School"},{"value":"224712","label":"Episcopal Theological Seminary of the Southwest"},{"value":"191083","label":"Erie Community College"},{"value":"212434","label":"Erie Institute of Technology Inc"},{"value":"409254","label":"Erikson Institute"},{"value":"217998","label":"Erskine College"},{"value":"241951","label":"Escuela de Artes Plasticas de Puerto Rico"},{"value":"184481","label":"Essex County College"},{"value":"384333","label":"Estrella Mountain Community College"},{"value":"200590","label":"ETI Technical College"},{"value":"144971","label":"Eureka College"},{"value":"177339","label":"Evangel University"},{"value":"212443","label":"Evangelical Theological Seminary"},{"value":"371982","label":"Everest College-Anaheim"},{"value":"443854","label":"Everest College-Arlington"},{"value":"366544","label":"Everest College-Aurora"},{"value":"234739","label":"Everest College-Bremerton"},{"value":"438647","label":"Everest College-Chesapeake"},{"value":"372037","label":"Everest College-City of Industry"},{"value":"126401","label":"Everest College-Colorado Springs"},{"value":"442790","label":"Everest College-Dallas"},{"value":"363590","label":"Everest College-Everett"},{"value":"445197","label":"Everest College-Fort Worth"},{"value":"460358","label":"Everest College-Fort Worth South"},{"value":"182148","label":"Everest College-Henderson"},{"value":"445470","label":"Everest College-McLean"},{"value":"447236","label":"Everest College-Mesa"},{"value":"232502","label":"Everest College-Newport News"},{"value":"440299","label":"Everest College-Ontario Metro"},{"value":"103644","label":"Everest College-Phoenix"},{"value":"210359","label":"Everest College-Portland"},{"value":"119359","label":"Everest College-Reseda"},{"value":"230472","label":"Everest College-Salt Lake City"},{"value":"119508","label":"Everest College-San Bernardino"},{"value":"179070","label":"Everest College-Springfield"},{"value":"444024","label":"Everest College-Tacoma"},{"value":"127787","label":"Everest College-Thornton"},{"value":"236993","label":"Everest College-Vancouver"},{"value":"368805","label":"Everest College-West Los Angeles"},{"value":"237604","label":"Everest Institute-Cross Lanes"},{"value":"409670","label":"Everest Institute-Kendall"},{"value":"443748","label":"Everest Institute-Norcross"},{"value":"135957","label":"Everest Institute-North Miami"},{"value":"212090","label":"Everest Institute-Pittsburgh"},{"value":"194967","label":"Everest Institute-Rochester"},{"value":"260293","label":"Everest University-Brandon"},{"value":"438902","label":"Everest University-Jacksonville"},{"value":"367909","label":"Everest University-Lakeland"},{"value":"137810","label":"Everest University-Largo"},{"value":"420006","label":"Everest University-Melbourne"},{"value":"136288","label":"Everest University-North Orlando"},{"value":"445434","label":"Everest University-Orange Park"},{"value":"134149","label":"Everest University-Pompano Beach"},{"value":"390701","label":"Everest University-South Orlando"},{"value":"137801","label":"Everest University-Tampa"},{"value":"235149","label":"Everett Community College"},{"value":"385619","label":"Everglades University"},{"value":"114266","label":"Evergreen Valley College"},{"value":"196680","label":"Excelsior College"},{"value":"447458","label":"Expression College for Digital Arts"},{"value":"129242","label":"Fairfield University"},{"value":"184694","label":"Fairleigh Dickinson University-College at Florham"},{"value":"184603","label":"Fairleigh Dickinson University-Metropolitan Campus"},{"value":"237367","label":"Fairmont State University"},{"value":"153320","label":"Faith Baptist Bible College and Theological Seminary"},{"value":"443049","label":"Faith Evangelical College & Seminary"},{"value":"212452","label":"Faith Theological Seminary"},{"value":"443058","label":"Family of Faith College"},{"value":"196042","label":"Farmingdale State College"},{"value":"114354","label":"Fashion Institute of Design & Merchandising-Los Angeles"},{"value":"248846","label":"Fashion Institute of Design & Merchandising-San Diego"},{"value":"114390","label":"Fashion Institute of Design & Merchandising-San Francisco"},{"value":"191126","label":"Fashion Institute of Technology"},{"value":"101189","label":"Faulkner University"},{"value":"198543","label":"Fayetteville State University"},{"value":"198534","label":"Fayetteville Technical Community College"},{"value":"114433","label":"Feather River Community College District"},{"value":"184612","label":"Felician University"},{"value":"169910","label":"Ferris State University"},{"value":"232089","label":"Ferrum College"},{"value":"114549","label":"Fielding Graduate University"},{"value":"436599","label":"FINE Mortuary College"},{"value":"191199","label":"Finger Lakes Community College"},{"value":"475422","label":"Finger Lakes Health College of Nursing"},{"value":"172440","label":"Finlandia University"},{"value":"165802","label":"Fisher College"},{"value":"220181","label":"Fisk University"},{"value":"165820","label":"Fitchburg State University"},{"value":"114585","label":"Five Branches University"},{"value":"191205","label":"Five Towns College"},{"value":"133711","label":"Flagler College-St Augustine"},{"value":"444990","label":"Flagler College-Tallahassee"},{"value":"180197","label":"Flathead Valley Community College"},{"value":"160481","label":"Fletcher Technical Community College"},{"value":"155052","label":"Flint Hills Technical College"},{"value":"218025","label":"Florence-Darlington Technical College"},{"value":"133650","label":"Florida Agricultural and Mechanical University"},{"value":"133669","label":"Florida Atlantic University"},{"value":"133997","label":"Florida Career College-Miami"},{"value":"434715","label":"Florida Coastal School of Law"},{"value":"133809","label":"Florida College"},{"value":"434441","label":"Florida College of Integrative Medicine"},{"value":"438294","label":"Florida College of Natural Health-Bradenton"},{"value":"438285","label":"Florida College of Natural Health-Maitland"},{"value":"420103","label":"Florida College of Natural Health-Miami"},{"value":"387925","label":"Florida College of Natural Health-Pompano Beach"},{"value":"135160","label":"Florida Gateway College"},{"value":"433660","label":"Florida Gulf Coast University"},{"value":"133881","label":"Florida Institute of Technology"},{"value":"480569","label":"Florida Institute of Technology-Online"},{"value":"133951","label":"Florida International University"},{"value":"133960","label":"Florida Keys Community College"},{"value":"133979","label":"Florida Memorial University"},{"value":"408844","label":"Florida National University-Main Campus"},{"value":"134079","label":"Florida Southern College"},{"value":"133508","label":"Florida SouthWestern State College"},{"value":"133702","label":"Florida State College at Jacksonville"},{"value":"134097","label":"Florida State University"},{"value":"134112","label":"Florida Technical College"},{"value":"444219","label":"Folsom Lake College"},{"value":"380368","label":"Fond du Lac Tribal and Community College"},{"value":"177418","label":"Fontbonne University"},{"value":"114716","label":"Foothill College"},{"value":"191241","label":"Fordham University"},{"value":"177427","label":"Forest Institute of Professional Psychology"},{"value":"218043","label":"Forrest College"},{"value":"198552","label":"Forsyth Technical Community College"},{"value":"155061","label":"Fort Hays State University"},{"value":"127185","label":"Fort Lewis College"},{"value":"180212","label":"Fort Peck Community College"},{"value":"155098","label":"Fort Scott Community College"},{"value":"139719","label":"Fort Valley State University"},{"value":"439738","label":"Fortis College-Baton Rouge"},{"value":"205179","label":"Fortis College-Centerville"},{"value":"450067","label":"Fortis College-Cincinnati"},{"value":"460020","label":"Fortis College-Columbia"},{"value":"450058","label":"Fortis College-Columbus"},{"value":"480143","label":"Fortis College-Cutler Bay"},{"value":"204307","label":"Fortis College-Cuyahoga Falls"},{"value":"458681","label":"Fortis College-Indianapolis"},{"value":"451909","label":"Fortis College-Landover"},{"value":"447360","label":"Fortis College-Largo"},{"value":"371052","label":"Fortis College-Mobile"},{"value":"455488","label":"Fortis College-Montgomery-Montgomery"},{"value":"233329","label":"Fortis College-Norfolk"},{"value":"439792","label":"Fortis College-Orange Park"},{"value":"456180","label":"Fortis College-Phoenix"},{"value":"201399","label":"Fortis College-Ravenna"},{"value":"382957","label":"Fortis College-Richmond"},{"value":"456454","label":"Fortis College-Salt Lake City"},{"value":"372921","label":"Fortis College-Smyrna"},{"value":"132806","label":"Fortis College-Winter Park"},{"value":"442745","label":"Fortis Institute"},{"value":"455628","label":"Fortis Institute-Birmingham"},{"value":"418870","label":"Fortis Institute-Cookeville"},{"value":"216418","label":"Fortis Institute-Erie"},{"value":"443438","label":"Fortis Institute-Fort Lauderdale"},{"value":"249609","label":"Fortis Institute-Forty Fort"},{"value":"445753","label":"Fortis Institute-Miami"},{"value":"452124","label":"Fortis Institute-Nashville"},{"value":"455479","label":"Fortis Institute-Pensacola"},{"value":"445744","label":"Fortis Institute-Port Saint Lucie"},{"value":"385503","label":"Fortis Institute-Scranton"},{"value":"221795","label":"Fountainhead College of Technology"},{"value":"415774","label":"Four-D College"},{"value":"145239","label":"Fox College"},{"value":"238722","label":"Fox Valley Technical College"},{"value":"165866","label":"Framingham State University"},{"value":"218061","label":"Francis Marion University"},{"value":"114734","label":"Franciscan School of Theology"},{"value":"205957","label":"Franciscan University of Steubenville"},{"value":"104665","label":"Frank Lloyd Wright School of Architecture"},{"value":"224891","label":"Frank Phillips College"},{"value":"212577","label":"Franklin and Marshall College"},{"value":"150604","label":"Franklin College"},{"value":"182795","label":"Franklin Pierce University"},{"value":"202806","label":"Franklin University"},{"value":"441982","label":"Franklin W Olin College of Engineering"},{"value":"162557","label":"Frederick Community College"},{"value":"220215","label":"Freed-Hardeman University"},{"value":"372073","label":"Fremont College"},{"value":"114789","label":"Fresno City College"},{"value":"114813","label":"Fresno Pacific University"},{"value":"155089","label":"Friends University"},{"value":"127200","label":"Front Range Community College"},{"value":"403469","label":"Frontier Community College"},{"value":"156727","label":"Frontier Nursing University"},{"value":"162584","label":"Frostburg State University"},{"value":"134237","label":"Full Sail University"},{"value":"114840","label":"Fuller Theological Seminary in California"},{"value":"114859","label":"Fullerton College"},{"value":"191302","label":"Fulton-Montgomery Community College"},{"value":"218070","label":"Furman University"},{"value":"481030","label":"Future Generations Graduate School"},{"value":"101240","label":"Gadsden State Community College"},{"value":"452948","label":"Galen College of Nursing-Cincinnati"},{"value":"156471","label":"Galen College of Nursing-Louisville"},{"value":"406033","label":"Galen College of Nursing-San Antonio"},{"value":"406024","label":"Galen College of Nursing-Tampa Bay"},{"value":"131450","label":"Gallaudet University"},{"value":"205513","label":"Gallipolis Career College"},{"value":"224961","label":"Galveston College"},{"value":"212601","label":"Gannon University"},{"value":"155104","label":"Garden City Community College"},{"value":"198561","label":"Gardner-Webb University"},{"value":"162609","label":"Garrett College"},{"value":"145275","label":"Garrett-Evangelical Theological Seminary"},{"value":"198570","label":"Gaston College"},{"value":"157438","label":"Gateway Community and Technical College"},{"value":"130396","label":"Gateway Community College-New Haven"},{"value":"105145","label":"GateWay Community College-Phoenix"},{"value":"238759","label":"Gateway Technical College"},{"value":"114938","label":"Gavilan College"},{"value":"191339","label":"Genesee Community College"},{"value":"212656","label":"Geneva College"},{"value":"101286","label":"George C Wallace State Community College-Dothan"},{"value":"101295","label":"George C Wallace State Community College-Hanceville"},{"value":"101301","label":"George C Wallace State Community College-Selma"},{"value":"208822","label":"George Fox University"},{"value":"232186","label":"George Mason University"},{"value":"131469","label":"George Washington University"},{"value":"156745","label":"Georgetown College"},{"value":"131496","label":"Georgetown University"},{"value":"461236","label":"Georgia Christian University"},{"value":"139861","label":"Georgia College and State University"},{"value":"447689","label":"Georgia Gwinnett College"},{"value":"139700","label":"Georgia Highlands College"},{"value":"139755","label":"Georgia Institute of Technology-Main Campus"},{"value":"485111","label":"Georgia Military College-Milledgeville"},{"value":"139384","label":"Georgia Northwestern Technical College"},{"value":"244437","label":"Georgia Perimeter College"},{"value":"244446","label":"Georgia Piedmont Technical College"},{"value":"139931","label":"Georgia Southern University"},{"value":"139764","label":"Georgia Southwestern State University"},{"value":"139940","label":"Georgia State University"},{"value":"184773","label":"Georgian Court University"},{"value":"232195","label":"Germanna Community College"},{"value":"212674","label":"Gettysburg College"},{"value":"169974","label":"Glen Oaks Community College"},{"value":"104708","label":"Glendale Community College-Glendale"},{"value":"115001","label":"Glendale Community College-Glendale"},{"value":"237385","label":"Glenville State College"},{"value":"455390","label":"Global Health College"},{"value":"188465","label":"Globe Institute of Technology"},{"value":"466514","label":"Globe University-Appleton"},{"value":"456816","label":"Globe University-Eau Claire"},{"value":"458751","label":"Globe University–Green Bay"},{"value":"458991","label":"Globe University-La Crosse"},{"value":"458733","label":"Globe University-Madison East"},{"value":"458760","label":"Globe University–Madison West"},{"value":"456834","label":"Globe University-Minneapolis"},{"value":"456807","label":"Globe University-Sioux Falls"},{"value":"458779","label":"Globe University–Wausau"},{"value":"173629","label":"Globe University-Woodbury"},{"value":"230889","label":"Goddard College"},{"value":"202903","label":"Gods Bible School and College"},{"value":"169992","label":"Gogebic Community College"},{"value":"115083","label":"Golden Gate University-San Francisco"},{"value":"115126","label":"Golden West College"},{"value":"130989","label":"Goldey-Beacom College"},{"value":"430157","label":"Golf Academy of America-Altamonte Springs"},{"value":"122366","label":"Golf Academy of America-Carlsbad"},{"value":"476337","label":"Golf Academy of America-Farmers Branch"},{"value":"434690","label":"Golf Academy of America-Myrtle Beach"},{"value":"430166","label":"Golf Academy of America-Phoenix"},{"value":"235316","label":"Gonzaga University"},{"value":"202912","label":"Good Samaritan College of Nursing and Health Science"},{"value":"132523","label":"Gooding Institute of Nurse Anesthesia"},{"value":"129154","label":"Goodwin College"},{"value":"165936","label":"Gordon College"},{"value":"139968","label":"Gordon State College"},{"value":"165945","label":"Gordon-Conwell Theological Seminary"},{"value":"150668","label":"Goshen College"},{"value":"162654","label":"Goucher College"},{"value":"145336","label":"Governors State University"},{"value":"170000","label":"Grace Bible College"},{"value":"150677","label":"Grace College and Theological Seminary"},{"value":"461528","label":"Grace College of Divinity"},{"value":"481058","label":"Grace Mission University"},{"value":"481401","label":"Grace School of Theology"},{"value":"181093","label":"Grace University"},{"value":"153366","label":"Graceland University-Lamoni"},{"value":"483285","label":"Graduate School USA"},{"value":"115214","label":"Graduate Theological Union"},{"value":"159009","label":"Grambling State University"},{"value":"104717","label":"Grand Canyon University"},{"value":"170055","label":"Grand Rapids Community College"},{"value":"170082","label":"Grand Valley State University"},{"value":"153375","label":"Grand View University"},{"value":"183257","label":"Granite State College"},{"value":"442569","label":"Grantham University"},{"value":"212771","label":"Gratz College"},{"value":"235334","label":"Grays Harbor College"},{"value":"225070","label":"Grayson College"},{"value":"182306","label":"Great Basin College"},{"value":"183150","label":"Great Bay Community College"},{"value":"180249","label":"Great Falls College Montana State University"},{"value":"170091","label":"Great Lakes Christian College"},{"value":"213181","label":"Great Lakes Institute of Technology"},{"value":"230898","label":"Green Mountain College"},{"value":"235343","label":"Green River College"},{"value":"165981","label":"Greenfield Community College"},{"value":"198598","label":"Greensboro College"},{"value":"145372","label":"Greenville College"},{"value":"218113","label":"Greenville Technical College"},{"value":"153384","label":"Grinnell College"},{"value":"115296","label":"Grossmont College"},{"value":"212805","label":"Grove City College"},{"value":"240745","label":"Guam Community College"},{"value":"198613","label":"Guilford College"},{"value":"198622","label":"Guilford Technical Community College"},{"value":"134343","label":"Gulf Coast State College"},{"value":"139995","label":"Gupton Jones College of Funeral Service"},{"value":"173647","label":"Gustavus Adolphus College"},{"value":"140003","label":"Gwinnett College-Lilburn"},{"value":"140012","label":"Gwinnett Technical College"},{"value":"212832","label":"Gwynedd Mercy University"},{"value":"102313","label":"H Councill Trenholm State Community College"},{"value":"162690","label":"Hagerstown Community College"},{"value":"198640","label":"Halifax Community College"},{"value":"225201","label":"Hallmark University"},{"value":"191515","label":"Hamilton College"},{"value":"153427","label":"Hamilton Technical College"},{"value":"173665","label":"Hamline University"},{"value":"232256","label":"Hampden-Sydney College"},{"value":"166018","label":"Hampshire College"},{"value":"232265","label":"Hampton University"},{"value":"177542","label":"Hannibal-LaGrange University"},{"value":"150756","label":"Hanover College"},{"value":"212869","label":"Harcum College"},{"value":"107044","label":"Harding University"},{"value":"225247","label":"Hardin-Simmons University"},{"value":"162706","label":"Harford Community College"},{"value":"145460","label":"Harrington College of Design"},{"value":"212878","label":"Harrisburg Area Community College-Harrisburg"},{"value":"446640","label":"Harrisburg University of Science and Technology"},{"value":"458432","label":"Harrison College-Grove City"},{"value":"151166","label":"Harrison College-Indianapolis"},{"value":"468398","label":"Harrison College-Morrisville"},{"value":"177551","label":"Harris-Stowe State University"},{"value":"129491","label":"Hartford Seminary"},{"value":"115393","label":"Hartnell College"},{"value":"191533","label":"Hartwick College"},{"value":"166027","label":"Harvard University"},{"value":"115409","label":"Harvey Mudd College"},{"value":"155140","label":"Haskell Indian Nations University"},{"value":"181127","label":"Hastings College"},{"value":"212911","label":"Haverford College"},{"value":"383190","label":"Hawaii Community College"},{"value":"141644","label":"Hawaii Pacific University"},{"value":"153445","label":"Hawkeye Community College"},{"value":"198668","label":"Haywood Community College"},{"value":"156790","label":"Hazard Community and Technical College"},{"value":"173683","label":"Hazelden Betty Ford Graduate School of Addiction Studies"},{"value":"115533","label":"Heald College-Concord"},{"value":"115472","label":"Heald College-Fresno"},{"value":"371779","label":"Heald College-Hayward"},{"value":"141468","label":"Heald College-Honolulu"},{"value":"459930","label":"Heald College-Modesto"},{"value":"430148","label":"Heald College-Portland"},{"value":"115454","label":"Heald College-Rancho Cordova"},{"value":"363387","label":"Heald College-Roseville"},{"value":"409874","label":"Heald College-Salinas"},{"value":"115515","label":"Heald College-San Francisco"},{"value":"115490","label":"Heald College-San Jose"},{"value":"371760","label":"Heald College-Stockton"},{"value":"384342","label":"Heartland Community College"},{"value":"166045","label":"Hebrew College"},{"value":"145497","label":"Hebrew Theological College"},{"value":"203067","label":"Hebrew Union College-Jewish Institute of Religion"},{"value":"203085","label":"Heidelberg University"},{"value":"180276","label":"Helena College University of Montana"},{"value":"191597","label":"Helene Fuld College of Nursing"},{"value":"166054","label":"Hellenic College-Holy Cross Greek Orthodox School of Theology"},{"value":"156851","label":"Henderson Community College"},{"value":"107071","label":"Henderson State University"},{"value":"107080","label":"Hendrix College"},{"value":"173708","label":"Hennepin Technical College"},{"value":"170240","label":"Henry Ford College"},{"value":"198677","label":"Heritage Bible College"},{"value":"101453","label":"Heritage Christian University"},{"value":"262509","label":"Heritage College-Denver"},{"value":"445814","label":"Heritage College-Kansas City"},{"value":"410070","label":"Heritage College-Oklahoma City"},{"value":"456320","label":"Heritage College-Wichita"},{"value":"135124","label":"Heritage Institute-Ft Myers"},{"value":"372772","label":"Heritage Institute-Jacksonville"},{"value":"235422","label":"Heritage University"},{"value":"191612","label":"Herkimer County Community College"},{"value":"140340","label":"Herzing University-Atlanta"},{"value":"101365","label":"Herzing University-Birmingham"},{"value":"459851","label":"Herzing University-Brookfield"},{"value":"433536","label":"Herzing University-Kenner"},{"value":"459842","label":"Herzing University-Kenosha"},{"value":"240392","label":"Herzing University-Madison"},{"value":"174154","label":"Herzing University-Minneapolis"},{"value":"457022","label":"Herzing University-Toledo"},{"value":"386472","label":"Herzing University-Winter Park"},{"value":"155177","label":"Hesston College"},{"value":"173735","label":"Hibbing Community College"},{"value":"177579","label":"Hickey College"},{"value":"198695","label":"High Point University"},{"value":"145521","label":"Highland Community College-Freeport"},{"value":"155186","label":"Highland Community College-Highland"},{"value":"180081","label":"Highlands College of Montana Tech"},{"value":"235431","label":"Highline College"},{"value":"191621","label":"Hilbert College"},{"value":"225371","label":"Hill College"},{"value":"134495","label":"Hillsborough Community College"},{"value":"170286","label":"Hillsdale College"},{"value":"207157","label":"Hillsdale Free Will Baptist College"},{"value":"175786","label":"Hinds Community College"},{"value":"203128","label":"Hiram College"},{"value":"220312","label":"Hiwassee College"},{"value":"191630","label":"Hobart William Smith Colleges"},{"value":"134510","label":"Hobe Sound Bible College"},{"value":"203155","label":"Hocking College"},{"value":"367884","label":"Hodges University"},{"value":"191649","label":"Hofstra University"},{"value":"232308","label":"Hollins University"},{"value":"175810","label":"Holmes Community College"},{"value":"129534","label":"Holy Apostles College and Seminary"},{"value":"150774","label":"Holy Cross College"},{"value":"212984","label":"Holy Family University"},{"value":"115728","label":"Holy Names University"},{"value":"166133","label":"Holyoke Community College"},{"value":"203386","label":"Hondros College"},{"value":"141680","label":"Honolulu Community College"},{"value":"162760","label":"Hood College"},{"value":"443076","label":"Hood Theological Seminary"},{"value":"170301","label":"Hope College"},{"value":"120537","label":"Hope International University"},{"value":"156860","label":"Hopkinsville Community College"},{"value":"457226","label":"Horizon University"},{"value":"218140","label":"Horry-Georgetown Technical College"},{"value":"191676","label":"Houghton College"},{"value":"129543","label":"Housatonic Community College"},{"value":"225399","label":"Houston Baptist University"},{"value":"225423","label":"Houston Community College"},{"value":"246345","label":"Houston Graduate School of Theology"},{"value":"225520","label":"Howard College"},{"value":"162779","label":"Howard Community College"},{"value":"225548","label":"Howard Payne University"},{"value":"131520","label":"Howard University"},{"value":"184995","label":"Hudson County Community College"},{"value":"191719","label":"Hudson Valley Community College"},{"value":"242112","label":"Huertas College"},{"value":"164368","label":"Hult International Business School"},{"value":"242121","label":"Humacao Community College"},{"value":"115755","label":"Humboldt State University"},{"value":"115773","label":"Humphreys College-Stockton and Modesto Campuses"},{"value":"101435","label":"Huntingdon College"},{"value":"237437","label":"Huntington Junior College"},{"value":"150941","label":"Huntington University"},{"value":"449348","label":"Huntsville Bible College"},{"value":"212993","label":"Hussian College School of Art"},{"value":"161165","label":"Husson University"},{"value":"225575","label":"Huston-Tillotson University"},{"value":"155195","label":"Hutchinson Community College"},{"value":"127839","label":"IBMC College"},{"value":"372329","label":"IBMC College"},{"value":"193405","label":"Icahn School of Medicine at Mount Sinai"},{"value":"437662","label":"ICDC College"},{"value":"242130","label":"ICPR Junior College-Arecibo"},{"value":"243841","label":"ICPR Junior College-General Institutional"},{"value":"460677","label":"ICPR Junior College-Manati"},{"value":"242149","label":"ICPR Junior College-Mayaguez"},{"value":"142276","label":"Idaho State University"},{"value":"483780","label":"IGlobal University"},{"value":"127273","label":"Iliff School of Theology"},{"value":"434584","label":"Ilisagvik College"},{"value":"145682","label":"Illinois Central College"},{"value":"145691","label":"Illinois College"},{"value":"145628","label":"Illinois College of Optometry"},{"value":"145725","label":"Illinois Institute of Technology"},{"value":"145813","label":"Illinois State University"},{"value":"145831","label":"Illinois Valley Community College"},{"value":"145646","label":"Illinois Wesleyan University"},{"value":"213011","label":"Immaculata University"},{"value":"115861","label":"Imperial Valley College"},{"value":"155201","label":"Independence Community College"},{"value":"465812","label":"Independence University"},{"value":"153472","label":"Indian Hills Community College"},{"value":"134608","label":"Indian River State College"},{"value":"151290","label":"Indiana Institute of Technology"},{"value":"151324","label":"Indiana State University"},{"value":"213020","label":"Indiana University of Pennsylvania-Main Campus"},{"value":"151351","label":"Indiana University-Bloomington"},{"value":"151388","label":"Indiana University-East"},{"value":"151333","label":"Indiana University-Kokomo"},{"value":"151360","label":"Indiana University-Northwest"},{"value":"151102","label":"Indiana University-Purdue University-Fort Wayne"},{"value":"151111","label":"Indiana University-Purdue University-Indianapolis"},{"value":"151342","label":"Indiana University-South Bend"},{"value":"151379","label":"Indiana University-Southeast"},{"value":"151801","label":"Indiana Wesleyan University"},{"value":"145886","label":"Institute for Clinical Social Work"},{"value":"462044","label":"Institute for Doctoral Studies in the Visual Arts"},{"value":"445869","label":"Institute for the Psychological Sciences"},{"value":"187745","label":"Institute of American Indian and Alaska Native Culture"},{"value":"444699","label":"Institute of Clinical Acupuncture & Oriental Med"},{"value":"191764","label":"Institute of Design and Construction"},{"value":"454616","label":"Institute of Production and Recording"},{"value":"454838","label":"Institute of Taoist Education and Acupuncture"},{"value":"431141","label":"Institute of Technology Inc-Clovis"},{"value":"455804","label":"Institute of World Politics"},{"value":"242422","label":"Instituto de Banca y Comercio Inc"},{"value":"242556","label":"Instituto Tecnologico de Puerto Rico-Recinto de Guayama"},{"value":"242042","label":"Instituto Tecnologico de Puerto Rico-Recinto de Manati"},{"value":"242565","label":"Instituto Tecnologico de Puerto Rico-Recinto de Ponce"},{"value":"242583","label":"Instituto Tecnologico de Puerto Rico-Recinto de San Juan"},{"value":"128179","label":"Intellitec College-Colorado Springs"},{"value":"128188","label":"Intellitec College-Grand Junction"},{"value":"242626","label":"Inter American University of Puerto Rico-Aguadilla"},{"value":"242635","label":"Inter American University of Puerto Rico-Arecibo"},{"value":"242644","label":"Inter American University of Puerto Rico-Barranquitas"},{"value":"242705","label":"Inter American University of Puerto Rico-Bayamon"},{"value":"242680","label":"Inter American University of Puerto Rico-Fajardo"},{"value":"242699","label":"Inter American University of Puerto Rico-Guayama"},{"value":"242653","label":"Inter American University of Puerto Rico-Metro"},{"value":"242662","label":"Inter American University of Puerto Rico-Ponce"},{"value":"242617","label":"Inter American University of Puerto Rico-San German"},{"value":"242723","label":"Inter American University of Puerto Rico-School of Law"},{"value":"404222","label":"Inter American University of Puerto Rico-School of Optometry"},{"value":"138655","label":"Interactive College of Technology-Chamblee"},{"value":"442435","label":"Interactive College of Technology-Gainesville"},{"value":"367361","label":"Interactive College of Technology-Houston"},{"value":"443696","label":"Interactive College of Technology-Houston"},{"value":"138664","label":"Interactive College of Technology-Morrow"},{"value":"367103","label":"Interactive College of Technology-Newport"},{"value":"440776","label":"Interactive College of Technology-Pasadena"},{"value":"366289","label":"InterCoast Colleges-Orange"},{"value":"140146","label":"Interdenominational Theological Center"},{"value":"235495","label":"Interface College-Spokane"},{"value":"116226","label":"Interior Designers Institute"},{"value":"446817","label":"International Academy of Design and Technology-Nashville"},{"value":"450447","label":"International Academy of Design and Technology-Sacramento"},{"value":"445124","label":"International Academy of Design and Technology-Troy"},{"value":"436614","label":"International Baptist College and Seminary"},{"value":"225779","label":"International Business College-El Paso-El Paso"},{"value":"225788","label":"International Business College-El Paso-El Paso"},{"value":"151458","label":"International Business College-Fort Wayne"},{"value":"151467","label":"International Business College-Indianapolis"},{"value":"203289","label":"International College of Broadcasting"},{"value":"448691","label":"International Institute for Restorative Practices"},{"value":"454740","label":"International Professional School of Bodywork"},{"value":"443128","label":"International Technological University"},{"value":"173799","label":"Inver Hills Community College"},{"value":"191931","label":"Iona College"},{"value":"153524","label":"Iowa Central Community College"},{"value":"153533","label":"Iowa Lakes Community College"},{"value":"153603","label":"Iowa State University"},{"value":"153621","label":"Iowa Wesleyan University"},{"value":"153630","label":"Iowa Western Community College"},{"value":"441238","label":"Irell & Manella Graduate School of Biological Sciences at City of Hope"},{"value":"116439","label":"Irvine Valley College"},{"value":"191959","label":"Island Drafting and Technical Institute"},{"value":"198710","label":"Isothermal Community College"},{"value":"173805","label":"Itasca Community College"},{"value":"175829","label":"Itawamba Community College"},{"value":"191968","label":"Ithaca College"},{"value":"159197","label":"ITI Technical College"},{"value":"459611","label":"ITT Technical Institute-Akron"},{"value":"434566","label":"ITT Technical Institute-Albany"},{"value":"369084","label":"ITT Technical Institute-Albuquerque"},{"value":"225849","label":"ITT Technical Institute-Arlington"},{"value":"260974","label":"ITT Technical Institute-Arlington Heights"},{"value":"434548","label":"ITT Technical Institute-Arnold"},{"value":"450243","label":"ITT Technical Institute-Atlanta"},{"value":"459675","label":"ITT Technical Institute-Aurora"},{"value":"366678","label":"ITT Technical Institute-Austin"},{"value":"450216","label":"ITT Technical Institute-Baton Rouge"},{"value":"414568","label":"ITT Technical Institute-Bessemer"},{"value":"142337","label":"ITT Technical Institute-Boise"},{"value":"470852","label":"ITT Technical Institute-Bradenton"},{"value":"470870","label":"ITT Technical Institute-Brooklyn Center"},{"value":"442338","label":"ITT Technical Institute-Canton"},{"value":"451936","label":"ITT Technical Institute-Cary"},{"value":"441964","label":"ITT Technical Institute-Chantilly"},{"value":"456445","label":"ITT Technical Institute-Charlotte North"},{"value":"448442","label":"ITT Technical Institute-Charlotte South"},{"value":"450261","label":"ITT Technical Institute-Chattanooga"},{"value":"451954","label":"ITT Technical Institute-Clive"},{"value":"448451","label":"ITT Technical Institute-Clovis"},{"value":"450225","label":"ITT Technical Institute-Columbia"},{"value":"451963","label":"ITT Technical Institute-Columbus"},{"value":"456427","label":"ITT Technical Institute-Concord"},{"value":"413884","label":"ITT Technical Institute-Cordova"},{"value":"459639","label":"ITT Technical Institute-Corona"},{"value":"459693","label":"ITT Technical Institute-Culver City"},{"value":"203313","label":"ITT Technical Institute-Dayton"},{"value":"459709","label":"ITT Technical Institute-Dearborn"},{"value":"479619","label":"ITT Technical Institute-Deerfield Beach"},{"value":"459657","label":"ITT Technical Institute-DeSoto"},{"value":"479637","label":"ITT Technical Institute-Douglasville"},{"value":"443526","label":"ITT Technical Institute-Duluth"},{"value":"448460","label":"ITT Technical Institute-Dunmore"},{"value":"462363","label":"ITT Technical Institute-Durham"},{"value":"176637","label":"ITT Technical Institute-Earth City"},{"value":"445081","label":"ITT Technical Institute-Eden Prairie"},{"value":"414531","label":"ITT Technical Institute-Everett"},{"value":"409069","label":"ITT Technical Institute-Fort Lauderdale"},{"value":"456436","label":"ITT Technical Institute-Fort Myers"},{"value":"151500","label":"ITT Technical Institute-Fort Wayne"},{"value":"479567","label":"ITT Technical Institute-Germantown"},{"value":"420404","label":"ITT Technical Institute-Getzville"},{"value":"440165","label":"ITT Technical Institute-Green Bay"},{"value":"238892","label":"ITT Technical Institute-Greenfield"},{"value":"413866","label":"ITT Technical Institute-Greenville"},{"value":"462372","label":"ITT Technical Institute-Hanover"},{"value":"430351","label":"ITT Technical Institute-Harrisburg"},{"value":"429599","label":"ITT Technical Institute-Henderson"},{"value":"430263","label":"ITT Technical Institute-Hialeah"},{"value":"451990","label":"ITT Technical Institute-High Point"},{"value":"443535","label":"ITT Technical Institute-Hilliard"},{"value":"366696","label":"ITT Technical Institute-Houston North"},{"value":"225858","label":"ITT Technical Institute-Houston West"},{"value":"456418","label":"ITT Technical Institute-Huntington"},{"value":"151519","label":"ITT Technical Institute-Indianapolis"},{"value":"479628","label":"ITT Technical Institute-Indianapolis East"},{"value":"407063","label":"ITT Technical Institute-Jacksonville"},{"value":"459648","label":"ITT Technical Institute-Johnson City"},{"value":"446899","label":"ITT Technical Institute-Kansas City"},{"value":"446905","label":"ITT Technical Institute-Kennesaw"},{"value":"366650","label":"ITT Technical Institute-Knoxville"},{"value":"372578","label":"ITT Technical Institute-Lake Mary"},{"value":"459718","label":"ITT Technical Institute-Las Vegas"},{"value":"437219","label":"ITT Technical Institute-Lathrop"},{"value":"440642","label":"ITT Technical Institute-Levittown"},{"value":"448488","label":"ITT Technical Institute-Lexington"},{"value":"413839","label":"ITT Technical Institute-Little Rock"},{"value":"434575","label":"ITT Technical Institute-Liverpool"},{"value":"413857","label":"ITT Technical Institute-Louisville"},{"value":"451945","label":"ITT Technical Institute-Madison-Madison"},{"value":"451981","label":"ITT Technical Institute-Madison-Madison"},{"value":"456393","label":"ITT Technical Institute-Madison-Madison"},{"value":"479558","label":"ITT Technical Institute-Marlton"},{"value":"448497","label":"ITT Technical Institute-Maumee"},{"value":"459587","label":"ITT Technical Institute-Merrillville"},{"value":"450252","label":"ITT Technical Institute-Mobile"},{"value":"230384","label":"ITT Technical Institute-Murray"},{"value":"470904","label":"ITT Technical Institute-Myrtle Beach"},{"value":"151494","label":"ITT Technical Institute-Nashville"},{"value":"116466","label":"ITT Technical Institute-National City"},{"value":"251251","label":"ITT Technical Institute-Newburgh"},{"value":"368601","label":"ITT Technical Institute-Norfolk"},{"value":"459666","label":"ITT Technical Institute-North Charleston"},{"value":"366580","label":"ITT Technical Institute-Norwood-Norwood"},{"value":"430379","label":"ITT Technical Institute-Norwood-Norwood"},{"value":"434557","label":"ITT Technical Institute-Oak Brook"},{"value":"467058","label":"ITT Technical Institute-Oakland"},{"value":"448503","label":"ITT Technical Institute-Oklahoma City"},{"value":"407319","label":"ITT Technical Institute-Omaha"},{"value":"116484","label":"ITT Technical Institute-Orange"},{"value":"414586","label":"ITT Technical Institute-Orland Park"},{"value":"470889","label":"ITT Technical Institute-Orlando"},{"value":"479646","label":"ITT Technical Institute-Overland Park"},{"value":"446914","label":"ITT Technical Institute-Owings Mills"},{"value":"413848","label":"ITT Technical Institute-Oxnard"},{"value":"479549","label":"ITT Technical Institute-Philadelphia"},{"value":"451972","label":"ITT Technical Institute-Phoenix"},{"value":"470861","label":"ITT Technical Institute-Phoenix West"},{"value":"414841","label":"ITT Technical Institute-Pittsburgh"},{"value":"442347","label":"ITT Technical Institute-Plymouth Meeting"},{"value":"208965","label":"ITT Technical Institute-Portland"},{"value":"108250","label":"ITT Technical Institute-Rancho Cordova"},{"value":"434052","label":"ITT Technical Institute-Richardson"},{"value":"437051","label":"ITT Technical Institute-Richmond"},{"value":"437042","label":"ITT Technical Institute-Saint Rose"},{"value":"459602","label":"ITT Technical Institute-Salem-Salem"},{"value":"479600","label":"ITT Technical Institute-Salem-Salem"},{"value":"377069","label":"ITT Technical Institute-San Antonio"},{"value":"481623","label":"ITT Technical Institute-San Antonio East"},{"value":"381909","label":"ITT Technical Institute-San Bernardino"},{"value":"116475","label":"ITT Technical Institute-San Dimas"},{"value":"235510","label":"ITT Technical Institute-Seattle"},{"value":"450270","label":"ITT Technical Institute-South Bend"},{"value":"479585","label":"ITT Technical Institute-Southfield"},{"value":"235529","label":"ITT Technical Institute-Spokane Valley"},{"value":"441955","label":"ITT Technical Institute-Springfield-Springfield"},{"value":"456409","label":"ITT Technical Institute-Springfield-Springfield"},{"value":"479655","label":"ITT Technical Institute-Springfield-Springfield"},{"value":"450207","label":"ITT Technical Institute-St Petersburg"},{"value":"430388","label":"ITT Technical Institute-Strongsville"},{"value":"448479","label":"ITT Technical Institute-Swartz Creek"},{"value":"244011","label":"ITT Technical Institute-Sylmar"},{"value":"459596","label":"ITT Technical Institute-Tallahassee"},{"value":"134909","label":"ITT Technical Institute-Tampa"},{"value":"430360","label":"ITT Technical Institute-Tarentum"},{"value":"105172","label":"ITT Technical Institute-Tempe"},{"value":"378406","label":"ITT Technical Institute-Torrance"},{"value":"261472","label":"ITT Technical Institute-Troy"},{"value":"105163","label":"ITT Technical Institute-Tucson"},{"value":"448512","label":"ITT Technical Institute-Tulsa"},{"value":"470898","label":"ITT Technical Institute-Waco"},{"value":"446923","label":"ITT Technical Institute-Warrensville Heights"},{"value":"427663","label":"ITT Technical Institute-Webster"},{"value":"479664","label":"ITT Technical Institute-West Chester"},{"value":"459684","label":"ITT Technical Institute-West Covina"},{"value":"479594","label":"ITT Technical Institute-West Palm Beach"},{"value":"244154","label":"ITT Technical Institute-Westminster"},{"value":"450234","label":"ITT Technical Institute-Wichita"},{"value":"439136","label":"ITT Technical Institute-Wilmington"},{"value":"170417","label":"ITT Technical Institute-Wyoming"},{"value":"206631","label":"ITT Technical Institute-Youngstown"},{"value":"150987","label":"Ivy Tech Community College"},{"value":"101462","label":"J F Drake State Community and Technical College"},{"value":"101471","label":"J F Ingram State Technical College"},{"value":"232414","label":"J Sargeant Reynolds Community College"},{"value":"170444","label":"Jackson College"},{"value":"220400","label":"Jackson State Community College"},{"value":"175856","label":"Jackson State University"},{"value":"225876","label":"Jacksonville College-Main Campus"},{"value":"101480","label":"Jacksonville State University"},{"value":"134945","label":"Jacksonville University"},{"value":"203678","label":"James A Rhodes State College"},{"value":"101161","label":"James H Faulkner State Community College"},{"value":"232423","label":"James Madison University"},{"value":"198729","label":"James Sprunt Community College"},{"value":"192004","label":"Jamestown Business College"},{"value":"191986","label":"Jamestown Community College"},{"value":"225885","label":"Jarvis Christian College"},{"value":"177676","label":"Jefferson College"},{"value":"231837","label":"Jefferson College of Health Sciences"},{"value":"156921","label":"Jefferson Community and Technical College"},{"value":"192022","label":"Jefferson Community College"},{"value":"101499","label":"Jefferson Davis Community College"},{"value":"101505","label":"Jefferson State Community College"},{"value":"455196","label":"Jersey College"},{"value":"192040","label":"Jewish Theological Seminary of America"},{"value":"419341","label":"Jna Institute of Culinary Arts"},{"value":"220464","label":"John A Gupton College"},{"value":"146205","label":"John A Logan College"},{"value":"107141","label":"John Brown University"},{"value":"101514","label":"John C Calhoun State Community College"},{"value":"203368","label":"John Carroll University"},{"value":"116712","label":"John F. Kennedy University"},{"value":"462354","label":"John Paul the Great Catholic University"},{"value":"232450","label":"John Tyler Community College"},{"value":"146278","label":"John Wood Community College"},{"value":"162928","label":"Johns Hopkins University"},{"value":"445708","label":"Johnson & Wales University-Charlotte"},{"value":"439288","label":"Johnson & Wales University-Denver"},{"value":"414823","label":"Johnson & Wales University-North Miami"},{"value":"460349","label":"Johnson & Wales University-Online"},{"value":"217235","label":"Johnson & Wales University-Providence"},{"value":"198756","label":"Johnson C Smith University"},{"value":"213233","label":"Johnson College"},{"value":"155210","label":"Johnson County Community College"},{"value":"230913","label":"Johnson State College"},{"value":"220473","label":"Johnson University"},{"value":"132879","label":"Johnson University Florida"},{"value":"198774","label":"Johnston Community College"},{"value":"146296","label":"Joliet Junior College"},{"value":"135063","label":"Jones College-Jacksonville"},{"value":"175883","label":"Jones County Junior College"},{"value":"444723","label":"Jones International University"},{"value":"461281","label":"Jose Maria Vargas University"},{"value":"101541","label":"Judson College"},{"value":"146339","label":"Judson University"},{"value":"461139","label":"Jung Tao School of Classical Chinese Medicine"},{"value":"213251","label":"Juniata College"},{"value":"170532","label":"Kalamazoo College"},{"value":"170541","label":"Kalamazoo Valley Community College"},{"value":"146348","label":"Kankakee Community College"},{"value":"177746","label":"Kansas City Art Institute"},{"value":"155308","label":"Kansas City College & Bible School"},{"value":"155292","label":"Kansas City Kansas Community College"},{"value":"179812","label":"Kansas City University of Medicine and Biosciences"},{"value":"155399","label":"Kansas State University"},{"value":"155414","label":"Kansas Wesleyan University"},{"value":"141796","label":"Kapiolani Community College"},{"value":"458715","label":"Kaplan College-Jacksonville"},{"value":"445346","label":"Kaplan College-Lubbock"},{"value":"480064","label":"Kaplan University-Augusta Campus"},{"value":"260910","label":"Kaplan University-Cedar Falls Campus"},{"value":"153418","label":"Kaplan University-Cedar Rapids Campus"},{"value":"260901","label":"Kaplan University-Davenport Campus"},{"value":"367024","label":"Kaplan University-Des Moines Campus"},{"value":"162681","label":"Kaplan University-Hagerstown Campus"},{"value":"181242","label":"Kaplan University-Lincoln Campus"},{"value":"160940","label":"Kaplan University-Maine Campus"},{"value":"153409","label":"Kaplan University-Mason City Campus"},{"value":"181400","label":"Kaplan University-Omaha Campus"},{"value":"146366","label":"Kaskaskia College"},{"value":"141802","label":"Kauai Community College"},{"value":"225991","label":"KD College Conservatory of Film and Dramatic Arts"},{"value":"185262","label":"Kean University"},{"value":"440031","label":"Keck Graduate Institute"},{"value":"183062","label":"Keene State College"},{"value":"192165","label":"Kehilath Yakov Rabbinical Seminary"},{"value":"135081","label":"Keiser University-Ft Lauderdale"},{"value":"170550","label":"Kellogg Community College"},{"value":"146393","label":"Kendall College"},{"value":"161192","label":"Kennebec Valley Community College"},{"value":"140164","label":"Kennesaw State University"},{"value":"177816","label":"Kenrick Glennon Seminary"},{"value":"203447","label":"Kent State University at Ashtabula"},{"value":"203456","label":"Kent State University at East Liverpool"},{"value":"203526","label":"Kent State University at Geauga"},{"value":"203517","label":"Kent State University at Kent"},{"value":"203492","label":"Kent State University at Salem"},{"value":"203465","label":"Kent State University at Stark"},{"value":"203474","label":"Kent State University at Trumbull"},{"value":"203483","label":"Kent State University at Tuscarawas"},{"value":"157100","label":"Kentucky Christian University"},{"value":"157030","label":"Kentucky Mountain Bible College"},{"value":"157058","label":"Kentucky State University"},{"value":"157076","label":"Kentucky Wesleyan College"},{"value":"203535","label":"Kenyon College"},{"value":"203544","label":"Kettering College"},{"value":"169983","label":"Kettering University"},{"value":"192192","label":"Keuka College"},{"value":"461315","label":"Keweenaw Bay Ojibwa Community College"},{"value":"134422","label":"Key College"},{"value":"213303","label":"Keystone College"},{"value":"210483","label":"Keystone Technical Institute"},{"value":"226019","label":"Kilgore College"},{"value":"219055","label":"Kilian Community College"},{"value":"220516","label":"King University"},{"value":"382504","label":"King's College-Charlotte"},{"value":"213321","label":"King's College-Wilkes-Barre"},{"value":"153737","label":"Kirkwood Community College"},{"value":"170587","label":"Kirtland Community College"},{"value":"146418","label":"Kishwaukee College"},{"value":"428392","label":"Klamath Community College"},{"value":"260956","label":"Knowledge Systems Institute"},{"value":"146427","label":"Knox College"},{"value":"484288","label":"Knox Theological Seminary"},{"value":"213349","label":"Kutztown University of Pennsylvania"},{"value":"171881","label":"Kuyper College"},{"value":"213358","label":"La Roche College"},{"value":"213367","label":"La Salle University"},{"value":"117627","label":"La Sierra University"},{"value":"155450","label":"Labette Community College"},{"value":"165264","label":"Laboure College"},{"value":"260372","label":"Lac Courte Oreilles Ojibwa Community College"},{"value":"213376","label":"Lackawanna College"},{"value":"213385","label":"Lafayette College"},{"value":"140234","label":"LaGrange College"},{"value":"117168","label":"Laguna College of Art and Design"},{"value":"219143","label":"Lake Area Technical Institute"},{"value":"203580","label":"Lake Erie College"},{"value":"407629","label":"Lake Erie College of Osteopathic Medicine"},{"value":"146481","label":"Lake Forest College"},{"value":"146490","label":"Lake Forest Graduate School of Management"},{"value":"146506","label":"Lake Land College"},{"value":"170620","label":"Lake Michigan College"},{"value":"200192","label":"Lake Region State College"},{"value":"173461","label":"Lake Superior College"},{"value":"170639","label":"Lake Superior State University"},{"value":"117195","label":"Lake Tahoe Community College"},{"value":"235699","label":"Lake Washington Institute of Technology"},{"value":"238980","label":"Lakeland College"},{"value":"203599","label":"Lakeland Community College"},{"value":"183123","label":"Lakes Region Community College"},{"value":"239008","label":"Lakeshore Technical College"},{"value":"135188","label":"Lake-Sumter State College"},{"value":"146533","label":"Lakeview College of Nursing"},{"value":"127389","label":"Lamar Community College"},{"value":"441760","label":"Lamar Institute of Technology"},{"value":"226107","label":"Lamar State College-Orange"},{"value":"226116","label":"Lamar State College-Port Arthur"},{"value":"226091","label":"Lamar University"},{"value":"213400","label":"Lancaster Bible College"},{"value":"418533","label":"Lancaster County Career and Technology Center"},{"value":"213446","label":"Lancaster Theological Seminary"},{"value":"218229","label":"Lander University"},{"value":"247649","label":"Landmark College"},{"value":"220598","label":"Lane College"},{"value":"209038","label":"Lane Community College"},{"value":"117247","label":"Laney College"},{"value":"207209","label":"Langston University"},{"value":"140243","label":"Lanier Technical College"},{"value":"213473","label":"Lansdale School of Business"},{"value":"170657","label":"Lansing Community College"},{"value":"240620","label":"Laramie County Community College"},{"value":"226134","label":"Laredo Community College"},{"value":"366401","label":"Las Positas College"},{"value":"166391","label":"Lasell College"},{"value":"117274","label":"Lassen Community College"},{"value":"230418","label":"Latter-day Saints Business College"},{"value":"250027","label":"Laurel Business Institute"},{"value":"408729","label":"Laurel Technical Institute-MEADVILLE"},{"value":"215992","label":"Laurel Technical Institute-Sharon"},{"value":"198747","label":"Laurel University"},{"value":"166407","label":"Lawrence Memorial Hospital School of Nursing"},{"value":"170675","label":"Lawrence Technological University"},{"value":"239017","label":"Lawrence University"},{"value":"101569","label":"Lawson State Community College-Birmingham Campus"},{"value":"443623","label":"Le Cordon Bleu College of Culinary Arts-Atlanta"},{"value":"364973","label":"Le Cordon Bleu College of Culinary Arts-Austin"},{"value":"452054","label":"Le Cordon Bleu College of Culinary Arts-Cambridge"},{"value":"144467","label":"Le Cordon Bleu College of Culinary Arts-Chicago"},{"value":"452063","label":"Le Cordon Bleu College of Culinary Arts-Dallas"},{"value":"445115","label":"Le Cordon Bleu College of Culinary Arts-Las Vegas"},{"value":"446835","label":"Le Cordon Bleu College of Culinary Arts-Miami"},{"value":"446844","label":"Le Cordon Bleu College of Culinary Arts-Minneapolis"},{"value":"442231","label":"Le Cordon Bleu College of Culinary Arts-Orlando"},{"value":"423980","label":"Le Cordon Bleu College of Culinary Arts-Pasadena"},{"value":"375841","label":"Le Cordon Bleu College of Culinary Arts-Portland"},{"value":"111009","label":"Le Cordon Bleu College of Culinary Arts-San Francisco"},{"value":"262332","label":"Le Cordon Bleu College of Culinary Arts-Scottsdale"},{"value":"192323","label":"Le Moyne College"},{"value":"220604","label":"Le Moyne-Owen College"},{"value":"213507","label":"Lebanon Valley College"},{"value":"456940","label":"L'Ecole Culinaire-Memphis"},{"value":"445726","label":"L'Ecole Culinaire-St Louis"},{"value":"226204","label":"Lee College"},{"value":"220613","label":"Lee University"},{"value":"413626","label":"Leech Lake Tribal College"},{"value":"198808","label":"Lees-McRae College"},{"value":"141811","label":"Leeward Community College"},{"value":"213525","label":"Lehigh Carbon Community College"},{"value":"213543","label":"Lehigh University"},{"value":"198817","label":"Lenoir Community College"},{"value":"198835","label":"Lenoir-Rhyne University"},{"value":"218265","label":"Lenoir-Rhyne University-Lutheran Theological Southern Seminary"},{"value":"166452","label":"Lesley University"},{"value":"226231","label":"LeTourneau University"},{"value":"209056","label":"Lewis & Clark College"},{"value":"146603","label":"Lewis and Clark Community College"},{"value":"146612","label":"Lewis University"},{"value":"142328","label":"Lewis-Clark State College"},{"value":"157207","label":"Lexington Theological Seminary"},{"value":"232557","label":"Liberty University"},{"value":"117520","label":"Life Chiropractic College West"},{"value":"117104","label":"Life Pacific College"},{"value":"140252","label":"Life University"},{"value":"192271","label":"LIM College"},{"value":"218238","label":"Limestone College"},{"value":"146667","label":"Lincoln Christian University"},{"value":"146676","label":"Lincoln College"},{"value":"128683","label":"Lincoln College of New England-Southington"},{"value":"163028","label":"Lincoln College of Technology-Columbia"},{"value":"126951","label":"Lincoln College of Technology-Denver"},{"value":"151661","label":"Lincoln College of Technology-Indianapolis"},{"value":"434159","label":"Lincoln College of Technology-Marietta"},{"value":"146700","label":"Lincoln College of Technology-Melrose Park"},{"value":"221148","label":"Lincoln College of Technology-Nashville"},{"value":"136066","label":"Lincoln College of Technology-West Palm Beach"},{"value":"146685","label":"Lincoln Land Community College"},{"value":"220631","label":"Lincoln Memorial University"},{"value":"213570","label":"Lincoln Technical Institute-Allentown"},{"value":"442037","label":"Lincoln Technical Institute-Northeast Philadelphia"},{"value":"213589","label":"Lincoln Technical Institute-Philadelphia"},{"value":"403478","label":"Lincoln Trail College"},{"value":"177940","label":"Lincoln University-Jefferson City"},{"value":"117557","label":"Lincoln University-Oakland"},{"value":"177968","label":"Lindenwood University"},{"value":"157216","label":"Lindsey Wilson College"},{"value":"437325","label":"Linfield College-Adult Degree Program"},{"value":"209065","label":"Linfield College-McMinnville Campus"},{"value":"437316","label":"Linfield College-School of Nursing"},{"value":"209074","label":"Linn-Benton Community College"},{"value":"219976","label":"Lipscomb University"},{"value":"180328","label":"Little Big Horn College"},{"value":"434016","label":"Little Priest Tribal College"},{"value":"192563","label":"LIU Brentwood"},{"value":"192439","label":"LIU Brooklyn"},{"value":"192554","label":"LIU Hudson at Rockland"},{"value":"432357","label":"LIU Hudson at Westchester"},{"value":"192448","label":"LIU Post"},{"value":"450766","label":"LIU Riverhead"},{"value":"421832","label":"Living Arts College"},{"value":"198862","label":"Livingstone College"},{"value":"213613","label":"Lock Haven University"},{"value":"177986","label":"Logan University"},{"value":"117636","label":"Loma Linda University"},{"value":"227182","label":"Lone Star College System"},{"value":"117645","label":"Long Beach City College"},{"value":"192509","label":"Long Island Business Institute"},{"value":"232566","label":"Longwood University"},{"value":"166489","label":"Longy School of Music of Bard College"},{"value":"203748","label":"Lorain County Community College"},{"value":"153825","label":"Loras College"},{"value":"232575","label":"Lord Fairfax Community College"},{"value":"117788","label":"Los Angeles City College"},{"value":"446385","label":"Los Angeles College of Music"},{"value":"117803","label":"Los Angeles County College of Nursing and Allied Health"},{"value":"436429","label":"Los Angeles Film School"},{"value":"117690","label":"Los Angeles Harbor College"},{"value":"117867","label":"Los Angeles Mission College"},{"value":"368780","label":"Los Angeles ORT College-Los Angeles Campus"},{"value":"381945","label":"Los Angeles ORT College-Van Nuys Campus"},{"value":"117706","label":"Los Angeles Pierce College"},{"value":"117715","label":"Los Angeles Southwest College"},{"value":"117724","label":"Los Angeles Trade Technical College"},{"value":"117733","label":"Los Angeles Valley College"},{"value":"117894","label":"Los Medanos College"},{"value":"198871","label":"Louisburg College"},{"value":"159568","label":"Louisiana College"},{"value":"449612","label":"Louisiana Culinary Institute"},{"value":"483212","label":"Louisiana Delta Community College"},{"value":"159391","label":"Louisiana State University and Agricultural & Mechanical College"},{"value":"159373","label":"Louisiana State University Health Sciences Center-New Orleans"},{"value":"435000","label":"Louisiana State University Health Sciences Center-Shreveport"},{"value":"159382","label":"Louisiana State University-Alexandria"},{"value":"159407","label":"Louisiana State University-Eunice"},{"value":"159416","label":"Louisiana State University-Shreveport"},{"value":"159647","label":"Louisiana Tech University"},{"value":"157298","label":"Louisville Presbyterian Theological Seminary"},{"value":"203757","label":"Lourdes University"},{"value":"235750","label":"Lower Columbia College"},{"value":"117946","label":"Loyola Marymount University"},{"value":"146719","label":"Loyola University Chicago"},{"value":"163046","label":"Loyola University Maryland"},{"value":"159656","label":"Loyola University New Orleans"},{"value":"226383","label":"Lubbock Christian University"},{"value":"363633","label":"Luna Community College"},{"value":"101602","label":"Lurleen B Wallace Community College"},{"value":"153834","label":"Luther College"},{"value":"135364","label":"Luther Rice University & Seminary"},{"value":"173896","label":"Luther Seminary"},{"value":"146728","label":"Lutheran School of Theology at Chicago"},{"value":"213631","label":"Lutheran Theological Seminary at Gettysburg"},{"value":"213640","label":"Lutheran Theological Seminary at Philadelphia"},{"value":"213659","label":"Luzerne County Community College"},{"value":"213668","label":"Lycoming College"},{"value":"232609","label":"Lynchburg College"},{"value":"230931","label":"Lyndon State College"},{"value":"132657","label":"Lynn University"},{"value":"106342","label":"Lyon College"},{"value":"173902","label":"Macalester College"},{"value":"146816","label":"MacCormac College"},{"value":"192624","label":"Machzikei Hadath Rabbinical College"},{"value":"146825","label":"MacMurray College"},{"value":"170790","label":"Macomb Community College"},{"value":"238263","label":"Madison Area Technical College"},{"value":"364168","label":"Madison Media Institute"},{"value":"148399","label":"Madison Media Institute-Rockford Career College"},{"value":"157304","label":"Madisonville Community College"},{"value":"170806","label":"Madonna University"},{"value":"153861","label":"Maharishi University of Management"},{"value":"161509","label":"Maine College of Art"},{"value":"161022","label":"Maine College of Health Professions"},{"value":"161299","label":"Maine Maritime Academy"},{"value":"203775","label":"Malone University"},{"value":"451103","label":"Management Resources College"},{"value":"129695","label":"Manchester Community College-Manchester"},{"value":"183132","label":"Manchester Community College-Manchester"},{"value":"151777","label":"Manchester University"},{"value":"192688","label":"Mandl School-The College of Allied Health"},{"value":"155487","label":"Manhattan Area Technical College"},{"value":"155496","label":"Manhattan Christian College"},{"value":"192703","label":"Manhattan College"},{"value":"192712","label":"Manhattan School of Music"},{"value":"192749","label":"Manhattanville College"},{"value":"213774","label":"Manor College"},{"value":"213783","label":"Mansfield University of Pennsylvania"},{"value":"446394","label":"Maple Springs Baptist Bible College and Seminary"},{"value":"239071","label":"Maranatha Baptist University"},{"value":"192785","label":"Maria College of Albany"},{"value":"166601","label":"Marian Court College"},{"value":"239080","label":"Marian University-Fond Du Lac"},{"value":"151786","label":"Marian University-Indianapolis"},{"value":"203845","label":"Marietta College"},{"value":"101648","label":"Marion Military Institute"},{"value":"203881","label":"Marion Technical College"},{"value":"192819","label":"Marist College"},{"value":"230940","label":"Marlboro College"},{"value":"440411","label":"Marlboro College Graduate & Professional Studies"},{"value":"239105","label":"Marquette University"},{"value":"198899","label":"Mars Hill University"},{"value":"123943","label":"Marshall B Ketchum University"},{"value":"237525","label":"Marshall University"},{"value":"153922","label":"Marshalltown Community College"},{"value":"198905","label":"Martin Community College"},{"value":"173452","label":"Martin Luther College"},{"value":"220701","label":"Martin Methodist College"},{"value":"151810","label":"Martin University"},{"value":"232672","label":"Mary Baldwin College"},{"value":"170842","label":"Marygrove College"},{"value":"163295","label":"Maryland Institute College of Art"},{"value":"164085","label":"Maryland University of Integrative Health"},{"value":"209108","label":"Marylhurst University"},{"value":"118541","label":"Marymount California University"},{"value":"192864","label":"Marymount Manhattan College"},{"value":"232706","label":"Marymount University"},{"value":"220710","label":"Maryville College"},{"value":"178059","label":"Maryville University of Saint Louis"},{"value":"213826","label":"Marywood University"},{"value":"166647","label":"Massachusetts Bay Community College"},{"value":"166674","label":"Massachusetts College of Art and Design"},{"value":"167288","label":"Massachusetts College of Liberal Arts"},{"value":"166683","label":"Massachusetts Institute of Technology"},{"value":"166692","label":"Massachusetts Maritime Academy"},{"value":"369002","label":"Massachusetts School of Law"},{"value":"166823","label":"Massasoit Community College"},{"value":"436702","label":"Mattia College"},{"value":"454698","label":"Mayfield College"},{"value":"198914","label":"Mayland Community College"},{"value":"365426","label":"Mayo Graduate School"},{"value":"173957","label":"Mayo Medical School"},{"value":"173966","label":"Mayo School of Health Sciences"},{"value":"157331","label":"Maysville Community and Technical College"},{"value":"200226","label":"Mayville State University"},{"value":"438212","label":"McCann School of Business & Technology"},{"value":"146977","label":"McCormick Theological Seminary"},{"value":"164270","label":"McDaniel College"},{"value":"198923","label":"McDowell Technical Community College"},{"value":"147004","label":"McHenry County College"},{"value":"147013","label":"McKendree University"},{"value":"226578","label":"McLennan Community College"},{"value":"226587","label":"McMurry University"},{"value":"367194","label":"McNally Smith College of Music"},{"value":"159717","label":"McNeese State University"},{"value":"155511","label":"McPherson College"},{"value":"166656","label":"MCPHS University"},{"value":"147031","label":"Meadville Lombard Theological School"},{"value":"414461","label":"Mech-Tech College"},{"value":"192925","label":"Medaille College"},{"value":"239169","label":"Medical College of Wisconsin"},{"value":"218335","label":"Medical University of South Carolina"},{"value":"448415","label":"MedTech College"},{"value":"456366","label":"MedTech College-Ft Wayne Campus"},{"value":"456357","label":"MedTech College-Greenwood Campus"},{"value":"456375","label":"MedTech College-Lexington Campus"},{"value":"131742","label":"Medtech Institute"},{"value":"444714","label":"MedTech Institute-Atlanta Campus"},{"value":"220792","label":"Meharry Medical College"},{"value":"192961","label":"Memorial School of Nursing"},{"value":"220808","label":"Memphis College of Art"},{"value":"220871","label":"Memphis Theological Seminary"},{"value":"118684","label":"Mendocino College"},{"value":"118693","label":"Menlo College"},{"value":"118718","label":"Merced College"},{"value":"185509","label":"Mercer County Community College"},{"value":"140447","label":"Mercer University"},{"value":"193016","label":"Mercy College"},{"value":"153977","label":"Mercy College of Health Sciences"},{"value":"203960","label":"Mercy College of Ohio"},{"value":"213987","label":"Mercyhurst University"},{"value":"480189","label":"Mercyhurst University-North East Campus"},{"value":"198950","label":"Meredith College"},{"value":"244279","label":"Meridian College"},{"value":"175935","label":"Meridian Community College"},{"value":"166850","label":"Merrimack College"},{"value":"118772","label":"Merritt College"},{"value":"105154","label":"Mesa Community College"},{"value":"173993","label":"Mesabi Range College"},{"value":"188261","label":"Mesalands Community College"},{"value":"461847","label":"Mesivta Keser Torah"},{"value":"193061","label":"Mesivta of Eastern Parkway-Yeshiva Zichron Meilech"},{"value":"193052","label":"Mesivta Torah Vodaath Rabbinical Seminary"},{"value":"193070","label":"Mesivtha Tifereth Jerusalem of America"},{"value":"417752","label":"Messenger College"},{"value":"213996","label":"Messiah College"},{"value":"147129","label":"Methodist College"},{"value":"203997","label":"Methodist Theological School in Ohio"},{"value":"198969","label":"Methodist University"},{"value":"455673","label":"Metro Business College-Arnold"},{"value":"178110","label":"Metro Business College-Cape Girardeau"},{"value":"245430","label":"Metro Business College-Jefferson City"},{"value":"245421","label":"Metro Business College-Rolla"},{"value":"214023","label":"Metropolitan Career Center Computer Technology Institute"},{"value":"190114","label":"Metropolitan College of New York"},{"value":"181303","label":"Metropolitan Community College Area"},{"value":"177995","label":"Metropolitan Community College-Kansas City-Kansas City"},{"value":"174020","label":"Metropolitan State University"},{"value":"127565","label":"Metropolitan State University of Denver"},{"value":"166869","label":"MGH Institute of Health Professions"},{"value":"135717","label":"Miami Dade College"},{"value":"204006","label":"Miami University-Hamilton"},{"value":"204015","label":"Miami University-Middletown"},{"value":"204024","label":"Miami University-Oxford"},{"value":"369862","label":"Miami-Jacobs Career College-Columbus"},{"value":"204060","label":"Miami-Jacobs Career College-Dayton"},{"value":"200633","label":"Miami-Jacobs Career College-Independence"},{"value":"441201","label":"Miami-Jacobs Career College-Sharonville"},{"value":"449126","label":"Miami-Jacobs Career College-Springboro"},{"value":"450003","label":"Miami-Jacobs Career College-Troy"},{"value":"169655","label":"MIAT College of Technology"},{"value":"434414","label":"Michigan Jewish Institute"},{"value":"169220","label":"Michigan School of Professional Psychology"},{"value":"171100","label":"Michigan State University"},{"value":"169628","label":"Michigan State University-College of Law"},{"value":"171128","label":"Michigan Technological University"},{"value":"171155","label":"Mid Michigan Community College"},{"value":"245953","label":"Mid-America Christian University"},{"value":"151962","label":"Mid-America College of Funeral Service"},{"value":"155520","label":"MidAmerica Nazarene University"},{"value":"199458","label":"Mid-Atlantic Christian University"},{"value":"482158","label":"Middle Georgia State College"},{"value":"220996","label":"Middle Tennessee School of Anesthesia Inc"},{"value":"220978","label":"Middle Tennessee State University"},{"value":"230959","label":"Middlebury College"},{"value":"166887","label":"Middlesex Community College-Bedford"},{"value":"129756","label":"Middlesex Community College-Middletown"},{"value":"185536","label":"Middlesex County College"},{"value":"226806","label":"Midland College"},{"value":"181330","label":"Midland University"},{"value":"218353","label":"Midlands Technical College"},{"value":"181312","label":"Mid-Plains Community College"},{"value":"481225","label":"Mid-South Christian College"},{"value":"147165","label":"Midstate College"},{"value":"239220","label":"Mid-State Technical College"},{"value":"157377","label":"Midway College"},{"value":"439020","label":"Midwest College of Oriental Medicine-Chicago"},{"value":"383020","label":"Midwest College of Oriental Medicine-Racine"},{"value":"178183","label":"Midwest Institute"},{"value":"178208","label":"Midwestern Baptist Theological Seminary"},{"value":"226833","label":"Midwestern State University"},{"value":"143853","label":"Midwestern University-Downers Grove"},{"value":"423643","label":"Midwestern University-Glendale"},{"value":"480985","label":"Midwives College of Utah"},{"value":"193201","label":"Mildred Elley School-Albany Campus"},{"value":"461014","label":"Mildred Elley-New York Campus"},{"value":"101675","label":"Miles College"},{"value":"180373","label":"Miles Community College"},{"value":"461883","label":"Millennia Atlantic University"},{"value":"449117","label":"Miller-Motte College-Cary"},{"value":"458405","label":"Miller-Motte College-Fayetteville"},{"value":"455655","label":"Miller-Motte College-Greenville"},{"value":"460817","label":"Miller-Motte College-Jacksonville"},{"value":"456205","label":"Miller-Motte College-Raleigh"},{"value":"198978","label":"Miller-Motte College-Wilmington"},{"value":"460826","label":"Miller-Motte Technical College-Augusta"},{"value":"441025","label":"Miller-Motte Technical College-Charleston"},{"value":"443650","label":"Miller-Motte Technical College-Chattanooga"},{"value":"382771","label":"Miller-Motte Technical College-Clarksville"},{"value":"458441","label":"Miller-Motte Technical College-Columbus"},{"value":"460835","label":"Miller-Motte Technical College-Conway"},{"value":"475079","label":"Miller-Motte Technical College-Gulfport"},{"value":"233091","label":"Miller-Motte Technical College-Lynchburg"},{"value":"475060","label":"Miller-Motte Technical College-Macon"},{"value":"448664","label":"Miller-Motte Technical College-Madison"},{"value":"475194","label":"Miller-Motte Technical College-Roanoke"},{"value":"214041","label":"Millersville University of Pennsylvania"},{"value":"221014","label":"Milligan College"},{"value":"147244","label":"Millikin University"},{"value":"118888","label":"Mills College"},{"value":"175980","label":"Millsaps College"},{"value":"239248","label":"Milwaukee Area Technical College"},{"value":"239309","label":"Milwaukee Institute of Art & Design"},{"value":"239318","label":"Milwaukee School of Engineering"},{"value":"178217","label":"Mineral Area College"},{"value":"174118","label":"Minneapolis Business College"},{"value":"174127","label":"Minneapolis College of Art and Design"},{"value":"174136","label":"Minneapolis Community and Technical College"},{"value":"474881","label":"Minneapolis Media Institute"},{"value":"451769","label":"Minnesota School of Business-Blaine"},{"value":"407285","label":"Minnesota School of Business-Brooklyn Center"},{"value":"456782","label":"Minnesota School of Business-Elk River"},{"value":"458742","label":"Minnesota School of Business-Lakeville"},{"value":"455585","label":"Minnesota School of Business-Moorhead"},{"value":"442578","label":"Minnesota School of Business-Plymouth"},{"value":"174279","label":"Minnesota School of Business-Richfield"},{"value":"447670","label":"Minnesota School of Business-Rochester"},{"value":"445920","label":"Minnesota School of Business-Waite Park"},{"value":"175263","label":"Minnesota State College-Southeast Technical"},{"value":"173559","label":"Minnesota State Community and Technical College"},{"value":"174358","label":"Minnesota State University Moorhead"},{"value":"173920","label":"Minnesota State University-Mankato"},{"value":"173638","label":"Minnesota West Community and Technical College"},{"value":"200253","label":"Minot State University"},{"value":"118912","label":"MiraCosta College"},{"value":"193247","label":"Mirrer Yeshiva Cent Institute"},{"value":"214069","label":"Misericordia University"},{"value":"118930","label":"Mission College"},{"value":"176053","label":"Mississippi College"},{"value":"176008","label":"Mississippi Delta Community College"},{"value":"176071","label":"Mississippi Gulf Coast Community College"},{"value":"176080","label":"Mississippi State University"},{"value":"176035","label":"Mississippi University for Women"},{"value":"176044","label":"Mississippi Valley State University"},{"value":"178244","label":"Missouri Baptist University"},{"value":"178305","label":"Missouri College"},{"value":"178341","label":"Missouri Southern State University"},{"value":"179566","label":"Missouri State University-Springfield"},{"value":"179344","label":"Missouri State University-West Plains"},{"value":"178350","label":"Missouri Tech"},{"value":"178411","label":"Missouri University of Science and Technology"},{"value":"178369","label":"Missouri Valley College"},{"value":"178387","label":"Missouri Western State University"},{"value":"129774","label":"Mitchell College"},{"value":"198987","label":"Mitchell Community College"},{"value":"219189","label":"Mitchell Technical Institute"},{"value":"178448","label":"Moberly Area Community College"},{"value":"118976","label":"Modesto Junior College"},{"value":"105206","label":"Mohave Community College"},{"value":"193283","label":"Mohawk Valley Community College"},{"value":"193292","label":"Molloy College"},{"value":"147341","label":"Monmouth College"},{"value":"185572","label":"Monmouth University"},{"value":"193308","label":"Monroe College"},{"value":"193326","label":"Monroe Community College"},{"value":"171225","label":"Monroe County Community College"},{"value":"262165","label":"Montana Bible College"},{"value":"180461","label":"Montana State University"},{"value":"180179","label":"Montana State University-Billings"},{"value":"180522","label":"Montana State University-Northern"},{"value":"180416","label":"Montana Tech of the University of Montana"},{"value":"171234","label":"Montcalm Community College"},{"value":"185590","label":"Montclair State University"},{"value":"119058","label":"Monterey Institute of International Studies"},{"value":"119067","label":"Monterey Peninsula College"},{"value":"163426","label":"Montgomery College"},{"value":"199023","label":"Montgomery Community College"},{"value":"214111","label":"Montgomery County Community College"},{"value":"199032","label":"Montreat College"},{"value":"166911","label":"Montserrat College of Art"},{"value":"147369","label":"Moody Bible Institute"},{"value":"214148","label":"Moore College of Art and Design"},{"value":"119137","label":"Moorpark College"},{"value":"239372","label":"Moraine Park Technical College"},{"value":"147378","label":"Moraine Valley Community College"},{"value":"214157","label":"Moravian College"},{"value":"157386","label":"Morehead State University"},{"value":"140553","label":"Morehouse College"},{"value":"140562","label":"Morehouse School of Medicine"},{"value":"460394","label":"Moreno Valley College"},{"value":"127617","label":"Morgan Community College"},{"value":"163453","label":"Morgan State University"},{"value":"154004","label":"Morningside College"},{"value":"218399","label":"Morris College"},{"value":"147396","label":"Morrison Institute of Technology"},{"value":"196051","label":"Morrisville State College"},{"value":"147411","label":"Morton College"},{"value":"221096","label":"Motlow State Community College"},{"value":"169275","label":"Mott Community College"},{"value":"140599","label":"Moultrie Technical College"},{"value":"214166","label":"Mount Aloysius College"},{"value":"209241","label":"Mount Angel Seminary"},{"value":"204176","label":"Mount Carmel College of Nursing"},{"value":"166939","label":"Mount Holyoke College"},{"value":"166948","label":"Mount Ida College"},{"value":"219198","label":"Mount Marty College"},{"value":"239390","label":"Mount Mary University"},{"value":"154013","label":"Mount Mercy University"},{"value":"204200","label":"Mount Saint Joseph University"},{"value":"193353","label":"Mount Saint Mary College"},{"value":"119173","label":"Mount Saint Mary's University"},{"value":"163462","label":"Mount St Mary's University"},{"value":"204194","label":"Mount Vernon Nazarene University"},{"value":"166957","label":"Mount Wachusett Community College"},{"value":"182865","label":"Mount Washington College"},{"value":"232788","label":"Mountain Empire Community College"},{"value":"237598","label":"Mountain State College"},{"value":"226930","label":"Mountain View College"},{"value":"444954","label":"Mountwest Community and Technical College"},{"value":"209250","label":"Mt Hood Community College"},{"value":"119164","label":"Mt San Antonio College"},{"value":"119216","label":"Mt San Jacinto Community College District"},{"value":"398130","label":"Mt Sierra College"},{"value":"118198","label":"MTI College"},{"value":"214175","label":"Muhlenberg College"},{"value":"209287","label":"Multnomah University"},{"value":"207236","label":"Murray State College"},{"value":"157401","label":"Murray State University"},{"value":"119270","label":"Musicians Institute"},{"value":"171304","label":"Muskegon Community College"},{"value":"204264","label":"Muskingum University"},{"value":"434432","label":"Myotherapy Institute"},{"value":"119331","label":"Napa Valley College"},{"value":"127653","label":"Naropa University"},{"value":"199087","label":"Nash Community College"},{"value":"239424","label":"Nashotah House"},{"value":"183141","label":"Nashua Community College"},{"value":"221184","label":"Nashville State Community College"},{"value":"193478","label":"Nassau Community College"},{"value":"248882","label":"National American University-Albuquerque"},{"value":"440758","label":"National American University-Albuquerque West"},{"value":"451875","label":"National American University-Austin"},{"value":"482307","label":"National American University-Austin South"},{"value":"477996","label":"National American University-Bellevue"},{"value":"436483","label":"National American University-Bloomington"},{"value":"440767","label":"National American University-Brooklyn Center"},{"value":"478005","label":"National American University-Burnsville"},{"value":"466161","label":"National American University-Centennial"},{"value":"127680","label":"National American University-Colorado Springs"},{"value":"466189","label":"National American University-Colorado Springs South"},{"value":"127699","label":"National American University-Denver"},{"value":"440749","label":"National American University-Ellsworth AFB Extension"},{"value":"482325","label":"National American University-Georgetown"},{"value":"485290","label":"National American University-Harold D. Buckingham Graduate School"},{"value":"247700","label":"National American University-Independence"},{"value":"482370","label":"National American University-Indianapolis"},{"value":"466170","label":"National American University-Lee's Summit"},{"value":"482316","label":"National American University-Lewisville"},{"value":"442718","label":"National American University-Overland Park"},{"value":"219204","label":"National American University-Rapid City"},{"value":"482343","label":"National American University-Rochester"},{"value":"174385","label":"National American University-Roseville"},{"value":"219213","label":"National American University-Sioux Falls"},{"value":"466152","label":"National American University-Tulsa"},{"value":"482352","label":"National American University-Weldon Spring"},{"value":"451884","label":"National American University-Wichita"},{"value":"482361","label":"National American University-Wichita West"},{"value":"448585","label":"National American University-Zona Rosa"},{"value":"209296","label":"National College of Natural Medicine"},{"value":"480480","label":"National College-Canton"},{"value":"453473","label":"National College-Cincinnati"},{"value":"457004","label":"National College-Columbus"},{"value":"453455","label":"National College-Dayton"},{"value":"157021","label":"National College-Lexington"},{"value":"388043","label":"National College-Nashville"},{"value":"453482","label":"National College-Stow"},{"value":"459833","label":"National College-Willoughby Hills"},{"value":"453464","label":"National College-Youngstown"},{"value":"441478","label":"National Graduate School of Quality Management"},{"value":"412003","label":"National Institute of Massotherapy"},{"value":"147536","label":"National Louis University"},{"value":"448114","label":"National Massage Therapy Institute"},{"value":"461023","label":"National Paralegal College"},{"value":"106980","label":"National Park Community College"},{"value":"119605","label":"National University"},{"value":"242981","label":"National University College-Arecibo"},{"value":"242972","label":"National University College-Bayamon"},{"value":"468723","label":"National University College-Caguas"},{"value":"458469","label":"National University College-Ponce"},{"value":"444042","label":"National University College-Rio Grande"},{"value":"147590","label":"National University of Health Sciences"},{"value":"129729","label":"Naugatuck Valley Community College"},{"value":"187596","label":"Navajo Technical University"},{"value":"119678","label":"Naval Postgraduate School"},{"value":"227146","label":"Navarro College"},{"value":"127714","label":"Nazarene Bible College"},{"value":"178518","label":"Nazarene Theological Seminary"},{"value":"193584","label":"Nazareth College"},{"value":"181376","label":"Nebraska Christian College"},{"value":"181765","label":"Nebraska College of Technical Agriculture"},{"value":"181419","label":"Nebraska Indian Community College"},{"value":"181297","label":"Nebraska Methodist College of Nursing & Allied Health"},{"value":"181446","label":"Nebraska Wesleyan University"},{"value":"155566","label":"Neosho County Community College"},{"value":"163532","label":"Ner Israel Rabbinical College"},{"value":"214272","label":"Neumann University"},{"value":"445692","label":"Neumont University"},{"value":"441900","label":"Nevada State College"},{"value":"185758","label":"New Brunswick Theological Seminary"},{"value":"214290","label":"New Castle School of Trades"},{"value":"262129","label":"New College of Florida"},{"value":"182980","label":"New England College"},{"value":"164438","label":"New England College of Business and Finance"},{"value":"167093","label":"New England College of Optometry"},{"value":"230977","label":"New England Culinary Institute"},{"value":"217305","label":"New England Institute of Technology"},{"value":"167215","label":"New England Law-Boston"},{"value":"167181","label":"New England School of Acupuncture"},{"value":"430810","label":"New Hampshire Institute of Art"},{"value":"208725","label":"New Hope Christian College-Eugene"},{"value":"185129","label":"New Jersey City University"},{"value":"185828","label":"New Jersey Institute of Technology"},{"value":"187897","label":"New Mexico Highlands University"},{"value":"187967","label":"New Mexico Institute of Mining and Technology"},{"value":"187903","label":"New Mexico Junior College"},{"value":"187912","label":"New Mexico Military Institute"},{"value":"187994","label":"New Mexico State University-Alamogordo"},{"value":"188003","label":"New Mexico State University-Carlsbad"},{"value":"187620","label":"New Mexico State University-Dona Ana"},{"value":"188021","label":"New Mexico State University-Grants"},{"value":"188030","label":"New Mexico State University-Main Campus"},{"value":"159948","label":"New Orleans Baptist Theological Seminary"},{"value":"447582","label":"New River Community and Technical College"},{"value":"232867","label":"New River Community College"},{"value":"366368","label":"New York Academy of Art"},{"value":"195845","label":"New York Career Institute"},{"value":"193751","label":"New York Chiropractic College"},{"value":"418126","label":"New York College of Health Professions"},{"value":"194073","label":"New York College of Podiatric Medicine"},{"value":"439783","label":"New York College of Traditional Chinese Medicine"},{"value":"421841","label":"New York Conservatory for Dramatic Arts"},{"value":"461148","label":"New York Film Academy"},{"value":"194091","label":"New York Institute of Technology"},{"value":"193821","label":"New York Law School"},{"value":"193830","label":"New York Medical College"},{"value":"194116","label":"New York School of Interior Design"},{"value":"193894","label":"New York Theological Seminary"},{"value":"193900","label":"New York University"},{"value":"218414","label":"Newberry College"},{"value":"167251","label":"Newbury College"},{"value":"155335","label":"Newman University"},{"value":"119775","label":"Newschool of Architecture and Design"},{"value":"183099","label":"NHTI-Concord's Community College"},{"value":"193946","label":"Niagara County Community College"},{"value":"193973","label":"Niagara University"},{"value":"159966","label":"Nicholls State University"},{"value":"167260","label":"Nichols College"},{"value":"239442","label":"Nicolet Area Technical College"},{"value":"444787","label":"Nightingale College"},{"value":"460464","label":"Norco College"},{"value":"232937","label":"Norfolk State University"},{"value":"174428","label":"Normandale Community College"},{"value":"461795","label":"North American University"},{"value":"107460","label":"North Arkansas College"},{"value":"199102","label":"North Carolina A & T State University"},{"value":"199157","label":"North Carolina Central University"},{"value":"199193","label":"North Carolina State University at Raleigh"},{"value":"199209","label":"North Carolina Wesleyan College"},{"value":"147660","label":"North Central College"},{"value":"418889","label":"North Central Institute"},{"value":"155593","label":"North Central Kansas Technical College"},{"value":"171395","label":"North Central Michigan College"},{"value":"179715","label":"North Central Missouri College"},{"value":"204422","label":"North Central State College"},{"value":"224110","label":"North Central Texas College"},{"value":"174437","label":"North Central University"},{"value":"194028","label":"North Country Community College"},{"value":"200305","label":"North Dakota State College of Science"},{"value":"200332","label":"North Dakota State University-Main Campus"},{"value":"136145","label":"North Florida Community College"},{"value":"140678","label":"North Georgia Technical College"},{"value":"218441","label":"North Greenville University"},{"value":"174376","label":"North Hennepin Community College"},{"value":"142443","label":"North Idaho College"},{"value":"154059","label":"North Iowa Area Community College"},{"value":"227191","label":"North Lake College"},{"value":"147679","label":"North Park University"},{"value":"236072","label":"North Seattle College"},{"value":"167312","label":"North Shore Community College"},{"value":"214379","label":"Northampton County Area Community College"},{"value":"239460","label":"Northcentral Technical College"},{"value":"444130","label":"Northcentral University"},{"value":"101897","label":"Northeast Alabama Community College"},{"value":"182917","label":"Northeast Catholic College"},{"value":"181491","label":"Northeast Community College"},{"value":"154110","label":"Northeast Iowa Community College"},{"value":"176169","label":"Northeast Mississippi Community College"},{"value":"204477","label":"Northeast Ohio Medical University"},{"value":"221908","label":"Northeast State Community College"},{"value":"227225","label":"Northeast Texas Community College"},{"value":"239488","label":"Northeast Wisconsin Technical College"},{"value":"147776","label":"Northeastern Illinois University"},{"value":"127732","label":"Northeastern Junior College"},{"value":"207290","label":"Northeastern Oklahoma A&M College"},{"value":"439817","label":"Northeastern Seminary"},{"value":"207263","label":"Northeastern State University"},{"value":"217837","label":"Northeastern Technical College"},{"value":"167358","label":"Northeastern University"},{"value":"482705","label":"Northeastern University Global Network"},{"value":"105330","label":"Northern Arizona University"},{"value":"147697","label":"Northern Baptist Theological Seminary"},{"value":"167376","label":"Northern Essex Community College"},{"value":"147703","label":"Northern Illinois University"},{"value":"157447","label":"Northern Kentucky University"},{"value":"161484","label":"Northern Maine Community College"},{"value":"240790","label":"Northern Marianas College"},{"value":"171456","label":"Northern Michigan University"},{"value":"188058","label":"Northern New Mexico College"},{"value":"207281","label":"Northern Oklahoma College"},{"value":"219259","label":"Northern State University"},{"value":"232946","label":"Northern Virginia Community College"},{"value":"239512","label":"Northland College"},{"value":"174473","label":"Northland Community and Technical College"},{"value":"239503","label":"Northland International University"},{"value":"105349","label":"Northland Pioneer College"},{"value":"217606","label":"Northpoint Bible College"},{"value":"160667","label":"Northshore Technical Community College"},{"value":"367459","label":"NorthWest Arkansas Community College"},{"value":"445948","label":"Northwest Career College"},{"value":"209409","label":"Northwest Christian University"},{"value":"240657","label":"Northwest College"},{"value":"377546","label":"Northwest College of Art & Design"},{"value":"136233","label":"Northwest Florida State College"},{"value":"380377","label":"Northwest Indian College"},{"value":"460941","label":"Northwest Institute of Literary Arts"},{"value":"154129","label":"Northwest Iowa Community College"},{"value":"155618","label":"Northwest Kansas Technical College"},{"value":"160010","label":"Northwest Louisiana Technical College"},{"value":"176178","label":"Northwest Mississippi Community College"},{"value":"178624","label":"Northwest Missouri State University"},{"value":"142461","label":"Northwest Nazarene University"},{"value":"458140","label":"Northwest School of Wooden Boat Building"},{"value":"204440","label":"Northwest State Community College"},{"value":"173115","label":"Northwest Technical College"},{"value":"236133","label":"Northwest University"},{"value":"420398","label":"Northwest Vista College"},{"value":"154101","label":"Northwestern College"},{"value":"147749","label":"Northwestern College-Chicago Campus"},{"value":"260992","label":"Northwestern College-Southwestern Campus"},{"value":"130040","label":"Northwestern Connecticut Community College"},{"value":"174507","label":"Northwestern Health Sciences University"},{"value":"171483","label":"Northwestern Michigan College"},{"value":"207306","label":"Northwestern Oklahoma State University"},{"value":"160038","label":"Northwestern State University of Louisiana"},{"value":"147767","label":"Northwestern University"},{"value":"101736","label":"Northwest-Shoals Community College"},{"value":"136206","label":"Northwood University-Florida"},{"value":"171492","label":"Northwood University-Michigan"},{"value":"227243","label":"Northwood University-Texas"},{"value":"130004","label":"Norwalk Community College"},{"value":"230995","label":"Norwich University"},{"value":"368452","label":"Nossi College of Art"},{"value":"204468","label":"Notre Dame College"},{"value":"120184","label":"Notre Dame de Namur University"},{"value":"163578","label":"Notre Dame of Maryland University"},{"value":"160029","label":"Notre Dame Seminary Graduate School of Theology"},{"value":"136215","label":"Nova Southeastern University"},{"value":"200086","label":"Nueta Hidatsa Sahnish College"},{"value":"158884","label":"Nunez Community College"},{"value":"194161","label":"Nyack College"},{"value":"174525","label":"Oak Hills Christian College"},{"value":"152099","label":"Oakland City University"},{"value":"171535","label":"Oakland Community College"},{"value":"171571","label":"Oakland University"},{"value":"147800","label":"Oakton Community College"},{"value":"101912","label":"Oakwood University"},{"value":"204501","label":"Oberlin College"},{"value":"227289","label":"Oblate School of Theology"},{"value":"120254","label":"Occidental College"},{"value":"185873","label":"Ocean County College"},{"value":"420431","label":"Oconee Fall Line Technical College"},{"value":"227304","label":"Odessa College"},{"value":"366465","label":"Ogeechee Technical College"},{"value":"219277","label":"Oglala Lakota College"},{"value":"140696","label":"Oglethorpe University"},{"value":"453747","label":"Ohio Business College-Hilliard"},{"value":"203739","label":"Ohio Business College-Sandusky"},{"value":"203720","label":"Ohio Business College-Sheffield"},{"value":"201964","label":"Ohio Christian University"},{"value":"204592","label":"Ohio College of Massotherapy Inc"},{"value":"204617","label":"Ohio Dominican University"},{"value":"206002","label":"Ohio Mid-Western College"},{"value":"204635","label":"Ohio Northern University"},{"value":"204662","label":"Ohio State University Agricultural Technical Institute"},{"value":"204671","label":"Ohio State University-Lima Campus"},{"value":"204796","label":"Ohio State University-Main Campus"},{"value":"204680","label":"Ohio State University-Mansfield Campus"},{"value":"204699","label":"Ohio State University-Marion Campus"},{"value":"204705","label":"Ohio State University-Newark Campus"},{"value":"204608","label":"Ohio Technical College"},{"value":"453817","label":"Ohio Technical College-PowerSport Institute"},{"value":"204820","label":"Ohio University-Chillicothe Campus"},{"value":"204802","label":"Ohio University-Eastern Campus"},{"value":"204848","label":"Ohio University-Lancaster Campus"},{"value":"204857","label":"Ohio University-Main Campus"},{"value":"204839","label":"Ohio University-Southern Campus"},{"value":"204866","label":"Ohio University-Zanesville Campus"},{"value":"204884","label":"Ohio Valley College of Technology"},{"value":"237640","label":"Ohio Valley University"},{"value":"204909","label":"Ohio Wesleyan University"},{"value":"120290","label":"Ohlone College"},{"value":"194189","label":"Ohr Hameir Theological Seminary"},{"value":"207403","label":"Oklahoma Baptist University"},{"value":"207324","label":"Oklahoma Christian University"},{"value":"207449","label":"Oklahoma City Community College"},{"value":"207458","label":"Oklahoma City University"},{"value":"207351","label":"Oklahoma Panhandle State University"},{"value":"207315","label":"Oklahoma State University Center for Health Sciences"},{"value":"207564","label":"Oklahoma State University Institute of Technology"},{"value":"207388","label":"Oklahoma State University-Main Campus"},{"value":"207397","label":"Oklahoma State University-Oklahoma City"},{"value":"469629","label":"Oklahoma Technical College"},{"value":"206835","label":"Oklahoma Wesleyan University"},{"value":"232982","label":"Old Dominion University"},{"value":"171599","label":"Olivet College"},{"value":"147828","label":"Olivet Nazarene University"},{"value":"145707","label":"Olney Central College"},{"value":"236188","label":"Olympic College"},{"value":"407328","label":"Omaha School of Massage and Healthcare of Herzing University"},{"value":"221254","label":"O'More College of Design"},{"value":"194222","label":"Onondaga Community College"},{"value":"207582","label":"Oral Roberts University"},{"value":"120342","label":"Orange Coast College"},{"value":"194240","label":"Orange County Community College"},{"value":"218487","label":"Orangeburg Calhoun Technical College"},{"value":"423652","label":"Oregon Coast Community College"},{"value":"209533","label":"Oregon College of Art and Craft"},{"value":"369659","label":"Oregon College of Oriental Medicine"},{"value":"209490","label":"Oregon Health & Science University"},{"value":"209506","label":"Oregon Institute of Technology"},{"value":"209542","label":"Oregon State University"},{"value":"454883","label":"Orion College"},{"value":"214528","label":"Orleans Technical Institute"},{"value":"127778","label":"Otero Junior College"},{"value":"120403","label":"Otis College of Art and Design"},{"value":"442897","label":"Ottawa University-Jeffersonville"},{"value":"155636","label":"Ottawa University-Kansas City"},{"value":"428259","label":"Ottawa University-Milwaukee"},{"value":"454582","label":"Ottawa University-Online"},{"value":"155627","label":"Ottawa University-Ottawa"},{"value":"105367","label":"Ottawa University-Phoenix"},{"value":"204936","label":"Otterbein University"},{"value":"107512","label":"Ouachita Baptist University"},{"value":"160074","label":"Our Lady of the Lake College"},{"value":"227331","label":"Our Lady of the Lake University"},{"value":"204945","label":"Owens Community College"},{"value":"247940","label":"Owensboro Community and Technical College"},{"value":"461120","label":"Oxford Graduate School"},{"value":"120421","label":"Oxnard College"},{"value":"178679","label":"Ozark Christian College"},{"value":"107549","label":"Ozarka College"},{"value":"177472","label":"Ozarks Technical Community College"},{"value":"214838","label":"Pace Institute"},{"value":"194310","label":"Pace University-New York"},{"value":"422695","label":"Pacific College"},{"value":"442842","label":"Pacific College of Oriental Medicine-Chicago"},{"value":"414595","label":"Pacific College of Oriental Medicine-New York"},{"value":"378576","label":"Pacific College of Oriental Medicine-San Diego"},{"value":"439862","label":"Pacific Islands University"},{"value":"120740","label":"Pacific Lutheran Theological Seminary"},{"value":"236230","label":"Pacific Lutheran University"},{"value":"209603","label":"Pacific Northwest College of Art"},{"value":"455406","label":"Pacific Northwest University of Health Sciences"},{"value":"120768","label":"Pacific Oaks College"},{"value":"457484","label":"Pacific Rim Christian University"},{"value":"120795","label":"Pacific School of Religion"},{"value":"120838","label":"Pacific States University"},{"value":"120865","label":"Pacific Union College"},{"value":"209612","label":"Pacific University"},{"value":"115746","label":"Pacifica Graduate Institute"},{"value":"130110","label":"Paier College of Art Inc"},{"value":"140720","label":"Paine College"},{"value":"243647","label":"Palau Community College"},{"value":"136330","label":"Palm Beach Atlantic University"},{"value":"136358","label":"Palm Beach State College"},{"value":"154174","label":"Palmer College of Chiropractic"},{"value":"246354","label":"Palo Alto College"},{"value":"120698","label":"Palo Alto University"},{"value":"120953","label":"Palo Verde College"},{"value":"120971","label":"Palomar College"},{"value":"199263","label":"Pamlico Community College"},{"value":"227386","label":"Panola College"},{"value":"364016","label":"Paradise Valley Community College"},{"value":"121628","label":"Pardee RAND Graduate School"},{"value":"227401","label":"Paris Junior College"},{"value":"178721","label":"Park University"},{"value":"243823","label":"Parker University"},{"value":"147916","label":"Parkland College"},{"value":"121044","label":"Pasadena City College"},{"value":"136400","label":"Pasco-Hernando State College"},{"value":"186034","label":"Passaic County Community College"},{"value":"666666","label":"Patrick Henry College"},{"value":"233019","label":"Patrick Henry Community College"},{"value":"233037","label":"Paul D Camp Community College"},{"value":"227429","label":"Paul Quinn College"},{"value":"194392","label":"Paul Smiths College of Arts and Science"},{"value":"204990","label":"Payne Theological Seminary"},{"value":"176239","label":"Pearl River Community College"},{"value":"214883","label":"Peirce College"},{"value":"221643","label":"Pellissippi State Community College"},{"value":"236258","label":"Peninsula College"},{"value":"214892","label":"Penn Commercial Business/Technical School"},{"value":"214944","label":"Pennco Tech-Bristol"},{"value":"214971","label":"Pennsylvania Academy of the Fine Arts"},{"value":"215053","label":"Pennsylvania College of Art and Design"},{"value":"442356","label":"Pennsylvania College of Health Sciences"},{"value":"366252","label":"Pennsylvania College of Technology"},{"value":"414911","label":"Pennsylvania Highlands Community College"},{"value":"261861","label":"Pennsylvania Institute of Health and Technology"},{"value":"214582","label":"Pennsylvania Institute of Technology"},{"value":"214616","label":"Pennsylvania State University-College of Medicine"},{"value":"212018","label":"Pennsylvania State University-Dickinson Law"},{"value":"214777","label":"Pennsylvania State University-Main Campus"},{"value":"214801","label":"Pennsylvania State University-Penn State Abington"},{"value":"214689","label":"Pennsylvania State University-Penn State Altoona"},{"value":"214698","label":"Pennsylvania State University-Penn State Beaver"},{"value":"214704","label":"Pennsylvania State University-Penn State Berks"},{"value":"214731","label":"Pennsylvania State University-Penn State Brandywine"},{"value":"214740","label":"Pennsylvania State University-Penn State DuBois"},{"value":"214591","label":"Pennsylvania State University-Penn State Erie-Behrend College"},{"value":"214759","label":"Pennsylvania State University-Penn State Fayette- Eberly"},{"value":"214607","label":"Pennsylvania State University-Penn State Great Valley"},{"value":"214786","label":"Pennsylvania State University-Penn State Greater Allegheny"},{"value":"214713","label":"Pennsylvania State University-Penn State Harrisburg"},{"value":"214768","label":"Pennsylvania State University-Penn State Hazleton"},{"value":"214670","label":"Pennsylvania State University-Penn State Lehigh Valley"},{"value":"214795","label":"Pennsylvania State University-Penn State Mont Alto"},{"value":"214625","label":"Pennsylvania State University-Penn State New Kensington"},{"value":"214810","label":"Pennsylvania State University-Penn State Schuylkill"},{"value":"214634","label":"Pennsylvania State University-Penn State Shenango"},{"value":"214643","label":"Pennsylvania State University-Penn State Wilkes-Barre"},{"value":"214652","label":"Pennsylvania State University-Penn State Worthington Scranton"},{"value":"214829","label":"Pennsylvania State University-Penn State York"},{"value":"479956","label":"Pennsylvania State University-World Campus"},{"value":"136473","label":"Pensacola State College"},{"value":"219842","label":"Pentecostal Theological Seminary"},{"value":"121150","label":"Pepperdine University"},{"value":"181534","label":"Peru State College"},{"value":"199306","label":"Pfeiffer University"},{"value":"215123","label":"Philadelphia College of Osteopathic Medicine"},{"value":"215099","label":"Philadelphia University"},{"value":"107600","label":"Philander Smith College"},{"value":"189282","label":"Phillips Beth Israel School of Nursing"},{"value":"107619","label":"Phillips Community College of the University of Arkansas"},{"value":"110307","label":"Phillips Graduate Institute"},{"value":"414966","label":"Phillips Theological Seminary"},{"value":"105428","label":"Phoenix College"},{"value":"447698","label":"Phoenix Institute of Herbal Medicine & Acupuncture"},{"value":"381459","label":"Phoenix Seminary"},{"value":"140818","label":"Piedmont College"},{"value":"199324","label":"Piedmont Community College"},{"value":"199315","label":"Piedmont International University"},{"value":"218520","label":"Piedmont Technical College"},{"value":"233116","label":"Piedmont Virginia Community College"},{"value":"235237","label":"Pierce College-Fort Steilacoom"},{"value":"439145","label":"Pierce College-Puyallup"},{"value":"443492","label":"Pierpont Community and Technical College"},{"value":"127820","label":"Pikes Peak Community College"},{"value":"440794","label":"Pillar College"},{"value":"105525","label":"Pima Community College"},{"value":"105543","label":"Pima Medical Institute-Albuquerque"},{"value":"461689","label":"Pima Medical Institute-Aurora"},{"value":"434140","label":"Pima Medical Institute-Chula Vista"},{"value":"442134","label":"Pima Medical Institute-Colorado Springs"},{"value":"404912","label":"Pima Medical Institute-Denver"},{"value":"456038","label":"Pima Medical Institute-East Valley"},{"value":"460136","label":"Pima Medical Institute-Houston"},{"value":"445230","label":"Pima Medical Institute-Las Vegas"},{"value":"260691","label":"Pima Medical Institute-Mesa"},{"value":"449074","label":"Pima Medical Institute-Renton"},{"value":"368629","label":"Pima Medical Institute-Seattle"},{"value":"105534","label":"Pima Medical Institute-Tucson"},{"value":"458159","label":"Pinchot University"},{"value":"167455","label":"Pine Manor College"},{"value":"174570","label":"Pine Technical & Community College"},{"value":"367097","label":"Pinnacle Career Institute-Lawrence"},{"value":"453109","label":"Pinnacle Career Institute-North Kansas City"},{"value":"177302","label":"Pinnacle Career Institute-South Kansas City"},{"value":"210076","label":"Pioneer Pacific College"},{"value":"199333","label":"Pitt Community College"},{"value":"155681","label":"Pittsburg State University"},{"value":"216782","label":"Pittsburgh Career Institute"},{"value":"215381","label":"Pittsburgh Institute of Aeronautics"},{"value":"215390","label":"Pittsburgh Institute of Mortuary Science Inc"},{"value":"215415","label":"Pittsburgh Technical Institute"},{"value":"215424","label":"Pittsburgh Theological Seminary"},{"value":"121257","label":"Pitzer College"},{"value":"260813","label":"Platt College-Aurora"},{"value":"207625","label":"Platt College-Central OKC"},{"value":"260789","label":"Platt College-Los Angeles"},{"value":"447379","label":"Platt College-Moore"},{"value":"445258","label":"Platt College-North OKC"},{"value":"432384","label":"Platt College-Ontario"},{"value":"480204","label":"Platt College-Riverside"},{"value":"121275","label":"Platt College-San Diego"},{"value":"245962","label":"Platt College-Tulsa"},{"value":"194499","label":"Plaza College"},{"value":"183080","label":"Plymouth State University"},{"value":"121309","label":"Point Loma Nazarene University"},{"value":"215442","label":"Point Park University"},{"value":"138868","label":"Point University"},{"value":"136516","label":"Polk State College"},{"value":"456481","label":"Polytechnic University of Puerto Rico-Miami"},{"value":"456490","label":"Polytechnic University of Puerto Rico-Orlando"},{"value":"190451","label":"Pomeroy College of Nursing at Crouse Hospital"},{"value":"121345","label":"Pomona College"},{"value":"243081","label":"Ponce Health Sciences University"},{"value":"243072","label":"Ponce Paramedical College Inc"},{"value":"241395","label":"Pontifical Catholic University of Puerto Rico-Arecibo"},{"value":"243586","label":"Pontifical Catholic University of Puerto Rico-Mayaguez"},{"value":"241410","label":"Pontifical Catholic University of Puerto Rico-Ponce"},{"value":"205027","label":"Pontifical College Josephinum"},{"value":"131405","label":"Pontifical Faculty of the Immaculate Conception at the Dominican House of Studies"},{"value":"455813","label":"Pontifical John Paul II Institute for Studies on Marriage and Family"},{"value":"167464","label":"Pope St John XXIII National Seminary"},{"value":"121363","label":"Porterville College"},{"value":"209746","label":"Portland Community College"},{"value":"209807","label":"Portland State University"},{"value":"130183","label":"Post University"},{"value":"237701","label":"Potomac State College of West Virginia University"},{"value":"148007","label":"Prairie State College"},{"value":"227526","label":"Prairie View A & M University"},{"value":"155715","label":"Pratt Community College"},{"value":"194578","label":"Pratt Institute-Main"},{"value":"218539","label":"Presbyterian College"},{"value":"105589","label":"Prescott College"},{"value":"219295","label":"Presentation College"},{"value":"163657","label":"Prince George's Community College"},{"value":"101958","label":"Prince Institute-Southeast"},{"value":"186122","label":"Princeton Theological Seminary"},{"value":"186131","label":"Princeton University"},{"value":"148016","label":"Principia College"},{"value":"215433","label":"Prism Career Institute-Upper Darby"},{"value":"437750","label":"Professional Golfers Career College"},{"value":"205054","label":"Professional Skills Institute"},{"value":"455770","label":"Providence Christian College"},{"value":"217402","label":"Providence College"},{"value":"380438","label":"Provo College"},{"value":"127884","label":"Pueblo Community College"},{"value":"241766","label":"Puerto Rico Conservatory of Music"},{"value":"107664","label":"Pulaski Technical College"},{"value":"152248","label":"Purdue University-Calumet Campus"},{"value":"243780","label":"Purdue University-Main Campus"},{"value":"152266","label":"Purdue University-North Central Campus"},{"value":"199412","label":"Queens University of Charlotte"},{"value":"167525","label":"Quincy College"},{"value":"148131","label":"Quincy University"},{"value":"130217","label":"Quinebaug Valley Community College"},{"value":"130226","label":"Quinnipiac University"},{"value":"167534","label":"Quinsigamond Community College"},{"value":"384421","label":"Rabbi Jacob Joseph School"},{"value":"194657","label":"Rabbinical Academy Mesivta Rabbi Chaim Berlin"},{"value":"194693","label":"Rabbinical College Beth Shraga"},{"value":"194666","label":"Rabbinical College Bobover Yeshiva Bnei Zion"},{"value":"186186","label":"Rabbinical College of America"},{"value":"194675","label":"Rabbinical College of Ch'san Sofer New York"},{"value":"194736","label":"Rabbinical College of Long Island"},{"value":"405854","label":"Rabbinical College of Ohr Shimon Yisroel"},{"value":"484871","label":"Rabbinical College Ohr Yisroel"},{"value":"205124","label":"Rabbinical College Telshe"},{"value":"194763","label":"Rabbinical Seminary of America"},{"value":"233277","label":"Radford University"},{"value":"481119","label":"Radians College"},{"value":"174604","label":"Rainy River Community College"},{"value":"186201","label":"Ramapo College of New Jersey"},{"value":"233301","label":"Randolph College"},{"value":"199421","label":"Randolph Community College"},{"value":"233295","label":"Randolph-Macon College"},{"value":"227687","label":"Ranger College"},{"value":"178891","label":"Ranken Technical College"},{"value":"233310","label":"Rappahannock Community College"},{"value":"186645","label":"Raritan Valley Community College"},{"value":"138309","label":"Rasmussen College-Florida"},{"value":"448673","label":"Rasmussen College-Illinois"},{"value":"175014","label":"Rasmussen College-Minnesota"},{"value":"200013","label":"Rasmussen College-North Dakota"},{"value":"450571","label":"Rasmussen College-Wisconsin"},{"value":"215585","label":"Reading Area Community College"},{"value":"215619","label":"Reconstructionist Rabbinical College"},{"value":"127909","label":"Red Rocks Community College"},{"value":"207069","label":"Redlands Community College"},{"value":"126605","label":"Redstone College"},{"value":"209922","label":"Reed College"},{"value":"117052","label":"Reedley College"},{"value":"215628","label":"Reformed Presbyterian Theological Seminary"},{"value":"105659","label":"Refrigeration School Inc"},{"value":"231651","label":"Regent University"},{"value":"167598","label":"Regis College"},{"value":"127918","label":"Regis University"},{"value":"101994","label":"Reid State Technical College"},{"value":"140872","label":"Reinhardt University"},{"value":"475033","label":"Relay Graduate School of Education"},{"value":"457183","label":"Remington College of Nursing Orlando"},{"value":"440271","label":"Remington College-Baton Rouge Campus"},{"value":"375416","label":"Remington College-Cleveland Campus"},{"value":"223463","label":"Remington College-Dallas Campus"},{"value":"377111","label":"Remington College-Fort Worth Campus"},{"value":"460783","label":"Remington College-Heathrow Campus"},{"value":"372958","label":"Remington College-Honolulu Campus"},{"value":"380094","label":"Remington College-Houston Campus"},{"value":"160524","label":"Remington College-Lafayette Campus"},{"value":"438869","label":"Remington College-Little Rock Campus"},{"value":"412599","label":"Remington College-Memphis Campus"},{"value":"366535","label":"Remington College-Mobile Campus"},{"value":"445249","label":"Remington College-Nashville Campus"},{"value":"445203","label":"Remington College-North Houston Campus"},{"value":"451866","label":"Remington College-Shreveport Campus"},{"value":"135939","label":"Remington College-Tampa Campus"},{"value":"148256","label":"Rend Lake College"},{"value":"129428","label":"Rensselaer Hartford Graduate Center Inc"},{"value":"194824","label":"Rensselaer Polytechnic Institute"},{"value":"236382","label":"Renton Technical College"},{"value":"178989","label":"Research College of Nursing"},{"value":"149763","label":"Resurrection University"},{"value":"217420","label":"Rhode Island College"},{"value":"217493","label":"Rhode Island School of Design"},{"value":"221351","label":"Rhodes College"},{"value":"227757","label":"Rice University"},{"value":"107743","label":"Rich Mountain Community College"},{"value":"233338","label":"Richard Bland College of the College of William and Mary"},{"value":"227766","label":"Richland College"},{"value":"148292","label":"Richland Community College"},{"value":"199449","label":"Richmond Community College"},{"value":"441104","label":"Richmont Graduate University"},{"value":"186283","label":"Rider University"},{"value":"175236","label":"Ridgewater College"},{"value":"136774","label":"Ringling College of Art and Design"},{"value":"475185","label":"Rio Grande Bible Institute"},{"value":"121886","label":"Rio Hondo College"},{"value":"105668","label":"Rio Salado College"},{"value":"239628","label":"Ripon College"},{"value":"436304","label":"River Parishes Community College"},{"value":"183114","label":"River Valley Community College"},{"value":"173063","label":"Riverland Community College"},{"value":"121901","label":"Riverside City College"},{"value":"233408","label":"Riverside College of Health Careers"},{"value":"183211","label":"Rivier University"},{"value":"221397","label":"Roane State Community College"},{"value":"233426","label":"Roanoke College"},{"value":"199467","label":"Roanoke-Chowan Community College"},{"value":"215655","label":"Robert Morris University"},{"value":"148335","label":"Robert Morris University Illinois"},{"value":"194958","label":"Roberts Wesleyan College"},{"value":"199476","label":"Robeson Community College"},{"value":"170967","label":"Rochester College"},{"value":"174738","label":"Rochester Community and Technical College"},{"value":"195003","label":"Rochester Institute of Technology"},{"value":"148380","label":"Rock Valley College"},{"value":"195049","label":"Rockefeller University"},{"value":"148405","label":"Rockford University"},{"value":"179043","label":"Rockhurst University"},{"value":"199485","label":"Rockingham Community College"},{"value":"195058","label":"Rockland Community College"},{"value":"180595","label":"Rocky Mountain College"},{"value":"127945","label":"Rocky Mountain College of Art and Design"},{"value":"475495","label":"Rocky Mountain University of Health Professions"},{"value":"480790","label":"Rocky Vista University"},{"value":"217518","label":"Roger Williams University"},{"value":"409616","label":"Roger Williams University School of Law"},{"value":"207661","label":"Rogers State University"},{"value":"209940","label":"Rogue Community College"},{"value":"136950","label":"Rollins College"},{"value":"148487","label":"Roosevelt University"},{"value":"145558","label":"Rosalind Franklin University of Medicine and Science"},{"value":"207670","label":"Rose State College"},{"value":"439899","label":"Rosedale Bible College"},{"value":"215682","label":"Rosedale Technical Institute"},{"value":"152318","label":"Rose-Hulman Institute of Technology"},{"value":"445735","label":"Roseman University of Health Sciences"},{"value":"215691","label":"Rosemont College"},{"value":"452081","label":"Ross College-Sylvania"},{"value":"183877","label":"Rowan College at Burlington County"},{"value":"184791","label":"Rowan College at Gloucester County"},{"value":"184782","label":"Rowan University"},{"value":"199494","label":"Rowan-Cabarrus Community College"},{"value":"167631","label":"Roxbury Community College"},{"value":"148511","label":"Rush University"},{"value":"176318","label":"Rust College"},{"value":"186371","label":"Rutgers University-Camden"},{"value":"186380","label":"Rutgers University-New Brunswick"},{"value":"186399","label":"Rutgers University-Newark"},{"value":"449506","label":"SABER College"},{"value":"122180","label":"Sacramento City College"},{"value":"172033","label":"Sacred Heart Major Seminary"},{"value":"239637","label":"Sacred Heart School of Theology"},{"value":"130253","label":"Sacred Heart University"},{"value":"122205","label":"Saddleback College"},{"value":"476948","label":"SAE Institute of Technology-Atlanta"},{"value":"446525","label":"SAE Institute of Technology-Nashville"},{"value":"410520","label":"Sage College"},{"value":"441070","label":"Saginaw Chippewa Tribal College"},{"value":"172051","label":"Saginaw Valley State University"},{"value":"154235","label":"Saint Ambrose University"},{"value":"183239","label":"Saint Anselm College"},{"value":"149028","label":"Saint Anthony College of Nursing"},{"value":"148876","label":"Saint Augustine College"},{"value":"199582","label":"Saint Augustine's University"},{"value":"157632","label":"Saint Catharine College"},{"value":"216047","label":"Saint Charles Borromeo Seminary-Overbrook"},{"value":"174783","label":"Saint Cloud State University"},{"value":"227845","label":"Saint Edward's University"},{"value":"195702","label":"Saint Elizabeth College of Nursing-Utica"},{"value":"148575","label":"Saint Francis Medical Center College of Nursing"},{"value":"215743","label":"Saint Francis University"},{"value":"195720","label":"Saint John Fisher College"},{"value":"137272","label":"Saint John Vianney College Seminary"},{"value":"137281","label":"Saint Johns River State College"},{"value":"167677","label":"Saint John's Seminary"},{"value":"174792","label":"Saint Johns University"},{"value":"160409","label":"Saint Joseph Seminary College"},{"value":"152363","label":"Saint Josephs College"},{"value":"161518","label":"Saint Joseph's College of Maine"},{"value":"195544","label":"Saint Joseph's College-New York"},{"value":"215770","label":"Saint Joseph's University"},{"value":"137032","label":"Saint Leo University"},{"value":"179256","label":"Saint Louis Christian College"},{"value":"179308","label":"Saint Louis Community College"},{"value":"179159","label":"Saint Louis University"},{"value":"179450","label":"Saint Luke's College of Health Sciences"},{"value":"236452","label":"Saint Martin's University"},{"value":"152381","label":"Saint Mary-of-the-Woods College"},{"value":"152390","label":"Saint Mary's College"},{"value":"123554","label":"Saint Mary's College of California"},{"value":"174817","label":"Saint Mary's University of Minnesota"},{"value":"152451","label":"Saint Meinrad School of Theology"},{"value":"231059","label":"Saint Michael's College"},{"value":"239716","label":"Saint Norbert College"},{"value":"175041","label":"Saint Paul College"},{"value":"179317","label":"Saint Paul School of Theology"},{"value":"186432","label":"Saint Peter's University"},{"value":"215798","label":"Saint Vincent College"},{"value":"136701","label":"Saint Vincent de Paul Regional Seminary"},{"value":"215813","label":"Saint Vincent Seminary"},{"value":"195580","label":"Saint Vladimirs Orthodox Theological Seminary"},{"value":"148627","label":"Saint Xavier University"},{"value":"199607","label":"Salem College"},{"value":"186469","label":"Salem Community College"},{"value":"237783","label":"Salem International University"},{"value":"167729","label":"Salem State University"},{"value":"155830","label":"Salina Area Technical College"},{"value":"163851","label":"Salisbury University"},{"value":"180647","label":"Salish Kootenai College"},{"value":"230746","label":"Salt Lake Community College"},{"value":"466523","label":"Salter College-Chicopee"},{"value":"167738","label":"Salter College-West Boylston"},{"value":"214564","label":"Salus University"},{"value":"217536","label":"Salve Regina University"},{"value":"227881","label":"Sam Houston State University"},{"value":"195289","label":"Samaritan Hospital School of Nursing"},{"value":"102049","label":"Samford University"},{"value":"199625","label":"Sampson Community College"},{"value":"122296","label":"Samuel Merritt University"},{"value":"227924","label":"San Antonio College"},{"value":"123527","label":"San Bernardino Valley College"},{"value":"112084","label":"San Diego Christian College"},{"value":"122339","label":"San Diego City College"},{"value":"122375","label":"San Diego Mesa College"},{"value":"122384","label":"San Diego Miramar College"},{"value":"122409","label":"San Diego State University"},{"value":"122454","label":"San Francisco Art Institute"},{"value":"122506","label":"San Francisco Conservatory of Music"},{"value":"122597","label":"San Francisco State University"},{"value":"122603","label":"San Francisco Theological Seminary"},{"value":"227979","label":"San Jacinto Community College"},{"value":"122649","label":"San Joaquin College of Law"},{"value":"122658","label":"San Joaquin Delta College"},{"value":"122685","label":"San Joaquin Valley College-Visalia"},{"value":"122746","label":"San Jose City College"},{"value":"122755","label":"San Jose State University"},{"value":"430670","label":"San Juan Bautista School of Medicine"},{"value":"188100","label":"San Juan College"},{"value":"199634","label":"Sandhills Community College"},{"value":"481535","label":"Sanford Burnham Prybis Medical Discovery Institute"},{"value":"420495","label":"Sanford-Brown College-Atlanta"},{"value":"475291","label":"Sanford-Brown College-Brooklyn Center"},{"value":"146010","label":"Sanford-Brown College-Chicago"},{"value":"404514","label":"Sanford-Brown College-Dallas"},{"value":"179201","label":"Sanford-Brown College-Fenton"},{"value":"404499","label":"Sanford-Brown College-Houston"},{"value":"446792","label":"Sanford-Brown College-Las Vegas"},{"value":"174394","label":"Sanford-Brown College-Mendota Heights"},{"value":"420501","label":"Sanford-Brown College-Middleburg Heights"},{"value":"456296","label":"Sanford-Brown College-Online"},{"value":"440925","label":"Sanford-Brown College-Orlando"},{"value":"450465","label":"Sanford-Brown College-San Antonio-San Antonio"},{"value":"446808","label":"Sanford-Brown College-Seattle"},{"value":"134680","label":"Sanford-Brown College-Tampa"},{"value":"234216","label":"Sanford-Brown College-Tysons Corner"},{"value":"385008","label":"Sanford-Brown Institute-Ft Lauderdale"},{"value":"404505","label":"Sanford-Brown Institute-Jacksonville"},{"value":"121619","label":"Santa Ana College"},{"value":"122834","label":"Santa Barbara Business College-Bakersfield"},{"value":"122852","label":"Santa Barbara Business College-Santa Maria"},{"value":"433420","label":"Santa Barbara Business College-Ventura"},{"value":"122889","label":"Santa Barbara City College"},{"value":"122931","label":"Santa Clara University"},{"value":"137096","label":"Santa Fe College"},{"value":"188137","label":"Santa Fe Community College"},{"value":"188146","label":"Santa Fe University of Art and Design"},{"value":"122977","label":"Santa Monica College"},{"value":"123013","label":"Santa Rosa Junior College"},{"value":"399212","label":"Santiago Canyon College"},{"value":"195304","label":"Sarah Lawrence College"},{"value":"148672","label":"Sauk Valley Community College"},{"value":"140951","label":"Savannah College of Art and Design"},{"value":"140960","label":"Savannah State University"},{"value":"140942","label":"Savannah Technical College"},{"value":"123095","label":"Saybrook University"},{"value":"192156","label":"SBI Campus-An Affiliate of Sanford-Brown"},{"value":"195322","label":"Schenectady County Community College"},{"value":"404338","label":"Schiller International University"},{"value":"143048","label":"School of the Art Institute of Chicago"},{"value":"166984","label":"School of the Museum of Fine Arts-Boston"},{"value":"197151","label":"School of Visual Arts"},{"value":"172200","label":"Schoolcraft College"},{"value":"228042","label":"Schreiner University"},{"value":"105747","label":"Scottsdale Community College"},{"value":"123165","label":"Scripps College"},{"value":"236513","label":"Seattle Central College"},{"value":"439914","label":"Seattle Institute of Oriental Medicine"},{"value":"236577","label":"Seattle Pacific University"},{"value":"236595","label":"Seattle University"},{"value":"102058","label":"Selma University"},{"value":"243498","label":"Seminario Evangelico de Puerto Rico"},{"value":"207740","label":"Seminole State College"},{"value":"137209","label":"Seminole State College of Florida"},{"value":"232885","label":"Sentara College of Health Sciences"},{"value":"475839","label":"Sessions College for Professional Design"},{"value":"186584","label":"Seton Hall University"},{"value":"215947","label":"Seton Hill University"},{"value":"221519","label":"Sewanee-The University of the South"},{"value":"155858","label":"Seward County Community College and Area Technical School"},{"value":"123280","label":"Shasta Bible College and Graduate School"},{"value":"123299","label":"Shasta College"},{"value":"199643","label":"Shaw University"},{"value":"148821","label":"Shawnee Community College"},{"value":"205443","label":"Shawnee State University"},{"value":"102067","label":"Shelton State Community College"},{"value":"233541","label":"Shenandoah University"},{"value":"237792","label":"Shepherd University"},{"value":"461485","label":"Shepherds Theological Seminary"},{"value":"240666","label":"Sheridan College"},{"value":"218751","label":"Sherman College of Straight Chiropractic"},{"value":"480499","label":"Shiloh University"},{"value":"148849","label":"Shimer College"},{"value":"216010","label":"Shippensburg University of Pennsylvania"},{"value":"195438","label":"Sh'or Yoshuv Rabbinical College"},{"value":"236610","label":"Shoreline Community College"},{"value":"107840","label":"Shorter College"},{"value":"140988","label":"Shorter University"},{"value":"448309","label":"Shorter University-College of Adult & Professional Programs"},{"value":"195474","label":"Siena College"},{"value":"172264","label":"Siena Heights University"},{"value":"123341","label":"Sierra College"},{"value":"182458","label":"Sierra Nevada College"},{"value":"239743","label":"Silver Lake College of the Holy Family"},{"value":"167783","label":"Simmons College"},{"value":"461759","label":"Simmons College of Kentucky"},{"value":"154350","label":"Simpson College"},{"value":"123457","label":"Simpson University"},{"value":"205470","label":"Sinclair Community College"},{"value":"219374","label":"Sinte Gleska University"},{"value":"219240","label":"Sioux Falls Seminary"},{"value":"219408","label":"Sisseton Wahpeton College"},{"value":"231068","label":"SIT Graduate Institute"},{"value":"200466","label":"Sitting Bull College"},{"value":"236638","label":"Skagit Valley College"},{"value":"195526","label":"Skidmore College"},{"value":"123509","label":"Skyline College"},{"value":"261931","label":"Skyline College-Roanoke"},{"value":"216038","label":"Slippery Rock University of Pennsylvania"},{"value":"167835","label":"Smith College"},{"value":"102076","label":"Snead State Community College"},{"value":"230597","label":"Snow College"},{"value":"110778","label":"Sofia University"},{"value":"163921","label":"Sojourner-Douglass College"},{"value":"399911","label":"Soka University of America"},{"value":"123563","label":"Solano Community College"},{"value":"459356","label":"SOLEX College"},{"value":"157711","label":"Somerset Community College"},{"value":"123572","label":"Sonoma State University"},{"value":"481094","label":"Sotheby's Institute of Art-NY"},{"value":"107974","label":"South Arkansas Community College"},{"value":"123633","label":"South Baylo University"},{"value":"218733","label":"South Carolina State University"},{"value":"173911","label":"South Central College"},{"value":"160913","label":"South Central Louisiana Technical College-Young Memorial Campus"},{"value":"123642","label":"South Coast College"},{"value":"220552","label":"South College"},{"value":"198242","label":"South College-Asheville"},{"value":"219347","label":"South Dakota School of Mines and Technology"},{"value":"219356","label":"South Dakota State University"},{"value":"366003","label":"South Florida Bible College and Theological Seminary"},{"value":"137315","label":"South Florida State College"},{"value":"482699","label":"South Georgia State College"},{"value":"141006","label":"South Georgia Technical College"},{"value":"216083","label":"South Hills School of Business & Technology"},{"value":"434061","label":"South Louisiana Community College"},{"value":"105792","label":"South Mountain Community College"},{"value":"197850","label":"South Piedmont Community College"},{"value":"228158","label":"South Plains College"},{"value":"236656","label":"South Puget Sound Community College"},{"value":"236504","label":"South Seattle College"},{"value":"149365","label":"South Suburban College"},{"value":"409315","label":"South Texas College"},{"value":"228194","label":"South Texas College of Law"},{"value":"468006","label":"South University-Accelerated Graduate Programs"},{"value":"480073","label":"South University-Austin"},{"value":"480082","label":"South University-Cleveland"},{"value":"251312","label":"South University-Columbia"},{"value":"481720","label":"South University-High Point"},{"value":"101116","label":"South University-Montgomery"},{"value":"468024","label":"South University-Novi"},{"value":"459259","label":"South University–Richmond"},{"value":"139579","label":"South University-Savannah"},{"value":"475121","label":"South University–Savannah Online"},{"value":"449898","label":"South University-Tampa"},{"value":"224776","label":"South University-The Art Institute of Dallas"},{"value":"468015","label":"South University-The Art Institute of Fort Worth"},{"value":"459268","label":"South University–Virginia Beach"},{"value":"133465","label":"South University-West Palm Beach"},{"value":"156338","label":"Southcentral Kentucky Community and Technical College"},{"value":"107637","label":"Southeast Arkansas College"},{"value":"181640","label":"Southeast Community College Area"},{"value":"157739","label":"Southeast Kentucky Community and Technical College"},{"value":"417734","label":"Southeast Missouri Hospital College of Nursing and Health Sciences"},{"value":"179557","label":"Southeast Missouri State University"},{"value":"219426","label":"Southeast Technical Institute"},{"value":"176336","label":"Southeastern Baptist College"},{"value":"199759","label":"Southeastern Baptist Theological Seminary"},{"value":"102261","label":"Southeastern Bible College"},{"value":"443270","label":"Southeastern College-Jacksonville"},{"value":"428170","label":"Southeastern College-West Palm Beach"},{"value":"154378","label":"Southeastern Community College-West Burlington"},{"value":"199722","label":"Southeastern Community College-Whiteville"},{"value":"148937","label":"Southeastern Illinois College"},{"value":"160612","label":"Southeastern Louisiana University"},{"value":"207847","label":"Southeastern Oklahoma State University"},{"value":"368911","label":"Southeastern Technical College"},{"value":"137564","label":"Southeastern University"},{"value":"221661","label":"Southern Adventist University"},{"value":"107983","label":"Southern Arkansas University Main Campus"},{"value":"107992","label":"Southern Arkansas University Tech"},{"value":"123952","label":"Southern California Institute of Architecture"},{"value":"399869","label":"Southern California Institute of Technology"},{"value":"117575","label":"Southern California Seminary"},{"value":"117672","label":"Southern California University of Health Sciences"},{"value":"459222","label":"Southern California University SOMA"},{"value":"221670","label":"Southern College of Optometry"},{"value":"130493","label":"Southern Connecticut State University"},{"value":"139986","label":"Southern Crescent Technical College"},{"value":"149222","label":"Southern Illinois University-Carbondale"},{"value":"149231","label":"Southern Illinois University-Edwardsville"},{"value":"161545","label":"Southern Maine Community College"},{"value":"228246","label":"Southern Methodist University"},{"value":"206862","label":"Southern Nazarene University"},{"value":"183026","label":"Southern New Hampshire University"},{"value":"210146","label":"Southern Oregon University"},{"value":"141097","label":"Southern Polytechnic State University"},{"value":"205966","label":"Southern State Community College"},{"value":"366553","label":"Southern Technical College-Fort Myers"},{"value":"446552","label":"Southern Technical College-Orlando"},{"value":"251260","label":"Southern Union State Community College"},{"value":"160621","label":"Southern University and A & M College"},{"value":"160630","label":"Southern University at New Orleans"},{"value":"160649","label":"Southern University at Shreveport"},{"value":"440916","label":"Southern University Law Center"},{"value":"230603","label":"Southern Utah University"},{"value":"231086","label":"Southern Vermont College"},{"value":"233611","label":"Southern Virginia University"},{"value":"217776","label":"Southern Wesleyan University"},{"value":"237817","label":"Southern West Virginia Community and Technical College"},{"value":"233082","label":"Southside Regional Medical Center Professional Schools"},{"value":"233639","label":"Southside Virginia Community College"},{"value":"413644","label":"Southwest Acupuncture College-Albuquerque"},{"value":"436261","label":"Southwest Acupuncture College-Boulder"},{"value":"366605","label":"Southwest Acupuncture College-Santa Fe"},{"value":"179326","label":"Southwest Baptist University"},{"value":"420246","label":"Southwest College of Naturopathic Medicine & Health Sciences"},{"value":"382911","label":"Southwest Collegiate Institute for the Deaf"},{"value":"141158","label":"Southwest Georgia Technical College"},{"value":"442879","label":"Southwest Institute of Healing Arts"},{"value":"175078","label":"Southwest Minnesota State University"},{"value":"176354","label":"Southwest Mississippi Community College"},{"value":"221485","label":"Southwest Tennessee Community College"},{"value":"228316","label":"Southwest Texas Junior College"},{"value":"451556","label":"Southwest University at El Paso"},{"value":"402776","label":"Southwest University of Visual Arts-Albuquerque"},{"value":"104188","label":"Southwest University of Visual Arts-Tucson"},{"value":"233648","label":"Southwest Virginia Community College"},{"value":"239910","label":"Southwest Wisconsin Technical College"},{"value":"228468","label":"Southwestern Adventist University"},{"value":"228325","label":"Southwestern Assemblies of God University"},{"value":"228486","label":"Southwestern Christian College"},{"value":"207856","label":"Southwestern Christian University"},{"value":"123800","label":"Southwestern College-Chula Vista"},{"value":"188207","label":"Southwestern College-Santa Fe"},{"value":"155900","label":"Southwestern College-Winfield"},{"value":"154396","label":"Southwestern Community College-Creston"},{"value":"199731","label":"Southwestern Community College-Sylva"},{"value":"143215","label":"Southwestern Illinois College"},{"value":"188216","label":"Southwestern Indian Polytechnic Institute"},{"value":"123970","label":"Southwestern Law School"},{"value":"172307","label":"Southwestern Michigan College"},{"value":"207865","label":"Southwestern Oklahoma State University"},{"value":"210155","label":"Southwestern Oregon Community College"},{"value":"228343","label":"Southwestern University"},{"value":"160579","label":"SOWELA Technical Community College"},{"value":"157757","label":"Spalding University"},{"value":"207254","label":"Spartan College of Aeronautics and Technology"},{"value":"218830","label":"Spartanburg Community College"},{"value":"218821","label":"Spartanburg Methodist College"},{"value":"141060","label":"Spelman College"},{"value":"433563","label":"Spencerian College-Lexington"},{"value":"157766","label":"Spencerian College-Louisville"},{"value":"148982","label":"Spertus College"},{"value":"236692","label":"Spokane Community College"},{"value":"236708","label":"Spokane Falls Community College"},{"value":"148991","label":"Spoon River College"},{"value":"172334","label":"Spring Arbor University"},{"value":"102234","label":"Spring Hill College"},{"value":"167899","label":"Springfield College"},{"value":"475273","label":"Springfield College-School of Professional and Continuing Studies"},{"value":"167905","label":"Springfield Technical Community College"},{"value":"199698","label":"St Andrews University"},{"value":"195155","label":"St Bernard's School of Theology and Ministry"},{"value":"195164","label":"St Bonaventure University"},{"value":"175005","label":"St Catherine University"},{"value":"262031","label":"St Charles Community College"},{"value":"172291","label":"St Clair County Community College"},{"value":"174756","label":"St Cloud Technical and Community College"},{"value":"195173","label":"St Francis College"},{"value":"163976","label":"St John's College"},{"value":"123855","label":"St John's Seminary"},{"value":"195809","label":"St John's University-New York"},{"value":"183248","label":"St Joseph School of Nursing-Nashua"},{"value":"195191","label":"St Joseph's College of Nursing at St Joseph's Hospital Health Center"},{"value":"195216","label":"St Lawrence University"},{"value":"442426","label":"St Louis College of Health Careers-Fenton"},{"value":"179511","label":"St Louis College of Health Careers-St Louis"},{"value":"179265","label":"St Louis College of Pharmacy"},{"value":"154262","label":"St Luke's College"},{"value":"163912","label":"St Mary's College of Maryland"},{"value":"228149","label":"St Mary's University"},{"value":"174844","label":"St Olaf College"},{"value":"189811","label":"St Paul's School of Nursing-Queens"},{"value":"195784","label":"St Paul's School of Nursing-Staten Island"},{"value":"137078","label":"St Petersburg College"},{"value":"227854","label":"St Philip's College"},{"value":"137476","label":"St Thomas University"},{"value":"130448","label":"St Vincent's College"},{"value":"207689","label":"St. Gregory's University"},{"value":"245652","label":"St. John's College"},{"value":"148593","label":"St. John's College-Department of Nursing"},{"value":"195243","label":"St. Thomas Aquinas College"},{"value":"446561","label":"Stanbridge College"},{"value":"483814","label":"Standard Healthcare Services-College of Nursing"},{"value":"243744","label":"Stanford University"},{"value":"199740","label":"Stanly Community College"},{"value":"205841","label":"Stark State College"},{"value":"123916","label":"Starr King School for Ministry"},{"value":"135391","label":"State College of Florida-Manatee-Sarasota"},{"value":"179539","label":"State Fair Community College"},{"value":"177977","label":"State Technical College of Missouri"},{"value":"196176","label":"State University of New York at New Paltz"},{"value":"448600","label":"Stautzenberger College-Brecksville"},{"value":"205887","label":"Stautzenberger College-Maumee"},{"value":"228431","label":"Stephen F Austin State University"},{"value":"179548","label":"Stephens College"},{"value":"231095","label":"Sterling College-Craftsbury Common"},{"value":"155937","label":"Sterling College-Sterling"},{"value":"137546","label":"Stetson University"},{"value":"186867","label":"Stevens Institute of Technology"},{"value":"460899","label":"Stevens-Henager College-Boise"},{"value":"474906","label":"Stevens-Henager College-Idaho Falls"},{"value":"446677","label":"Stevens-Henager College-Logan"},{"value":"438151","label":"Stevens-Henager College-Murray"},{"value":"230630","label":"Stevens-Henager College-Orem"},{"value":"477950","label":"Stevens-Henager College-St. George"},{"value":"230621","label":"Stevens-Henager College-West Haven"},{"value":"164173","label":"Stevenson University"},{"value":"178767","label":"Stevens-The Institute of Business & Arts"},{"value":"102270","label":"Stillman College"},{"value":"186876","label":"Stockton University"},{"value":"366340","label":"Stone Child College"},{"value":"167996","label":"Stonehill College"},{"value":"196097","label":"Stony Brook University"},{"value":"438498","label":"Stratford University"},{"value":"450377","label":"Strayer University-Alabama"},{"value":"458885","label":"Strayer University-Arkansas"},{"value":"450298","label":"Strayer University-Delaware"},{"value":"131803","label":"Strayer University-District of Columbia"},{"value":"449038","label":"Strayer University-Florida"},{"value":"458919","label":"Strayer University-Georgia"},{"value":"459994","label":"Strayer University-Global Region"},{"value":"458937","label":"Strayer University-Louisiana"},{"value":"430184","label":"Strayer University-Maryland"},{"value":"458955","label":"Strayer University-Mississippi"},{"value":"453215","label":"Strayer University-New Jersey"},{"value":"453163","label":"Strayer University-North Carolina"},{"value":"443784","label":"Strayer University-Pennsylvania"},{"value":"458964","label":"Strayer University-South Carolina"},{"value":"443766","label":"Strayer University-Tennessee"},{"value":"458973","label":"Strayer University-Texas"},{"value":"233684","label":"Strayer University-Virginia"},{"value":"456621","label":"Strayer University-West Virginia"},{"value":"366395","label":"Suffolk County Community College"},{"value":"168005","label":"Suffolk University"},{"value":"228501","label":"Sul Ross State University"},{"value":"157270","label":"Sullivan College of Technology and Design"},{"value":"195988","label":"Sullivan County Community College"},{"value":"157793","label":"Sullivan University"},{"value":"447953","label":"SUM Bible College and Theological Seminary"},{"value":"181543","label":"Summit Christian College"},{"value":"208512","label":"Sumner College"},{"value":"196060","label":"SUNY at Albany"},{"value":"196079","label":"SUNY at Binghamton"},{"value":"196158","label":"SUNY at Fredonia"},{"value":"196219","label":"SUNY at Purchase College"},{"value":"189547","label":"SUNY Broome Community College"},{"value":"196130","label":"SUNY Buffalo State"},{"value":"196121","label":"SUNY College at Brockport"},{"value":"196149","label":"SUNY College at Cortland"},{"value":"196167","label":"SUNY College at Geneseo"},{"value":"196237","label":"SUNY College at Old Westbury"},{"value":"196194","label":"SUNY College at Oswego"},{"value":"196246","label":"SUNY College at Plattsburgh"},{"value":"196200","label":"SUNY College at Potsdam"},{"value":"196033","label":"SUNY College of Agriculture and Technology at Cobleskill"},{"value":"196103","label":"SUNY College of Environmental Science and Forestry"},{"value":"196228","label":"SUNY College of Optometry"},{"value":"196006","label":"SUNY College of Technology at Alfred"},{"value":"196015","label":"SUNY College of Technology at Canton"},{"value":"196024","label":"SUNY College of Technology at Delhi"},{"value":"196255","label":"SUNY Downstate Medical Center"},{"value":"196264","label":"SUNY Empire State College"},{"value":"196291","label":"SUNY Maritime College"},{"value":"196185","label":"SUNY Oneonta"},{"value":"196112","label":"SUNY Polytechnic Institute"},{"value":"197294","label":"SUNY Westchester Community College"},{"value":"199768","label":"Surry Community College"},{"value":"216278","label":"Susquehanna University"},{"value":"247603","label":"Sussex County Community College"},{"value":"216287","label":"Swarthmore College"},{"value":"196389","label":"Swedish Institute a College of Health Sciences"},{"value":"233718","label":"Sweet Briar College"},{"value":"196413","label":"Syracuse University"},{"value":"155973","label":"Tabor College"},{"value":"236753","label":"Tacoma Community College"},{"value":"124113","label":"Taft College"},{"value":"454689","label":"Taft University System"},{"value":"102298","label":"Talladega College"},{"value":"137759","label":"Tallahassee Community College"},{"value":"137777","label":"Talmudic College of Florida"},{"value":"186900","label":"Talmudical Academy-New Jersey"},{"value":"196440","label":"Talmudical Institute of Upstate New York"},{"value":"451404","label":"Talmudical Seminary of Bobov"},{"value":"196431","label":"Talmudical Seminary Oholei Torah"},{"value":"216311","label":"Talmudical Yeshiva of Philadelphia"},{"value":"228529","label":"Tarleton State University"},{"value":"228547","label":"Tarrant County College District"},{"value":"149310","label":"Taylor Business Institute"},{"value":"449524","label":"Taylor College"},{"value":"152530","label":"Taylor University"},{"value":"196468","label":"Teachers College at Columbia University"},{"value":"196477","label":"Technical Career Institutes"},{"value":"217712","label":"Technical College of the Lowcountry"},{"value":"149329","label":"Telshe Yeshiva-Chicago"},{"value":"228608","label":"Temple College"},{"value":"216339","label":"Temple University"},{"value":"221838","label":"Tennessee State University"},{"value":"221847","label":"Tennessee Technological University"},{"value":"221856","label":"Tennessee Temple University"},{"value":"221731","label":"Tennessee Wesleyan College"},{"value":"206011","label":"Terra State Community College"},{"value":"228699","label":"Texarkana College"},{"value":"226152","label":"Texas A & M International University"},{"value":"483036","label":"Texas A & M University-Central Texas"},{"value":"228723","label":"Texas A & M University-College Station"},{"value":"224554","label":"Texas A & M University-Commerce"},{"value":"224147","label":"Texas A & M University-Corpus Christi"},{"value":"228705","label":"Texas A & M University-Kingsville"},{"value":"224545","label":"Texas A & M University-Texarkana"},{"value":"228866","label":"Texas Chiropractic College Foundation Inc"},{"value":"228875","label":"Texas Christian University"},{"value":"228884","label":"Texas College"},{"value":"441487","label":"Texas County Technical College"},{"value":"430704","label":"Texas Health and Science University"},{"value":"228981","label":"Texas Lutheran University"},{"value":"229063","label":"Texas Southern University"},{"value":"229319","label":"Texas State Technical College-Harlingen"},{"value":"408394","label":"Texas State Technical College-Marshall"},{"value":"228680","label":"Texas State Technical College-Waco"},{"value":"229328","label":"Texas State Technical College-West Texas"},{"value":"228459","label":"Texas State University"},{"value":"229115","label":"Texas Tech University"},{"value":"229337","label":"Texas Tech University Health Sciences Center"},{"value":"229160","label":"Texas Wesleyan University"},{"value":"229179","label":"Texas Woman's University"},{"value":"216296","label":"Thaddeus Stevens College of Technology"},{"value":"138813","label":"The Art Institute of Atlanta"},{"value":"451820","label":"The Art Institute of Austin"},{"value":"450085","label":"The Art Institute of Charleston"},{"value":"197832","label":"The Art Institute of Charlotte"},{"value":"200624","label":"The Art Institute of Cincinnati-AIC College of Design"},{"value":"126702","label":"The Art Institute of Colorado"},{"value":"132338","label":"The Art Institute of Fort Lauderdale"},{"value":"222938","label":"The Art Institute of Houston"},{"value":"448345","label":"The Art Institute of Indianapolis"},{"value":"182111","label":"The Art Institute of Las Vegas"},{"value":"451796","label":"The Art Institute of Michigan"},{"value":"365055","label":"The Art Institute of New York City"},{"value":"446668","label":"The Art Institute of Ohio-Cincinnati"},{"value":"210942","label":"The Art Institute of Philadelphia"},{"value":"428444","label":"The Art Institute of Phoenix"},{"value":"210960","label":"The Art Institute of Pittsburgh"},{"value":"451662","label":"The Art Institute of Pittsburgh-Online Division"},{"value":"208239","label":"The Art Institute of Portland"},{"value":"452027","label":"The Art Institute of Raleigh-Durham"},{"value":"450049","label":"The Art Institute of Salt Lake City"},{"value":"458982","label":"The Art Institute of San Antonio"},{"value":"234492","label":"The Art Institute of Seattle"},{"value":"482398","label":"The Art Institute of St Louis"},{"value":"449010","label":"The Art Institute of Tennessee-Nashville"},{"value":"444927","label":"The Art Institute of Tucson"},{"value":"458496","label":"The Art Institute of Virginia Beach"},{"value":"440341","label":"The Art Institute of Washington"},{"value":"456010","label":"The Art Institute of Washington-Dulles"},{"value":"470092","label":"The Art Institute of Wisconsin"},{"value":"452018","label":"The Art Institutes International–Kansas City"},{"value":"173887","label":"The Art Institutes International-Minnesota"},{"value":"210906","label":"The Art Institutes of York-PA"},{"value":"132408","label":"The Baptist College of Florida"},{"value":"164933","label":"The Boston Conservatory"},{"value":"111188","label":"The California Maritime Academy"},{"value":"143978","label":"The Chicago School of Professional Psychology at Chicago"},{"value":"455433","label":"The Chicago School of Professional Psychology at Irvine"},{"value":"455664","label":"The Chicago School of Professional Psychology at Los Angeles"},{"value":"459745","label":"The Chicago School of Professional Psychology at Washington DC"},{"value":"455682","label":"The Chicago School of Professional Psychology at Westwood"},{"value":"201821","label":"The Christ College of Nursing and Health Sciences"},{"value":"437635","label":"The College of Health Care Professions-Austin"},{"value":"480824","label":"The College of Health Care Professions-Dallas"},{"value":"480833","label":"The College of Health Care Professions-Fort Worth"},{"value":"142294","label":"The College of Idaho"},{"value":"187134","label":"The College of New Jersey"},{"value":"193645","label":"The College of New Rochelle"},{"value":"195234","label":"The College of Saint Rose"},{"value":"174899","label":"The College of Saint Scholastica"},{"value":"197285","label":"The College of Westchester"},{"value":"206589","label":"The College of Wooster"},{"value":"456542","label":"The Commonwealth Medical College"},{"value":"434672","label":"The Community College of Baltimore County"},{"value":"430485","label":"The Creative Center"},{"value":"235167","label":"The Evergreen State College"},{"value":"191320","label":"The General Theological Seminary"},{"value":"148177","label":"The Illinois Institute of Art-Chicago"},{"value":"428286","label":"The Illinois Institute of Art-Schaumburg"},{"value":"146241","label":"The John Marshall Law School"},{"value":"192110","label":"The Juilliard School"},{"value":"454184","label":"The King’s College"},{"value":"439701","label":"The King's University"},{"value":"161208","label":"The Landing School"},{"value":"213598","label":"The Lincoln University"},{"value":"117751","label":"The Master's College and Seminary"},{"value":"119544","label":"The National Hispanic University"},{"value":"167057","label":"The New England Conservatory of Music"},{"value":"167321","label":"The New England Institute of Art"},{"value":"193654","label":"The New School"},{"value":"215637","label":"The Restaurant School at Walnut Hill College"},{"value":"448804","label":"The Robert B Miller College"},{"value":"195128","label":"The Sage Colleges"},{"value":"475228","label":"The Santa Barbara and Ventura Colleges of Law–Santa Barbara"},{"value":"125037","label":"The Santa Barbara and Ventura Colleges of Law-Ventura"},{"value":"441131","label":"The Seattle School of Theology & Psychology"},{"value":"157748","label":"The Southern Baptist Theological Seminary"},{"value":"100751","label":"The University of Alabama"},{"value":"202763","label":"The University of Findlay"},{"value":"180489","label":"The University of Montana"},{"value":"180692","label":"The University of Montana-Western"},{"value":"137847","label":"The University of Tampa"},{"value":"221740","label":"The University of Tennessee-Chattanooga"},{"value":"221759","label":"The University of Tennessee-Knoxville"},{"value":"221768","label":"The University of Tennessee-Martin"},{"value":"227368","label":"The University of Texas - Rio Grande Valley"},{"value":"228769","label":"The University of Texas at Arlington"},{"value":"228778","label":"The University of Texas at Austin"},{"value":"228787","label":"The University of Texas at Dallas"},{"value":"228796","label":"The University of Texas at El Paso"},{"value":"229027","label":"The University of Texas at San Antonio"},{"value":"228802","label":"The University of Texas at Tyler"},{"value":"229300","label":"The University of Texas Health Science Center at Houston"},{"value":"228644","label":"The University of Texas Health Science Center at San Antonio"},{"value":"416801","label":"The University of Texas MD Anderson Cancer Center"},{"value":"228653","label":"The University of Texas Medical Branch"},{"value":"229018","label":"The University of Texas of the Permian Basin"},{"value":"215105","label":"The University of the Arts"},{"value":"233897","label":"The University of Virginia's College at Wise"},{"value":"138354","label":"The University of West Florida"},{"value":"126012","label":"The Wright Institute"},{"value":"216357","label":"Thiel College"},{"value":"124292","label":"Thomas Aquinas College"},{"value":"161563","label":"Thomas College"},{"value":"187046","label":"Thomas Edison State University"},{"value":"126049","label":"Thomas Jefferson School of Law"},{"value":"216366","label":"Thomas Jefferson University"},{"value":"157809","label":"Thomas More College"},{"value":"183275","label":"Thomas More College of Liberal Arts"},{"value":"233754","label":"Thomas Nelson Community College"},{"value":"141167","label":"Thomas University"},{"value":"129808","label":"Three Rivers Community College-Norwich"},{"value":"179645","label":"Three Rivers Community College-Poplar Bluff"},{"value":"103778","label":"Thunderbird School of Global Management"},{"value":"233772","label":"Tidewater Community College"},{"value":"206048","label":"Tiffin University"},{"value":"420723","label":"Tillamook Bay Community College"},{"value":"141185","label":"Toccoa Falls College"},{"value":"442781","label":"Tohono O'Odham Community College"},{"value":"196565","label":"Tompkins Cortland Community College"},{"value":"196583","label":"Torah Temimah Talmudical Seminary"},{"value":"176406","label":"Tougaloo College"},{"value":"196592","label":"Touro College"},{"value":"459736","label":"Touro University California"},{"value":"459824","label":"Touro University Nevada"},{"value":"459727","label":"Touro University Worldwide"},{"value":"164076","label":"Towson University"},{"value":"157818","label":"Transylvania University"},{"value":"210234","label":"Treasure Valley Community College"},{"value":"221892","label":"Trevecca Nazarene University"},{"value":"448859","label":"Triangle Tech Inc-Bethlehem"},{"value":"216454","label":"Triangle Tech Inc-Dubois"},{"value":"216427","label":"Triangle Tech Inc-Erie"},{"value":"216445","label":"Triangle Tech Inc-Greensburg"},{"value":"216436","label":"Triangle Tech Inc-Pittsburgh"},{"value":"443377","label":"Triangle Tech Inc-Sunbury"},{"value":"460747","label":"Tribeca Flashpoint College"},{"value":"199795","label":"Tri-County Community College"},{"value":"218885","label":"Tri-County Technical College"},{"value":"218894","label":"Trident Technical College"},{"value":"450979","label":"Trident University International"},{"value":"152567","label":"Trine University"},{"value":"414878","label":"Trine University-Regional/Non-Traditional Campuses"},{"value":"128258","label":"Trinidad State Junior College"},{"value":"137953","label":"Trinity Baptist College"},{"value":"200484","label":"Trinity Bible College"},{"value":"149505","label":"Trinity Christian College"},{"value":"130590","label":"Trinity College"},{"value":"137962","label":"Trinity College of Florida"},{"value":"146755","label":"Trinity College of Nursing & Health Sciences"},{"value":"216463","label":"Trinity Episcopal School for Ministry"},{"value":"135610","label":"Trinity International University-Florida"},{"value":"149514","label":"Trinity International University-Illinois"},{"value":"123448","label":"Trinity Law School"},{"value":"235769","label":"Trinity Lutheran College"},{"value":"206215","label":"Trinity Lutheran Seminary"},{"value":"229267","label":"Trinity University"},{"value":"225308","label":"Trinity Valley Community College"},{"value":"131876","label":"Trinity Washington University"},{"value":"206154","label":"Tri-State Bible College"},{"value":"130581","label":"Tri-State College of Acupuncture"},{"value":"149532","label":"Triton College"},{"value":"196653","label":"Trocaire College"},{"value":"102368","label":"Troy University"},{"value":"182500","label":"Truckee Meadows Community College"},{"value":"141237","label":"Truett-McConnell College"},{"value":"178615","label":"Truman State University"},{"value":"206224","label":"Trumbull Business College"},{"value":"168148","label":"Tufts University"},{"value":"160755","label":"Tulane University of Louisiana"},{"value":"207935","label":"Tulsa Community College"},{"value":"207962","label":"Tulsa Welding School-Tulsa-Tulsa"},{"value":"130606","label":"Tunxis Community College"},{"value":"200527","label":"Turtle Mountain Community College"},{"value":"221953","label":"Tusculum College"},{"value":"102377","label":"Tuskegee University"},{"value":"229355","label":"Tyler Junior College"},{"value":"196699","label":"Ulster County Community College"},{"value":"441371","label":"Ultimate Medical Academy-Clearwater"},{"value":"450173","label":"Ultimate Medical Academy-Tampa"},{"value":"481252","label":"Ultrasound Medical Institute"},{"value":"210270","label":"Umpqua Community College"},{"value":"246789","label":"Unification Theological Seminary"},{"value":"157863","label":"Union College-Barbourville"},{"value":"181738","label":"Union College-Lincoln"},{"value":"196866","label":"Union College-Schenectady"},{"value":"187198","label":"Union County College"},{"value":"446932","label":"Union Graduate College"},{"value":"206279","label":"Union Institute & University"},{"value":"233842","label":"Union Presbyterian Seminary"},{"value":"196884","label":"Union Theological Seminary in the City of New York"},{"value":"221971","label":"Union University"},{"value":"124681","label":"United Education Institute-Huntington Park Campus"},{"value":"128328","label":"United States Air Force Academy"},{"value":"130624","label":"United States Coast Guard Academy"},{"value":"197027","label":"United States Merchant Marine Academy"},{"value":"197036","label":"United States Military Academy"},{"value":"164155","label":"United States Naval Academy"},{"value":"102395","label":"United States Sports Academy"},{"value":"447050","label":"United States University"},{"value":"197018","label":"United Talmudical Seminary"},{"value":"206288","label":"United Theological Seminary"},{"value":"175139","label":"United Theological Seminary of the Twin Cities"},{"value":"200554","label":"United Tribes Technical College"},{"value":"459204","label":"Unitek College"},{"value":"161572","label":"Unity College"},{"value":"446598","label":"Universal College of Healing Arts"},{"value":"106041","label":"Universal Technical Institute of Arizona Inc"},{"value":"376385","label":"Universal Technology College of Puerto Rico"},{"value":"241191","label":"Universidad Adventista de las Antillas"},{"value":"241225","label":"Universidad Central de Bayamon"},{"value":"243568","label":"Universidad Central Del Caribe"},{"value":"243346","label":"Universidad Del Este"},{"value":"243443","label":"Universidad del Sagrado Corazon"},{"value":"243601","label":"Universidad Del Turabo"},{"value":"475811","label":"Universidad Internacional Iberoamericana"},{"value":"241739","label":"Universidad Metropolitana"},{"value":"441690","label":"Universidad Pentecostal Mizpa"},{"value":"243577","label":"Universidad Politecnica de Puerto Rico"},{"value":"241614","label":"Universidad Teologica del Caribe"},{"value":"196088","label":"University at Buffalo"},{"value":"363934","label":"University of Advancing Technology"},{"value":"200800","label":"University of Akron Main Campus"},{"value":"200846","label":"University of Akron Wayne College"},{"value":"100663","label":"University of Alabama at Birmingham"},{"value":"100706","label":"University of Alabama in Huntsville"},{"value":"102553","label":"University of Alaska Anchorage"},{"value":"102614","label":"University of Alaska Fairbanks"},{"value":"102632","label":"University of Alaska Southeast"},{"value":"442930","label":"University of Antelope Valley"},{"value":"104179","label":"University of Arizona"},{"value":"106397","label":"University of Arkansas"},{"value":"106245","label":"University of Arkansas at Little Rock"},{"value":"106485","label":"University of Arkansas at Monticello"},{"value":"106412","label":"University of Arkansas at Pine Bluff"},{"value":"106999","label":"University of Arkansas Community College-Batesville"},{"value":"107725","label":"University of Arkansas Community College-Hope"},{"value":"107585","label":"University of Arkansas Community College-Morrilton"},{"value":"106263","label":"University of Arkansas for Medical Sciences"},{"value":"108092","label":"University of Arkansas-Fort Smith"},{"value":"161873","label":"University of Baltimore"},{"value":"128744","label":"University of Bridgeport"},{"value":"110635","label":"University of California-Berkeley"},{"value":"110644","label":"University of California-Davis"},{"value":"110398","label":"University of California-Hastings College of Law"},{"value":"110653","label":"University of California-Irvine"},{"value":"110662","label":"University of California-Los Angeles"},{"value":"445188","label":"University of California-Merced"},{"value":"110671","label":"University of California-Riverside"},{"value":"110680","label":"University of California-San Diego"},{"value":"110699","label":"University of California-San Francisco"},{"value":"110705","label":"University of California-Santa Barbara"},{"value":"110714","label":"University of California-Santa Cruz"},{"value":"106704","label":"University of Central Arkansas"},{"value":"132903","label":"University of Central Florida"},{"value":"176965","label":"University of Central Missouri"},{"value":"206941","label":"University of Central Oklahoma"},{"value":"237312","label":"University of Charleston"},{"value":"144050","label":"University of Chicago"},{"value":"201955","label":"University of Cincinnati-Blue Ash College"},{"value":"201946","label":"University of Cincinnati-Clermont College"},{"value":"201885","label":"University of Cincinnati-Main Campus"},{"value":"126614","label":"University of Colorado Boulder"},{"value":"126580","label":"University of Colorado Colorado Springs"},{"value":"126562","label":"University of Colorado Denver"},{"value":"129020","label":"University of Connecticut"},{"value":"224323","label":"University of Dallas"},{"value":"202480","label":"University of Dayton"},{"value":"130943","label":"University of Delaware"},{"value":"127060","label":"University of Denver"},{"value":"169716","label":"University of Detroit Mercy"},{"value":"153278","label":"University of Dubuque"},{"value":"447801","label":"University of East-West Medicine"},{"value":"150534","label":"University of Evansville"},{"value":"134130","label":"University of Florida"},{"value":"457402","label":"University of Fort Lauderdale"},{"value":"139959","label":"University of Georgia"},{"value":"180258","label":"University of Great Falls"},{"value":"240754","label":"University of Guam"},{"value":"129525","label":"University of Hartford"},{"value":"141565","label":"University of Hawaii at Hilo"},{"value":"141574","label":"University of Hawaii at Manoa"},{"value":"141839","label":"University of Hawaii Maui College"},{"value":"141981","label":"University of Hawaii-West Oahu"},{"value":"160065","label":"University of Holy Cross"},{"value":"225511","label":"University of Houston"},{"value":"225414","label":"University of Houston-Clear Lake"},{"value":"225432","label":"University of Houston-Downtown"},{"value":"225502","label":"University of Houston-Victoria"},{"value":"142285","label":"University of Idaho"},{"value":"145600","label":"University of Illinois at Chicago"},{"value":"148654","label":"University of Illinois at Springfield"},{"value":"145637","label":"University of Illinois at Urbana-Champaign"},{"value":"151263","label":"University of Indianapolis"},{"value":"153658","label":"University of Iowa"},{"value":"200156","label":"University of Jamestown"},{"value":"155317","label":"University of Kansas"},{"value":"157085","label":"University of Kentucky"},{"value":"117140","label":"University of La Verne"},{"value":"160658","label":"University of Louisiana at Lafayette"},{"value":"159993","label":"University of Louisiana at Monroe"},{"value":"157289","label":"University of Louisville"},{"value":"161253","label":"University of Maine"},{"value":"161217","label":"University of Maine at Augusta"},{"value":"161226","label":"University of Maine at Farmington"},{"value":"161235","label":"University of Maine at Fort Kent"},{"value":"161244","label":"University of Maine at Machias"},{"value":"161341","label":"University of Maine at Presque Isle"},{"value":"437097","label":"University of Management and Technology"},{"value":"200217","label":"University of Mary"},{"value":"226471","label":"University of Mary Hardin-Baylor"},{"value":"232681","label":"University of Mary Washington"},{"value":"163338","label":"University of Maryland Eastern Shore"},{"value":"163259","label":"University of Maryland-Baltimore"},{"value":"163268","label":"University of Maryland-Baltimore County"},{"value":"163286","label":"University of Maryland-College Park"},{"value":"163204","label":"University of Maryland-University College"},{"value":"166708","label":"University of Massachusetts Medical School Worcester"},{"value":"166629","label":"University of Massachusetts-Amherst"},{"value":"166638","label":"University of Massachusetts-Boston"},{"value":"167987","label":"University of Massachusetts-Dartmouth"},{"value":"166513","label":"University of Massachusetts-Lowell"},{"value":"220862","label":"University of Memphis"},{"value":"135726","label":"University of Miami"},{"value":"170976","label":"University of Michigan-Ann Arbor"},{"value":"171137","label":"University of Michigan-Dearborn"},{"value":"171146","label":"University of Michigan-Flint"},{"value":"174075","label":"University of Minnesota-Crookston"},{"value":"174233","label":"University of Minnesota-Duluth"},{"value":"174251","label":"University of Minnesota-Morris"},{"value":"456959","label":"University of Minnesota-Rochester"},{"value":"174066","label":"University of Minnesota-Twin Cities"},{"value":"176017","label":"University of Mississippi"},{"value":"178396","label":"University of Missouri-Columbia"},{"value":"178402","label":"University of Missouri-Kansas City"},{"value":"178420","label":"University of Missouri-St Louis"},{"value":"101693","label":"University of Mobile"},{"value":"101709","label":"University of Montevallo"},{"value":"199069","label":"University of Mount Olive"},{"value":"204185","label":"University of Mount Union"},{"value":"181215","label":"University of Nebraska at Kearney"},{"value":"181394","label":"University of Nebraska at Omaha"},{"value":"181428","label":"University of Nebraska Medical Center"},{"value":"181464","label":"University of Nebraska-Lincoln"},{"value":"182281","label":"University of Nevada-Las Vegas"},{"value":"182290","label":"University of Nevada-Reno"},{"value":"161457","label":"University of New England"},{"value":"183071","label":"University of New Hampshire at Manchester"},{"value":"183044","label":"University of New Hampshire-Main Campus"},{"value":"182829","label":"University of New Hampshire-School of Law"},{"value":"129941","label":"University of New Haven"},{"value":"187958","label":"University of New Mexico-Gallup Campus"},{"value":"187976","label":"University of New Mexico-Los Alamos Campus"},{"value":"187985","label":"University of New Mexico-Main Campus"},{"value":"188225","label":"University of New Mexico-Taos Campus"},{"value":"188049","label":"University of New Mexico-Valencia County Campus"},{"value":"159939","label":"University of New Orleans"},{"value":"101879","label":"University of North Alabama"},{"value":"199111","label":"University of North Carolina at Asheville"},{"value":"199120","label":"University of North Carolina at Chapel Hill"},{"value":"199139","label":"University of North Carolina at Charlotte"},{"value":"199148","label":"University of North Carolina at Greensboro"},{"value":"199281","label":"University of North Carolina at Pembroke"},{"value":"199184","label":"University of North Carolina School of the Arts"},{"value":"199218","label":"University of North Carolina Wilmington"},{"value":"200280","label":"University of North Dakota"},{"value":"136172","label":"University of North Florida"},{"value":"482680","label":"University of North Georgia"},{"value":"227216","label":"University of North Texas"},{"value":"484905","label":"University of North Texas at Dallas"},{"value":"228909","label":"University of North Texas Health Science Center"},{"value":"127741","label":"University of Northern Colorado"},{"value":"154095","label":"University of Northern Iowa"},{"value":"204486","label":"University of Northwestern Ohio"},{"value":"174491","label":"University of Northwestern-St Paul"},{"value":"152080","label":"University of Notre Dame"},{"value":"207342","label":"University of Oklahoma-Health Sciences Center"},{"value":"207500","label":"University of Oklahoma-Norman Campus"},{"value":"209551","label":"University of Oregon"},{"value":"215062","label":"University of Pennsylvania"},{"value":"450456","label":"University of Phoenix-Alabama"},{"value":"484613","label":"University of Phoenix-Arizona"},{"value":"484622","label":"University of Phoenix-Arkansas"},{"value":"484631","label":"University of Phoenix-California"},{"value":"484640","label":"University of Phoenix-Colorado"},{"value":"448822","label":"University of Phoenix-Connecticut"},{"value":"484668","label":"University of Phoenix-Florida"},{"value":"484677","label":"University of Phoenix-Georgia"},{"value":"420042","label":"University of Phoenix-Hawaii"},{"value":"440466","label":"University of Phoenix-Idaho"},{"value":"442161","label":"University of Phoenix-Illinois"},{"value":"443544","label":"University of Phoenix-Indiana"},{"value":"446729","label":"University of Phoenix-Iowa"},{"value":"445391","label":"University of Phoenix-Kentucky"},{"value":"484686","label":"University of Phoenix-Louisiana"},{"value":"434973","label":"University of Phoenix-Maryland"},{"value":"440420","label":"University of Phoenix-Massachusetts"},{"value":"484695","label":"University of Phoenix-Michigan"},{"value":"445319","label":"University of Phoenix-Minnesota"},{"value":"462390","label":"University of Phoenix-Mississippi"},{"value":"484701","label":"University of Phoenix-Missouri"},{"value":"484710","label":"University of Phoenix-Nevada"},{"value":"445300","label":"University of Phoenix-New Jersey"},{"value":"405997","label":"University of Phoenix-New Mexico"},{"value":"484729","label":"University of Phoenix-North Carolina"},{"value":"439297","label":"University of Phoenix-Ohio"},{"value":"484738","label":"University of Phoenix-Oklahoma"},{"value":"432241","label":"University of Phoenix-Oregon"},{"value":"484783","label":"University of Phoenix-Pennsylvania"},{"value":"382063","label":"University of Phoenix-Puerto Rico"},{"value":"448567","label":"University of Phoenix-South Carolina"},{"value":"484747","label":"University of Phoenix-Tennessee"},{"value":"484756","label":"University of Phoenix-Texas"},{"value":"380465","label":"University of Phoenix-Utah"},{"value":"484765","label":"University of Phoenix-Virginia"},{"value":"432223","label":"University of Phoenix-Washington"},{"value":"450483","label":"University of Phoenix-Washington DC"},{"value":"440457","label":"University of Phoenix-Wisconsin"},{"value":"157535","label":"University of Pikeville"},{"value":"215266","label":"University of Pittsburgh-Bradford"},{"value":"215275","label":"University of Pittsburgh-Greensburg"},{"value":"215284","label":"University of Pittsburgh-Johnstown"},{"value":"215293","label":"University of Pittsburgh-Pittsburgh Campus"},{"value":"215309","label":"University of Pittsburgh-Titusville"},{"value":"209825","label":"University of Portland"},{"value":"243106","label":"University of Puerto Rico-Aguadilla"},{"value":"243115","label":"University of Puerto Rico-Arecibo"},{"value":"243133","label":"University of Puerto Rico-Bayamon"},{"value":"243142","label":"University of Puerto Rico-Carolina"},{"value":"243151","label":"University of Puerto Rico-Cayey"},{"value":"243179","label":"University of Puerto Rico-Humacao"},{"value":"243197","label":"University of Puerto Rico-Mayaguez"},{"value":"243203","label":"University of Puerto Rico-Medical Sciences"},{"value":"243212","label":"University of Puerto Rico-Ponce"},{"value":"243221","label":"University of Puerto Rico-Rio Piedras"},{"value":"243188","label":"University of Puerto Rico-Utuado"},{"value":"236328","label":"University of Puget Sound"},{"value":"121691","label":"University of Redlands"},{"value":"217484","label":"University of Rhode Island"},{"value":"233374","label":"University of Richmond"},{"value":"205203","label":"University of Rio Grande"},{"value":"195030","label":"University of Rochester"},{"value":"152336","label":"University of Saint Francis-Fort Wayne"},{"value":"130314","label":"University of Saint Joseph"},{"value":"155812","label":"University of Saint Mary"},{"value":"148885","label":"University of Saint Mary of the Lake"},{"value":"122436","label":"University of San Diego"},{"value":"122612","label":"University of San Francisco"},{"value":"207722","label":"University of Science and Arts of Oklahoma"},{"value":"215929","label":"University of Scranton"},{"value":"219383","label":"University of Sioux Falls"},{"value":"102094","label":"University of South Alabama"},{"value":"218645","label":"University of South Carolina-Aiken"},{"value":"218654","label":"University of South Carolina-Beaufort"},{"value":"218663","label":"University of South Carolina-Columbia"},{"value":"218672","label":"University of South Carolina-Lancaster"},{"value":"218681","label":"University of South Carolina-Salkehatchie"},{"value":"218690","label":"University of South Carolina-Sumter"},{"value":"218706","label":"University of South Carolina-Union"},{"value":"218742","label":"University of South Carolina-Upstate"},{"value":"219471","label":"University of South Dakota"},{"value":"137351","label":"University of South Florida-Main Campus"},{"value":"451671","label":"University of South Florida-Sarasota-Manatee"},{"value":"448840","label":"University of South Florida-St Petersburg"},{"value":"123961","label":"University of Southern California"},{"value":"151306","label":"University of Southern Indiana"},{"value":"161554","label":"University of Southern Maine"},{"value":"176372","label":"University of Southern Mississippi"},{"value":"134121","label":"University of Southernmost Florida"},{"value":"367954","label":"University of St Augustine for Health Sciences"},{"value":"148584","label":"University of St Francis"},{"value":"227863","label":"University of St Thomas-Houston"},{"value":"174914","label":"University of St Thomas-Saint Paul"},{"value":"228635","label":"University of Texas Southwestern Medical Center"},{"value":"156541","label":"University of the Cumberlands"},{"value":"131399","label":"University of the District of Columbia"},{"value":"363721","label":"University of the District of Columbia-David A Clarke School of Law"},{"value":"225627","label":"University of the Incarnate Word"},{"value":"107558","label":"University of the Ozarks"},{"value":"120883","label":"University of the Pacific"},{"value":"442639","label":"University of the Potomac-VA Campus"},{"value":"384412","label":"University of the Potomac-Washington DC Campus"},{"value":"441308","label":"University of the Rockies"},{"value":"215132","label":"University of the Sciences"},{"value":"188182","label":"University of the Southwest"},{"value":"243665","label":"University of the Virgin Islands"},{"value":"449870","label":"University of the West"},{"value":"206084","label":"University of Toledo"},{"value":"207971","label":"University of Tulsa"},{"value":"230764","label":"University of Utah"},{"value":"216542","label":"University of Valley Forge"},{"value":"231174","label":"University of Vermont"},{"value":"234076","label":"University of Virginia-Main Campus"},{"value":"377555","label":"University of Washington-Bothell Campus"},{"value":"236948","label":"University of Washington-Seattle Campus"},{"value":"377564","label":"University of Washington-Tacoma Campus"},{"value":"101587","label":"University of West Alabama"},{"value":"141334","label":"University of West Georgia"},{"value":"210438","label":"University of Western States"},{"value":"240055","label":"University of Wisconsin Colleges"},{"value":"240268","label":"University of Wisconsin-Eau Claire"},{"value":"240277","label":"University of Wisconsin-Green Bay"},{"value":"240329","label":"University of Wisconsin-La Crosse"},{"value":"240444","label":"University of Wisconsin-Madison"},{"value":"240453","label":"University of Wisconsin-Milwaukee"},{"value":"240365","label":"University of Wisconsin-Oshkosh"},{"value":"240374","label":"University of Wisconsin-Parkside"},{"value":"240462","label":"University of Wisconsin-Platteville"},{"value":"240471","label":"University of Wisconsin-River Falls"},{"value":"240480","label":"University of Wisconsin-Stevens Point"},{"value":"240417","label":"University of Wisconsin-Stout"},{"value":"240426","label":"University of Wisconsin-Superior"},{"value":"240189","label":"University of Wisconsin-Whitewater"},{"value":"240727","label":"University of Wyoming"},{"value":"154493","label":"Upper Iowa University"},{"value":"196307","label":"Upstate Medical University"},{"value":"429128","label":"Urban College of Boston"},{"value":"206330","label":"Urbana University"},{"value":"455099","label":"Urshan Graduate School of Theology"},{"value":"216524","label":"Ursinus College"},{"value":"206349","label":"Ursuline College"},{"value":"446604","label":"Uta Mesivta of Kiryas Joel"},{"value":"230728","label":"Utah State University"},{"value":"230737","label":"Utah Valley University"},{"value":"197045","label":"Utica College"},{"value":"197081","label":"Utica School of Commerce"},{"value":"141264","label":"Valdosta State University"},{"value":"138187","label":"Valencia College"},{"value":"200572","label":"Valley City State University"},{"value":"377652","label":"Valley College-Beckley"},{"value":"152600","label":"Valparaiso University"},{"value":"199838","label":"Vance-Granville Community College"},{"value":"221999","label":"Vanderbilt University"},{"value":"149639","label":"VanderCook College of Music"},{"value":"123651","label":"Vanguard University of Southern California"},{"value":"197133","label":"Vassar College"},{"value":"455567","label":"Vatterott College-Appling Farms"},{"value":"245342","label":"Vatterott College-Berkeley"},{"value":"442408","label":"Vatterott College-Cleveland"},{"value":"373058","label":"Vatterott College-Des Moines"},{"value":"440873","label":"Vatterott College-Dividend"},{"value":"481988","label":"Vatterott College-ex'treme Institute by Nelly-St Louis"},{"value":"404374","label":"Vatterott College-Joplin"},{"value":"404383","label":"Vatterott College-Kansas City"},{"value":"437060","label":"Vatterott College-Oklahoma City"},{"value":"148140","label":"Vatterott College-Quincy"},{"value":"181756","label":"Vatterott College-Spring Valley"},{"value":"404365","label":"Vatterott College-Springfield"},{"value":"445559","label":"Vatterott College-St Charles"},{"value":"436182","label":"Vatterott College-St Joseph"},{"value":"436191","label":"Vatterott College-Sunset Hills"},{"value":"440882","label":"Vatterott College-Tulsa"},{"value":"440891","label":"Vatterott College-Wichita"},{"value":"188340","label":"Vaughn College of Aeronautics and Technology"},{"value":"125028","label":"Ventura College"},{"value":"175157","label":"Vermilion Community College"},{"value":"455992","label":"Vermont College of Fine Arts"},{"value":"231147","label":"Vermont Law School"},{"value":"231165","label":"Vermont Technical College"},{"value":"229504","label":"Vernon College"},{"value":"213914","label":"Vet Tech Institute"},{"value":"223472","label":"Vet Tech Institute of Houston"},{"value":"125091","label":"Victor Valley College"},{"value":"229540","label":"Victoria College"},{"value":"197142","label":"Villa Maria College"},{"value":"216597","label":"Villanova University"},{"value":"152637","label":"Vincennes University"},{"value":"482228","label":"Virginia Baptist College"},{"value":"458256","label":"Virginia College-Augusta"},{"value":"441928","label":"Virginia College-Austin"},{"value":"460774","label":"Virginia College-Baton Rouge"},{"value":"450191","label":"Virginia College-Biloxi"},{"value":"420307","label":"Virginia College-Birmingham"},{"value":"456056","label":"Virginia College-Charleston"},{"value":"458593","label":"Virginia College-Columbia"},{"value":"475370","label":"Virginia College-Columbus"},{"value":"480107","label":"Virginia College-Florence"},{"value":"454625","label":"Virginia College-Greenville"},{"value":"420316","label":"Virginia College-Huntsville"},{"value":"441919","label":"Virginia College-Jackson"},{"value":"455716","label":"Virginia College-Jacksonville"},{"value":"475617","label":"Virginia College-Knoxville"},{"value":"460844","label":"Virginia College-Macon"},{"value":"445090","label":"Virginia College-Mobile"},{"value":"452115","label":"Virginia College-Montgomery"},{"value":"389727","label":"Virginia College-Pensacola"},{"value":"460923","label":"Virginia College-Richmond"},{"value":"475352","label":"Virginia College-Savannah"},{"value":"450289","label":"Virginia College-School of Business and Health-Chattanooga"},{"value":"475866","label":"Virginia College-Shreveport Bossier City"},{"value":"460853","label":"Virginia College-Spartanburg"},{"value":"475592","label":"Virginia College-Tulsa"},{"value":"234030","label":"Virginia Commonwealth University"},{"value":"233903","label":"Virginia Highlands Community College"},{"value":"206394","label":"Virginia Marti College of Art and Design"},{"value":"234085","label":"Virginia Military Institute"},{"value":"233921","label":"Virginia Polytechnic Institute and State University"},{"value":"234155","label":"Virginia State University"},{"value":"459082","label":"Virginia Tech Carilion School of Medicine"},{"value":"234164","label":"Virginia Union University"},{"value":"234137","label":"Virginia University of Lynchburg"},{"value":"234173","label":"Virginia Wesleyan College"},{"value":"233949","label":"Virginia Western Community College"},{"value":"449764","label":"Visible Music College"},{"value":"365204","label":"Vista College"},{"value":"377342","label":"Vista College-Online"},{"value":"240107","label":"Viterbo University"},{"value":"222053","label":"Volunteer State Community College"},{"value":"218919","label":"Voorhees College"},{"value":"152673","label":"Wabash College"},{"value":"403487","label":"Wabash Valley College"},{"value":"226879","label":"Wade College"},{"value":"197197","label":"Wagner College"},{"value":"199847","label":"Wake Forest University"},{"value":"199856","label":"Wake Technical Community College"},{"value":"125231","label":"Walden University"},{"value":"154518","label":"Waldorf College"},{"value":"236887","label":"Walla Walla Community College"},{"value":"236896","label":"Walla Walla University"},{"value":"172608","label":"Walsh College of Accountancy and Business Administration"},{"value":"206437","label":"Walsh University"},{"value":"222062","label":"Walters State Community College"},{"value":"210304","label":"Warner Pacific College"},{"value":"480198","label":"Warner Pacific College Adult Degree Program"},{"value":"138275","label":"Warner University"},{"value":"245625","label":"Warren County Community College"},{"value":"199865","label":"Warren Wilson College"},{"value":"154527","label":"Wartburg College"},{"value":"154536","label":"Wartburg Theological Seminary"},{"value":"156082","label":"Washburn University"},{"value":"216667","label":"Washington & Jefferson College"},{"value":"162210","label":"Washington Adventist University"},{"value":"234207","label":"Washington and Lee University"},{"value":"164216","label":"Washington College"},{"value":"161581","label":"Washington County Community College"},{"value":"206446","label":"Washington State Community College"},{"value":"236939","label":"Washington State University"},{"value":"179867","label":"Washington University in St Louis"},{"value":"172617","label":"Washtenaw Community College"},{"value":"392840","label":"Watkins College of Art Design & Film"},{"value":"149727","label":"Waubonsee Community College"},{"value":"240125","label":"Waukesha County Technical College"},{"value":"229780","label":"Wayland Baptist University"},{"value":"199892","label":"Wayne Community College"},{"value":"172635","label":"Wayne County Community College District"},{"value":"181783","label":"Wayne State College"},{"value":"172644","label":"Wayne State University"},{"value":"216694","label":"Waynesburg University"},{"value":"229799","label":"Weatherford College"},{"value":"197221","label":"Webb Institute"},{"value":"138293","label":"Webber International University"},{"value":"230782","label":"Weber State University"},{"value":"179894","label":"Webster University"},{"value":"190424","label":"Weill Cornell Medicine"},{"value":"220206","label":"Welch College"},{"value":"168218","label":"Wellesley College"},{"value":"197230","label":"Wells College"},{"value":"447999","label":"WellSpring School of Allied Health-Kansas City"},{"value":"236975","label":"Wenatchee Valley College"},{"value":"168227","label":"Wentworth Institute of Technology"},{"value":"179919","label":"Wentworth Military Academy and College"},{"value":"176451","label":"Wesley Biblical Seminary"},{"value":"131098","label":"Wesley College"},{"value":"131973","label":"Wesley Theological Seminary"},{"value":"141325","label":"Wesleyan College"},{"value":"130697","label":"Wesleyan University"},{"value":"216764","label":"West Chester University of Pennsylvania"},{"value":"441229","label":"West Coast Ultrasound Institute"},{"value":"477039","label":"West Coast University-Dallas"},{"value":"443331","label":"West Coast University-Los Angeles"},{"value":"458229","label":"West Coast University-Ontario"},{"value":"458210","label":"West Coast University-Orange County"},{"value":"139278","label":"West Georgia Technical College"},{"value":"125462","label":"West Hills College-Coalinga"},{"value":"448594","label":"West Hills College-Lemoore"},{"value":"157483","label":"West Kentucky Community and Technical College"},{"value":"237932","label":"West Liberty University"},{"value":"125471","label":"West Los Angeles College"},{"value":"172671","label":"West Shore Community College"},{"value":"222099","label":"West Tennessee Business College"},{"value":"229814","label":"West Texas A & M University"},{"value":"125499","label":"West Valley College"},{"value":"237978","label":"West Virginia Business College-Wheeling"},{"value":"442383","label":"West Virginia Junior College-Bridgeport"},{"value":"237987","label":"West Virginia Junior College-Charleston"},{"value":"237996","label":"West Virginia Junior College-Morgantown"},{"value":"238014","label":"West Virginia Northern Community College"},{"value":"237880","label":"West Virginia School of Osteopathic Medicine"},{"value":"237899","label":"West Virginia State University"},{"value":"238032","label":"West Virginia University"},{"value":"237686","label":"West Virginia University at Parkersburg"},{"value":"237950","label":"West Virginia University Institute of Technology"},{"value":"237969","label":"West Virginia Wesleyan College"},{"value":"200004","label":"Western Carolina University"},{"value":"130776","label":"Western Connecticut State University"},{"value":"219480","label":"Western Dakota Technical Institute"},{"value":"433387","label":"Western Governors University"},{"value":"149772","label":"Western Illinois University"},{"value":"106102","label":"Western International University"},{"value":"154572","label":"Western Iowa Tech Community College"},{"value":"157951","label":"Western Kentucky University"},{"value":"172699","label":"Western Michigan University"},{"value":"172477","label":"Western Michigan University-Thomas M. Cooley Law School"},{"value":"181817","label":"Western Nebraska Community College"},{"value":"182564","label":"Western Nevada College"},{"value":"168254","label":"Western New England University"},{"value":"188304","label":"Western New Mexico University"},{"value":"208035","label":"Western Oklahoma State College"},{"value":"210429","label":"Western Oregon University"},{"value":"199908","label":"Western Piedmont Community College"},{"value":"210368","label":"Western Seminary"},{"value":"126030","label":"Western State College of Law at Argosy University"},{"value":"128391","label":"Western State Colorado University"},{"value":"224660","label":"Western Technical College-El Paso"},{"value":"224679","label":"Western Technical College-El Paso"},{"value":"240170","label":"Western Technical College-La Crosse"},{"value":"229832","label":"Western Texas College"},{"value":"172705","label":"Western Theological Seminary"},{"value":"112525","label":"Western University of Health Sciences"},{"value":"237011","label":"Western Washington University"},{"value":"240693","label":"Western Wyoming Community College"},{"value":"168263","label":"Westfield State University"},{"value":"179946","label":"Westminster College-Fulton"},{"value":"216807","label":"Westminster College-New Wilmington"},{"value":"230807","label":"Westminster College-Salt Lake City"},{"value":"216816","label":"Westminster Theological Seminary"},{"value":"125718","label":"Westminster Theological Seminary in California"},{"value":"125727","label":"Westmont College"},{"value":"216825","label":"Westmoreland County Community College"},{"value":"437848","label":"Westwood College-Anaheim"},{"value":"448628","label":"Westwood College-Annandale"},{"value":"447069","label":"Westwood College-Arlington Ballston"},{"value":"445072","label":"Westwood College-Atlanta Midtown"},{"value":"443687","label":"Westwood College-Chicago Loop"},{"value":"127024","label":"Westwood College-Denver North"},{"value":"381787","label":"Westwood College-Denver South"},{"value":"406194","label":"Westwood College-Dupage"},{"value":"440484","label":"Westwood College-Inland Empire"},{"value":"122843","label":"Westwood College-Los Angeles"},{"value":"445276","label":"Westwood College-Northlake"},{"value":"178226","label":"Westwood College-O'Hare Airport"},{"value":"440147","label":"Westwood College-River Oaks"},{"value":"121381","label":"Westwood College-South Bay"},{"value":"229841","label":"Wharton County Junior College"},{"value":"237039","label":"Whatcom Community College"},{"value":"168281","label":"Wheaton College-Norton"},{"value":"149781","label":"Wheaton College-Wheaton"},{"value":"238078","label":"Wheeling Jesuit University"},{"value":"168290","label":"Wheelock College"},{"value":"434751","label":"White Earth Tribal and Community College"},{"value":"183105","label":"White Mountains Community College"},{"value":"237057","label":"Whitman College"},{"value":"125763","label":"Whittier College"},{"value":"237066","label":"Whitworth University"},{"value":"475200","label":"Whitworth University-Adult Degree Programs"},{"value":"156107","label":"Wichita Area Technical College"},{"value":"156125","label":"Wichita State University"},{"value":"156134","label":"Wichita Technical Institute"},{"value":"244190","label":"Widener University-Delaware Campus"},{"value":"402828","label":"Widener University-Harrisburg Campus"},{"value":"216852","label":"Widener University-Main Campus"},{"value":"206491","label":"Wilberforce University"},{"value":"229887","label":"Wiley College"},{"value":"199926","label":"Wilkes Community College"},{"value":"216931","label":"Wilkes University"},{"value":"210401","label":"Willamette University"},{"value":"176479","label":"William Carey University"},{"value":"166717","label":"William James College"},{"value":"122728","label":"William Jessup University"},{"value":"179955","label":"William Jewell College"},{"value":"175281","label":"William Mitchell College of Law"},{"value":"222105","label":"William Moore College of Technology"},{"value":"187444","label":"William Paterson University of New Jersey"},{"value":"199272","label":"William Peace University"},{"value":"154590","label":"William Penn University"},{"value":"149842","label":"William Rainey Harper College"},{"value":"179964","label":"William Woods University"},{"value":"107877","label":"Williams Baptist College"},{"value":"168342","label":"Williams College"},{"value":"218955","label":"Williamsburg Technical College"},{"value":"443340","label":"Williamson Christian College"},{"value":"200341","label":"Williston State College"},{"value":"206507","label":"Wilmington College"},{"value":"131113","label":"Wilmington University"},{"value":"217013","label":"Wilson College"},{"value":"199953","label":"Wilson Community College"},{"value":"141990","label":"Windward Community College"},{"value":"206516","label":"Winebrenner Theological Seminary"},{"value":"199962","label":"Wingate University"},{"value":"175272","label":"Winona State University"},{"value":"199999","label":"Winston-Salem State University"},{"value":"218964","label":"Winthrop University"},{"value":"141255","label":"Wiregrass Georgia Technical College"},{"value":"240198","label":"Wisconsin Indianhead Technical College"},{"value":"240338","label":"Wisconsin Lutheran College"},{"value":"240213","label":"Wisconsin School of Professional Psychology"},{"value":"206525","label":"Wittenberg University"},{"value":"218973","label":"Wofford College"},{"value":"451130","label":"Wolford College"},{"value":"442064","label":"Won Institute of Graduate Studies"},{"value":"197522","label":"Wood Tobe-Coburn School"},{"value":"125897","label":"Woodbury University"},{"value":"455512","label":"Woodland Community College"},{"value":"168421","label":"Worcester Polytechnic Institute"},{"value":"168430","label":"Worcester State University"},{"value":"141936","label":"World Medicine Institute"},{"value":"401223","label":"World Mission University"},{"value":"369455","label":"Worsham College of Mortuary Science"},{"value":"164313","label":"Wor-Wic Community College"},{"value":"406200","label":"Wright Career College"},{"value":"206613","label":"Wright State University-Lake Campus"},{"value":"206604","label":"Wright State University-Main Campus"},{"value":"441089","label":"Wyo Tech-Blairsville"},{"value":"132268","label":"Wyotech-Daytona"},{"value":"123208","label":"Wyotech-Fremont"},{"value":"240718","label":"Wyotech-Laramie"},{"value":"398574","label":"Wyotech-Long Beach"},{"value":"234377","label":"Wytheville Community College"},{"value":"206622","label":"Xavier University"},{"value":"160904","label":"Xavier University of Louisiana"},{"value":"237109","label":"Yakima Valley Community College"},{"value":"130794","label":"Yale University"},{"value":"106148","label":"Yavapai College"},{"value":"245731","label":"Yeshiva and Kollel Harbotzas Torah"},{"value":"434937","label":"Yeshiva College of the Nations Capital"},{"value":"197647","label":"Yeshiva Derech Chaim"},{"value":"420325","label":"Yeshiva D'monsey Rabbinical College"},{"value":"375230","label":"Yeshiva Gedolah Imrei Yosef D'spinka"},{"value":"481410","label":"Yeshiva Gedolah Kesser Torah"},{"value":"247773","label":"Yeshiva Gedolah of Greater Detroit"},{"value":"476692","label":"Yeshiva Gedolah Zichron Leyma"},{"value":"197601","label":"Yeshiva Karlin Stolin"},{"value":"190752","label":"Yeshiva of Far Rockaway Derech Ayson Rabbinical Seminary"},{"value":"455257","label":"Yeshiva of Machzikai Hadas"},{"value":"197674","label":"Yeshiva of Nitra Rabbinical College"},{"value":"431983","label":"Yeshiva of the Telshe Alumni"},{"value":"126076","label":"Yeshiva Ohr Elchonon Chabad West Coast Talmudical Seminary"},{"value":"197692","label":"Yeshiva Shaar Hatorah"},{"value":"441609","label":"Yeshiva Shaarei Torah of Rockland"},{"value":"451398","label":"Yeshiva Toras Chaim"},{"value":"128425","label":"Yeshiva Toras Chaim Talmudical Seminary"},{"value":"197708","label":"Yeshiva University"},{"value":"481438","label":"Yeshiva Yesodei Hatorah"},{"value":"451370","label":"Yeshivas Be'er Yitzchok"},{"value":"405058","label":"Yeshivas Novominsk"},{"value":"197610","label":"Yeshivat Mikdash Melech"},{"value":"217040","label":"Yeshivath Beth Moshe"},{"value":"197735","label":"Yeshivath Viznitz"},{"value":"197744","label":"Yeshivath Zichron Moshe"},{"value":"401250","label":"Yo San University of Traditional Chinese Medicine"},{"value":"181853","label":"York College"},{"value":"217059","label":"York College Pennsylvania"},{"value":"420440","label":"York County Community College"},{"value":"218991","label":"York Technical College"},{"value":"217086","label":"Yorktowne Business Institute"},{"value":"141361","label":"Young Harris College"},{"value":"206695","label":"Youngstown State University"},{"value":"375939","label":"YTI Career Institute-Altoona"},{"value":"217077","label":"YTI Career Institute-York"},{"value":"126119","label":"Yuba College"},{"value":"204255","label":"Zane State College"}] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/jobTitles.json b/vite-app/src/apps/Auth2/resources/dataSources/jobTitles.json new file mode 100644 index 00000000..298b166a --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/jobTitles.json @@ -0,0 +1,17 @@ +[ + { "value": "CEO", "label": "CEO" }, + { "value": "CSO", "label": "CSO" }, + { "value": "Scientific Director", "label": "Scientific Director" }, + { "value": "Principal Investigator", "label": "Principal Investigator" }, + { "value": "Co-investigator", "label": "Co-investigator" }, + { "value": "Staff Scientist", "label": "Staff Scientist" }, + { "value": "Research Associate", "label": "Research Associate" }, + { "value": "Postdoctoral Scientist", "label": "Postdoctoral Scientist" }, + { "value": "Graduate Student", "label": "Graduate Student" }, + { "value": "Undergraduate Student", "label": "Undergraduate Student" }, + { "value": "Assistant Professor", "label": "Assistant Professor" }, + { "value": "Associate Professor", "label": "Associate Professor" }, + { "value": "Professor", "label": "Professor" }, + { "value": "Physician", "label": "Physician" }, + { "value": "Other", "label": "Other" } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/nationalLabs.json b/vite-app/src/apps/Auth2/resources/dataSources/nationalLabs.json new file mode 100644 index 00000000..657fa0bf --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/nationalLabs.json @@ -0,0 +1,134 @@ +[ + { + "name": "Ames Laboratory", + "city": "Ames", + "state": "Iowa", + "initials": "Ames", + "type": "OSL" + }, + { + "name": "Argonne National Laboratory", + "city": "Argonne", + "state": "Illinois", + "initials": "ANL", + "type": "OSL" + }, + { + "name": "Brookhaven National Laboratory", + "city": "Upton", + "state": "New York", + "initials": "BNL", + "type": "OSL" + }, + { + "name": "Fermi National Accelerator Laboratory", + "city": "Berkeley", + "state": "California", + "initials": "FERMILAB", + "type": "OSL" + }, + { + "name": "Oak Ridge National Laboratory", + "city": "Oak Ridge", + "state": "Tennessee", + "initials": "ORNL", + "type": "OSL" + }, + { + "name": "Lawrence Berkeley National Laboratory", + "city": "Berkeley", + "state": "California", + "initials": "LBNL", + "type": "OSL" + }, + { + "name": "Pacific Northwest National Laboratory", + "city": "Richland", + "state": "Washington", + "initials": "PNNL", + "type": "OSL" + }, + { + "name": "Princeton Plasma Physics Laboratory", + "city": "Princeton", + "state": "New Jersey", + "initials": "PPPL", + "type": "OSL" + }, + { + "name": "SLAC National Accelerator Laboratory", + "city": "Newport News", + "state": "Virginia", + "initials": "SLAC", + "type": "OSL" + }, + { + "name": "Idaho National Laboratory", + "city": "Idaho Falls", + "state": "Idaho", + "initials": "INL", + "type": "OTHER" + }, + { + "name": "National Energy Technology Laboratory", + "locations": [ + { + "city": "Morgantown", + "state": "West Virginia" + }, + { + "city": "Pittsburgh", + "state": "Pennsylvania" + }, + { + "city": "Albany", + "state": "Orgegon" + } + ], + "initials": "NETL", + "type": "OTHER" + }, + { + "name": "National Renewable Energy Laboratory", + "city": "Golden", + "state": "Colorado", + "initials": "NREL", + "type": "OTHER" + }, + { + "name": "Savannah River National Laboratory", + "city": "Aiken", + "state": "South Carolina", + "initials": "SRNL", + "type": "OTHER" + }, + { + "name": "Lawrence Livermore National Laboratory", + "city": "Livermore", + "state": "California", + "initials": "LLNL", + "type": "NNSA" + }, + { + "name": "Los Alamos National Laboratory", + "city": "Los Alamos", + "state": "New Mexico", + "initials": "LANL", + "type": "NNSA" + }, + { + "name": "Sandia National Laboratory", + "locations": [ + { + "city": "Albequerque", + "state": "New Mexico" + }, + { + "city": "Livermore", + "state": "California" + } + ], + "initials": "SNL", + "type": "NNSA" + } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/nationalLabs.yaml b/vite-app/src/apps/Auth2/resources/dataSources/nationalLabs.yaml new file mode 100644 index 00000000..ad398ff9 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/nationalLabs.yaml @@ -0,0 +1,112 @@ +# National Labs +--- +- + name: Ames Laboratory + city: Ames + state: Iowa + initials: Ames + type: OSL +- + name: Argonne National Laboratory + city: Argonne + state: Illinois + initials: ANL + type: OSL +- + name: Brookhaven National Laboratory + city: Upton + state: New York + initials: BNL + type: OSL +- + name: Fermi National Accelerator Laboratory + city: Berkeley + state: California + initials: FERMILAB + type: OSL +- + name: Oak Ridge National Laboratory + city: Oak Ridge + state: Tennessee + initials: ORNL + type: OSL +- + name: Lawrence Berkeley National Laboratory + city: Berkeley + state: California + initials: LBNL + type: OSL +- + name: Pacific Northwest National Laboratory + city: Richland + state: Washington + initials: PNNL + type: OSL +- + name: Princeton Plasma Physics Laboratory + city: Princeton + state: New Jersey + initials: PPPL + type: OSL +- + name: SLAC National Accelerator Laboratory + city: Newport News + state: Virginia + initials: SLAC + type: OSL +- + name: Idaho National Laboratory + city: Idaho Falls + state: Idaho + initials: INL + type: OTHER +- + name: National Energy Technology Laboratory + locations: + - + city: Morgantown + state: West Virginia + - + city: Pittsburgh + state: Pennsylvania + - + city: Albany + state: Orgegon + initials: NETL + type: OTHER +- + name: National Renewable Energy Laboratory + city: Golden + state: Colorado + initials: NREL + type: OTHER +- + name: Savannah River National Laboratory + city: Aiken + state: South Carolina + initials: SRNL + type: OTHER + +- + name: Lawrence Livermore National Laboratory + city: Livermore + state: California + initials: LLNL + type: NNSA +- + name: Los Alamos National Laboratory + city: Los Alamos + state: New Mexico + initials: LANL + type: NNSA +- + name: Sandia National Laboratory + locations: + - + city: Albequerque + state: New Mexico + - + city: Livermore + state: California + initials: SNL + type: NNSA diff --git a/vite-app/src/apps/Auth2/resources/dataSources/otherLabs.json b/vite-app/src/apps/Auth2/resources/dataSources/otherLabs.json new file mode 100644 index 00000000..4bbae19a --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/otherLabs.json @@ -0,0 +1,16 @@ +[ + { + "name": "Cold Spring Harbor Laboratory", + "city": "Cold Spring Harbor", + "state": "New York", + "initials": "CSHL", + "type": "private" + }, + { + "name": "Joint Genome Institute", + "city": "Walnut Creek", + "state": "CA", + "initials": "JGI", + "type": "doe" + } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/otherLabs.yaml b/vite-app/src/apps/Auth2/resources/dataSources/otherLabs.yaml new file mode 100644 index 00000000..05dbeef5 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/otherLabs.yaml @@ -0,0 +1,14 @@ +# Other Labs +--- +- + name: Cold Spring Harbor Laboratory + city: Cold Spring Harbor + state: New York + initials: CSHL + type: private +- + name: Joint Genome Institute + city: Walnut Creek + state: CA + initials: JGI + type: doe \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/researchInterests.json b/vite-app/src/apps/Auth2/resources/dataSources/researchInterests.json new file mode 100644 index 00000000..8bb5154d --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/researchInterests.json @@ -0,0 +1,41 @@ +[{ + "value": "annotation", + "label": "Genome Annotation" + }, + { + "value": "assembly", + "label": "Genome Assembly" + }, + { + "value": "communities", + "label": "Microbial Communities" + }, + { + "value": "comparative_genomics", + "label": "Comparative Genomics" + }, + { + "value": "expression", + "label": "Expression" + }, + { + "value": "metabolic_modeling", + "label": "Metabolic Modeling" + }, + { + "value": "reads", + "label": "Read Processing" + }, + { + "value": "sequence", + "label": "Sequence Analysis" + }, + { + "value": "util", + "label": "Utilities" + }, + { + "value": "other", + "label": "Other" + } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/dataSources/states.json b/vite-app/src/apps/Auth2/resources/dataSources/states.json new file mode 100644 index 00000000..367074a4 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/dataSources/states.json @@ -0,0 +1,237 @@ +[{ + "name": "Alabama", + "abbreviation": "AL" + }, + { + "name": "Alaska", + "abbreviation": "AK" + }, + { + "name": "American Samoa", + "abbreviation": "AS" + }, + { + "name": "Arizona", + "abbreviation": "AZ" + }, + { + "name": "Arkansas", + "abbreviation": "AR" + }, + { + "name": "California", + "abbreviation": "CA" + }, + { + "name": "Colorado", + "abbreviation": "CO" + }, + { + "name": "Connecticut", + "abbreviation": "CT" + }, + { + "name": "Delaware", + "abbreviation": "DE" + }, + { + "name": "District Of Columbia", + "abbreviation": "DC" + }, + { + "name": "Federated States Of Micronesia", + "abbreviation": "FM" + }, + { + "name": "Florida", + "abbreviation": "FL" + }, + { + "name": "Georgia", + "abbreviation": "GA" + }, + { + "name": "Guam", + "abbreviation": "GU" + }, + { + "name": "Hawaii", + "abbreviation": "HI" + }, + { + "name": "Idaho", + "abbreviation": "ID" + }, + { + "name": "Illinois", + "abbreviation": "IL" + }, + { + "name": "Indiana", + "abbreviation": "IN" + }, + { + "name": "Iowa", + "abbreviation": "IA" + }, + { + "name": "Kansas", + "abbreviation": "KS" + }, + { + "name": "Kentucky", + "abbreviation": "KY" + }, + { + "name": "Louisiana", + "abbreviation": "LA" + }, + { + "name": "Maine", + "abbreviation": "ME" + }, + { + "name": "Marshall Islands", + "abbreviation": "MH" + }, + { + "name": "Maryland", + "abbreviation": "MD" + }, + { + "name": "Massachusetts", + "abbreviation": "MA" + }, + { + "name": "Michigan", + "abbreviation": "MI" + }, + { + "name": "Minnesota", + "abbreviation": "MN" + }, + { + "name": "Mississippi", + "abbreviation": "MS" + }, + { + "name": "Missouri", + "abbreviation": "MO" + }, + { + "name": "Montana", + "abbreviation": "MT" + }, + { + "name": "Nebraska", + "abbreviation": "NE" + }, + { + "name": "Nevada", + "abbreviation": "NV" + }, + { + "name": "New Hampshire", + "abbreviation": "NH" + }, + { + "name": "New Jersey", + "abbreviation": "NJ" + }, + { + "name": "New Mexico", + "abbreviation": "NM" + }, + { + "name": "New York", + "abbreviation": "NY" + }, + { + "name": "North Carolina", + "abbreviation": "NC" + }, + { + "name": "North Dakota", + "abbreviation": "ND" + }, + { + "name": "Northern Mariana Islands", + "abbreviation": "MP" + }, + { + "name": "Ohio", + "abbreviation": "OH" + }, + { + "name": "Oklahoma", + "abbreviation": "OK" + }, + { + "name": "Oregon", + "abbreviation": "OR" + }, + { + "name": "Palau", + "abbreviation": "PW" + }, + { + "name": "Pennsylvania", + "abbreviation": "PA" + }, + { + "name": "Puerto Rico", + "abbreviation": "PR" + }, + { + "name": "Rhode Island", + "abbreviation": "RI" + }, + { + "name": "South Carolina", + "abbreviation": "SC" + }, + { + "name": "South Dakota", + "abbreviation": "SD" + }, + { + "name": "Tennessee", + "abbreviation": "TN" + }, + { + "name": "Texas", + "abbreviation": "TX" + }, + { + "name": "Utah", + "abbreviation": "UT" + }, + { + "name": "Vermont", + "abbreviation": "VT" + }, + { + "name": "Virgin Islands", + "abbreviation": "VI" + }, + { + "name": "Virginia", + "abbreviation": "VA" + }, + { + "name": "Washington", + "abbreviation": "WA" + }, + { + "name": "West Virginia", + "abbreviation": "WV" + }, + { + "name": "Wisconsin", + "abbreviation": "WI" + }, + { + "name": "Wyoming", + "abbreviation": "WY" + } +] \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/docs/design.md b/vite-app/src/apps/Auth2/resources/docs/design.md new file mode 100644 index 00000000..f7d7deb3 --- /dev/null +++ b/vite-app/src/apps/Auth2/resources/docs/design.md @@ -0,0 +1,73 @@ +# Auth2 Javascript Client Design Ideas + +## Lifecycle + +client created + +client queries auth2 service for session state + - for now we need to extract the cookie manually and send that, + + +so - to extract cookie or not - three ideas: + +1. for now - the cookie set by auth2, and read by the client. the client needs to know the cookie name, read it, and extract the token (the only value), to use with the api (e.g. introspection) + +pros: +- the way it works now +- api usage same as non-browser clients + +cons: +- requires client and auth service to be on same host (e.g. via proxy) and path (/). +- requires client to know the session cookie name (configuration sync) + +2. the auth2 service sets and reads the cookie, the client doesn't touch it. The cookie would be implicitly sent in all communication with the service. This simplifies the client, configuration (cookie name), and is symmetric (auth2 sets and reads the same cookie) + +pros: +- cookie known only to auth service +- client does not need to be configured with cookie name +- client code is simpler +- client and auth server may be on different hosts +- in fact, by allowing the cookie be on a different host and/or path the cookie is protected from accidental meddling by the client + +cons: +- api usage is different than non-browser apps which need to use token explicitly + +3. the auth2 service provides and receives the token via an api argument, and the client manages cookies. This has the advantage that the client is in control of the client environment, and the disadvantage of the same (duplication of the more complex client code across environments.) + +pros: +- client environment controlled by client +- client api same across all environments + +cons: +- token must be exposed in redirect response + (on the other hand, token is always exposed via the browser developer tools anyway) +- client coding more complex + (but this is the way we already do it) + +More detail + +1. cookie set by auth2, read by client + +- user requests client resource with browser +- client starts +- client reads session cookie by known name +- client asks auth2 service via api call for token info (aka "introspection") +- auth2 service may return either token error or token info +- token error is same as no token for this logic +- if token is required (none or error) send browser to login page +- on login page user selects auth provider and continues +- ... skip this part in which the user authenticates ... +- browser is redirected back to client either to one of: + 1. requested url with token + 2. auth canceled page + 3. more info needed page +- 1) successful case + - start back at top + + +2. auth2 service sets and gets cookie, client session interaction solely through api + +- user requests client resource with browser +- client starts +- client makes api call to auth2 service +- \ No newline at end of file diff --git a/vite-app/src/apps/Auth2/resources/doodle.png b/vite-app/src/apps/Auth2/resources/doodle.png new file mode 100755 index 0000000000000000000000000000000000000000..23dd44486a44d9054148da99f3e3d8fdc1c4bc82 GIT binary patch literal 6760 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/200px/disabled.png b/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/200px/disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..484e2caf63d8d45e17e32bd9712c038ed828865b GIT binary patch literal 4736 zcma)=cQhPayT!*Cy#^6wqKD`$5-nOx7`=BfdPI~#lpsn*kkNZD(IOaKwCJNnufgCo zqa?)WUE+H0{nq#QJ!|dr+vi#P`TwjPt*4_#Mb1JF005|<>Z%5}9K4kTDe>*ite>)W z3j%KgH5CAA4E*c%;qPb$b<)-b2;6#70EmDEK=g0qRtf~H|Mkxa9s&secMb#qB3%HW z|73J-`R`G`)xSIcN5TSv|Dm~kO`=Y1(;ud6{>gL`600sTOA^>FN zFaZE}3ZbgXM*al5*1xi0 zBYH`5%$5ES9YkRF(SBb8hS=|#beV3G%;~%TKN^tRO z*>5lKEZ1-RRBnsE$@JaP6~fE`-h~b2C;44kWm1GDKoWi=gk;fl2JUA3wa{BqY(H>R z9-Ys6Z42+J5`>5J92!1vnDPllq-EG9Nc!kw`&$11EU z7w5C0X|G^U4PGaex`Z0CES|6%b>BAY-_h{$gA}NrYwBy4id3#h`(=-w)=+fV3AT%y zLS33JmEs$>m-CEh;sruTNN7E0deBI{{qJW?KBfA2oC(}CW#jkNjenQzSE#v5ZR<(P zzI@8a_6`Jz1REIq*4x6$2wSjH%O`~*IKVbmEJ=YY394KCOqz;%t+2J1R+j^Gbd)rM z^;b)1oEK^|=4f9CPu`s7Dd_e%>^pNmACQP{TxR-SyvO@DRr&)r=hYNgwVT-ls(XJo z;?JJlN!5_1OP;@Z_fD#;zMn;UUys1N%kJiKF_`&qZ0I^@L~LgNE=?2-6u~ZS#bjT< z@PJWw5TVFxW5t|g_|&psjqR;WFZAfjHNd>~x}ePPv6Qif3-mI0lI!?XcQ`#gl81KW z#WkDIdLvI=UXShMqBqB%p{$(F5PuDP%%})In9Vt{Va`~cU+a40wGr_Ep#e_Bgf}0r zD#nmp;n(kAW11}8K_U*7LtrBZT8lB}c0J;s$tr)`&pnx%eIe)(>~H;n@4EC)W&ib7 zR}xTy9XTZRvghIgj0aY#1_rmtw^ZCk8G*vZ1*v9rTu^Wg>r@JhQT}xI<@8?*0WCq! zbmCB2b<@O#nbzW}T7%*5j*S>GN7z0si0ORkY zsRQ?m?}4Tcj~Pa9W?`dZNJ35W!F4S?-rzgYd|DuoMct&9es$FnYO0 z=WI%4V#iBP)M@PZR7?BAZHl&tFv+Tsj$Li9O)N}dHBIU(7;I*s)Zbp86q-sq#7NuE zl+C(KUf3GsYIdC{ZASyze_5sn#>@c=)zvArF-gs_1NJ?7ymZzHlBQ~ayL`nJRXX>_ z&lFSf5({MW(CL9yj5a;>vV!>ilxo@#`J+Ck*@lwFw+lcO)sJC8cTwgan4EcO8S~P| zd740gE{Z9%Yq_81GwleY)?o%uu}!Mshk9s#V!P*@D;R^4%^~kAZM)J<*{{vRnhZ*k zViHA{EH_3A=l zY3WVI+}-=lp-h8npJbHcVv>EheFN}68T)(|;v>TkSMEJon_~8NXRj6?gQz*~5`mWw=p;H5 zLfafAWcj6_E!`Oa#4qfqczLx*dbyH1mT9Z}VHokTIz6T#=#$30-N;Nx$fD=?LOmtd zrvIPOjozv%Dz*RuK&UTHVq6P(cy#Y{a4G*}xXZKYv2%#z8cYtSAaeR-}Mx5M3dr;H_R)dUW>YD0*skVl2u!sNU>@b7t%8D?Uwo- zwmz>g1T6PzI0|M7?B-f$wXHdT zHQ%Rc{D!ikcJoN&0v{E9sMz}(gXxJ(6X+jlUo+5u^n(4k{FJ-xak)g=z^Iw&#V4Z7 zh^v;lhG1`NfijhQ+w5i4%77$|m$ZMcZEn1Y$hrv!d+wG0Kp_84jZRj&1VtB%c$;P^ z$or{<@wEXyCQ##FzGw`ca9fvu6ddlab+n$n(>ok1_r|9}7GsuugRk$1AKAs;cVg>) zXHR7pqfkAR=rG;&S=ZOiC5bu%A9j!+!TLDxPXArP9${q@zuNV%pNvigQ54!j%h*+1__O^uc7$sH`%DF85gV8j@)`8#fgt%Y8w0Rm1F7p* zCY*&X;_?Xgv36{Ub<14MhCO(c+xb@X0k}1G@nUJkR;H=iT1twWcASB>U*`GRgni3P zGQ}gdj1wDSxX6*79pxdEVa|JX*$^*v=0Wu~Rcg%-C=sEdNvG+yhZ;w#B z)FVata?pnyat-xx)=Rta<^vj@xZaPsg64~|^{ zl@D-+zu?f4tAmW!xbQ;<2H4oM1ZGL5XbJ_>P}koBdodn9L*zK}T?@z4X?Mz{*aBsz z&dA;AaMryo+drdm^e1%-tp;x#8Dv|duZ8;LQWHWBrL3xfI!T)h2})u@TOI|(6ehM| z%Hf$nRZCKhpWC6jsa=Me5>CaLTPj}*!3xCRr!7o{?j&yrM@NgpRz8PzCYBZy-kf&(_48irRzw<8b61HEjP-i4 zzGZ6cELFQ-bR~(J9!nk5{$($?Ff|%o<5f zm-Bpn9YUOI45IuYRf}!W@YvG{9t>w$ zj{F2KN!#}Nk1=9W2+8GQ3HigjlIyZ!Hq^jm_=-njC5uVb6?-L^)tnFu1Ae!DcWm@kA*ZP%!d@pLpKvge$y(9Zq2DH% zIpnxDXw|8lg`CuO4k1nuAy+IoTmS9O$y4{2x-(0F0K0EgS8+O*#T{RO4~-iwgknHkaI0O4e)qydkN8Tn^`HDrOee;m3msAKB%Yh2fkaM?{g zV(PpTYtL+%i>C07&@cz~u)4fIWzBnz$8}r7;S$=Y#(UWp_Y+BZaLQ$G7Cn{gv|gCg zo08eFI-RkLii?FDb(*F&IWt2xRf^;H(D4=%UxKLIaw+Och@JSO5})hqUv2q`4w1E2 zsedmnv^llKc;fJgoR&vX-lg%=TO2bOqy*g@l=;2aSSCDd5;9}25Ly!fK#1YR6>u^! zGDvYg8jnfq=_Vo5LcurJu(p}rS4>F3fbl1Io#B9(Cl$0ha{6q0KaM-a9IwxmH+%F0 z*o`yj&)0}L6f{q)cSI5mBOh0Q(HeFiQ};trL$QD1GV^kAL0aYDrR7Qu%b2a<$PjkK z+)S*>^M0_E*i4oy#0UOT+h3=nEl=~u2uh8Ba~n-``4AoM6HR6_?WK)VNXzD1YxLLN zeCq$LF*Iou@5;TTB}_^&633-}eU44oKLatv?^ku{7Pe5kxrT@2%GtM@B$s&}Q)>-= z{mM7fv$SMRk35Jf@b-~Zz znC=U&&8+HRZ6XBYCj#U_-`~eFf%Znce}XE+IB}Bt7e9Ln8s>D%=be68q;SE}26Sm` zs&-_3qSOwp=`=g9i1l~;oq=9%F!B>?yG>(hQ4GwcW24}EOgHuVdvW-r$7?*B!-kHPTGM07~V-s%P1hhJ_YKF5H*}7T=q;& zFS(d>qPOpO5VidS-j0=fw5dkzq+=eNn=St^7iH`r{K{eEb^ELn9QI8*!BELxnVifu z?$pDTcv!#a#Tgj#I6#0_--A+x_aU3zK>DEp$+f-1xPG9QA0@>y>+@^2$Ox#DXF$%v zF&7D~1gp&#JE#Uj#~TLYHi~mwQlk$&XI0^%tAtNb1W*;?^}drQ0-NTdyp~(SR@6fL z9PPp)I>c^hh|bAUTduGaxpLtgUxJENF0H5}=DHD*Cbl0r4Xhy@Nky#rLiAPcs0gQW zc&HQ#3T*a#h00)RW!H5vq$=hnJ--9*EJm9h!@W#1$zkr>sv=2^rZ-FDFZ{Nu zxDMo7vKEb literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/200px/hover.png b/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/200px/hover.png new file mode 100644 index 0000000000000000000000000000000000000000..62617d35a0907ff2b49169b025548fac7b3c46e1 GIT binary patch literal 5237 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 D`dh(w literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/hover.png b/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/hover.png new file mode 100644 index 0000000000000000000000000000000000000000..4e193df3e2b612ba6b3fa2099e4174ddabc85cfd GIT binary patch literal 4558 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 Pzlbi}K(iKR_w0WFSxkII literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/light/btn-disabled.png b/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/light/btn-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..70db5ba645878f01b2c77dbcfe168d9efd57735e GIT binary patch literal 4940 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/light/btn-pressed.png b/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/light/btn-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..376b0da415fc87e52846d2597dd9e773828c21d5 GIT binary patch literal 6545 zcmbVRcQ{<#)*nP~36dyLf*_b?3^N$Ljp!wUR~R#+n-K=1izG^-Mi->05hZ%GXwgNB zNDw5tAfiW$Z*uQ_@Av(2pZmvmp68ss_d2Wo)>`N6=bUI`LmgHoUM2tlz>3z@G^LDv zloP~2N4dJZj!>cuJS44KBr~ET$q(a&2dLqQ4tOE72gV6+ipSvm@ATp+Of+N{^IN1_ z2KowEq6Y}`hX+LV@T5os07@!kPYl)#PZDy#JGl^0!kdjP!a^=Ml&~e-0Ak>&fp>P% z4e-L71sIxR1KhAkoUn?rkP=yeqQC=B!U&N)+zH+aWR&nf^eRy1f5>2Ap?|QD+)%>* zbn2FYv5*GQ3oir*$pNuY7(z%M34+3r2pL&vAsGl%4h%tpp|U^-Q~`oifIx-*bqG_e zdEp!tOf|LtWs9;x2|JTWo(f>FpPwJd4+bK7If0=_BoYjf0n5k$DI7p=e*y_Z1`@nQ z{??$0_r`j;c#>R*1ff3~F%Co@5=xlj=|4m8@H8;^w_<|#zks4Z1}0-X!B7wc?BVez zu77ZQlT7jd>&AcN_BQwT#Dh)o-b5cSEF~X~B7X~0u>0?Z{xDL!Q84myp(F+4u1UoD zc;E>nv?fZJatDNS!70chv2sWZ3=hQM5D1_w1}6hV;<0i-7(^b2g~`ew-kUe zNLhpyL>nQaEsxNGLbc@7Au{S38gMOjO{fM;0}B6J7ESObVF+0K-?m*Sw*Msy{jahL z8eVt|iRficB)b1y1;)-q64Be4=qaS3@h9u@LJ|fTtP9}}@%o=c{WES&yqAkF9;fX^ z^bq<7(h4sB!3#$yLJkJQ!+=OE(h(>NgFz@*IADMfJVM67QP$BB<4B3(pYpi>FM?o- zQ{X@4@_)+bZxW>@|4jeg43x#c+X+vg^pF>&S%NRiod5tA%h8%@=H$usY=6&>7OCAv zkJEzbE2|y=-7CQ_+`}bG5!Eoshp}$gtEUhi6WD_R!Rec^=6;Hwt$pjkz_Mr5Y%gLZ zm{<}VV!7Kn7~H6F^p!+!74iD5Ei!nig7xdBc{5YXapN&+wrV;s^qedl9<9NK9FwC( zsNU(hsuK1%CFNRYXQ!!!g^ylDqKJ;3x_Y>*tSq8xaTu?qrlwXIavE^``t_|NkhHY^ z+}s?lC*kT`C0Ky`m1^QO=H5WI;z2=7OpM*9j~^c--8M0~`t92{HsdP|(s#YK7to7$ z{FvC-W{%dYhJN4Kn5@C)>croK)PI3-FW{8+#>@n{6Ev+2%xrCedwY9>B?_d83qdH~ z^;@(tiVyDJ*N=&cV#rbO`7R>CSaeYWAR;96OkRiz&xYLf7UH@qFLP;(;lL@aP)@y#oqVM{ zk&fo!O4NC@QEcLK6enIafId2!A?5pIfD7pbfz6hhWEjSQtJZlvBFyI}kaF;L@+zMn ze+p+xO}ba1nk+)X_{cXl%|>iLkx$zv={#2O1?Gy^N+sRHeu%Q;*z6^I@5x1^_6=Fx zTb>D;5wyp$&9$3Si7HJshBt{QX`>maKF7RBUcorkBaO>o+MH6cwvwZAKlvW18!eXS zH6t2in}LF2(xSTU`fnGX?DrFY*II8gONq)NdaPI@K^o7vBf7r?_@h&$t&^loFjwcc zS6k(Ic8X0x$FDI$LUUur50%S}fB)JKcv)2D#%a%nB%!IVeL?(it6l65wA)OMf~1}M z^>s@U{*pS+#x!PEKlWn~+=umh#n+y0oru1IFWBt^aNVm8L4vHoYpG!?o=8xz;I(1T zKnsKBrk(f=Q>SW8&7yvK-S2q)7Oo6faKbz72wfBZl&q3sv&gdu=<4?|K}n_Sc8)*N z;w=~T^v#QQb>mXX&?BSQpw@5`SP=y-j&piZTjDZxmwU!h4~ngtE*PFhDWhdJ6B$i? zE3HEg`p){^V!QFWLz)>oM)&e8ml4q{?5UTPdmry1X^XX%fS*fv#i1be{+T--f;{On z=ru1kq5`QmEnpGwcZ zvE!I)Uu+%WtQ2q24^9#?yO7EFH6^Pk^~|cpQXt?5-{CuF-Ydb~fp=CO)95ur>wE>I zEn3MU`&t2c@A?vE7$2wEfvf_VEdsx;>uA2gefWVj4QjIfOO5Kb-_HrRwvq0ZjN=)) z!}c&Kr7@q|Vqwh!gGc0?gNn^Tag(z{LdWd>V6D;Ji0kS7s^Eb;Vm@{&NChWVwWFty z5N&_0(j&>4sDwLd_a&m^*^)%ArF?(###$^+MqGbFCKnze*+*-indcwBr0arzRb@o3 zKP>Ne5}ed%YinzG)*UaH#wl*N0&8(B{Y;uM(wCQ$yFF|+k+T8yHHuh59iG&Fvjwqn z>KPcsCa0vV+U0Bn<*bsyyH~Om1v?>PY(cgf*eAO2kC;YUF4CDJ7RJ97#;{(D^xq;v zrg#z0CaC+2EfW^f%$?0ku`tr#+_(tgQMqOp_v9AZs^&sU_$fQlR zb7FF8YG3fdw78FtPr$n?bnL9G9<;qDhdb9qL^Qf$`3n6f7pr(xA(2uyOA>;Q_g#>q z4Ww0JOS|Bjyuw1a<5!mDso9EteI-^^lkgeXb?*_tgSZGfdP(nEAH!F*W#|&@2q`n5 zR?PB)OJ-E^o1XJNU*j#ui<1N~vOPLdeyhih)o_~cRX+YQ1l7!w<7^Sp8Z53+1gB5- z_pfi->f+91-}+@~>BpeM!^6z(xR2w@ zH~Illf+4@uW&+lLtDh@!sih?)_0-<@tlhM##6>He{OnMOcjoiBPCeUaqql87(DGOxo3LQN+dLx-1JT}!WFea#T53neQ-Wr1r!|} zt>FJbNS3z0%c2~S$IZHoo3a#wBp1yQ9!yc69q^Ws-sqOy!Z|VUvbMw5-H~e~5 zMmu+x3DXVePi3|?OZg@luTYB?Qcr53M0>p_+94tPY_u*h4`k1&&%O<|G0+QfzP!}h zOz7%ocOej)r~yX{NV+2}e!-xhcX!u58U1KjE4$gIJ{1-*buYQb+nF{@ahRLgKCGSx z>|x`f&Ev-LL9nYMV9ULxsnM}IsO!zI8=)l-Nonb^T6ezR=_IFxt5^=!^%0Ys9*XO> zcwP?;*++Ke)wkx$HT%mn@?Ar&?gbWhp-qGCF9?9#fcLI{>d!M0n9(v&#I0Xk&Bi&G zpYxx~|HyPnbt%rEeGIC7>^>2!KO9dJzV0OcylLrAO~fmKw5d`uX6HJ1Ft=x*wul6 zG!FxIkuaE9t^34_0@l`ifk~@3p3h5c8*jETr27vk)jxR_6H2Mw%(HPD;zwxx?B=tw z+Ok9#Ti4-Ynq6_cZpgVY1NmvuW{T6LG)p?L#I&OerggI+jd}U`t5qLklEe&5!%V<# zTDH578hDHd1j5=Rj7aG>LLE9-+XNgG^@=V}uX;q9^>#JWNU6hoN$ANmAv*q1LSyL2 ztiJ2B#FLuG?f@BYy@)N?cOyn1O?bsU(W4B13B$Y3L z`6vGShz#WQj&vM|_F~-Wb}aqE*9y*Je?-y5C1?iZlZB;i{=ng+TlsZJ$*My>%rsle zaqcqsc8O31(z_s&0~NS$PN$JM(fKaR=50{Do>6Ou@bh{(;!KdWd8|xIN{VD+DSB#V zdzbO0o?TT{)gJ%p;%wl-4~w5PY+@wg;6 zG-&gTE1Hza*&n*@gp@yt`*m@>R=i86Z=jcF6bRMc=i+8f;+1l%yIdsJDvEVS?AsuTdQ`!CoZ~Zu-&GkjZ`BwU4jT zGOq#RWFWjTard=2a(&3eeC4k@+7J;Rvck9OSo1=qJ-g7;Jpmh*JxMM)c7c+~yG}vRAUM)Wjy}iA?Z9X5stkYO%^?{u^9H0>|fHH(3 zhi;G&5)!J)wn}f|zY56O1VZq;$fL@zVQ~Q_K4*G6mT~7}?-hcO75qO9R5NXMu z0T9Q1PDLjW3poXxLuh{C#Y{|g?7p+{SI?j&O^ebPdDRT)OTSl~p{1{P^ipGd?w;x@Dz?qjBTh;E-)f~}Dzg0=(4ed*! zGya+Jt4$U%2LJR|?r6F)4FRy>B4btRdU`R8n0@;<#{fWd_wH6hBpJmBW7wGI`O<3i zLV%ki_Um9z45K&0OZKQK>XG-*5+VTr}yTA0LH$rM28os zodK9+5H-yyHn>HW$>YP_<;#S`Ln+@P68lzL%zhs@H1xBjw93N8I*_Mcqy(c}QfC+5 zN-Orn%bmU6-`$8dtQ??TlXfiW{B$JPY~ekAY7cd~nt5L2fs2J}c#Y50=Obac7ah1t z&-;&{cT4i>MxQ(YOGpfN){XLf7_e#n5wk%glSdHAUCmM6WA4|-8%FfRSmR`tz<~yfjO>ZS@(MIdoT!5t1b->*2L<6Bf*w0 zJp)83_%ESa3;4I+*f5;*&>&ns9qBl8Nz*P-b8@sM7=}*qQ6Dhh{6+n=Y%rxIG$l7? zg;{hjLSsV5e8sL5 zzL@qcE2aF6iLS#bo1EVl+Uee;$A$5EKYWXg3p(BV)Mu~jWW;$-ZbjZ7DtLXZOlxY2 zKApw$Mapc*@y5;Nr`yieL(0ec*}>c&nW(t44)671#x~y`8y*8ZOH}S|(wj}$GdfD9%&6n0mR>sP6j&WH8J?e)66Okl#Ul@t{gu60pX5GRxXk zx0=Hx#cs$aQ68LAI(QQLw*Kbr-*xEkJ7YB!jJ={2s)#=QE2a!x?JD+a_Mn`NoQ~bq z4{-K4F_ta?2E!snPV3&~Uj4ViQprAP&c9RZmM)u!h${YOJ*1*{Nx#$E+iNY*HCGO= zx1YRjR#0Sivirfv&78Slxmob$r z_w5a%Q(HiOXD^W`2%-rjJ>K+Y#V!R^UcoTC~(6X&wC&HBzKKNHZ`nQ~H9 z6`}#QHJm?k{4w&vnf`l?_1*gJvFbKPzOK6V7{6*Y-ktZqf*6IWrypLF8lNT4$6^5+ zeJN5?>|A-u;t|UO$4AM>KYb#goY;=V-YK1)s2ELF9ziK$oGN}fh5Nm!RB)qj!nY;< z?&Y;;8E{;SdGLapJT!|OLYAkTfb*A=DErPDXo zvuU;3F@!H({lKFO@a+i$h@YcyEONhAVjog4eX-88rFqe#WyA5=`+4B|%q+RxjU2~d zuF0B3CHbqUe*ZQ4!!M^-CuHX`8`9=1OgOVF#U;H^RGDH{Q|kO@fh^o@$0rHP2; zrfPbL4Y}s^I3<;IR1v&*Sg5LOP0CEiC&_C*-Ew>k?T#z@YeGeVLZK9a95&`>(985;|b%9h0laUN^1J32%{--%;?FUs>S__Y&b*gUd zEa)3fDUe(e?RXzlnIq<=wjaJ*;bP7BCL(Q+N&2=$3C9-#`eTosM)Z z9q)97)*IWIF}ffn4!?xIf1Kg{&bik9@V!TeXpNb9<518cXDuyvy6nl71O#usL23B8 zv(s|z?`(&e>p?#26J}OFrwQ2K$^F@8M}5OHi~$^Lx zb4-Wb5vMYt{&69l__+koc8>~sq8dt}mWRW)=Q%SSS8R+YcEtJdtZ-W_Pwmes+oS1k zkCQ%jrLZMr1z&qS?S<>i1R9J6#k*}y{dt(q1Hv$O!&&6N7y^h5h+RygzF(aci(U&o9oUbdRe8`8^!04 zVi=PUx%oe#2!--U9@fg@z4N%{ke^SAY|PVdjG8&@dFylp_{p5beQ5fNwJX%C=lLTx z3CS&+D?wZUmVvqkg21OLf4?`i$iG<5L;3+M{_)&Z(IQ*)Oh&qDmaZ`O1jVkMqwB6}oq>ZhL9wzwKgtuRuzq>EwqT-JzF%Ue@?rjjGh% z)sPbn3t?V)d6Siu<&lw*;ietS3*XmQUY$$ONNeI{WLfxft8+B}#w@Yob*3Q| zlTQ7O8#kB>4W8^fw}hOQ3HN5mMTQV?L2Ct+z2QA8E2~%5(q$25VWTflt`8qR^ew&J z9Pl*j-r3d9S0h1c)C^fh#kE3PO9S(G%i5DG6o@VzsZh}Ys#HM?e2-5@|NJCDYZ+>m IsoRJD56HzAHvj+t literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/normal.png b/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..460bc100060a33258d07decd855f0093572b08db GIT binary patch literal 4527 zcmZ`-Ra6vEyJbLHKpJ6$QE+Hb5E1ESq>&sLknWJ7V;BJ)8iwv11VKtlq`OO`yThRy z5iZ{QumA0ywf5Qj?6tqA?`fY<4K+nF5=Ign92_!;lAP8ZSKWb^h~Vxf#7NiO5df~G zD1%cv1l+!RcvJ}nlFk(OL@w(gLSpUa=-pI%xrI2h=Y+dD-5BjKRD?l_fvs&J{6E(W_w%#|; zq%%EDV@FsE^dzT2k+LuslxAsy2L{L}O?^ZAn}AaWEEdi)dLLN{5T{6`LVErpntL11 z=io!)oAtMUGMwv$!%R7ynLu#^AL@hg>@rc6ag3Tl{#V!Wr8L^PUkoNUyE!RF5WojW zt7o^z%}GsY}ZH*CJMAMDG>odZdP2p=^@%w-4t}*D$mm6!n9EEdI??KQS03?M~3e zGJt^!Yj5xADxQKTJ_JYu_?MIeXDKXK-E=AKUX<84{LIal=f^40pAyC0d0JTF94M2MjmW2YAT9+}^fxDUipLW! zN=0Xwe55_@ddyS4j~c5t)9@Tt4E72I%dflJOi(#H#R12;g70~?NI4Ag7BvkT6Bt+W z0WvaSNIeOOPv01Mp^)`=Ag1JgM~p^Mwg%Tb8^`=CK>j${E0sJ49DU6qsX?1J7YRC#3`svx917*L zHXJP=9A*+s?Z*JH{X}G`vqRU+V1b4cfmNs>$;Vjad>Byxy_feZN+c8HwQy^{Jb;i8 zug@;+pm(U!>+sN4D-Kbu3KV6qH%^WOnRphz7c5`A?dH55j@r*IKz(O*)mTI~I*wW* zqfZ%lxOxb|e7G!-fs-Kx~j2Zp6$;5vBVZVGug zob=_cC~DsNXtYoqc_8H(!NeT=TvJ-3*x4I0)`G1&UR4Ay<+HPorR!IJ13RnJe}ziu zDD5tm{Yi4iuj_CEZqdMA;~th$PZAA?y;SDJfQGxS*NAw$Ky+mRemLxv_RC)vcnFZ43dE~ysbTJ*e=KUYIl|s(iV{R0y)e3}w0M$e{%W?0s-b52 zRViJff!lNvIil%>!N7;^D#u%VvAT4Sy6<&K&1W zVZL79`Mm>;92}qQR4@ug%v^fcc@)DuxqN+Jn_C34;QCz^Bo)0ShCyM`SD$scjmuH2 zE!`gz4Oy__-o&b}p^3d93y86X+72-j3S+oPvm>1E`?iwKK)zbPcK80x1@=6+R<79b zLtb9cxI0#}CG(?5oI;3l?beBY{UO6(rw<#`jW-=P-5ee})O#f_sD#^1OCaqEVPp4# z%DjDPd56s|LHn0^cPmdr;~@vsZQ^?4jYACLstY%Qh4wxnBP+F}Q9ur%eShZhO7iW! zKfX)HLg7o>8xhr6%$(&foS@Qk)u6*~V~ zsm$2EKw>}osNND~yOV6uHOg%D;ihjGJtp2=#uCwfc_c&@Y=$p5wYB_?Kf%};8M~7l za+bigstS5f!Q1%W^;(N~!a*$9)fF%iV{v}wCZ{#c4v#^b6Ij|HXo&jWXOZ}SXz2O_i zu{{A7+xIJ;RP@I^y{V&Y&P2tP5~@s?9}s5AD<)`$2468}?X? zv4S$w>y-VR)I>;;zF7o8%(DA~NHs31Pd}_MXS_D|ODUlH8}zWXX3T3ll=GK*nsyT3 z9O*1bl44B93$oAY6N|~ha5en6!Fh>Du-ds&g7SGZ9Dm0dTA8lEfYYU=Atl>l`_J^V zj2g$aZ#qBlT(7Uw00a`hf8}eazr@Hh8B$Cw@)G9=(vwzf#IfdXtKsq&1BZE=^ni+= zd}e3zVZYr;Z20?zl|sl{noeAQ(hMX@oueD z-ryN>p+U602T9LtDlxQ#4Q>)0;Ot3V`oNw%zQ9*<$_j40aep^G~e*z?b&dKhe{(KNc?_;#1?Ii675~6tg}`J#mgL z2kddFs6XS2)H0k9O&W^qJTLhD{KY`lj!baKdHO(`p`k#wV4(}R;2!0ggnhP+krFam zzbOCgcBrH-YHQ!ocAY(nj9Nj@vuxPzqluwO!4SP$A&ObGpBlN*gz^9pL%1t*ReTKe zmFr$akprJJf8jFF!R9X6Nz)FQ@Uhs=@TZ}zqHov%r2oJ7%MD$+0K`i}w+S#R^ z;`xf6y{GwpD7V(BMC0y*kxf^U!=tMpjHKa)qmrQM7skC+DJQVFD@SahMLU|Ly-|rB zEWIF=8Bs?ac(4>d`sj_Gnuw!17B`&auxonG%!vO>dk_RoL_zi;&KxD{u-Kp&HJG$` zm?vX{eUVY~F%*yII*vm`Vh${oq_g0sRF(04eE?t}cNWUqVLpc5ZMAzt2KgnLL!e5U zc{`?d6a(xSz?inJ#?n~3@qY6?oY$c+d$@hjJ$AgmCeZkEg2aH=Vy&_E?+dOii7luT zc**6vA!LCle?}U4vi>ym;vm0{=+re(8nS+G%a`b$UF-lgC;wFnJ_Ib=lbBMt)zxwM zO_8#DOk`aDR);_)@cOkM$YFcmW5;4s7kO#~ei=BG=2Fm+`A8fP&H1?NBBp9Tt`S6) zZ%q%W|I8ayE8cmZ?7_Q@qrjTyX~p0myn5q@-+9aA!mT1{n`b^*`CYlc&h$1XjLp)I z&Oq_Mr+rUhwIHg3JwKJyMe=bKD|C&&>HBIvnXW1JULiy9DX=rR&RpetK}_mz&Wx%+ zsu*2<<+d@-QT=KgV5W~n?tz*L0~5sQwfRzuEGUZ{9!+xb5EUQ>9TF)DCt*dZKV&gAW;@IBc>ySsI7VLZrchhI zF3ZvJ7(VR(yec|6rkZim7B%iOL_O*nEN4kWdVixwO7Ggrmg*A)F^y~=cTtPbx1ln6 z9W$DbW=R7U3JfY#DM5U-vR^$^7{u?PZ#JcdY1VZnW1Rd&#pe-BL$gXLRFOnl0aJ?g zmxJ;bYyFiyAlU>Ho24U`K_+K`jww(3Otsn31QDZ~Ui;{IoS25dfefG{RD9}PoR+dd_hiiDU71h9zxTd!VMP-0$QQ&E zwDbkk2D`lu2HdZ+$$Gfy)i47P>+-`s`0aB0s;bVk3zotH-^RpslFZdpPBrdOfm10X zIfDVRhtY_m6b?i_l4m9Xd$_w}s2BIvre$-VR-@Wp(6sG7G9U5#njYW0GR|L)I2F79 zSW?v2GV}A2ykf`AvPpAgH^$mi8`b|Rq)l0b{bhw+XA`WqnY((qXKlyx9D>p{M8xQh zhK*(}{ON{hYYT^&o&9vUSmDvtB1#KAHNBY+i%K7)tpO0)iS?FTWs!ozvb@v!FKP8_ z*Q>lWv*v55@|zZzzdO4<+wPBY40;)Y@#wuA`q(i10r%#VEm_1a84Xj~=eAoe`e_!M z;xwHGw9uQlHgU*Jx5ibDq~!T|I<1qKVHj2NhYz$~7nxx-Q+;lJyBFkq*p>==mjQi} zi2WMn_g#o~_{J3V><9zjn03#}0yohZUi|Pjx|I*T)tWLa8V1mj50$raP?~JwLi7`7 zI$6mIFReAGcEkSto%QS1b#e~;bQ44*|WH;k9```{B zXbEbngKApad)C!H2)Rg`PL9JA^X|fwJflgDX^kVVV^a-ZF3WKnn*w{PJtLcD`id~T zY>|=k?!cvG!taurDC7n)2G+;!qKQlCEqdPq#0Ygy7JLqj)~eAxc@S_!<~h7oPy1G1 zAWJMMT=MTe_CbS4E1y7nCPT`V%`if$CzPT*$q^LF;YK@^e-kBxVx+U= zrVt#Y-Ta9la2sK9R!Dm=gEDEOzv!j@hLrVP;9m8W%Q^My@bQPd#55tOo z^^}cdm#4-hZV3{UK+zU%6@|oq1i6+9Z9e1lg5)U9KD%{E#}_XXcna%<)ic;!3TSA( z6$;}LieEF4&N=c4lVg15VFOx#iqI10wOw^`Lo=Sg<*St>bRxE~^&)0_ep!$&McSON zRXmCwH3ek}`bW2S0$yu9bUotg8Pt^yRnUoNHHywlc{+kIriQuTHVevM8*whSCmEZQ zuo6phO5otUcs|FHAo@AJfpbJ~*~+ zo6@pUC#v1$cK)n%jIQ-$A^d^AwWnf&lPtw^*ZddOkO?e5g!%bQlsBZ*;Zg){>TvD7 z;nKT8@2GdyPrq+V-hg)|010Ohv4t?1j m@&sdr^e=x15dK(cxy3sn5X_}*&r|*P@d1%nlPi^Z7x+Kkr+wo9 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/pressed.png b/vite-app/src/apps/Auth2/resources/providers/globus/signin-button/pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..8e2b29bc3b5382bc9a14a53d2c11badcd1fa34f9 GIT binary patch literal 4575 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/google/logo.png b/vite-app/src/apps/Auth2/resources/providers/google/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e795c0794b7a527c25743030b2f5b0bb0818d1c9 GIT binary patch literal 1323 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 L22*WRv5EW-l`j<6 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/google/signin-button/200px/normal.png b/vite-app/src/apps/Auth2/resources/providers/google/signin-button/200px/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..48b8ce6e8f4984d963f6d2bf09b045d1376f6533 GIT binary patch literal 4293 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/google/signin-button/200px/pressed.png b/vite-app/src/apps/Auth2/resources/providers/google/signin-button/200px/pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..a78c42a5e8876043e74f936edefe452c28657dee GIT binary patch literal 4314 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 F`X6y83#|YE literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/google/signin-button/disabled.png b/vite-app/src/apps/Auth2/resources/providers/google/signin-button/disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..f57a56e40c953b663ab94a11b311f49167872d19 GIT binary patch literal 3597 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 OVfD4)T1}cyUj7Hk;&=T3 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/google/signin-button/light/btn-disabled.png b/vite-app/src/apps/Auth2/resources/providers/google/signin-button/light/btn-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..735d17eea04ff2022721523504b4a9444fff49b2 GIT binary patch literal 2308 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/google/signin-button/light/btn-pressed.png b/vite-app/src/apps/Auth2/resources/providers/google/signin-button/light/btn-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..e286c89accc00d2ab9f9a48a70b84cc1ce34fc6f GIT binary patch literal 4135 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/google/signin-button/pressed.png b/vite-app/src/apps/Auth2/resources/providers/google/signin-button/pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d529b544009b383cc714d393cf8f0152ad1505 GIT binary patch literal 3989 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/google_logo.png b/vite-app/src/apps/Auth2/resources/providers/google_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e795c0794b7a527c25743030b2f5b0bb0818d1c9 GIT binary patch literal 1323 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/orcid/logox.png b/vite-app/src/apps/Auth2/resources/providers/orcid/logox.png new file mode 100644 index 0000000000000000000000000000000000000000..fa59b2780a6ffdd1c58e122a3c56608fd443b4c9 GIT binary patch literal 2119 zcmV-N2)Or&P)Px#32;bRa{vGf6951U69E94oEQKA2kc2iK~z`?wODO%R96{(&bjyQZZ@H?P?8`G z)K)qr15U-tNOg26mX^fYKeprO$S5PJ4AA0N?GLA>wWB{;>o9yZ8T&CRQwA)V3IsxDk|VFdm>qyTg*@&->s`l#u_=D(5qSk|JqkOq0$vC% zx^uY8cw^xlp9NPec^w>oD}MaS^vF!v-6FsZudJj=)&}54F@z?H=nm(!HqcIi@mB~E zN0us%$)`{-^ujV+a(_T`kE0}_ZxUUN=4Knd`(4;hV$^-1;N|MY#g>yp!RzK>4loq{ z%oyzB$7SrDWHR+IqyNdo%EH1Ld}rVFp{jD9Hs1TpLh{@fgKQN*p_N2qv>(Ku(2DyM zEN>@#=X#oL7Ugy^JeI@qpFlqAFih^H>_5X#*-bMs8X54ZQ7V~8mA2_Z z(}FFl9)WK)!qP9oQorMKH9>C1*2XS4m7k!6e*~?n2_Ep(Z4;@R?6`()?g*4cCB%~Q zkrwnBs-F8kH{6bLmj-vx4|r16fgoXumST#O!Xi*G1IcPBjb%6PtV+ot zI;BOQp#@>yWkQKr>Ihhs)^M>>siNS>cX&`^G;&V(HfG6WU!+d;&_%Q&HwuA?%CH}5 zGNfN=%2b3yqfbM?(I&Doq;v+S+yXYX$1!lWxMo_7K{w~?s(rjYV31DxXjVM<6^+;c zQj9tbO*cokh=L3H{E|eH=3@Y)yD{sPAwyr*q<#}7=GkjdV7yk=GB!yC1;)e;1+u}p zUM%v@)6=wH=OA`hduW#;_A4KSh5rDa2L63Nh$C-6~PL_L{NG@`eThaGO!ovszb12XY+!>B{IO z?O($;ON#(Se#ffA$hp5@kHM;FjffcoYpQ;pYCj6OcHUUHM#qTT9>Ml*073Z-`22IE zn3mvuDqsD1LnHNv02P|{)WOzsdHSch>2bPyNQ@F#Q@|=-6p(!cnKNH!|0Q0vF43BU zti!y`sJ4LXV0R#S?qO_c$V~+sW#xYQS%y+Runm>Z=GenTbDYX|;(>z;82I1gvIZ7^ zxk$u0=P*fjBd;E3{kCA4yLrMCdGsi15^eaY#GssL%1vR@;acPd9)qo(QMh-vg=?oh zMDo3eZ4Em{)i*b5oL#z)rRbOB;B){oI2)LnFPtP@T9lBkN!LOx$fK92`6YLXY}@(W{R z%70P#;mb*6GB=ahR};@`*uH9~sFO-k4^Q>rSGQ#+)L;C)`;q_V<$jF)eHDmT&BV~~ zo#ehHP~I+V`SOtv3$u^~-O?2h^B!6r*1>T8|MN`qXGVQ}0+^m+A})iU`8=V%!*FUQ zxZdcdyeybw(B4W`XExLOzvP1tsKeE{KCaFU1e`PgAk68Fr+(G74jFc3IlbFkTSlSC`SU(9l|E7z zN>p+orBGW%x*p`klv@^37OBWWTvd`!uO$uL$ncrZq^cnc@WAFha@$e3bGjy521@`1 zq)RuP5b~ xv(PRNLonujy6!aVaW9hg0G?dQte-k@{||7c=7lsC4iNwV002ovPDHLkV1h3?5BC57 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/200px/disabled.png b/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/200px/disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..cf7018f7d6c0a24438213bf07189ce07487d18f9 GIT binary patch literal 3402 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/200px/hover.png b/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/200px/hover.png new file mode 100644 index 0000000000000000000000000000000000000000..0b30c2d8bb68df8ba03428b349d2d57dd31f9325 GIT binary patch literal 3888 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/disabled.png b/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..c8d22bc5ff314ef7c35e443e05fe14c501d9830f GIT binary patch literal 3524 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 DWdApd literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/normal.png b/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..e960c66272e7f55ee01e31df684c382a0ff6f5bc GIT binary patch literal 3833 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 + // `; + // } + + // doFilterFeeds(filter: string) { + // if (this.state.feedsState.status !== AsyncProcessStatus.SUCCESS) { + // return; + // } + // this.setState({ + // feedsState: { + // ...this.state.feedsState, + // value: { + // ...this.state.feedsState.value, + // feedsFilter: filter, + // feeds: this.state.feedsState.value.feeds.filter((value) => { + // // const {show, {id, feed}} = value; + // return true; + // }) + // } + // } + // }) + // } + + selectFeed(feed: FeedWithId) { + // TODO: refactor to select the feed item first, then set the navigation for + // Europa w/o actual navigation. + this.queue.addItem(async () => { + return new Promise((resolve) => { + if (this.state.feedsState.status !== RepeatAsyncProcessStatus.SUCCESS) { + console.warn('Feeds state not SUCCESS, so cannot select a feed'); + return; + } + + + if (!(feed.id in this.state.feedsState.value.feedsMap)) { + this.setState({ + feedsState: { + status: RepeatAsyncProcessStatus.ERROR, + error: { + message: `Could not find feed ${feed.id}` + } + } + }); + return; + } + + // $GlobalMessenger.send('europa', 'navigate', { + // path: 'feeds2', params: {tab: feed.id} + // }) + + navigate2({path: 'feeds', params: {tab: feed.id}, type: 'kbaseui', newWindow: false}); + + this.setState({ + feedsState: { + ...this.state.feedsState, + value: { + ...this.state.feedsState.value, + selectedFeed: this.state.feedsState.value.feedsMap[feed.id]!.value + } + } + }, () => resolve()); + }); + + // navigate2({path: 'feeds2', params: {tab: feed.id}, type: 'kbaseui', newWindow: false}); + }); + } + + // applyFilter(state: FeedData, feedsFilter: FeedsFilter): FeedData { + // function filterIt(feed: FeedWithId): Filterable { + // const show = (() => { + // switch (feedsFilter) { + // case 'all': return true; + // case 'unseen': return feed.feed.unseen > 0; + // } + // })(); + // return {show, value: feed} + // } + + // const allFeeds = state.allFeeds.map(({value}) => { + // return filterIt(value); + // }); + + // const feedsMap = allFeeds.reduce< Record>>((accum, feed) => { + // accum[feed.value.id] = feed; + // return accum; + // },{}); + + + // const feeds = state.feeds.map(({value}) => { + // return filterIt(value); + // }); + + // const selectedFeed = (() => { + // if (state.selectedFeed) { + // const selectedFeed = state.selectedFeed; + // const filteredFeed = feedsMap[selectedFeed.id]; + // if (!filteredFeed || !filteredFeed.show) { + // const firstShown = allFeeds.filter(({show}) => show)[0]; + // if (firstShown) { + // return firstShown.value; + // } + // return; + // } + // return filteredFeed.value; + // } + // })(); + + // return { + // ...state, + // feedsFilter, + // feedsMap, + // allFeeds, + // global: filterIt(state.global.value), + // user: filterIt(state.user.value), + // feeds, + // selectedFeed + // }; + // } + + applyFilter(feeds: Array, feedsFilter: FeedsFilter, selectedFeedId?: string): FilterData { + function filterIt(feed: FeedWithId): Filterable { + const show = (() => { + switch (feedsFilter) { + case 'all': return true; + case 'unseen': return feed.feed.unseen > 0; + } + })(); + return {show, value: feed} + } + + const allFeeds = feeds.map((feed) => { + return filterIt(feed); + }); + + const feedsMap = allFeeds.reduce< Record>>((accum, feed) => { + accum[feed.value.id] = feed; + return accum; + },{}); + + + allFeeds.sort((a: Filterable, b: Filterable) => { + return a.value.feed.name.localeCompare(b.value.feed.name); + }) + + const userFeeds = allFeeds + .filter((feed) => { + return feed.value.id !== "global" && feed.value.id !== "user" && feed.show; + }) + .map(({value}) => value); + const global = feedsMap['global'].show? feedsMap['global'].value : undefined; + const user = feedsMap['user'].show? feedsMap['user'].value : undefined; + + // const selectedFeedId = this.props.match.params.get('tab') || 'global' + + const selectedFeed = (() => { + const feedId = selectedFeedId || this.props.match.params.get('tab'); + if (feedId) { + const selectedFeed = feedsMap[feedId] + // const filteredFeed = feedsMap[selectedFeed.id]; + if (!selectedFeed || !selectedFeed.show) { + const firstShown = allFeeds.filter(({show}) => show)[0]; + if (firstShown) { + return firstShown.value; + } + return; + } + return selectedFeed.value; + } + return global || user || (userFeeds.length > 0 ? userFeeds[0] : undefined); + })(); + + + const notifications: Array = []; + + for (const feed of feeds) { + for (const notification of feed.feed.feed) { + if (!notification.seen || (notification.seen && feedsFilter === 'all')) { + notifications.push(notification) + } + } + } + + return { + feedsFilter, + feedsMap, + allFeeds, + global, + user, + userFeeds, + notifications, + selectedFeed + }; + } + + doFilterFeed(feedsFilter: FeedsFilter) { + this.queue.addItem(async () => { + return new Promise((resolve) => { + if (this.state.feedsState.status !== RepeatAsyncProcessStatus.SUCCESS) { + console.warn('Feeds state not SUCCESS, so cannot select a feed'); + return; + } + const {selectedFeed} = this.state.feedsState.value; + this.setState({ + feedsState: { + ...this.state.feedsState, + value: { + ...this.state.feedsState.value, + ...this.applyFilter(this.state.feedsState.value.feeds, feedsFilter, selectedFeed ? selectedFeed.id : undefined) + } + } + }, () => resolve()); + }); + }); + } + + doFilterNotifications(_notificationsFilter: NotificationsFilter) { + if (this.state.feedsState.status !== RepeatAsyncProcessStatus.SUCCESS) { + console.warn('Feeds state not SUCCESS, so cannot select a feed'); + return; + } + } + + async doToggleSeen(notification: FeedNotification) { + this.queue.addItem(async () => { + // But this won't trigger a re-render cascade right now, so + if (this.state.feedsState.status !== RepeatAsyncProcessStatus.SUCCESS) { + return; + } + const feedsClient2 = new FeedsClient({ + url: this.props.config.services.Feeds.url, + token: this.props.authState.authInfo.token + }) + try { + if (notification.seen) { + await feedsClient2.markUnseen([notification.id]) + } else { + await feedsClient2.markSeen([notification.id]) + } + this.reloadData(); + } catch (ex) { + const message = ex instanceof Error ? ex.message : 'Unknown error'; + //{title, message, autodismiss, variant} + notifyError(message) + } + }) + + } + + doRefresh() { + this.queue.addItem(async () => { + return this.reloadData(); + }); + } + + changeFeedsLayout(feedsLayout: FeedsLayout) { + if (this.state.feedsState.status !== RepeatAsyncProcessStatus.SUCCESS) { + console.warn('Feeds state not SUCCESS, so cannot select a feed view'); + return; + } + this.setState({ + feedsState: { + ...this.state.feedsState, + value: { + ...this.state.feedsState.value, + feedsLayout + } + } + }) + } + + render() { + switch (this.state.feedsState.status) { + case RepeatAsyncProcessStatus.NONE: + case RepeatAsyncProcessStatus.PENDING: + return ; + case RepeatAsyncProcessStatus.ERROR: + return + case RepeatAsyncProcessStatus.SUCCESS_PENDING: + case RepeatAsyncProcessStatus.SUCCESS: + const {isAdmin, global, user, userFeeds, notifications, feedsFilter, notificationsFilter, selectedFeed, feedsLayout} = this.state.feedsState.value; + return + } + } + } + diff --git a/vite-app/src/apps/Feeds/components/feed.xts b/vite-app/src/apps/Feeds/components/feed.xts new file mode 100644 index 00000000..162ce4d2 --- /dev/null +++ b/vite-app/src/apps/Feeds/components/feed.xts @@ -0,0 +1,156 @@ +define([ + './notification', + '../util' +], (Notification, + Utils) => { + 'use strict'; + class Feed { + /** + * + * @param {object} config + * - runtime - the runtime object + * - refreshFn - gets invoked when the feed wants to be refreshed + * - feedName - the feed name, shown in the header + * - showControls - boolean, if true, shows controls. + * - showSeen - boolean, if true, gives the option to dismiss (mark as seen) notifications + */ + constructor(config) { + this.runtime = config.runtime; + this.refreshFn = config.refreshFn; + this.userName = config.feedName || ''; + this.showControls = config.showControls || false; + this.showSeen = (config.showSeen === undefined || config.showSeen === null) ? true : config.showSeen; + + this.element = document.createElement('div'); + this.element.classList.add('panel', 'panel-default'); + // xss safe + this.element.innerHTML = ` +
    + + ${Utils.cleanText(this.userName)} notifications + + ${this.showControls ? this.renderFilters() : ''} +
    +
    + `; + this.ctrlState = { + includeSeen: false, + reverseSort: false, + level: null, + verb: null, + source: null + }; + if (this.showControls) { + this.bindEvents(); + } + } + + bindEvents() { + const ctrls = this.element.querySelector('.panel-heading div#feed-inputs'); + // toggle eye + ctrls.querySelector('#seen-btn').onclick = () => { + const btnIcon = ctrls.querySelector('#seen-btn .fa'); + if (btnIcon.classList.contains('fa-eye-slash')) { + btnIcon.classList.replace('fa-eye-slash', 'fa-eye'); + this.ctrlState.includeSeen = true; + } + else { + btnIcon.classList.replace('fa-eye', 'fa-eye-slash'); + this.ctrlState.includeSeen = false; + } + this.refresh(); + }; + + // toggle order + ctrls.querySelector('#sort-btn').onclick = () => { + const btnIcon = ctrls.querySelector('#sort-btn .fa'); + if (btnIcon.classList.contains('fa-sort-numeric-desc')) { + btnIcon.classList.replace('fa-sort-numeric-desc', 'fa-sort-numeric-asc'); + this.ctrlState.reverseSort = false; + } + else { + btnIcon.classList.replace('fa-sort-numeric-asc', 'fa-sort-numeric-desc'); + this.ctrlState.reverseSort = true; + } + this.refresh(); + }; + + // level filter + ctrls.querySelector('#level-filter').onchange = (e) => { + if (e.target.selectedIndex === 0) { + this.ctrlState.level = null; + } + else { + this.ctrlState.level = e.target.value; + } + this.refresh(); + }; + + // source filter + ctrls.querySelector('#source-filter').onchange = (e) => { + if (e.target.selectedIndex === 0) { + this.ctrlState.source = null; + } + else { + this.ctrlState.source = e.target.value; + } + this.refresh(); + }; + } + + refresh() { + // get filter info from controls + // run the refresh function + // update this feed with the results + this.refreshFn(this.ctrlState); + } + + renderFilters() { + const levels = ['alert', 'warning', 'error', 'request'], services = ['groups', 'workspace', 'jobs', 'narrative'], filterHtml = ` +
    + + + + +
    + `; + + return filterHtml; + } + + remove() { + this.element.querySelector('.panel-body').innerHTML = ''; + } + + updateFeed(feed, token) { + this.remove(); + const userFeed = this.element.querySelector('.panel-body'); + feed.feed.forEach(note => { + const noteObj = new Notification(note, { + runtime: this.runtime, + token: token, + refreshFn: this.refresh.bind(this), + showSeen: this.showSeen + }); + userFeed.appendChild(noteObj.element); + }); + } + + setUserName(userName) { + this.userName = userName; + // xss safe + this.element.querySelector('#user-feed-name').innerHTML = Utils.cleanText(userName); + } + } + return Feed; +}); diff --git a/vite-app/src/apps/Feeds/components/feedTabs.xts b/vite-app/src/apps/Feeds/components/feedTabs.xts new file mode 100644 index 00000000..9ec2df35 --- /dev/null +++ b/vite-app/src/apps/Feeds/components/feedTabs.xts @@ -0,0 +1,237 @@ +/** + * + */ +define(['./notification', '../util', '../api/feeds'], function (Notification, Util, FeedsAPI) { + 'use strict'; + const SEEN_TIMEOUT = 10000; + + class FeedTabs { + /** + * + * @param {Object} config + * feeds = list of feeds in order they should appear (key and full name) + * - [[global, KBase], [user, Some User], [group1, My Special Group], ...] + * element = target DOM node to render in + * + */ + constructor(config) { + this.userId = config.userId; + this.isAdmin = config.isAdmin; + this.runtime = config.runtime; + this.feedUpdateFn = config.feedUpdateFn; + const feeds = config.feeds; + this.feeds = {}; + this.order = []; + this.element = document.createElement('div'); + this.element.classList.add('feeds-tabs-container'); + feeds.forEach((f) => { + this.feeds[f[0]] = f[1]; + this.order.push(f[0]); + }); + this.notes = config.globalFeed; + this.render(); + this.setUnseenCounts(config.unseen); + this.renderFeed(); + } + + render() { + // Make the general structure + // run addFeed on each element + // select the first one and refresh it + this.mainElem = document.createElement('div'); + this.element.appendChild(this.mainElem); + const structure = ` +
    +
    + `; + // xss safe + this.element.innerHTML = structure; + this.order.forEach((f) => this.addFeed(f, this.feeds[f])); + this.element.querySelector('.feed-tabs div:first-child').classList.add('feed-selected'); + } + + addFeed(feedKey, feedName) { + const tab = document.createElement('div'); + tab.classList.add('feed-tab-btn'); + // xss safe + tab.innerHTML = ` + ${Util.cleanText(feedName)} +
    ${name}`; + } + + groupLink(id, name) { + name = name || id; + return `${name}`; + } + + userLink(userId, name) { + let viewString = name ? name : userId; + if (userId === this.currentUserId) { + viewString += ' (you)'; + } + return `${viewString}`; + } + + buildHtml() { + return new Promise((resolve) => { + const actor = this.entityHtml(this.note.actor); + const objText = this.note.object.name ? this.note.object.name : this.note.object.id; + let msg = actor + ' ' + this.note.verb; + switch (this.note.verb) { + case 'invited': + msg += ' you to join the group ' + objText; + break; + case 'shared': + msg += ' with you.'; + break; + case 'requested': + msg += ' to join the group ' + objText; + break; + default: + msg += ' ' + objText; + } + resolve(msg); + }); + } + + getLink() { + if (this.note.context && this.note.context.link) { + return this.note.context.link; + } + else { + return ''; + } + } + } + + return Base; +}); diff --git a/vite-app/src/apps/Feeds/notifications/groups.xts b/vite-app/src/apps/Feeds/notifications/groups.xts new file mode 100644 index 00000000..bddda5fc --- /dev/null +++ b/vite-app/src/apps/Feeds/notifications/groups.xts @@ -0,0 +1,111 @@ +define([ + './base', + '../api/groups' +], function ( + BaseNotification, + GroupsAPI +) { + 'use strict'; + + class GroupNotification extends BaseNotification { + constructor(note, currentUserId, runtime) { + super(note, currentUserId); + this.runtime = runtime; + } + + /** + * Updates note info with missing information. Currently checks if the note's target is missing + * the entity name (if it's a narrative and is missing the name, for instance), and makes a + * call to the groups service to get it. + * + * If that fails, just silently moves on as a no-op. + */ + updateNoteInfo() { + if (this.note.verb === 'requested' && this.note.target.length === 1 && + this.note.target[0].type === 'workspace' && !this.note.target[0].hasOwnProperty('name')) { + let groupsClient = new GroupsAPI( + this.runtime.getConfig('services.groups.url'), + this.runtime.service('session').getAuthToken() + ); + return groupsClient.getResourceInfo(this.note.external_key) + .then((info) => { + this.note.target[0].name = info.narrname; + }) + .catch((error) => { + console.error(error); + }); + } else { + return Promise.resolve(); + } + } + + /** + * Returns an HTML string of the rendered notification. + * I.e. goes from the structure from the Feeds service to + * a readable string that makes sense. + */ + buildHtml() { + let actor = this.entityHtml(this.note.actor), + msg = '', + target = this.note.target; + + return this.updateNoteInfo() + .then(() => { + switch (this.note.verb) { + case 'requested': + if (target.length && target.length === 1) { + if (target[0].type === 'user' && target[0].id === this.note.actor.id) { + msg = actor + ' has requested to join '; + } + else { + msg = actor + ' has requested to add ' + this.entityHtml(target[0]) + ' to '; + } + } + else { + msg = actor + ' has requested to join '; + } + msg += this.entityHtml(this.note.object) + '.'; + break; + case 'invited': + msg = actor + ' has invited you to join ' + this.entityHtml(this.note.object) + '.'; + break; + case 'accepted': + if (target && target.length) { + msg = target.map(t => this.entityHtml(t)).join(', '); + if (target.length > 1) { + msg += ' have '; + } + else { + msg += ' has '; + } + msg += ' been added to ' + this.entityHtml(this.note.object) + '.'; + } + else { + msg = this.actorHtml() + ' accepted the invitation from ' + this.entityHtml(this.note.object); + } + break; + default: + msg = actor + ' ' + this.note.verb + ' ' + this.entityHtml(this.note.object); + } + return msg; + }); + } + + /** + * Returns a link to where a user can resolve this notification, based on + * the notification's context. If no link is necessary (this is just an + * alert with no action required), returns null; + */ + getLink() { + switch (this.note.verb) { + case 'requested': + case 'invited': + return '/#orgs'; + default: + return ''; + } + } + } + + return GroupNotification; +}); diff --git a/vite-app/src/apps/Feeds/notifications/icons.xts b/vite-app/src/apps/Feeds/notifications/icons.xts new file mode 100644 index 00000000..e20459c4 --- /dev/null +++ b/vite-app/src/apps/Feeds/notifications/icons.xts @@ -0,0 +1,28 @@ +define(() => { + 'use strict'; + + const ENTITY_ICONS = { + 'user': 'fa fa-user', + 'narrative': 'fa fa-file-o', + 'workspace': 'fa fa-file-o', + 'job': 'fa fa-suitcase', + 'group': 'fa fa-users' + }; + const DEFAULT_ICON = 'fa fa-cog'; + + /** + * Returns an i element for an entity icon. Generally something like "fa fa-foobar" + * @param {string} type - an entity type + */ + function entityIcon(type) { + let icon = DEFAULT_ICON; + if (ENTITY_ICONS[type]) { + icon = ENTITY_ICONS[type]; + } + return ``; + } + + return { + entity: entityIcon + }; +}); diff --git a/vite-app/src/apps/Feeds/notifications/narrative.xts b/vite-app/src/apps/Feeds/notifications/narrative.xts new file mode 100644 index 00000000..7bc0cbfd --- /dev/null +++ b/vite-app/src/apps/Feeds/notifications/narrative.xts @@ -0,0 +1,68 @@ +define([ + './base' +], function ( + BaseNotification +) { + 'use strict'; + + class NarrativeNotification extends BaseNotification { + constructor(note, currentUserId) { + super(note, currentUserId); + } + + /** + * Returns an HTML string of the rendered notification. + * I.e. goes from the structure from the Feeds service to + * a readable string that makes sense. + */ + buildHtml() { + let actor = this.entityHtml(this.note.actor), + msg = ''; + + return new Promise((resolve) => { + switch(this.note.verb) { + case 'requested': + msg = actor + ' has requested ' + this.permissionLevel() + 'access to '; + msg += this.entityHtml(this.note.object) + '.'; + break; + default: + msg = actor + ' ' + this.note.verb + ' ' + this.entityHtml(this.note.object); + } + resolve(msg); + }); + } + + permissionLevel() { + const perms = { + r: 'view only', + w: 'edit and save', + a: 'edit, save, and share' + }; + let level = ''; + if (this.note.context && this.note.context.level) { + level = this.note.context.level; + if (level in perms) { + level = perms[level]; + } + } + return level + ' '; + } + + /** + * Returns a link to where a user can resolve this notification, based on + * the notification's context. If no link is necessary (this is just an + * alert with no action required), returns null; + */ + getLink() { + switch(this.note.verb) { + case 'requested': + case 'invited': + return '/narrative/' + this.note.object.id; + default: + return ''; + } + } + } + + return NarrativeNotification; +}); diff --git a/vite-app/src/apps/Feeds/utils.ts b/vite-app/src/apps/Feeds/utils.ts new file mode 100644 index 00000000..11fc1137 --- /dev/null +++ b/vite-app/src/apps/Feeds/utils.ts @@ -0,0 +1,45 @@ + +export function cleanText(text: string) { + const n = document.createElement('div'); + n.textContent = text; + return n.innerHTML; +} + + + +/** + * Converts JS Date object to

    !t_99i-%g9)K@` zp^fSHaN8HgHK?)4mE6LY*3=ME*h)WFeSZIVJMZeL2MW$dh+10~)t1auHYsFTP##pS zN11-y)ATWvepJ}|v7z10HE9dn7!4j^U(oJ;?-v#nZZaOpLfk7eCdxT&2e@~r?U;K* za-TK83Cqlt-B#Btvy7_eZ?r6k6umXt(Ta=2ma zx=s709#aq+P$+?)FUn>*2qw^k5I?>n5VqJF$LU}5qq~Nr5u+Epiityv)LYMzzpFey zuA@qT^Usz(%X+xqY0MHRt%R0aAOihK0y2CFw%Ej^zuSq@jtTr8_xJMB5AECY2^I#w~_h*;1vY}zIr`i?+VXpivd%b@}bk?9f!D`RSz eROW+sUb>N#MX*tsR(Sr2kSYqA@)fd{!T$k=*&amz literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/pressed.png b/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/darker/pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..51d68099435ba9dc85384f5d4fb6859aa0f4d968 GIT binary patch literal 3882 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/light/btn-disabled.png b/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/light/btn-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..70db5ba645878f01b2c77dbcfe168d9efd57735e GIT binary patch literal 4940 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/light/btn-pressed.png b/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/light/btn-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..376b0da415fc87e52846d2597dd9e773828c21d5 GIT binary patch literal 6545 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 IsoRJD56HzAHvj+t literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/normal.png b/vite-app/src/apps/Auth2/resources/providers/orcid/signin-button/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..2c8db80c5faa1649a6d01b561f0cc18cda56369b GIT binary patch literal 3464 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 literal 0 HcmV?d00001 diff --git a/vite-app/src/apps/Catalog.tsx b/vite-app/src/apps/Catalog.tsx index 0794799e..d1fc28fc 100644 --- a/vite-app/src/apps/Catalog.tsx +++ b/vite-app/src/apps/Catalog.tsx @@ -1,9 +1,10 @@ import { Component } from 'react'; import PluginWrapper2 from '../components/PluginWrapper/PluginWrapper2'; import { RouteProps, Router } from '../components/Router2'; -import { AuthenticationState } from '../contexts/Auth'; +import { AuthenticationState } from '../contexts/EuropaContext'; import { Route, SimplePluginRouteSpec } from '../lib/Route'; import { Config } from '../types/config'; +import { SignIn } from './Auth2/SignIn/SignIn'; export interface CatalogProps extends RouteProps { config: Config; @@ -14,10 +15,7 @@ export interface CatalogProps extends RouteProps { interface CatalogState { } - export default class Catalog extends Component { - - render() { const common = { name: "catalog", @@ -60,7 +58,7 @@ export default class Catalog extends Component { { path: 'catalog/stats', auth: false, - view: 'catalogStatus' + view: 'catalogStats' }, { path: '^(appcatalog|catalog)$/^(app|apps)$/:namespace/:id/:tag?', @@ -110,7 +108,21 @@ export default class Catalog extends Component { }); }); - return + const authRoute = new Route( + '^login|signin|signup$', + {authenticationRequired: false}, + (props: RouteProps) => { + return + } + ) + return } } diff --git a/vite-app/src/apps/Feeds/api/Feeds.ts b/vite-app/src/apps/Feeds/api/Feeds.ts new file mode 100644 index 00000000..ade0fd64 --- /dev/null +++ b/vite-app/src/apps/Feeds/api/Feeds.ts @@ -0,0 +1,175 @@ +import { RestClient } from "./RestClient"; + +const API_PATH = 'api/V1/notification'; + +/** + * Instantiates the Feeds API. Requires both the endpoint (i.e. https://kbase.us/services/feeds) + * and a valid KBase Auth token. The token is NOT validated before use. + * @param {string} endpoint - the endpoint for the Feeds service + * @param {string} token - the user's auth token + */ + +export interface FeedEntity { + id: string; // e.g. username + name: string // e.g. realname + type: string // "user" +} + +export interface FeedActor extends FeedEntity { + // id: string; // e.g. username + // name: string // e.g. realname + // type: string // "user" +} + +export interface FeedObject extends FeedEntity{ + // id: string; + // name: string; + // type: string ; // "group" +} + +export interface FeedTarget extends FeedEntity { + // id: string; + // name: string; + // type: string; +} + +export interface FeedItem { + actor: FeedActor + context: null | Record + created: number; + expires: number; + external_key: string; + id: string; + level: string; + object: FeedObject; + seen: boolean; + source: string; + target: Array; + verb: string; +} + +export interface Feed { + feed: Array + name: string; + unseen: number; +} + +export type Notifications = Record; + +export interface GetNotificationsOptions { + reverseSort?: boolean; + verb?: string | number; + level?: string | number; + includeSeen?: boolean; +} + +export interface Notification { + verb: string; + object: string; + level: number; + context: Record +} + +export interface GlobalNotification { + verb: string; + object: string; + level: number; + context: Record; + expires?: number; +} + +export interface UnseenNotificationCount { + global: number; + user: number; +} + +export interface UnseenNotificationCountResult { + unseen: UnseenNotificationCount +} + +export class FeedsAPI extends RestClient { + + /** + * Returns the list of notifications for a single user. + * @param {object} options + * - reverseSort - boolean + * - verb - string or int + * - level - string or int + * - includeSeen - boolean + */ + async getNotifications(options: GetNotificationsOptions): Promise { + let params = []; + if (options.reverseSort) { + params.push('rev=1'); + } + if (options.verb) { + params.push('v=' + options.verb); + } + if (options.level) { + params.push('l=' + options.level); + } + if (options.includeSeen) { + params.push('seen=1'); + } + let path = 'api/V1/notifications/?' + params.join('&'); + + return this.makeCall('GET', path); + } + + /** + * Posts a single notification. User's gotta be special. + * Note - this was mainly for early-stage debugging. Probably doesn't work + * anymore unless the user's auth token is really a service token. And if + * you're logging in with a service token.... don't. + * @param {object} data + * - verb + * - object + * - level + * - context (keys text, link) + */ + postNotification(data: Notification) { + return this.makeCall('POST', API_PATH, data); + } + + /** + * Posts a Global notification on behalf of an admin. Requires + * the used auth token to have the custom auth role FEEDS_ADMIN + * or an error will occur. + * @param {object} data + * - verb + * - object + * - level + * - context (keys: text, link) + * - expires (optional, default = 30 days after posting) + */ + postGlobalNotification(data: GlobalNotification) { + return this.makeCall('POST', `${API_PATH}/global`, data); + } + + /** + * Marks an array of notification ids as seen by the user. + * @param {Array} noteIds - array of note id strings + */ + markSeen(noteIds: Array) { + return this.makeCall('POST', `${API_PATH}/see`, { note_ids: noteIds }); + } + + /** + * Marks an array of notification ids as unseen by the given user. + * @param {Array} noteIds - array of note id strings + */ + markUnseen(noteIds: Array) { + return this.makeCall('POST', `${API_PATH}/unsee`, { note_ids: noteIds }); + } + + /** + * Expires a single global notification from its id. + * Requires the user to have the custom auth role FEEDS_ADMIN, or an error + * will occur. + * @param {string} noteId - a single notification id + */ + expireGlobalNotification(noteId: string) { + return this.makeCall('POST', `${API_PATH}/expire`, { note_ids: [noteId] }); + } + +} diff --git a/vite-app/src/apps/Feeds/api/Groups.ts b/vite-app/src/apps/Feeds/api/Groups.ts new file mode 100644 index 00000000..3759e9fa --- /dev/null +++ b/vite-app/src/apps/Feeds/api/Groups.ts @@ -0,0 +1,32 @@ +import { RestClient } from "./RestClient"; + +/** + * Groups API - some useful endpoints. + */ +export class GroupsAPI extends RestClient { + constructor(endpoint: string, token: string) { + super(endpoint, token); + } + + /** + * Returns the resource info from a groups request. + * From the Groups docs: + * + * GET /request/id//resource + * RETURNS: a resource entry (but see below). + * + * Resource entries are described in Resources above. The resource entry returned here is + * slightly different: a) there is no added field because presumably the resource has not + * yet been added to the group, and b) there is an additional resourcetype field that + * specifies the type of the resource. + * + * The request must be open and the type must be Request, the resource type cannot be + * user, and the user must be a group administrator. + * @param {string} requestId + */ + getResourceInfo(requestId: string) { + return this.makeCall('GET', `request/id/${requestId}/resource`); + } +} + + diff --git a/vite-app/src/apps/Feeds/api/RestClient.ts b/vite-app/src/apps/Feeds/api/RestClient.ts new file mode 100644 index 00000000..4425fb3f --- /dev/null +++ b/vite-app/src/apps/Feeds/api/RestClient.ts @@ -0,0 +1,85 @@ + +/** + * A generic REST(ish) API caller. + * Really simple. This just ensures that a URL and token exist, + * it makes calls to them and returns the results. + * + * Child classes should implement what endpoints should be use + * and how to parse the final results, if at all. + */ +export class RestClient { + endpoint: string; + token: string; + constructor(endpoint: string, token: string) { + if (!endpoint) { + throw new Error('Feeds endpoint required!'); + } + if (!endpoint.endsWith('/')) { + endpoint = endpoint + '/'; + } + if (!token) { + throw new Error('Auth token required'); + } + + this.endpoint = endpoint; + this.token = token; + } + + /** + * Makes a generic API call to the feeds service. + * Really, this could probably be used for any RESTish service. + * It's also really really simple. Just given the method, path, + * and data, it crafts the REST call by using the Fetch API. + * If the method isn't one of the usual HTTP verbs (GET, POST, PUT, DELETE), + * this raises an error. + * This returns a Promise with either the result of the call de-JSONified, + * or it raises an error. + * @param {string} method + * @param {string} path + * @param {object} options + */ + async makeCall(method: string, path: string, data?: any) { + // remove the first slash, if present + if (path.startsWith('/')) { + path = path.substring(1); + } + method = method.toLocaleUpperCase(); + if (!['GET', 'POST', 'PUT', 'DELETE'].includes(method)) { + throw new Error('Method ' + method + ' not usable'); + } + let url = this.endpoint + path; + let request: RequestInit = { + method, + cache: 'no-cache', + headers: { + 'Content-type': 'application/json; charset=utf-8', + 'Authorization': this.token + }, + redirect: 'follow', + referrer: 'no-referrer' + }; + if (data) { + request.body = JSON.stringify(data); + } + + const response = this.handleErrors(await fetch(url, request)); + + return await response.json(); + } + + /** + * Invisibly deals with errors from Fetch. Fetch is nice, but annoying in + * that the 400-level errors don't raise errors on their own. This wraps + * the call and deals with that before returning the response to whatever + * called this API. + * @param {object} response - a response from the Fetch API. + */ + handleErrors(response: Response) { + if (!response.ok) { + console.error(response); + throw Error(response.statusText); + } + return response; + } +} + diff --git a/vite-app/src/apps/Feeds/components/Entity.tsx b/vite-app/src/apps/Feeds/components/Entity.tsx new file mode 100644 index 00000000..f7b84dfc --- /dev/null +++ b/vite-app/src/apps/Feeds/components/Entity.tsx @@ -0,0 +1,96 @@ +import UILink from 'components/UILink2'; +import { Component } from 'react'; +import { FeedEntity } from '../api/Feeds'; + +export type Variant = 'danger' | 'warning' | 'info'; + +export interface EntityIconProps { + type: string; +} + +const DEFAULT_ICON = 'cog'; + +const ENTITY_ICONS: Record = { + user: 'user', + narrative: 'file-o', + workspace: 'file-o', + job: 'suitcase', + group: 'users', +}; + +export class EntityIcon extends Component { + render() { + const iconClassFragment = ENTITY_ICONS[this.props.type] || DEFAULT_ICON; + return ; + } +} + +export interface EntityProps { + username: string; + entity: FeedEntity; +} + +export default class Entity extends Component { + renderNarrativeLink(id: string, name: string) { + name = name || id; + return ( + + {name} + + ); + } + + renderWorkspaceLink(id: string, name: string) { + name = name || id; + return ( + + {name} + + ); + } + + renderGroupLink(id: string, name: string) { + name = name || id; + return ( + + {name || '(name not accessible)'} + + ); + } + + renderUserLink(userId: string, name: string) { + let label = name ? name : userId; + if (userId === this.props.username) { + label += ' (you)'; + } + return ( + + {label} + + ); + } + + renderEntityLink(type: string, id: string, name: string) { + switch (type) { + case 'user': + return this.renderUserLink(id, name); + case 'group': + return this.renderGroupLink(id, name); + case 'workspace': + return this.renderWorkspaceLink(id, name); + case 'narrative': + return this.renderNarrativeLink(id, name); + default: + return name === null ? id : `${name} (${id})`; + } + } + + render() { + const { type, id, name } = this.props.entity; + return ( + + {this.renderEntityLink(type, id, name)} + + ); + } +} diff --git a/vite-app/src/apps/Feeds/components/controller.tsx b/vite-app/src/apps/Feeds/components/controller.tsx new file mode 100644 index 00000000..a4895fa3 --- /dev/null +++ b/vite-app/src/apps/Feeds/components/controller.tsx @@ -0,0 +1,828 @@ +// define(['../api/feeds', './globalPoster', './feedTabs', '../util'], function (FeedsAPI, GlobalPoster, FeedTabs, Util) { + +import ErrorAlert from "components/ErrorAlert"; +import Loading from "components/Loading"; + +import { RouteProps } from "components/Router2"; +import { AuthenticationStateAuthenticated, notifyError } from "contexts/EuropaContext"; +import { RepeatAsyncProcess, RepeatAsyncProcessStatus } from "lib/RepeatableAsyncProcess"; +import { SimpleError } from "lib/SimpleError"; +import { Feed, FeedNotification, FeedsClient, UnseenNotificationCount } from "lib/clients/Feeds"; +import { Component } from "react"; +import { Config } from "types/config"; +// import { Feed, FeedsAPI, Notifications, UnseenNotificationCount } from "../api/Feeds"; +import AsyncQueue from "apps/Navigator/components/NarrativeList/AsyncQueue"; +import { Monitor } from "lib/Monitor"; +import { navigate2 } from "lib/navigation"; +import FeedsView, { FeedsLayout } from "./view"; + + +const FEEDS_ADMIN_ROLE = 'FEEDS_ADMIN'; + +export interface FeedsControllerProps extends RouteProps { + config: Config; + authState: AuthenticationStateAuthenticated; + setTitle: (title: string) => void; +} + +export interface FeedWithId { + id: string; + feed: Feed; +} + +export interface Filterable { + show: boolean; + value: T; +} + +export type FeedsFilter = 'all' | 'unseen'; +export type NotificationsFilter = 'all' | 'unssen'; + +export interface FilterData { + feedsFilter: FeedsFilter; + allFeeds: Array>; + feedsMap: Record>; + + global?: FeedWithId; + user?: FeedWithId; + userFeeds: Array; + notifications: Array; + selectedFeed?: FeedWithId; +} + +export interface FeedData extends FilterData{ + isAdmin: boolean; + // global: Filterable; + // user: Filterable; + // feeds: Array; + // userFeeds: Array>; + // allFeeds: Array>; + // feedsMap: Record>; + unseen: UnseenNotificationCount; + totalUnseenCount: number; + feedsLayout: FeedsLayout; + + // selectedFeed?: FeedWithId; + // feedsFilter: FeedsFilter; + notificationsFilter: NotificationsFilter; + feeds: Array; +} + +interface FeedsControllerState { + feedsState: RepeatAsyncProcess; +} + +export default class FeedsController extends Component { + monitor: Monitor; + queue: AsyncQueue; + constructor(props: FeedsControllerProps) { + super(props); + + this.state = { + feedsState: { + status: RepeatAsyncProcessStatus.NONE + } + } + + this.monitor = new Monitor({ + callback: this.doRefreshAlarm.bind(this), + interval: 10000 + }); + + this.queue = new AsyncQueue({queuePauseTime: 250}); + } + + async doRefreshAlarm() { + // TODO: if the reloadData is async, we could ensure it is accounted for in + // the monitor loop. Should not be a problem though, as the refresh time, + // dominated by fetching the notifications from the service, should be much + // shorter, far less than a second, than the refresh poll interval, which + // should be on the order of 10 secons. + this.doRefresh(); + } + + componentDidMount() { + this.props.setTitle('Notification Feeds'); + this.loadData(); + this.monitor.start(); + } + + componentWillUnmount(): void { + this.monitor.stop(); + } + + componentDidUpdate(prevProps: FeedsControllerProps) { + const prevSelectedFeedId = prevProps.match.params.get('tab') || 'global'; + const selectedFeedId = this.props.match.params.get('tab') || 'global'; + + if (prevSelectedFeedId === selectedFeedId) { + return; + } + + if (this.state.feedsState.status !== RepeatAsyncProcessStatus.SUCCESS) { + return; + } + + if (!(selectedFeedId in this.state.feedsState.value.feedsMap)) { + this.setState({ + feedsState: { + status: RepeatAsyncProcessStatus.ERROR, + error: { + message: `Could not find feed ${selectedFeedId}` + } + } + }); + return; + } + + this.setState({ + feedsState: { + ...this.state.feedsState, + value: { + ...this.state.feedsState.value, + selectedFeed: this.state.feedsState.value.feedsMap[selectedFeedId]!.value + } + } + }); + } + + async fetchFeeds() { + const feedsClient2 = new FeedsClient({ + url: this.props.config.services.Feeds.url, + token: this.props.authState.authInfo.token + }) + + // Get the initial feed. + const rawFeeds = await feedsClient2.getNotifications({limit: 100, includeSeen: true}); + const {unseen} = await feedsClient2.getUnseenNotificationsCount(); + + // Determine if an admin. + const isAdmin = this.props.authState.authInfo.account.customroles.includes(FEEDS_ADMIN_ROLE) + + // GLOBAL POSTER? + + const feeds: Array = Object.entries(rawFeeds) + .map(([id, feed]) => { + return { + id, + feed + } + }) + + + return {unseen, isAdmin, feeds} + } + + async loadData() { + this.setState({ + feedsState: { + status: RepeatAsyncProcessStatus.PENDING + } + }) + + try { + + const {unseen, isAdmin, feeds} = await this.fetchFeeds(); + // // Get the initial feed. + // const rawFeeds = await feedsClient2.getNotifications({limit: 100, includeSeen: true}); + // const {unseen} = await feedsClient2.getUnseenNotificationsCount(); + + // // Determine if an admin. + // const isAdmin = this.props.authState.authInfo.account.customroles.includes(FEEDS_ADMIN_ROLE) + + // // GLOBAL POSTER? + + // const feeds: Array = Object.entries(rawFeeds) + // .map(([id, feed]) => { + // return { + // id, + // feed + // } + // }) + + // const notifications: Array = []; + + // for (const [id, feed] of Object.entries(rawFeeds)) { + // for (const notification of feed.feed) { + // notifications.push(notification) + // } + // } + + const feedsWithFilterApplied = this.applyFilter(feeds, 'all', this.props.match.params.get('tab') || 'global'); + + this.setState({ + feedsState: { + status: RepeatAsyncProcessStatus.SUCCESS, + value: { + isAdmin, + unseen, + totalUnseenCount: unseen.global + unseen.user, + notificationsFilter: 'all', + feedsLayout: 'source', + feeds, + ...feedsWithFilterApplied + } + } + }) + + } catch (ex) { + this.setState({ + feedsState: { + status: RepeatAsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + } + }) + } + // this.initializeData().then((feedData) => { + // const token = runtime.service('session').getAuthToken(); + // return runtime + // .service('session') + // .auth2Client.getMe(token) + // .then(({ customroles }) => { + // this.element.innerHTML = ''; + // if (customroles.includes('FEEDS_ADMIN')) { + // this.isAdmin = true; + // this.globalPoster = new GlobalPoster({ + // afterSubmitFn: this.refreshFeed.bind(this), + // runtime: runtime + // }); + // this.element.appendChild(this.globalPoster.element); + // } + + // this.myFeeds = {}; + // // make an object from all feeds where key = feed id, value = feed info + // Object.keys(feedData).forEach((feed) => { + // this.myFeeds[feed] = [feed, feedData[feed].name]; + // }); + // this.myFeeds.global[1] = 'KBase Announcements'; + // // make the order. Should be: + // // 0. global + // // 1. user + // // rest = other feeds in alphabetical order + // // seed with just global and user + // const feedOrder = Object.keys(this.myFeeds); + // feedOrder.splice(feedOrder.indexOf('global'), 1); + // feedOrder.splice(feedOrder.indexOf('user'), 1); + // feedOrder.sort((a, b) => { + // return feedData[a].name.localeCompare(feedData[b].name); + // }); + // feedOrder.unshift('user'); + // feedOrder.unshift('global'); + + // const feedList = feedOrder.map((feed) => this.myFeeds[feed]); + + // const unseenSet = {}; + // for (const f in feedData) { + // unseenSet[f] = feedData[f].unseen; + // } + + // this.feedTabs = new FeedTabs({ + // feeds: feedList, + // feedUpdateFn: this.updateFeed.bind(this), + // unseen: unseenSet, + // globalFeed: feedData.global.feed, + // runtime: runtime, + // isAdmin: this.isAdmin, + // userId: this.userId + // }); + // this.element.appendChild(this.feedTabs.element); + // }); + // }); + } + + async reloadData() { + if (this.state.feedsState.status !== RepeatAsyncProcessStatus.SUCCESS) { + return; + } + // const feedFilter = this.state.feedsState.value.feedsFilter; + + this.setState({ + feedsState: { + ...this.state.feedsState, + status: RepeatAsyncProcessStatus.SUCCESS_PENDING + } + }) + // const feedsClient = new FeedsAPI(this.props.config.services.Feeds.url, this.props.authState.authInfo.token); + // const feedsClient2 = new FeedsClient({ + // url: this.props.config.services.Feeds.url, + // token: this.props.authState.authInfo.token + // }) + try { + + const {unseen, isAdmin, feeds} = await this.fetchFeeds(); + // // Get the initial feed. + // const notifications = await feedsClient2.getNotifications({limit: 100, includeSeen: true}); + // const {unseen} = await feedsClient2.getUnseenNotificationsCount(); + + // // GLOBAL POSTER? + + // // Determine if an admin. + // const isAdmin = this.props.authState.authInfo.account.customroles.includes(FEEDS_ADMIN_ROLE) + + // // GLOBAL POSTER? + + // const feeds: Array = Object.entries(notifications) + // .map(([id, feed]) => { + // return { + // id, + // feed + // } + // }) + + const {feedsFilter, selectedFeed, feedsLayout} = this.state.feedsState.value; + + const feedsWithFilterApplied = this.applyFilter(feeds, feedsFilter, selectedFeed ? selectedFeed.id : undefined); + + this.setState({ + feedsState: { + status: RepeatAsyncProcessStatus.SUCCESS, + value: { + isAdmin, + unseen, + totalUnseenCount: unseen.global + unseen.user, + notificationsFilter: 'all', + feedsLayout, + feeds, + ...feedsWithFilterApplied + } + } + }) + } catch (ex) { + this.setState({ + feedsState: { + status: RepeatAsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + } + }) + } + } + + // async reloadData2() { + // if (this.state.feedsState.status !== RepeatAsyncProcessStatus.SUCCESS) { + // return; + // } + // const feedFilter = this.state.feedsState.value.feedsFilter; + + // await new Promise((resolve) => { + // if (this.state.feedsState.status !== RepeatAsyncProcessStatus.SUCCESS) { + // return; + // } + // this.setState({ + // feedsState: { + // ...this.state.feedsState, + // status: RepeatAsyncProcessStatus.SUCCESS_PENDING + // } + // }, () => resolve); + // }); + + // // const feedsClient = new FeedsAPI(this.props.config.services.Feeds.url, this.props.authState.authInfo.token); + // const feedsClient2 = new FeedsClient({ + // url: this.props.config.services.Feeds.url, + // token: this.props.authState.authInfo.token + // }) + // try { + // // Get the initial feed. + // const notifications = await feedsClient2.getNotifications({limit: 100, includeSeen: true}); + // const {unseen} = await feedsClient2.getUnseenNotificationsCount(); + + // // GLOBAL POSTER? + + // function filterIt(feed: FeedWithId): Filterable { + // const show = (() => { + // switch (feedFilter) { + // case 'all': return true; + // case 'unseen': return feed.feed.unseen > 0; + // } + // })(); + // return {show, value: feed} + // } + + // const allFeeds: Array> = Object.entries(notifications) + // .map(([id, feed]) => { + // // Show if current feed filter is honored. + // return filterIt({id, feed}); + // }) + + // allFeeds.sort((a: Filterable, b: Filterable) => { + // return a.value.feed.name.localeCompare(b.value.feed.name); + // }) + + // const userFeeds = allFeeds.filter((feed) => { + // return feed.value.id !== "global" && feed.value.id !== "user" + // }) + + // const selectedFeedId = this.props.match.params.get('tab') || 'global' + + // const feedsMap = allFeeds.reduce< Record>>((accum, feed) => { + // accum[feed.value.id] = feed; + // return accum; + // },{}); + + + // // const globalFeed: FeedWithId = {id: 'global', feed: notifications['global']!} + + // const global = feedsMap['global']; + + // // const global = { + // // show: true, + // // value: globalFeed + // // }; + + // // const userFeed: FeedWithId = {id: 'user', feed: notifications['user']!}; + // const user = feedsMap['user']; + + // return new Promise((resolve) => { + // if (this.state.feedsState.status === RepeatAsyncProcessStatus.SUCCESS_PENDING) { + // this.setState({ + // feedsState: { + // status: RepeatAsyncProcessStatus.SUCCESS, + // value: { + // ...this.state.feedsState.value, + // allFeeds, + // feedsMap, + // feeds: userFeeds, + // unseen, + // totalUnseenCount: unseen.global + unseen.user, + // global, + // user, + // selectedFeed: {id: selectedFeedId, feed: notifications[selectedFeedId]!}, + // } + // } + // }, () => resolve); + // } else { + // resolve(null); + // } + // }); + // } catch (ex) { + // return new Promise((resolve) => { + // this.setState({ + // feedsState: { + // status: RepeatAsyncProcessStatus.ERROR, + // error: { + // message: ex instanceof Error ? ex.message : 'Unknown Error' + // } + // } + // }, () => resolve) + // }); + // } + // } + + // updateFeed(feedKey) { + // return this.feedsApi + // .getNotifications({ includeSeen: true }) + // .then((feed) => { + // if (feed[feedKey]) { + // return feed[feedKey]; + // } else { + // return {}; + // } + // }) + // .catch((err) => { + // console.error(err); + // }); + // } + + // async initializeData() { + + // } + + /** + * + * @param {object} filters + * - reverseSort - boolean + * - verb - string or int + * - level - string or int + * - source - string + * - includeSeen - boolean + */ + // refreshFeed() { + // this.feedsApi + // .getNotifications({ includeSeen: true }) + // .then((feed) => { + // this.feedTabs.refresh(feed); + // const unseenSet = {}; + // for (const f in feed) { + // unseenSet[f] = feed[f].unseen; + // } + // this.feedTabs.setUnseenCounts(unseenSet); + // }) + // .catch((err) => { + // this.renderError(err); + // }); + // } + + // renderError(err) { + // console.error(err); + // // xss safe + // this.element.innerHTML = ` + //

    + ); + } + render() { + return
    + {this.renderToolbar()} + {this.renderJobLog()} +
    ; + } +} diff --git a/vite-app/src/apps/JobBrowser/components/JobStatusBadge.tsx b/vite-app/src/apps/JobBrowser/components/JobStatusBadge.tsx new file mode 100644 index 00000000..daf46092 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/JobStatusBadge.tsx @@ -0,0 +1,204 @@ +import { InfoCircleOutlined, LoadingOutlined } from '@ant-design/icons'; +import { Tag, Tooltip } from 'antd'; +import NiceTimeDuration from 'components/NiceTimeDuration'; +import { Component } from 'react'; +import { Job } from '../store'; +import { JobEvent, JobStateType } from '../types/jobState'; +import NiceElapsedTime from './NiceElapsedTime'; +import NiceRelativeTime from './NiceRelativeTime'; + +const STALE_AFTER = 300000; + +function currentEvent(job: Job): JobEvent { + return job.eventHistory[job.eventHistory.length - 1]; +} + + +/** + * Translates a job status value to a color value acceptable for the color + * prop for the job status tag. + * + * @param status - the status of the job + */ +export function jobColor(job: Job): string { + switch (currentEvent(job).type) { + case JobStateType.CREATE: + return 'purple'; + case JobStateType.QUEUE: + return 'orange'; + case JobStateType.RUN: + return 'blue'; + case JobStateType.COMPLETE: + return 'green'; + case JobStateType.ERROR: + return 'red'; + case JobStateType.TERMINATE: + return 'gray'; + default: + throw new Error('Invalid job status'); + } +} + +export interface JobStatusProps { + job: Job; + showTiming?: boolean; +} + +interface JobStatusState { + +} + +export default class JobStatusBadge extends Component { + renderTag() { + const label = this.renderJobStatusLabel(); + const color = jobColor(this.props.job); + return + {label} + ; + } + /** +* Translates a job status value to a label, with optional icon, suitable for +* display as the child of the job status tag. +* +* @param status - the status of the job +* +* @note Since the switch is over an enum, we don't have to worry about the default case +*/ + renderJobStatusLabel() { + switch (currentEvent(this.props.job).type) { + case JobStateType.CREATE: + return 'Created'; + case JobStateType.QUEUE: + return ( + + Queued + + ); + case JobStateType.RUN: + return ( + + Running + + ); + case JobStateType.COMPLETE: + return 'Completed'; + case JobStateType.ERROR: + return 'Errored'; + case JobStateType.TERMINATE: + return 'Canceled'; + default: + throw new Error('Invalid job status'); + } + } + + renderJobStatusTooltip() { + const event = currentEvent(this.props.job); + switch (event.type) { + case JobStateType.CREATE: + // A created job is stale if over 5 minutes old + const stale = () => { + const now = new Date().getTime(); + const elapsed = now - event.at; + if (elapsed > STALE_AFTER) { + return

    + This job is considered orphaned, since it was created + ago. + A job should move into a queue within {}. +

    ; + } + }; + return ( +
    +

    This job has been received by the execution engine, but not yet queued for running.

    + {stale()} +
    + ); + case JobStateType.QUEUE: + return ( +
    +

    + This job has been queued for running +

    +

    + You may inspect the job log by clicking the button in the leftmost column. +

    +
    + ); + case JobStateType.RUN: + return ( +
    + +

    + This job is currently running. +

    +

    + You may inspect the job log by clicking the button in the leftmost column. +

    +
    + ); + case JobStateType.COMPLETE: + return ( +
    +

    + This job has completed successfully. +

    +

    + You may inspect the job log by clicking the button in the leftmost column. +

    +
    + ); + case JobStateType.ERROR: + return ( +
    +

    + This job experienced an error. +

    +

    + You may inspect the error and job log by clicking the button in the leftmost column. +

    +
    + ); + case JobStateType.TERMINATE: + return ( +
    +

    + This job has been canceled. +

    +

    + You may inspect the job log by clicking the button in the leftmost column. +

    +
    + ); + default: + throw new Error('Invalid job status'); + } + } + + renderTiming() { + const job = this.props.job; + const event = currentEvent(job); + switch (event.type) { + case JobStateType.CREATE: + return -; + case JobStateType.QUEUE: + case JobStateType.RUN: + return ; + default: + return + + ; + } + } + + render() { + const timing = this.props.showTiming ? this.renderTiming() : ''; + return ( + + {this.renderTag()} + {timing} + + ); + } +} diff --git a/vite-app/src/apps/JobBrowser/components/Main/index.tsx b/vite-app/src/apps/JobBrowser/components/Main/index.tsx new file mode 100644 index 00000000..f87f71d0 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/Main/index.tsx @@ -0,0 +1,113 @@ +import { Alert, Spin } from 'antd'; +import JobBrowserBFFClient from 'apps/JobBrowser/lib/JobBrowserBFFClient'; +import ErrorAlert from 'components/ErrorAlert'; +import { RouteProps } from 'components/Router2'; +import { AuthenticationStateAuthenticated } from 'contexts/EuropaContext'; +import { AsyncProcess, AsyncProcessStatus } from 'lib/AsyncProcess'; +import { SimpleError } from 'lib/SimpleError'; +import * as React from 'react'; +import { Config } from 'types/config'; +import Main from './view'; + +export interface JobBrowserState { + isAdmin: boolean; +} + +export interface LoaderProps extends RouteProps{ + config: Config; + authState: AuthenticationStateAuthenticated; + setTitle: (title: string) => void; +} + +type LoaderState = AsyncProcess; + +export default class Loader extends React.Component { + constructor(props: LoaderProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + }; + } + + componentDidMount() { + this.props.setTitle('Job Browser'); + this.initialize(); + } + + async initialize() { + const jobBrowserBFF = new JobBrowserBFFClient({ + token: this.props.authState.authInfo.token, + url: this.props.config.services.ServiceWizard.url, + timeout: this.props.config.ui.constants.clientTimeout, + version: this.props.config.dynamicServices.JobBrowserBFF.version + }); + + this.setState({ + status: AsyncProcessStatus.PENDING + }); + + try { + const { is_admin } = await jobBrowserBFF.is_admin(); + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + isAdmin: is_admin + } + }) + + } catch (ex) { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }) + } + } + + renderLoading() { + const message = ( +
    + Loading Job Browser ... +
    + ); + return ( + + ); + } + + renderError({message}: SimpleError) { + return + } + + renderSuccess({isAdmin}: JobBrowserState) { + return
    + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + return this.renderLoading(); + case AsyncProcessStatus.PENDING: + return this.renderLoading(); + case AsyncProcessStatus.ERROR: + return this.renderError(this.state.error); + case AsyncProcessStatus.SUCCESS: + return this.renderSuccess(this.state.value); + } + } +} diff --git a/vite-app/src/apps/JobBrowser/components/Main/style.css b/vite-app/src/apps/JobBrowser/components/Main/style.css new file mode 100644 index 00000000..44818504 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/Main/style.css @@ -0,0 +1,48 @@ +.Main { + margin: 1rem; +} + +.FlexTabs { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.FlexTabs .ant-tabs-top-bar { + flex: 0 0 auto; +} + +.FlexTabs .ant-tabs-content { + flex: 1 1 0px; + overflow-y: auto; +} + + +.Row { + flex: 0 0 auto; + display: flex; + flex-direction: row; +} + +.Row-fullheight { + flex: 1 1 0px; + display: flex; + flex-direction: row; +} + +.Row-scrollable { + min-height: 0; + min-width: 0; +} + +.Col-scrollable { + min-height: 0; + min-width: 0; +} + +.Col { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} diff --git a/vite-app/src/apps/JobBrowser/components/Main/view.tsx b/vite-app/src/apps/JobBrowser/components/Main/view.tsx new file mode 100644 index 00000000..8a902700 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/Main/view.tsx @@ -0,0 +1,128 @@ +import { faLockOpen } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { AuthenticationStateAuthenticated } from 'contexts/EuropaContext'; +import React, { CSSProperties, ReactNode } from 'react'; +import { Nav, Tab } from 'react-bootstrap'; +import { Config } from 'types/config'; +import AdminJobs from '../AdminJobs'; +import MyJobs from '../MyJobs'; +import PublicAppStats from '../PublicAppStats'; +import UserRunSummary from '../UserRunSummary'; +import './style.css'; + +export interface MainProps { + config: Config; + authState: AuthenticationStateAuthenticated; + isAdmin: boolean; + // params: MainParams; + // view: string; + tab?: string; + setTitle: (title: string) => void; + // setView: (view: string) => void; + // setParams: (params: MainParams) => void; +} + +interface MainState { +} + +export default class Main extends React.Component { + defaultTabKey: string; + constructor(props: MainProps) { + super(props); + this.defaultTabKey = 'myJobs'; + } + + componentDidMount() { + this.props.setTitle('Job Browser'); + } + + renderTabs() { + const tabPaneStyle: CSSProperties = { + position: 'absolute', top: '0', right: '0', bottom: '0', left: '0', display: 'flex', flexDirection: 'column' + } + const tabContentStyle: CSSProperties = { flex: '1 1 0', position: 'relative' } + return +
    + +
    +
    + + + + + { + ((): ReactNode => { + if (!this.props.isAdmin) { + return; + } + return + + + })() + } + + + + { + ((): ReactNode => { + if (!this.props.isAdmin) { + return; + } + return + + + })() + } + +
    +
    + } + + render() { + return
    + {this.renderTabs()} +
    ; + } +} diff --git a/vite-app/src/apps/JobBrowser/components/Monitor.tsx b/vite-app/src/apps/JobBrowser/components/Monitor.tsx new file mode 100644 index 00000000..b91e7645 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/Monitor.tsx @@ -0,0 +1,182 @@ +import * as React from 'react'; +import { Progress, Tooltip, Switch } from 'antd'; +import PubSub, { PubSubProxy } from '../lib/PubSub'; +import { Poller } from '../lib/Poller'; + +const MONITORING_INTERVAL = 10000; +const MONITORING_FEEDBACK_STEPS = 100; +const WATCH_INTERVAL = 100; + +export interface MonitorProps { + defaultRunning: boolean; + pubsub: PubSub; + onPoll: () => void; +} + +export interface MonitorState { + /** Support for job monitoring */ + isMonitoring: boolean; + isPollingInitiated: boolean; + pollingStartedAt: number; + /** Monitoring progress */ + pollWaitProgress: number; + isPolling: boolean; + isOpen: boolean; +} + +export default class Monitor extends React.Component { + monitoringTimer: number | null; + monitoringStatusTimer: number | null; + pollWatcherTimer: number | null; + searchListenerID: string | null; + pubsubProxy: PubSubProxy; + + poller: Poller; + + constructor(props: MonitorProps) { + super(props); + + this.monitoringTimer = null; + this.monitoringStatusTimer = null; + this.pollWatcherTimer = null; + this.searchListenerID = null; + this.pubsubProxy = new PubSubProxy(this.props.pubsub); + + this.poller = new Poller({ + onPoll: this.props.onPoll, + onProgress: this.onProgress.bind(this), + pubsub: this.props.pubsub, + pollInterval: MONITORING_INTERVAL, + progressSteps: MONITORING_FEEDBACK_STEPS, + watchInterval: WATCH_INTERVAL + }); + + this.state = { + isMonitoring: false, + pollWaitProgress: 0, + isPollingInitiated: false, + pollingStartedAt: 0, + isPolling: false, + isOpen: this.props.defaultRunning + }; + } + + onProgress(progress: number) { + this.setState({ + pollWaitProgress: progress + }); + } + + componentDidMount() { + this.pubsubProxy.on('searching', ({ is }) => { + if (is) { + this.setState({ + isPolling: true + }); + } else { + this.setState({ + isPolling: false + }); + } + }); + } + + componentWillUnmount() { + this.stopMonitoring(); + this.poller.stop(); + this.pubsubProxy.off(); + } + + componentDidUpdate() { + + } + + startMonitoring() { + this.setState({ + isMonitoring: true + }); + this.poller.startPolling(); + } + + stopMonitoring() { + this.poller.stopPolling(); + this.setState({ + isMonitoring: false + }); + } + + toggleMonitoring() { + if (this.state.isMonitoring) { + this.stopMonitoring(); + } else { + this.startMonitoring(); + } + } + + onToggleOpen(isOpen: boolean) { + this.setState({ isOpen }); + if (isOpen) { + this.startMonitoring(); + } else { + this.stopMonitoring(); + } + } + + render() { + let monitoringStatus; + const opener = ( + + ); + + if (this.state.isMonitoring) { + if (!this.state.isPolling) { + monitoringStatus = ( + + {' '} + + + ); + } else { + monitoringStatus = ( + + {' '} + + ); + } + } + let title; + if (this.state.isMonitoring) { + title = `Polling is running, with an interval of ${MONITORING_INTERVAL}ms and ${MONITORING_FEEDBACK_STEPS} update steps.`; + } else { + title = 'Polling is currently stopped.'; + } + let monitor; + if (this.state.isOpen) { + monitor = + {monitoringStatus} + ; + } + return ( + + {opener} + {' '} + {monitor} + + ); + } +} diff --git a/vite-app/src/apps/JobBrowser/components/MyJobs/MyJobsRequest.ts b/vite-app/src/apps/JobBrowser/components/MyJobs/MyJobsRequest.ts new file mode 100644 index 00000000..d553ce30 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/MyJobs/MyJobsRequest.ts @@ -0,0 +1,74 @@ +import { Job, JobsSearchExpression } from "apps/JobBrowser/store"; +import { extractTimeRange, serviceJobToUIJob } from "apps/JobBrowser/utils"; +import CancelableRequest, { Task } from "../../lib/CancelableRequest"; +import JobBrowserBFFClient, { QueryJobsParams } from "../../lib/JobBrowserBFFClient"; + +interface MyJobsParam { + token: string, + searchExpression: JobsSearchExpression; + username: string, + serviceWizardURL: string, + timeout: number; + version: string; +} + +type MyJobsResult = { + jobs: Array, + foundCount: number, + totalCount: number; +}; + +export default class MyJobsRequest extends CancelableRequest { + request({ token, timeout, searchExpression, username, serviceWizardURL, version }: MyJobsParam): Task { + const jobBrowserBFF = new JobBrowserBFFClient({ + token, + url: serviceWizardURL, + timeout, + version + }); + + const [timeRangeStart, timeRangeEnd] = extractTimeRange(searchExpression.timeRange); + + const queryParams: QueryJobsParams = { + time_span: { + from: timeRangeStart, + to: timeRangeEnd + }, // TODO: really handle sort + offset: searchExpression.offset, + limit: searchExpression.limit, + timeout, + filter: searchExpression.filter + }; + + if (searchExpression.sort) { + switch (searchExpression.sort.field) { + case 'created': + queryParams.sort = [{ + key: 'created', + direction: searchExpression.sort.direction + }]; + } + } + + const promise = jobBrowserBFF + .query_jobs(queryParams) + .then(({ jobs, found_count, total_count }) => { + + return { + jobs: jobs.map((jobInfo) => { + return serviceJobToUIJob(jobInfo, username); + }), + foundCount: found_count, + totalCount: total_count + }; + }); + + const task: Task = { + id: this.newID(), + promise, + isCanceled: false + }; + this.pendingTasks.set(task.id, task); + return task; + } +} \ No newline at end of file diff --git a/vite-app/src/apps/JobBrowser/components/MyJobs/index.tsx b/vite-app/src/apps/JobBrowser/components/MyJobs/index.tsx new file mode 100644 index 00000000..c20536ef --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/MyJobs/index.tsx @@ -0,0 +1,167 @@ +import { message } from 'antd'; +import { Job, JobsSearchExpression } from 'apps/JobBrowser/store'; +import { JobStateType } from 'apps/JobBrowser/types/jobState'; +import { AuthenticationStateAuthenticated } from 'contexts/EuropaContext'; +import React from 'react'; +import { Config } from 'types/config'; +import JobBrowserBFFClient from '../../lib/JobBrowserBFFClient'; +// import { JSONRPC20Exception } from '../../lib/comm/JSONRPC20/JSONRPC20'; +import { JSONRPC20Exception } from 'lib/kb_lib/comm/JSONRPC20/JSONRPC20'; +import { AsyncProcessState, DataSource } from '../Table'; +import MyJobsRequest from './MyJobsRequest'; +import View from './view'; + +export interface DataProps { + config: Config; + authState: AuthenticationStateAuthenticated; +} + +interface DataState { + dataSource: DataSource; +} + +const myJobsSearchRequests = new MyJobsRequest(); + +export default class Data extends React.Component { + constructor(props: DataProps) { + super(props); + this.state = { + dataSource: { + status: AsyncProcessState.NONE + } + }; + } + + async doSearch(searchExpression: JobsSearchExpression) { + if (this.state.dataSource.status === AsyncProcessState.SUCCESS) { + this.setState({ + dataSource: { + ...this.state.dataSource, + status: AsyncProcessState.REPROCESSING + } + }); + } else { + this.setState({ + dataSource: { + status: AsyncProcessState.PROCESSING + } + }); + } + + const task = myJobsSearchRequests.spawn({ + token: this.props.authState.authInfo.token, + username: this.props.authState.authInfo.account.user, + serviceWizardURL: this.props.config.services.ServiceWizard.url, + searchExpression, + version: this.props.config.dynamicServices.JobBrowserBFF.version, + timeout: this.props.config.ui.constants.clientTimeout + }); + + try { + const { jobs, foundCount, totalCount } = await task.promise; + if (task.isCanceled) { + // just do nothing + return; + } + + myJobsSearchRequests.done(task); + + const { limit, offset } = searchExpression; + const page = Math.ceil((offset + limit) / limit); + const pageCount = Math.ceil(totalCount / limit); + + this.setState({ + dataSource: { + status: AsyncProcessState.SUCCESS, + data: jobs, + count: foundCount, + total: totalCount, + limit, + offset, + page, + pageCount + } + }); + } catch (ex) { + if (ex instanceof JSONRPC20Exception) { + console.error('error', ex.error); + this.setState({ + dataSource: { + status: AsyncProcessState.ERROR, + error: { + code: ex.error.code, + message: ex.error.message, + data: ex.error.data + } + } + }); + } else { + this.setState({ + dataSource: { + status: AsyncProcessState.ERROR, + error: { + code: 0, + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + } + }); + } + } + } + + search(searchExpression: JobsSearchExpression) { + this.doSearch(searchExpression); + } + + cancelJob(jobId: string, timeout: number) { + // do it + const client = new JobBrowserBFFClient({ + url: this.props.config.services.ServiceWizard.url, + token: this.props.authState.authInfo.token, + timeout: this.props.config.ui.constants.clientTimeout, + version: this.props.config.dynamicServices.JobBrowserBFF.version + }); + client + .cancel_job({ + job_id: jobId, + timeout, + admin: false + }) + .then(() => { + const dataSource = this.state.dataSource; + message.success('Successfully canceled the job'); + if (this.state.dataSource.status === AsyncProcessState.SUCCESS) { + for (const datum of this.state.dataSource.data) { + if (datum.id === jobId) { + datum.eventHistory.push({ + at: new Date().getTime(), + type: JobStateType.TERMINATE, + code: 0 + }); + this.setState({ + dataSource + }); + return; + } + } + } + }) + .catch((err) => { + console.error("error canceling job", err); + message.error('Error canceling job: ' + err.message); + }); + } + + refreshSearch() { + } + + render() { + return ; + } +} \ No newline at end of file diff --git a/vite-app/src/apps/JobBrowser/components/MyJobs/style.css b/vite-app/src/apps/JobBrowser/components/MyJobs/style.css new file mode 100644 index 00000000..2cdeaf62 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/MyJobs/style.css @@ -0,0 +1,375 @@ +.MyJobs { + min-height: 0; + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table { + table-layout: fixed; +} + +.MyJobs-tableCell, +.MyJobs-table td, +.MyJobs-table th { + max-width: 0; + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + + +.MyJobs-table .ant-table-header-column { + /* max-width: 0; */ + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.MyJobs-filterArea { + padding: 6px; + margin: 0 20px 0 20px; + border: 1px solid rgba(150, 150, 150, 0.3); + box-shadow: 4px 4px 4px; + border-radius: 4px; + background-color: rgba(200, 200, 200, 0.95); +} + +.MyJobs-filterPanel { + position: absolute; + left: 0; + top: 0; + right: 0; + z-index: 1000; +} + +.ant-modal-wrap { + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content>.ant-table-body { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table-pagination.ant-pagination { + flex: 0 0 auto; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table .ant-table-row { + height: 30px; +} + + +.MyJobs .Table-row>.Table-cell:nth-child(1) { + flex: 0 0 4em; + align-items: center; +} + +.MyJobs .Table-row>.Table-cell:nth-child(2) { + flex: 1 1 0px; + min-width: 10em; +} + + +.MyJobs .Table-row>.Table-cell:nth-child(3) { + min-width: 10em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(4) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(5) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(6) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(7) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(8) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(9) { + flex: 0 0 4em; + align-items: center; + +} + +.MyJobs .-controlBar { + margin: 10px; +} + + + +.ant-modal.FullScreenModal { + /* width: 80% !important; + top: 10% !important; + bottom: 10% !important; */ + flex: 1 1 0px; + display: flex; + flex-direction: column; + width: unset !important; + top: unset !important; + padding-bottom: 0; + margin: 5%; +} + +.ant-modal.FullScreenModal .ant-modal-content { + flex: 1 1 0px; + display: flex; + flex-direction: column; + height: 90%; + top: unset; + min-height: 0; +} + +.ant-modal.FullScreenModal .ant-modal-content .ant-modal-header { + flex: 0 0 auto; +} + +.ant-modal.FullScreenModal .ant-modal-content .ant-modal-body { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ant-modal.FullScreenModal .ant-modal-content .ant-modal-footer { + flex: 0 0 auto; +} + + + +.ant-tabs.FullHeightTabs { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ant-tabs.FullHeightTabs>.ant-tabs-content { + flex: 1 1 0px !important; + display: flex !important; + flex-direction: column !important; + min-height: 0; +} + +.ant-tabs.FullHeightTabs>.ant-tabs-content>.ant-tabs-tabpane { + flex: 1 1 0px !important; + display: flex !important; + flex-direction: column !important; + min-height: 0; +} + +/* flex table */ + + +.FlexTable { + flex: 1 1 0px; + flex-basis: 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.FlexTable-header { + flex: 0 0 auto; + display: flex; + flex-direction: column; +} + +.FlexTable-row { + flex: 0 0 auto; + display: flex; + flex-direction: row; + /* padding: 4px; */ + /* margin: 4px; */ + border-bottom: 1px silver solid; +} + +.FlexTable-col { + flex: 0 0 auto; + /* border: 1px silver dashed; */ + padding: 4px; + overflow-wrap: break-word; + word-wrap: break-word; +} + +.FlexTable-col:last-child { + flex: 1 1 0px; +} + +.FlexTable-body { + flex: 1 1 0px; + overflow-y: auto; + display: flex; + flex-direction: column; + min-height: 0; +} + +/* .FlexTable-col:nth-child(1) { + flex: 0 0 4em; +} + +.FlexTable-col:nth-child(2) { + flex: 1 1 0px; + +} + +.FlexTable-body .Table-col:nth-child(2) { + font-family: monospace; + font-size: 90%; + white-space: pre-wrap +} */ + +.FullyCenteredBox { + flex: 1 1 0px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + + +.ScrollingFlexTable.ant-table-wrapper { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content>.ant-table-scroll { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content>.ant-table-scroll>.ant-table-header { + flex: 0 0 auto; +} + + +/* */ +.PreciseTable { + table-layout: fixed; +} + +.PreciseTable-cell, +.PreciseTable td { + max-width: 0; + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + + +.PreciseTable .ant-table-column-title { + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.NumericColumn { + text-align: right; + padding-right: 1em; +} + + +.InfoTable { + display: flex; + flex-direction: column; +} + +.InfoTable-row { + display: flex; + flex-direction: row; + padding: 4px; +} + +.InfoTable-labelCol { + flex: 0 0 auto; + font-weight: bold; + color: rgba(150, 150, 150, 1); +} + +.InfoTable-dataCol { + flex: 1 1 0px; + text-align: left; +} + diff --git a/vite-app/src/apps/JobBrowser/components/MyJobs/view.tsx b/vite-app/src/apps/JobBrowser/components/MyJobs/view.tsx new file mode 100644 index 00000000..2f231215 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/MyJobs/view.tsx @@ -0,0 +1,840 @@ +/** + * A component for browsing through (search, filter, sort) jobs submitted by + * the current user. + */ + +import { CloseOutlined, InfoCircleOutlined, SearchOutlined } from '@ant-design/icons'; +import { Button, Form, Modal, Popconfirm, Select, Switch, Tooltip } from 'antd'; +import { + Job, + JobContextType, + JobsSearchExpression, + SortSpec, + TimeRange, + TimeRangePresets, +} from 'apps/JobBrowser/store'; +import { JobEvent, JobStateType } from 'apps/JobBrowser/types/jobState'; +import UILink from 'components/UILink2'; +import { AuthenticationStatus, EuropaContext } from 'contexts/EuropaContext'; +import dayjs from 'dayjs'; +import { AsyncProcessStatus } from 'lib/AsyncProcess'; +import React from 'react'; +import { FilterSpec, JobContextNarrative } from '../../lib/JobBrowserBFFClient'; +import PubSub from '../../lib/PubSub'; +import DatePicker from '../DatePicker'; +import FilterEditor from '../FilterEditor/controller'; +import JobDetail from '../JobDetail'; +import JobStatusBadge from '../JobStatusBadge'; +import Monitor from '../Monitor'; +import NarrativeLink from '../NarrativeLink'; +import NiceElapsedTime from '../NiceElapsedTime'; +import NiceRelativeTime from '../NiceRelativeTime'; +import Table2, { AsyncProcessState, Column, DataSource, TableConfig } from '../Table'; +import './style.css'; + +const CANCEL_TIMEOUT = 10000; + +/** + * This version of the job status defines the set of strings that may be used + * in the ui controls. + * + */ +// type JobStatusFilterKey = "queued" | "running" | "canceled" | "success" | "error"; + +/** + * Translates an array of job status filter keys, as provided by the ui job status + * filter checkboxes, to an array of job statuses suitable for passing to the job + * status search. + * + * @param filter - an array of job status filter keys + * + * @note Since the switch is over an enum, we don't have to worry about the default case + * + * @returns an array of job statuses + */ +// function jobStatusFilterOptionsToJobStatus(filter: Array): Array { +// let jobStatuses: Array = []; +// filter.forEach(status => { +// switch (status) { +// case "queued": +// jobStatuses.push(JobStatus.QUEUED); +// break; +// case "running": +// jobStatuses.push(JobStatus.RUNNING); +// break; +// case "canceled": +// jobStatuses.push(JobStatus.CANCELED_QUEUED); +// jobStatuses.push(JobStatus.CANCELED_RUNNING); +// break; +// case "success": +// jobStatuses.push(JobStatus.FINISHED); +// break; +// case "error": +// jobStatuses.push(JobStatus.ERRORED_QUEUED); +// jobStatuses.push(JobStatus.ERRORED_RUNNING); +// break; +// } +// }); +// return jobStatuses; +// } + +/** + * Semantic aliasing of for epoch time in milliseconds, as produced + * by Date.now(), new Date().getTime(), etc. + * + * @todo move to a common location + */ + +/** + * Props for the MyJobs component + */ +export interface MyJobsProps { + dataSource: DataSource; + + /** Triggers a redux action to search of the user's jobs according to the given search expression + * @remarks Since at present the service used to fetch the jobs can suffer performance issues, the + * default search action does not fetch search results each time (rather ??). + * @todo when job search is more performant, this function may be removed and redirected to the + * search function. + */ + search: (searchExpression: JobsSearchExpression) => void; + refreshSearch: () => void; + cancelJob: (jobID: string, timeout: number) => void; + narrativeMethodStoreURL: string; +} + +/** + * State for the MyJobs component + */ +interface MyJobsState { + /** Flag to show the date controls */ + showDates: boolean; + /** Contains the current selection of job statuses in the checkbox control */ + // currentJobStatusFilter: Array; + /** Contains the initial timestamp (ms epoch time) for time range */ + timeRange: TimeRange; + + isFilterOpen: boolean; + + selectedJob: Job | null; + currentSort: SortSpec | null; + // rowsPerPage: number; + + filter: FilterSpec; +} + +/** + * A View Component for browsing through the current user's jobs. + * + * @remarks + * This component is really just a tabular view into a user's jobs. It provides + * support for free text searching, filtering by job state, and date ranges. + * + */ +export default class MyJobs extends React.Component { + currentQuery?: string; + offset: number; + limit: number; + sorting: SortSpec; + currentPage: number; + // rowsPerPage: number; + + static defaultTimeRangePreset: TimeRangePresets = 'lastWeek'; + + pubsub: PubSub; + + constructor(props: MyJobsProps) { + super(props); + + this.currentQuery = ''; + this.pubsub = new PubSub(); + this.offset = 0; + this.limit = 1; + this.currentPage = 0; + this.sorting = { + field: 'created', + direction: 'descending', + }; + + this.state = { + showDates: false, + filter: { + status: ['create', 'queue', 'run', 'terminate', 'complete', 'error'], + }, + timeRange: { kind: 'preset', preset: MyJobs.defaultTimeRangePreset }, + isFilterOpen: false, + selectedJob: null, + currentSort: null, + // rowsPerPage: 1 + }; + } + + async componentDidMount() {} + + // onResize(rowsPerPage: number) { + // // It would be nice to rely upon the table component to trigger a + // // change even if we change the rows per page ... but we change the + // // rows per page via the table props, not by a trigger. + // // Perhaps by wrapping the table or subclassing it? + + // this.limit = rowsPerPage; + // this.offset = this.currentPage * rowsPerPage; + + // // This causes the table to rerender, but without triggering a + // // re-search; + // // this.setState({ + // // rowsPerPage + // // }); + + // // This triggers a fresh search. + // this.doSearch(false); + // } + + componentDidUpdate() { + if ( + this.props.dataSource.status === AsyncProcessState.PROCESSING || + this.props.dataSource.status === AsyncProcessState.REPROCESSING + ) { + this.pubsub.send('searching', { is: true }); + } else { + this.pubsub.send('searching', { is: false }); + } + } + + onChangeTimeRange(value: string) { + // TODO: should narrow the string value + if (value === 'customRange') { + // TODO: utilize dates from time range presets. + this.setState({ + showDates: true, + timeRange: { kind: 'literal', start: Date.now(), end: Date.now() }, + }); + // nothing else to do. + return; + } else { + this.setState( + { + showDates: false, + timeRange: { + kind: 'preset', + preset: value as TimeRangePresets, + }, + }, + () => { + // Because this may obsolete the page. + // This is a simplification, for sure. + this.offset = 0; + this.doSearch(true); + }, + ); + } + } + + onChangeQuery(event: React.ChangeEvent) { + this.currentQuery = event.target.value; + } + + onSubmit(_fields: any) { + this.doSearch(true); + } + + onFirstPage() { + if (this.props.dataSource.status !== AsyncProcessState.SUCCESS) { + return; + } + + const dataSource = this.props.dataSource; + + if (dataSource.page <= 1) { + return; + } + + // here we do it. + this.offset = 0; + + this.doSearch(false); + } + + onPreviousPage() { + if (this.props.dataSource.status !== AsyncProcessState.SUCCESS) { + return; + } + + const dataSource = this.props.dataSource; + + if (dataSource.page <= 1) { + return; + } + + // here we do it. + this.offset = (dataSource.page - 2) * dataSource.limit; + this.limit = dataSource.limit; + + this.doSearch(false); + } + + onNextPage() { + if (this.props.dataSource.status !== AsyncProcessState.SUCCESS) { + return; + } + + const dataSource = this.props.dataSource; + + if (dataSource.page >= dataSource.pageCount) { + return; + } + + // here we do it. + this.offset = dataSource.page * dataSource.limit; + this.limit = dataSource.limit; + + this.doSearch(false); + } + + onLastPage() { + if (this.props.dataSource.status !== AsyncProcessState.SUCCESS) { + return; + } + + const dataSource = this.props.dataSource; + + if (dataSource.page >= dataSource.pageCount) { + return; + } + + // here we do it. + this.offset = (dataSource.pageCount - 1) * dataSource.limit; + this.limit = dataSource.limit; + + this.doSearch(false); + } + + onReset() { + this.offset = 0; + this.doSearch(true); + } + + doSearch(forceSearch: boolean) { + const searchExpression: JobsSearchExpression = { + query: this.currentQuery, + timeRange: this.state.timeRange, + filter: this.state.filter, + forceSearch, + sort: this.sorting, + offset: this.offset, + limit: this.limit, + }; + + // TODO: document wth is happening here. + this.pubsub.send('search', { is: true }); + + this.props.search(searchExpression); + return false; + } + + onRangeChange(range: [dayjs.Dayjs | null, dayjs.Dayjs | null] | null) { + if (!range) { + return; + } + + const [fromDate, toDate] = range; + + let existingTimeRange = this.state.timeRange; + let timeRange: TimeRange; + switch (existingTimeRange.kind) { + case 'preset': + timeRange = { + kind: 'literal', + start: fromDate ? fromDate.valueOf() : 0, + end: toDate ? toDate.valueOf() : Infinity, + }; + break; + case 'literal': + timeRange = { + kind: 'literal', + start: fromDate ? fromDate.valueOf() : 0, + end: toDate ? toDate.valueOf() : Infinity, + }; + break; + default: + return; + } + + this.setState({ + timeRange, + }); + } + + renderSearchInput() { + let dateControls; + if (this.state.showDates) { + const timeRange = this.state.timeRange; + if (timeRange.kind === 'literal') { + dateControls = ( + + + + + + ); + } + } + return ( +
    + + + + {dateControls} + + + + + ); + const title = ( + + Detail for Job {this.state.selectedJob.id} + + ); + return ( + + + {(value) => { + if (value === null || value.status !== AsyncProcessStatus.SUCCESS) { + return; + } + if (value.value.authState.status !== AuthenticationStatus.AUTHENTICATED) { + return; + } + + const { + config, + authState: { + authInfo: { token }, + }, + } = value.value; + + return ( + + ); + }} + + + ); + } + + renderView() { + return ( + +
    {this.renderControlBar()}
    + {this.renderJobsTable()} + {this.renderJobDetail()} +
    + ); + } + + render() { + return ( +
    + {this.renderView()} +
    + ); + } +} diff --git a/vite-app/src/apps/JobBrowser/components/NarrativeLink.tsx b/vite-app/src/apps/JobBrowser/components/NarrativeLink.tsx new file mode 100644 index 00000000..e22a808e --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/NarrativeLink.tsx @@ -0,0 +1,16 @@ +import UILink from 'components/UILink2'; +import { Component, PropsWithChildren } from 'react'; + +export interface NarrativeLinkProps extends PropsWithChildren { + narrativeID: number; +} + +export default class NarrativeLink extends Component { + render() { + return ( + + {this.props.children} + + ); + } +} diff --git a/vite-app/src/apps/JobBrowser/components/NiceElapsedTime.tsx b/vite-app/src/apps/JobBrowser/components/NiceElapsedTime.tsx new file mode 100644 index 00000000..e3540763 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/NiceElapsedTime.tsx @@ -0,0 +1,96 @@ +import { Tooltip } from 'antd'; +import * as React from 'react'; +import { niceElapsed } from '../lib/time'; + + +const SECOND = 1000; +// const MINUTE = 60 * SECOND; +// const HOUR = 60 * MINUTE; +// const DAY = 24 * HOUR; +const CLOCK_INTERVAL_SECOND = SECOND / 4; +// const CLOCK_INTERVAL_MINUTE = MINUTE / 4; +// const CLOCK_INTERVAL_HOUR = HOUR / 4; + +export interface NiceElapsedTimeProps { + from: number; + to?: number; + precision?: number; + showTooltip?: boolean; + tooltipPrefix?: string; + useClock?: boolean; +} + +interface NiceElapsedTimeState { + clockTime: number; +} + +export default class NiceElapsedTime extends React.Component { + clockTimer: number | null; + + constructor(props: NiceElapsedTimeProps) { + super(props); + this.clockTimer = null; + this.state = { + clockTime: Date.now() + }; + } + + startClock() { + this.clockTimer = window.setInterval(() => { + this.setState({ + clockTime: Date.now() + }); + }, CLOCK_INTERVAL_SECOND); + } + + stopClock() { + if (this.clockTimer) { + window.clearInterval(this.clockTimer); + } + } + + componentDidMount() { + if (!this.props.to && this.props.useClock) { + this.startClock(); + } + } + + componentWillUnmount() { + this.stopClock(); + } + render() { + let elapsed; + if (this.props.to) { + elapsed = this.props.to - this.props.from; + } else { + elapsed = this.state.clockTime - this.props.from; + } + const { label: content } = niceElapsed(elapsed, {}); + if (this.props.showTooltip === false) { + return {content}; + } + + let tooltip; + if (this.props.tooltipPrefix) { + tooltip = ( + + {this.props.tooltipPrefix} + {content} + + ); + } else { + tooltip = {content}; + } + const { label: tooltipContent } = niceElapsed(elapsed, { + precision: this.props.precision, + + }); + return ( + + + {tooltipContent} + + + ); + } +} diff --git a/vite-app/src/apps/JobBrowser/components/NiceRelativeTime.tsx b/vite-app/src/apps/JobBrowser/components/NiceRelativeTime.tsx new file mode 100644 index 00000000..709ed050 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/NiceRelativeTime.tsx @@ -0,0 +1,123 @@ +import * as React from 'react'; + +import { Tooltip } from 'antd'; +import { niceRelativeTime } from '../lib/time'; + +export interface NiceRelativeTimeProps { + time: Date; + showTooltip?: boolean; + tooltipPrefix?: string; + absoluteAfter?: number; +} + +interface NiceRelativeTimeState { + now: Date; +} + +// dynamic intervals, based on the range of elapsed time +// TODO: using intervals we should actually set the interval to +// trigger based on the datetime to display. +const intervals = [ + // below 1 minute, every 1/2 sec + [60 * 1000, 500], + // between 1 minute and 1 hour, every 30 seconds + [60 * 60 * 1000, 30 * 1000], + // between 1 hour and 1 day, every 30 minutes + [60 * 60 * 24 * 1000, 60 * 1000 * 30], + // over 1 day, once per day + [Infinity, 60 * 60 * 24 * 1000] +]; + +export default class NiceRelativeTime extends React.Component { + nowTimer: number | null; + interval: number; + constructor(props: NiceRelativeTimeProps) { + super(props); + + this.nowTimer = null; + + this.state = { + now: new Date() + }; + + this.interval = this.calcInterval(); + } + + calcInterval(): number { + const elapsed = this.state.now.getTime() - this.props.time.getTime(); + for (const [upto, interval] of intervals) { + if (elapsed < upto) { + return interval; + } + } + console.error('hmm again', elapsed, intervals); + throw new Error('did not find interval'); + } + + handleInterval() { + const now = new Date(); + this.setState({ now }, () => { + const interval = this.calcInterval(); + if (this.interval !== interval) { + this.interval = interval; + this.startIntervalTimer(); + } + }); + } + + startIntervalTimer() { + if (this.nowTimer) { + window.clearInterval(this.nowTimer); + } + this.nowTimer = window.setInterval(() => { + this.handleInterval(); + }, this.interval); + } + + componentDidMount() { + this.startIntervalTimer(); + } + + componentWillUnmount() { + if (this.nowTimer) { + window.clearInterval(this.nowTimer); + } + } + + render() { + if (this.props.showTooltip === false) { + return {niceRelativeTime(this.props.time, { absoluteAfter: 30, now: this.state.now })}; + } + + const fullDate = ( + + {Intl.DateTimeFormat('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + hour: 'numeric', + minute: 'numeric', + timeZoneName: 'short' + }).format(this.props.time)} + + ); + let tooltip; + if (this.props.tooltipPrefix) { + tooltip = ( + + {this.props.tooltipPrefix} + {fullDate} + + ); + } else { + tooltip = fullDate; + } + return ( + + + {niceRelativeTime(this.props.time, { absoluteAfter: this.props.absoluteAfter || 30, now: this.state.now })} + + + ); + } +} diff --git a/vite-app/src/apps/JobBrowser/components/PublicAppStats/index.tsx b/vite-app/src/apps/JobBrowser/components/PublicAppStats/index.tsx new file mode 100644 index 00000000..81b6f66c --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/PublicAppStats/index.tsx @@ -0,0 +1,177 @@ +import { PublicAppStatsQuery } from 'apps/JobBrowser/store/PublicAppStats'; +import { AppStat } from 'apps/JobBrowser/store/base'; +import { calcAverage, calcRate } from 'apps/JobBrowser/utils'; +import ErrorAlert from 'components/ErrorAlert'; +import Loading from 'components/Loading'; +import { AuthenticationStateAuthenticated } from 'contexts/EuropaContext'; +import { AsyncProcess, AsyncProcessStatus } from 'lib/AsyncProcess'; +import { SimpleError } from 'lib/SimpleError'; +import CatalogClient from 'lib/kb_lib/comm/coreServices/Catalog'; +import React from 'react'; +import { Config } from 'types/config'; +import PublicAppStats from './view'; + +export interface ControllerProps { + config: Config; + auth: AuthenticationStateAuthenticated +} + +export interface Filtered { + show: boolean; + value: T; +} + +export interface PublicAppStatsState { + stats: Array> +} + +export type ControllerState = AsyncProcess + +export default class Controller extends React.Component { + constructor(props: ControllerProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + } + } + + componentDidMount() { + this.initialize(); + } + + async initialize() { + // Start off by getting everything. + // Note that this was optimistic, in that I had hoped that ee2 would eventually + // support fully search semantics (offset, limit, sort, query), but for now I + // believe we still just have to get everything and perform it all client-side. + this.setState({ + status: AsyncProcessStatus.PENDING + }) + try { + const stats = await this.loadInitialData() + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + stats + } + }) + } catch (ex) { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }) + } + } + + async loadInitialData() { + const catalogClient = new CatalogClient({ + token: this.props.auth.authInfo.token, + url: this.props.config.services.Catalog.url, + timeout: this.props.config.ui.constants.clientTimeout + }); + + const rawStats = await catalogClient.get_exec_aggr_stats({}); + return rawStats.map>((stat) => { + const [moduleId, functionId] = stat.full_app_id.split('/'); + if (!moduleId || !functionId) { + console.warn('bad app!', stat); + } + const successRate = calcRate(stat.number_of_calls - stat.number_of_errors, stat.number_of_calls); + const averageRunTime = calcAverage(stat.total_exec_time, stat.number_of_calls); + const averageQueueTime = calcAverage(stat.total_queue_time, stat.number_of_calls); + return { + show: true, + value: { + appId: stat.full_app_id, + moduleId, + functionId: functionId || '', + moduleTitle: moduleId, + functionTitle: functionId || '', + runCount: stat.number_of_calls, + errorCount: stat.number_of_errors, + successRate, + averageRunTime, + averageQueueTime, + totalRunTime: stat.total_queue_time + } + } + }); + } + + async search(query: PublicAppStatsQuery) { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + try { + const terms = query.query.split(/\s+/); + + const expression = terms.map((term) => { + return new RegExp(term, 'i'); + }); + + const stats = this.state.value.stats.map(({value}) => { + const show = expression.length === 0 || expression.every((term) => { + return ( + term.test(value.moduleTitle) || + term.test(value.moduleId) || + term.test(value.functionTitle) || + term.test(value.functionId) + ); + }); + return {show, value}; + }); + + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + stats + } + }) + } catch (ex) { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }) + } + } + + renderLoading() { + return ; + } + + onSearch(query: PublicAppStatsQuery): void { + this.search(query); + } + + renderSuccess({stats}: PublicAppStatsState) { + const filteredStats = stats + .filter(({show}) => { + return show; + }) + .map(({value}) => { + return value; + }); + return ; + } + + renderError(error: SimpleError) { + return ; + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return this.renderLoading(); + case AsyncProcessStatus.SUCCESS: + return this.renderSuccess(this.state.value); + case AsyncProcessStatus.ERROR: + return this.renderError(this.state.error); + } + } +} diff --git a/vite-app/src/apps/JobBrowser/components/PublicAppStats/style.css b/vite-app/src/apps/JobBrowser/components/PublicAppStats/style.css new file mode 100644 index 00000000..de2a5854 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/PublicAppStats/style.css @@ -0,0 +1,7 @@ +.PublicAppStats { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; + margin-top: 1rem; +} \ No newline at end of file diff --git a/vite-app/src/apps/JobBrowser/components/PublicAppStats/view.tsx b/vite-app/src/apps/JobBrowser/components/PublicAppStats/view.tsx new file mode 100644 index 00000000..45c8be16 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/PublicAppStats/view.tsx @@ -0,0 +1,248 @@ +import { SearchOutlined } from '@ant-design/icons'; +import { Button, Form, Input, Progress, Spin, Table, Tooltip } from 'antd'; +import { PublicAppStatsQuery } from 'apps/JobBrowser/store/PublicAppStats'; +import { AppStat } from 'apps/JobBrowser/store/base'; +import NiceTimeDuration from 'components/NiceTimeDuration'; +import UILink from 'components/UILink2'; +import React from 'react'; +import './style.css'; + +export function nullableNumberCompare(a: number | null, b: number | null): number { + if (a === null) { + if (blur === null) { + return 0; + } else { + return -1; + } + } else { + if (b === null) { + return 1; + } else { + return a - b; + } + } +} + +export interface PublicAppStatsProps { + stats: Array; + // searchState: SearchState; + // appStats: Array; + onSearch: (query: PublicAppStatsQuery) => void; +} + +interface PublicAppStatsState { + appStats: Array; +} + +export default class PublicAppStats extends React.Component { + currentQuery: string; + constructor(props: PublicAppStatsProps) { + super(props); + this.currentQuery = ''; + } + // componentDidMount() { + // this.props.onSearch({ + // query: this.currentQuery + // }); + // } + onSubmitSearch(_fields: any) { + // event.preventDefault(); + this.props.onSearch({ + query: this.currentQuery, + }); + } + + onChangeQuery(event: React.ChangeEvent) { + this.currentQuery = event.target.value; + } + + renderControlBar() { + // TODO: refactor - the clear does not resend the query. + return ( +
    + + + + + + +
    + } + /> + {this.renderErrorModal(dataSource)} + ; + } + + renderErrorModal(dataSource: DataSourceError) { + const description =
    +
    Code: {dataSource.error.code}
    +
    Message: {dataSource.error.message}
    +
    Data:
    +
    + {dataSource.error.data && this.renderJSON(dataSource.error.data)} +
    +
    ; + return { + this.setState({ + showError: false + }); + }} + style={{ + maxWidth: '50em', + top: '20px', + bottom: '20px', + flex: '1 1 0px', + display: 'flex', + flexDirection: 'column' + }} + width="50em" + bodyStyle={{ + flex: '1 1 0px', + display: 'flex', + flexDirection: 'column' + }} + + footer={[ + , + + ]} + > + {description} + ; + } + + /* + + */ + + renderLoading() { + return + + ; + } + + renderBodyOverlay() { + switch (this.props.dataSource.status) { + case AsyncProcessState.NONE: + case AsyncProcessState.PROCESSING: + case AsyncProcessState.REPROCESSING: + return
    +
    + {this.props.loadingPhrase || 'Loading...'} +
    +
    ; + case AsyncProcessState.SUCCESS: + case AsyncProcessState.ERROR: + } + } + + renderBody() { + const content = ((): ReactNode => { + switch (this.props.dataSource.status) { + case AsyncProcessState.NONE: + // return this.renderLoading(); + case AsyncProcessState.PROCESSING: + // return this.renderLoading(); + return; + case AsyncProcessState.REPROCESSING: + return this.renderTableRows(this.props.dataSource); + case AsyncProcessState.SUCCESS: + return this.renderTableRows(this.props.dataSource); + case AsyncProcessState.ERROR: + return this.renderError(this.props.dataSource); + } + })(); + + return
    + {this.renderBodyOverlay()} + {content} +
    ; + } + + renderNav() { + if (this.state.status === TableStatus.OK) { + switch (this.props.dataSource.status) { + case AsyncProcessState.NONE: + return ; + case AsyncProcessState.PROCESSING: + return ; + case AsyncProcessState.REPROCESSING: + case AsyncProcessState.SUCCESS: + return ; + case AsyncProcessState.ERROR: + return ; + } + } else { + return ; + } + } + + render() { + return
    + {this.renderHeader()} + {this.renderBody()} + {this.renderNav()} +
    ; + } +} \ No newline at end of file diff --git a/vite-app/src/apps/JobBrowser/components/UILink.xtsx b/vite-app/src/apps/JobBrowser/components/UILink.xtsx new file mode 100644 index 00000000..0de9c651 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UILink.xtsx @@ -0,0 +1,26 @@ +import React from 'react'; + +export interface UILinkProps { + path: string; + openIn: 'same-window' | 'new-tab'; +} + +interface UILinkState { + +} + +export default class UILink extends React.Component { + render() { + const href = `/#${this.props.path}`; + switch (this.props.openIn) { + case 'same-window': + return + {this.props.children} + ; + case 'new-tab': + return + {this.props.children} + ; + } + } +} \ No newline at end of file diff --git a/vite-app/src/apps/JobBrowser/components/UserJobs/MyJobsRequest.ts b/vite-app/src/apps/JobBrowser/components/UserJobs/MyJobsRequest.ts new file mode 100644 index 00000000..d553ce30 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UserJobs/MyJobsRequest.ts @@ -0,0 +1,74 @@ +import { Job, JobsSearchExpression } from "apps/JobBrowser/store"; +import { extractTimeRange, serviceJobToUIJob } from "apps/JobBrowser/utils"; +import CancelableRequest, { Task } from "../../lib/CancelableRequest"; +import JobBrowserBFFClient, { QueryJobsParams } from "../../lib/JobBrowserBFFClient"; + +interface MyJobsParam { + token: string, + searchExpression: JobsSearchExpression; + username: string, + serviceWizardURL: string, + timeout: number; + version: string; +} + +type MyJobsResult = { + jobs: Array, + foundCount: number, + totalCount: number; +}; + +export default class MyJobsRequest extends CancelableRequest { + request({ token, timeout, searchExpression, username, serviceWizardURL, version }: MyJobsParam): Task { + const jobBrowserBFF = new JobBrowserBFFClient({ + token, + url: serviceWizardURL, + timeout, + version + }); + + const [timeRangeStart, timeRangeEnd] = extractTimeRange(searchExpression.timeRange); + + const queryParams: QueryJobsParams = { + time_span: { + from: timeRangeStart, + to: timeRangeEnd + }, // TODO: really handle sort + offset: searchExpression.offset, + limit: searchExpression.limit, + timeout, + filter: searchExpression.filter + }; + + if (searchExpression.sort) { + switch (searchExpression.sort.field) { + case 'created': + queryParams.sort = [{ + key: 'created', + direction: searchExpression.sort.direction + }]; + } + } + + const promise = jobBrowserBFF + .query_jobs(queryParams) + .then(({ jobs, found_count, total_count }) => { + + return { + jobs: jobs.map((jobInfo) => { + return serviceJobToUIJob(jobInfo, username); + }), + foundCount: found_count, + totalCount: total_count + }; + }); + + const task: Task = { + id: this.newID(), + promise, + isCanceled: false + }; + this.pendingTasks.set(task.id, task); + return task; + } +} \ No newline at end of file diff --git a/vite-app/src/apps/JobBrowser/components/UserJobs/index.tsx b/vite-app/src/apps/JobBrowser/components/UserJobs/index.tsx new file mode 100644 index 00000000..aa33d0bc --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UserJobs/index.tsx @@ -0,0 +1,180 @@ +import { message } from 'antd'; +import React from 'react'; +import View from './view'; + +// import { Job, JobsSearchExpression } from '../../redux/store'; +import JobBrowserBFFClient from '../../lib/JobBrowserBFFClient'; +import { AsyncProcessState, DataSource } from '../Table'; +import MyJobsRequest from './MyJobsRequest'; +// import { JobStateType } from '../../redux/types/jobState'; +// import { SERVICE_TIMEOUT } from '../../constants'; +import { Job, JobsSearchExpression } from 'apps/JobBrowser/store'; +import { JobStateType } from 'apps/JobBrowser/types/jobState'; +import { AuthenticationStateAuthenticated } from 'contexts/EuropaContext'; +import { JSONRPC20Exception } from 'lib/kb_lib/comm/JSONRPC20/JSONRPC20'; +import { Config } from 'types/config'; +// import { JSONRPC20Exception } from '../../lib/comm/JSONRPC20/JSONRPC20'; +// import { DynamicServiceConfig } from '@kbase/ui-components/lib/redux/integration/store'; + +export interface DataProps { + config: Config; + authState: AuthenticationStateAuthenticated; + // token: string; + // username: string; + // serviceWizardURL: string; + // narrativeMethodStoreURL: string; + // jobBrowserBFFConfig: DynamicServiceConfig; +} + +interface DataState { + dataSource: DataSource; +} + +const myJobsSearchRequests = new MyJobsRequest(); + +export default class Data extends React.Component { + searchExpression: JobsSearchExpression | null; + constructor(props: DataProps) { + super(props); + this.searchExpression = null; + this.state = { + dataSource: { + status: AsyncProcessState.NONE + } + }; + } + async doSearch(searchExpression: JobsSearchExpression) { + if (this.state.dataSource.status === AsyncProcessState.SUCCESS) { + this.setState({ + dataSource: { + ...this.state.dataSource, + status: AsyncProcessState.REPROCESSING + } + }); + } else { + this.setState({ + dataSource: { + status: AsyncProcessState.PROCESSING + } + }); + } + + const task = myJobsSearchRequests.spawn({ + token: this.props.authState.authInfo.token, + username: this.props.authState.authInfo.account.user, + serviceWizardURL: this.props.config.services.ServiceWizard.url, + searchExpression, + version: this.props.config.dynamicServices.JobBrowserBFF.version, + timeout: this.props.config.ui.constants.clientTimeout + }); + + try { + const { jobs, foundCount, totalCount } = await task.promise; + if (task.isCanceled) { + // just do nothing + return; + } + + myJobsSearchRequests.done(task); + + const { limit, offset } = searchExpression; + const page = Math.ceil((offset + limit) / limit); + const pageCount = Math.ceil(totalCount / limit); + + this.setState({ + dataSource: { + status: AsyncProcessState.SUCCESS, + data: jobs, + count: foundCount, + total: totalCount, + limit, + offset, + page, + pageCount + } + }); + } catch (ex) { + if (ex instanceof JSONRPC20Exception) { + // console.error('error', ex.error); + + this.setState({ + dataSource: { + status: AsyncProcessState.ERROR, + error: { + code: ex.error.code, + message: ex.error.message, + data: ex.error.data + } + } + }); + } else { + this.setState({ + dataSource: { + status: AsyncProcessState.ERROR, + error: { + code: 0, + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + } + }); + } + } + } + + search(searchExpression: JobsSearchExpression) { + this.searchExpression = searchExpression; + this.doSearch(searchExpression); + } + + cancelJob(jobId: string, timeout: number) { + // do it + const client = new JobBrowserBFFClient({ + url: this.props.config.services.ServiceWizard.url, + token: this.props.authState.authInfo.token, + timeout: this.props.config.ui.constants.clientTimeout, + version: this.props.config.dynamicServices.JobBrowserBFF.version + }); + client + .cancel_job({ + job_id: jobId, + timeout, + admin: false + }) + .then(() => { + const dataSource = this.state.dataSource; + message.success('Successfully canceled the job'); + if (this.state.dataSource.status === AsyncProcessState.SUCCESS) { + for (const datum of this.state.dataSource.data) { + if (datum.id === jobId) { + datum.eventHistory.push({ + at: new Date().getTime(), + type: JobStateType.TERMINATE, + code: 0 + }); + this.setState({ + dataSource + }); + return; + } + } + } + }) + .catch((err) => { + console.error("error canceling job", err); + message.error('Error canceling job: ' + err.message); + }); + } + + refreshSearch() { + + } + render() { + return ; + } +} \ No newline at end of file diff --git a/vite-app/src/apps/JobBrowser/components/UserJobs/index.xtsx b/vite-app/src/apps/JobBrowser/components/UserJobs/index.xtsx new file mode 100644 index 00000000..301cf650 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UserJobs/index.xtsx @@ -0,0 +1,61 @@ +import { Dispatch, Action } from 'redux'; +import { connect } from 'react-redux'; +import Data from './data'; + +import { + StoreState +} from '../../redux/store'; +import { DynamicServiceConfig } from '@kbase/ui-components/lib/redux/integration/store'; + +export interface OwnProps { +} + +interface StateProps { + token: string; + username: string; + serviceWizardURL: string; + narrativeMethodStoreURL: string; + jobBrowserBFFConfig: DynamicServiceConfig; +} + +interface DispatchProps { +} + +function mapStateToProps(state: StoreState, props: OwnProps): StateProps { + const { + auth: { userAuthorization }, + app: { + config: { + services: { + ServiceWizard: { url: serviceWizardURL }, + NarrativeMethodStore: { url: narrativeMethodStoreURL } + }, + dynamicServices: { + JobBrowserBFF: jobBrowserBFFConfig + } + } + } + } = state; + + if (!userAuthorization) { + throw new Error('Not authorized!'); + } + + const { token, username } = userAuthorization; + + return { + token, username, + serviceWizardURL, + narrativeMethodStoreURL, + jobBrowserBFFConfig + }; +} + +function mapDispatchToProps(dispatch: Dispatch, ownProps: OwnProps): DispatchProps { + return {}; +} + +export default connect( + mapStateToProps, + mapDispatchToProps +)(Data); diff --git a/vite-app/src/apps/JobBrowser/components/UserJobs/style.css b/vite-app/src/apps/JobBrowser/components/UserJobs/style.css new file mode 100644 index 00000000..2cdeaf62 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UserJobs/style.css @@ -0,0 +1,375 @@ +.MyJobs { + min-height: 0; + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table { + table-layout: fixed; +} + +.MyJobs-tableCell, +.MyJobs-table td, +.MyJobs-table th { + max-width: 0; + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + + +.MyJobs-table .ant-table-header-column { + /* max-width: 0; */ + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.MyJobs-filterArea { + padding: 6px; + margin: 0 20px 0 20px; + border: 1px solid rgba(150, 150, 150, 0.3); + box-shadow: 4px 4px 4px; + border-radius: 4px; + background-color: rgba(200, 200, 200, 0.95); +} + +.MyJobs-filterPanel { + position: absolute; + left: 0; + top: 0; + right: 0; + z-index: 1000; +} + +.ant-modal-wrap { + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content>.ant-table-body { + flex: 1 1 0px; + display: flex; + flex-direction: column; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table-pagination.ant-pagination { + flex: 0 0 auto; +} + +.MyJobs-table.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table .ant-table-row { + height: 30px; +} + + +.MyJobs .Table-row>.Table-cell:nth-child(1) { + flex: 0 0 4em; + align-items: center; +} + +.MyJobs .Table-row>.Table-cell:nth-child(2) { + flex: 1 1 0px; + min-width: 10em; +} + + +.MyJobs .Table-row>.Table-cell:nth-child(3) { + min-width: 10em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(4) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(5) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(6) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(7) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(8) { + flex: 0 0 8em; +} + +.MyJobs .Table-row>.Table-cell:nth-child(9) { + flex: 0 0 4em; + align-items: center; + +} + +.MyJobs .-controlBar { + margin: 10px; +} + + + +.ant-modal.FullScreenModal { + /* width: 80% !important; + top: 10% !important; + bottom: 10% !important; */ + flex: 1 1 0px; + display: flex; + flex-direction: column; + width: unset !important; + top: unset !important; + padding-bottom: 0; + margin: 5%; +} + +.ant-modal.FullScreenModal .ant-modal-content { + flex: 1 1 0px; + display: flex; + flex-direction: column; + height: 90%; + top: unset; + min-height: 0; +} + +.ant-modal.FullScreenModal .ant-modal-content .ant-modal-header { + flex: 0 0 auto; +} + +.ant-modal.FullScreenModal .ant-modal-content .ant-modal-body { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ant-modal.FullScreenModal .ant-modal-content .ant-modal-footer { + flex: 0 0 auto; +} + + + +.ant-tabs.FullHeightTabs { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ant-tabs.FullHeightTabs>.ant-tabs-content { + flex: 1 1 0px !important; + display: flex !important; + flex-direction: column !important; + min-height: 0; +} + +.ant-tabs.FullHeightTabs>.ant-tabs-content>.ant-tabs-tabpane { + flex: 1 1 0px !important; + display: flex !important; + flex-direction: column !important; + min-height: 0; +} + +/* flex table */ + + +.FlexTable { + flex: 1 1 0px; + flex-basis: 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.FlexTable-header { + flex: 0 0 auto; + display: flex; + flex-direction: column; +} + +.FlexTable-row { + flex: 0 0 auto; + display: flex; + flex-direction: row; + /* padding: 4px; */ + /* margin: 4px; */ + border-bottom: 1px silver solid; +} + +.FlexTable-col { + flex: 0 0 auto; + /* border: 1px silver dashed; */ + padding: 4px; + overflow-wrap: break-word; + word-wrap: break-word; +} + +.FlexTable-col:last-child { + flex: 1 1 0px; +} + +.FlexTable-body { + flex: 1 1 0px; + overflow-y: auto; + display: flex; + flex-direction: column; + min-height: 0; +} + +/* .FlexTable-col:nth-child(1) { + flex: 0 0 4em; +} + +.FlexTable-col:nth-child(2) { + flex: 1 1 0px; + +} + +.FlexTable-body .Table-col:nth-child(2) { + font-family: monospace; + font-size: 90%; + white-space: pre-wrap +} */ + +.FullyCenteredBox { + flex: 1 1 0px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + + +.ScrollingFlexTable.ant-table-wrapper { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content>.ant-table-scroll { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; +} + + +.ScrollingFlexTable.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table>.ant-table-content>.ant-table-scroll>.ant-table-header { + flex: 0 0 auto; +} + + +/* */ +.PreciseTable { + table-layout: fixed; +} + +.PreciseTable-cell, +.PreciseTable td { + max-width: 0; + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + + +.PreciseTable .ant-table-column-title { + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.NumericColumn { + text-align: right; + padding-right: 1em; +} + + +.InfoTable { + display: flex; + flex-direction: column; +} + +.InfoTable-row { + display: flex; + flex-direction: row; + padding: 4px; +} + +.InfoTable-labelCol { + flex: 0 0 auto; + font-weight: bold; + color: rgba(150, 150, 150, 1); +} + +.InfoTable-dataCol { + flex: 1 1 0px; + text-align: left; +} + diff --git a/vite-app/src/apps/JobBrowser/components/UserJobs/view.tsx b/vite-app/src/apps/JobBrowser/components/UserJobs/view.tsx new file mode 100644 index 00000000..a9e8de3f --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UserJobs/view.tsx @@ -0,0 +1,867 @@ +/** + * A component for browsing through (search, filter, sort) jobs submitted by + * the current user. + */ + +/** imports */ +// 3rd party imports +import { Button, Form, Modal, Popconfirm, Select, Switch, Tooltip } from 'antd'; +import React from 'react'; + +// import moment, { Moment } from 'moment'; +import dayjs from 'dayjs'; + +// project imports + +import JobDetail from '../JobDetail'; + +// kbase imports (or should be kbase imports) +// import { NiceRelativeTime, NiceElapsedTime } from '@kbase/ui-components'; +import JobStatusBadge from '../JobStatusBadge'; + +// file imports +import { CloseOutlined, InfoCircleOutlined, SearchOutlined } from '@ant-design/icons'; +import { + Job, + JobContextType, + JobsSearchExpression, + SortSpec, + TimeRange, + TimeRangePresets, +} from 'apps/JobBrowser/store'; +import { JobEvent, JobStateType } from 'apps/JobBrowser/types/jobState'; +import { FilterSpec, JobContextNarrative } from '../../lib/JobBrowserBFFClient'; +import PubSub from '../../lib/PubSub'; +import DatePicker from '../DatePicker'; +// import FilterEditor, { JobFilter } from "../FilterEditor"; +import UILink from 'components/UILink2'; +import { AuthenticationStatus, EuropaContext } from 'contexts/EuropaContext'; +import { AsyncProcessStatus } from 'lib/AsyncProcess'; +import Monitor from '../Monitor'; +import NarrativeLink from '../NarrativeLink'; +import NiceElapsedTime from '../NiceElapsedTime'; +import NiceRelativeTime from '../NiceRelativeTime'; +import Table2, { AsyncProcessState, Column, DataSource, TableConfig } from '../Table'; +import './style.css'; + +const CANCEL_TIMEOUT = 10000; + +/** + * This version of the job status defines the set of strings that may be used + * in the ui controls. + * + */ +// type JobStatusFilterKey = "queued" | "running" | "canceled" | "success" | "error"; + +/** + * Translates an array of job status filter keys, as provided by the ui job status + * filter checkboxes, to an array of job statuses suitable for passing to the job + * status search. + * + * @param filter - an array of job status filter keys + * + * @note Since the switch is over an enum, we don't have to worry about the default case + * + * @returns an array of job statuses + */ +// function jobStatusFilterOptionsToJobStatus(filter: Array): Array { +// let jobStatuses: Array = []; +// filter.forEach(status => { +// switch (status) { +// case "queued": +// jobStatuses.push(JobStatus.QUEUED); +// break; +// case "running": +// jobStatuses.push(JobStatus.RUNNING); +// break; +// case "canceled": +// jobStatuses.push(JobStatus.CANCELED_QUEUED); +// jobStatuses.push(JobStatus.CANCELED_RUNNING); +// break; +// case "success": +// jobStatuses.push(JobStatus.FINISHED); +// break; +// case "error": +// jobStatuses.push(JobStatus.ERRORED_QUEUED); +// jobStatuses.push(JobStatus.ERRORED_RUNNING); +// break; +// } +// }); +// return jobStatuses; +// } + +/** + * Semantic aliasing of for epoch time in milliseconds, as produced + * by Date.now(), new Date().getTime(), etc. + * + * @todo move to a common location + */ + +/** + * Props for the MyJobs component + */ +export interface MyJobsProps { + dataSource: DataSource; + // view: MyJobsView; + /** The list of jobs to display */ + + // jobs: Array; + // foundCount: number; + // totalCount: number; + + /** The current search state, used to control the primary display (none, searching, searched, error) */ + + // searchState: SearchState; + // showMonitoringControls: boolean + + /** Triggers a redux action to search of the user's jobs according to the given search expression + * @remarks Since at present the service used to fetch the jobs can suffer performance issues, the + * default search action does not fetch search results each time (rather ??). + * @todo when job search is more performant, this function may be removed and redirected to the + * search function. + */ + search: (searchExpression: JobsSearchExpression) => void; + refreshSearch: () => void; + /** Triggers a redux action to cancel the indicated job */ + cancelJob: (jobID: string, timeout: number) => void; + // searchExpression: JobsSearchExpression; + narrativeMethodStoreURL: string; +} + +/** + * State for the MyJobs component + */ +interface MyJobsState { + /** Flag to show the date controls */ + showDates: boolean; + /** Contains the current selection of job statuses in the checkbox control */ + // currentJobStatusFilter: Array; + /** Contains the initial timestamp (ms epoch time) for time range */ + timeRange: TimeRange; + + isFilterOpen: boolean; + + selectedJob: Job | null; + currentSort: SortSpec | null; + // rowsPerPage: number; + + filter: FilterSpec; +} + +/** + * A View Component for browsing through the current user's jobs. + * + * @remarks + * This component is really just a tabular view into a user's jobs. It provides + * support for free text searching, filtering by job state, and date ranges. + * + */ +export default class MyJobs extends React.Component { + currentQuery?: string; + offset: number; + limit: number; + sorting: SortSpec; + currentPage: number; + // rowsPerPage: number; + + static defaultTimeRangePreset: TimeRangePresets = 'lastWeek'; + + pubsub: PubSub; + + constructor(props: MyJobsProps) { + super(props); + + this.currentQuery = ''; + this.pubsub = new PubSub(); + this.offset = 0; + this.limit = 1; + this.currentPage = 0; + this.sorting = { + field: 'created', + direction: 'descending', + }; + + this.state = { + showDates: false, + filter: { + status: ['create', 'queue', 'run', 'terminate', 'complete', 'error'], + }, + timeRange: { kind: 'preset', preset: MyJobs.defaultTimeRangePreset }, + isFilterOpen: false, + selectedJob: null, + currentSort: null, + // rowsPerPage: 1 + }; + } + + async componentDidMount() {} + + // onResize(rowsPerPage: number) { + // // It would be nice to rely upon the table component to trigger a + // // change even if we change the rows per page ... but we change the + // // rows per page via the table props, not by a trigger. + // // Perhaps by wrapping the table or subclassing it? + + // this.limit = rowsPerPage; + // this.offset = this.currentPage * rowsPerPage; + + // // This causes the table to rerender, but without triggering a + // // re-search; + // // this.setState({ + // // rowsPerPage + // // }); + + // // This triggers a fresh search. + // this.doSearch(false); + // } + + componentDidUpdate() { + if ( + this.props.dataSource.status === AsyncProcessState.PROCESSING || + this.props.dataSource.status === AsyncProcessState.REPROCESSING + ) { + this.pubsub.send('searching', { is: true }); + } else { + this.pubsub.send('searching', { is: false }); + } + } + + onChangeTimeRange(value: string) { + // TODO: should narrow the string value + if (value === 'customRange') { + // TODO: utilize dates from time range presets. + this.setState({ + showDates: true, + timeRange: { kind: 'literal', start: Date.now(), end: Date.now() }, + }); + // nothing else to do. + return; + } else { + this.setState( + { + showDates: false, + timeRange: { + kind: 'preset', + preset: value as TimeRangePresets, + }, + }, + () => { + // Because this may obsolete the page. + // This is a simplification, for sure. + this.offset = 0; + this.doSearch(true); + }, + ); + } + } + + onChangeQuery(event: React.ChangeEvent) { + this.currentQuery = event.target.value; + } + + onSubmit(_fields: any) { + this.doSearch(true); + } + + onFirstPage() { + if (this.props.dataSource.status !== AsyncProcessState.SUCCESS) { + return; + } + + const dataSource = this.props.dataSource; + + if (dataSource.page <= 1) { + return; + } + + // here we do it. + this.offset = 0; + + this.doSearch(false); + } + + onPreviousPage() { + if (this.props.dataSource.status !== AsyncProcessState.SUCCESS) { + return; + } + + const dataSource = this.props.dataSource; + + if (dataSource.page <= 1) { + return; + } + + // here we do it. + this.offset = (dataSource.page - 2) * dataSource.limit; + this.limit = dataSource.limit; + + this.doSearch(false); + } + + onNextPage() { + if (this.props.dataSource.status !== AsyncProcessState.SUCCESS) { + return; + } + + const dataSource = this.props.dataSource; + + if (dataSource.page >= dataSource.pageCount) { + return; + } + + // here we do it. + this.offset = dataSource.page * dataSource.limit; + this.limit = dataSource.limit; + + this.doSearch(false); + } + + onLastPage() { + if (this.props.dataSource.status !== AsyncProcessState.SUCCESS) { + return; + } + + const dataSource = this.props.dataSource; + + if (dataSource.page >= dataSource.pageCount) { + return; + } + + // here we do it. + this.offset = (dataSource.pageCount - 1) * dataSource.limit; + this.limit = dataSource.limit; + + this.doSearch(false); + } + + onReset() { + this.offset = 0; + this.doSearch(true); + } + + doSearch(forceSearch: boolean) { + const searchExpression: JobsSearchExpression = { + query: this.currentQuery, + timeRange: this.state.timeRange, + filter: this.state.filter, + forceSearch, + sort: this.sorting, + offset: this.offset, + limit: this.limit, + }; + + // TODO: document wth is happening here. + this.pubsub.send('search', { is: true }); + + this.props.search(searchExpression); + return false; + } + + onRangeChange(range: [dayjs.Dayjs | null, dayjs.Dayjs | null] | null) { + if (!range) { + return; + } + + const [fromDate, toDate] = range; + + let existingTimeRange = this.state.timeRange; + let timeRange: TimeRange; + switch (existingTimeRange.kind) { + case 'preset': + timeRange = { + kind: 'literal', + start: fromDate ? fromDate.valueOf() : 0, + end: toDate ? toDate.valueOf() : Infinity, + }; + break; + case 'literal': + timeRange = { + kind: 'literal', + start: fromDate ? fromDate.valueOf() : 0, + end: toDate ? toDate.valueOf() : Infinity, + }; + break; + default: + return; + } + + this.setState({ + timeRange, + }); + } + + renderSearchInput() { + let dateControls; + if (this.state.showDates) { + const timeRange = this.state.timeRange; + if (timeRange.kind === 'literal') { + dateControls = ( + + + + + + ); + } + } + return ( +
    + + + + {dateControls} + + + + + ); + const title = ( + + Detail for Job {this.state.selectedJob.id} + + ); + return ( + + + {(value) => { + if (value === null || value.status !== AsyncProcessStatus.SUCCESS) { + return; + } + if (value.value.authState.status !== AuthenticationStatus.AUTHENTICATED) { + return; + } + + const { + config, + authState: { + authInfo: { token }, + }, + } = value.value; + + return ( + + ); + }} + + + ); + } + + renderView() { + return ( + +
    {this.renderControlBar()}
    + {this.renderJobsTable()} + {this.renderJobDetail()} +
    + ); + } + + render() { + return ( +
    + {this.renderView()} +
    + ); + } +} diff --git a/vite-app/src/apps/JobBrowser/components/UserRunSummary/index.tsx b/vite-app/src/apps/JobBrowser/components/UserRunSummary/index.tsx new file mode 100644 index 00000000..1f14d6bc --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UserRunSummary/index.tsx @@ -0,0 +1,140 @@ +import { UserRunSummaryQuery, UserRunSummaryStat } from 'apps/JobBrowser/store/UserRunSummary'; +import ErrorAlert from 'components/ErrorAlert'; +import Loading from 'components/Loading'; +import { AuthenticationStateAuthenticated } from 'contexts/EuropaContext'; +import { AsyncProcess, AsyncProcessStatus } from 'lib/AsyncProcess'; +import { SimpleError } from 'lib/SimpleError'; +import CatalogClient from 'lib/kb_lib/comm/coreServices/Catalog'; +import React from 'react'; +import { Config } from 'types/config'; +import UserRunSummary from './view'; + +export interface UserRunSummaryControllerProps { + config: Config; + auth: AuthenticationStateAuthenticated +} +export interface Filtered { + show: boolean; + value: T; +} +interface UserRunSummaryControllerData { + userRunSummary: Array>; + query: UserRunSummaryQuery +} + +export type UserRunSummaryControllerState = AsyncProcess + +export default class UserRunSummaryController extends React.Component { + constructor(props: UserRunSummaryControllerProps) { + super(props); + this.state = { + status: AsyncProcessStatus.NONE + } + } + + componentDidMount() { + this.initialize(); + } + + async initialize() { + this.fetchData(); + } + + async fetchData() { + this.setState({ + status: AsyncProcessStatus.PENDING + }) + + try { + const catalogClient = new CatalogClient({ + token: this.props.auth.authInfo.token, + url: this.props.config.services.Catalog.url, + timeout: this.props.config.ui.constants.clientTimeout + }); + const params = { + begin: 0, + end: Date.now() + }; + const rawStats = await catalogClient.get_exec_aggr_table(params); + const userRunSummary: Array> = rawStats.map>((stat) => { + let appId: string | null = stat.app; + if (!appId) { + appId = null; + } + + return { + show: true, + value: { + username: stat.user, + isApp: stat.app ? true : false, + appId: stat.app || null, + moduleName: stat.func_mod, + functionName: stat.func, + runCount: stat.n + } + }; + }); + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + userRunSummary, + query: {query: ''} + } + }) + } catch (ex) { + this.setState({ + status: AsyncProcessStatus.ERROR, + error: { + message: ex instanceof Error ? ex.message : 'Unknown Error' + } + }) + } + } + + search(query: UserRunSummaryQuery) { + if (this.state.status !== AsyncProcessStatus.SUCCESS) { + return; + } + + const expression = query.query.split(/\s+/).map((term) => { + return new RegExp(term, 'i'); + }); + const userRunSummary = this.state.value.userRunSummary.map(({value}) => { + const show = expression.length === 0 || (expression.every((term) => { + return (value.appId && term.test(value.appId)) || + term.test(value.moduleName) || + term.test(value.functionName) || + term.test(value.username); + })); + return {show, value}; + }); + + this.setState({ + status: AsyncProcessStatus.SUCCESS, + value: { + userRunSummary, + query + } + }) + } + + renderSuccess({userRunSummary}: UserRunSummaryControllerData) { + return show).map(({value}) => value)} + search={this.search.bind(this)} + /> + } + + render() { + switch (this.state.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + return ; + case AsyncProcessStatus.SUCCESS: + return this.renderSuccess(this.state.value); + case AsyncProcessStatus.ERROR: + return + } + } +} diff --git a/vite-app/src/apps/JobBrowser/components/UserRunSummary/index.xtsx b/vite-app/src/apps/JobBrowser/components/UserRunSummary/index.xtsx new file mode 100644 index 00000000..eb0ab8b9 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UserRunSummary/index.xtsx @@ -0,0 +1,44 @@ +import { StoreState, SearchState, UserRunSummaryStat, UserRunSummaryQuery, ComponentLoadingState } from '../../redux/store'; +import { Action, Dispatch } from 'redux'; +import { connect } from 'react-redux'; +import Component from './view'; +import { search } from '../../redux/actions/userRunSummary'; + +export interface OwnProps { } + +interface StateProps { + searchState: SearchState; + userRunSummary: Array; +} + +interface DispatchProps { + search: (query: UserRunSummaryQuery) => void; +} + +function mapStateToProps(state: StoreState, props: OwnProps): StateProps { + const { + views: { + userRunSummaryView + } + } = state; + + if (userRunSummaryView.loadingState !== ComponentLoadingState.SUCCESS) { + throw new Error('Invalid component loading state'); + } + + const { searchState, userRunSummary } = userRunSummaryView; + return { searchState, userRunSummary }; +} + +function mapDispatchToProps(dispatch: Dispatch, ownProps: OwnProps): DispatchProps { + return { + search: (query: UserRunSummaryQuery) => { + dispatch(search(query) as any); + } + }; +} + +export default connect( + mapStateToProps, + mapDispatchToProps +)(Component); diff --git a/vite-app/src/apps/JobBrowser/components/UserRunSummary/style.css b/vite-app/src/apps/JobBrowser/components/UserRunSummary/style.css new file mode 100644 index 00000000..14b57f79 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UserRunSummary/style.css @@ -0,0 +1,7 @@ +.UserRunSummary { + flex: 1 1 0px; + display: flex; + flex-direction: column; + min-height: 0; + margin-top: 1rem; +} \ No newline at end of file diff --git a/vite-app/src/apps/JobBrowser/components/UserRunSummary/view.tsx b/vite-app/src/apps/JobBrowser/components/UserRunSummary/view.tsx new file mode 100644 index 00000000..f8a9c4e5 --- /dev/null +++ b/vite-app/src/apps/JobBrowser/components/UserRunSummary/view.tsx @@ -0,0 +1,164 @@ +import { SearchOutlined } from '@ant-design/icons'; +import { Alert, Button, Form, Input, Spin, Table, Tooltip } from 'antd'; +import { + UserRunSummaryQuery, + UserRunSummaryStat, + UserRunSummaryViewDataError, +} from 'apps/JobBrowser/store/UserRunSummary'; +import UILink from 'components/UILink2'; +import { Component } from 'react'; +import './style.css'; + +export interface UserRunSummaryProps { + userRunSummary: UserRunSummaryStat[]; + search: (query: UserRunSummaryQuery) => void; +} + +interface UserRunSummaryState {} + +export default class UserRunSummary extends Component { + currentQuery: UserRunSummaryQuery; + constructor(props: UserRunSummaryProps) { + super(props); + this.currentQuery = { + query: '', + }; + } + componentDidMount() { + this.props.search(this.currentQuery); + } + onSubmitSearch(_fields: any) { + this.props.search(this.currentQuery); + } + onChangeQuery(event: React.ChangeEvent) { + this.currentQuery.query = event.target.value; + } + renderControlBar() { + return ( +
    + + + + +
    +
    + ); + })} +
    +
    + +
    +
    +
    + ); + }} + +
    + ); + } + + function renderAffiliations() { + return renderAffiliationsEditor(); + } + + /** + * event Handlers + * + * + */ + + // AVATAR + + function gravatarURL(gravatarHash: string, gravatarDefault: string) { + return `https://www.gravatar.com/avatar/${gravatarHash}?s=300&r=pg&d=${gravatarDefault}`; + } + + function avatarImageSrc(avatarOption: string, gravatarDefault: string | null, gravatarHash?: string): string { + switch (avatarOption) { + case 'silhouette': + // Opting out of gravatar causes this one image to be shown, in all cases. + return image('nouserpic'); + case 'gravatar': + if (!gravatarHash) { + // Should never occur, but may in some old test profiles. + return image('nouserpic'); } - return ( - <> - {renderJobTitle()} - {renderDepartmentField()} - {renderOrganizationField()} - {renderPrimaryFundingSource()} - {renderLocation()} - - ); + return gravatarURL(gravatarHash, gravatarDefault || 'identicon'); + default: + // should never occur, but may in some old test profiles. + return image('nouserpic'); } + } + // Set gravatarURL + function avatarImageSrcEdit(): string { + const { gravatarHash } = props.profileView.profile; + return avatarImageSrc(avatarOptionWatch, gravatarDefaultWatch, gravatarHash); + } - function renderSection(title: string, body: string | undefined | JSX.Element) { - return
    -
    - {title} -
    -
    - {body} -
    -
    ; - } - + function renderAvatarOptionsField() { + return ( + + + + {avatarOptions.map(({ value, label, description }) => { + return ( + + {label} - {description} + + ); + })} + + + + ); + } - /** - * builds User Nutshell card - * - Choose between the non-auth user profile - * vs. editable user profile - * - Return either form or plain text - */ - function renderUserNutshell() { - return renderUserNutshellEditor(); + function renderGravatarDefaultField() { + if (avatarOptionWatch !== 'gravatar') { + return; } - - function renderResearchStatementField() { - return { - noScriptTag(value); - } - } - ]} - // validateStatus={this.state.status || undefined}> - > -
    -
    - -
    -
    - { - const value = rawValue.trim(); - if (!(/[0-9]{4}/.test(value))) { - throw new Error('must be a 4-digit year'); - } - const year = parseInt(value, 10); - if ((year < 1900) || (year > 2100)) { - throw new Error('must be between 1900 and 2100'); - } - - const ended = form.getFieldValue(['affiliations', index, 'ended']); - if (!ended) { - return; - } - if (year > parseInt(ended, 10)) { - throw new Error('must be less than or equal to the end year'); - } - } - } - ]} - > - - -
    -
    - { - const value = rawValue.trim(); - if (value.length === 0) { - return; - } - if (!(/[0-9]{4}/.test(value))) { - throw new Error('must bea a 4-digit year'); - } - const year = parseInt(value, 10); - if ((year < 1900) || (year > 2100)) { - throw new Error('must be between 1900 and 2100'); - } - - const started = form.getFieldValue(['affiliations', index, 'started']); - if (!started) { - return; - } - if (year < parseInt(started, 10)) { - throw new Error('must be greater than or equal to the start year'); - } - } - } - ]} - > - - -
    -
    -
    -
    - })} -
    -
    - -
    -
    -
    - }} - - ; - } + function renderAvatarEditor() { + return ( + <> +
    + Avatar +
    + {renderAvatarImage(avatarImageSrcEdit)} +
    {renderAvatarOptionsField()}
    +
    {renderGravatarDefaultField()}
    + + ); + } + function renderAvatarImage(srcRenderer: () => string) { + return ( + User avatar + ); + } - function renderAffiliations() { - return renderAffiliationsEditor(); - } + function renderAvatar() { + return ( +
    +
    {renderAvatarEditor()}
    +
    + ); + } - /** - * event Handlers - * - * - */ + async function saveForm() { + const update = formToUpdate(form.getFieldsValue()); + await saveProfile(update); + const { isValid, isTouched } = checkForm(); - // AVATAR + setIsFormValid(isValid); + setIsFormTouched(isTouched); + } - function gravatarURL(gravatarHash: string, gravatarDefault: string) { - return `https://www.gravatar.com/avatar/${gravatarHash}?s=300&r=pg&d=${gravatarDefault}`; + function checkForm(fields?: Array) { + const isValid = (() => { + if (fields) { + return fields.every(({ errors }) => { + return !errors || errors.length === 0; + }); + } + const fieldsError = form.getFieldsError(); + if (!fieldsError) { + return true; + } + return fieldsError.every(({ errors }) => { + return errors.length === 0; + }); + })(); + + const isTouched = form.isFieldsTouched(); + + return { isValid, isTouched }; + } + + function cancelForm() { + const { isTouched } = checkForm(); + if (isTouched) { + const title = ( +
    +

    Close Form and Abandon Changes?

    +

    You will lose any changes that have been made.

    +
    + ); + + Modal.confirm({ + title, + onOk: () => { + resetForm(); + disableEditing(); + }, + }); + } else { + resetForm(); + disableEditing(); } - - function avatarImageSrc(avatarOption: string, gravatarDefault: string | null, gravatarHash?: string): string { - switch (avatarOption) { - case 'silhouette': - // Opting out of gravatar causes this one image to be shown, in all cases. - return image('nouserpic'); - case 'gravatar': - if (!gravatarHash) { - // Should never occur, but may in some old test profiles. - return image('nouserpic'); - } - return gravatarURL(gravatarHash, gravatarDefault || 'identicon'); - default: - // should never occur, but may in some old test profiles. - return image('nouserpic'); + } + + function onORCIDLink() { + const params: Record = {}; + + const returnURL = new URL(window.location.href); + const returnLink = { + url: returnURL.toString(), + label: 'User Profile', + }; + params.return_link = JSON.stringify(returnLink); + + navigate2({ + path: 'orcidlink/link', + type: 'kbaseui', + params, + newWindow: false, + }); + } + + function resetForm() { + form.resetFields(); + const { isValid, isTouched } = checkForm(); + + setIsFormValid(isValid); + setIsFormTouched(isTouched); + } + + function renderControls() { + // const warnings = (() => { + // if (props.profileView.warnings.length > 0) { + // const showWarnings = () => { + // Modal.warning({ + // title: 'Warnings', + // content: { + // return {warning} + // }} /> + // }) + // } + // return + // } + // })(); + + const orcidLinkButton2 = (() => { + if (props.orcidState.status === AsyncProcessStatus.SUCCESS) { + if (props.orcidState.value.orcidId) { + return; } - } - + return ( + + + + ); + } + })(); + + const button = ( + + + + + {orcidLinkButton2} + + ); - // Set gravatarURL - function avatarImageSrcEdit(): string { - const { gravatarHash } = props.profileView.profile; - return avatarImageSrc(avatarOptionWatch, gravatarDefaultWatch, gravatarHash); - } + return ( +
    +
    {button}
    +
    + ); + } + function renderResearchInterests() { + return renderResearchInterestsEditor(); + } - function renderAvatarOptionsField() { - return - - - {avatarOptions.map(({ value, label, description }) => { - return {label} - {description} - })} - - + function renderResearchInterestsEditor() { + return ( +
    + + + + {researchInterestsList.map(({ value, label }) => { + return ( + + + {label} + + + ); + })} + + + + + +
    + ); + } + + function hasORCIDId(): boolean { + const { orcidState } = props; + switch (orcidState.status) { + case AsyncProcessStatus.NONE: + case AsyncProcessStatus.PENDING: + case AsyncProcessStatus.ERROR: + return false; + case AsyncProcessStatus.SUCCESS: + return !!orcidState.value.orcidId; } + } - function renderGravatarDefaultField() { - if (avatarOptionWatch !== 'gravatar') { - return; - } - const gravatarHelpLink = - generated or generic image - ; - return <> - - - - ; + if (!formUpdate.state) { + delete userdata.state; + } else { + userdata.state = formUpdate.state; } - function hasORCIDId(): boolean { - const { orcidState } = props; - switch (orcidState.status) { - case AsyncProcessStatus.NONE: - case AsyncProcessStatus.PENDING: - case AsyncProcessStatus.ERROR: - return false; - case AsyncProcessStatus.SUCCESS: - return !!(orcidState.value.orcidId); - } + if (!formUpdate.postalCode) { + delete userdata.postalCode; + } else { + userdata.postalCode = formUpdate.postalCode; } - function renderORCIDIcon() { - return ORCID® icon + if (!formUpdate.country) { + delete userdata.country; + } else { + userdata.country = formUpdate.country; } - function makeUIURL(path: string) { - const url = new URL(props.uiOrigin); - url.hash = `${path}`; - return url.toString(); + if (!formUpdate.researchStatement) { + delete userdata.researchStatement; + } else { + userdata.researchStatement = formUpdate.researchStatement; } - function renderORCIDIdLinkEdit(orcidId: string) { - // const visibilityMessage = (() => { - // if (showORCIDIdWatched) { - // return showing in profile - // } - // return not showing in profile - // })(); - - return
    -
    {renderORCIDIdLink(orcidId)}
    - {/*
    {visibilityMessage}
    */} -
    - - - -
    - -
    - + if (formUpdate.researchInterests && formUpdate.researchInterests.length > 0) { + userdata.researchInterests = formUpdate.researchInterests; + } else { + delete userdata.researchInterests; } - function renderORCIDIdLink(orcidId: string) { - return - {renderORCIDIcon()} -
    - {ORCID_URL}/{orcidId} -
    - ; + if (!formUpdate.researchInterestsOther) { + delete userdata.researchInterestsOther; + } else { + userdata.researchInterestsOther = formUpdate.researchInterestsOther; } - function renderORCIDId(orcidId: string | null) { - if (orcidId) { - return renderORCIDIdLinkEdit(orcidId); - } - - const alertMessage =
    - Have an ORCID® account? Create an KBase ORCID® Link to - connect your KBase to ORCID® account, and show your ORCID® iD - right here in your profile. - -
    - return - + if (!formUpdate.jobTitle) { + delete userdata.jobTitle; + } else { + userdata.jobTitle = formUpdate.jobTitle; } - function renderORCIDRow() { - const { orcidState } = props; - switch (orcidState.status) { - case AsyncProcessStatus.NONE: - case AsyncProcessStatus.PENDING: - return ; - case AsyncProcessStatus.ERROR: - // TODO: improve error - propagate error code. - return ; - case AsyncProcessStatus.SUCCESS: - - return - - ORCID® iD - - - {renderORCIDId(orcidState.value.orcidId)} - - - - } + if (!formUpdate.jobTitleOther) { + delete userdata.jobTitleOther; + } else { + userdata.jobTitleOther = formUpdate.jobTitleOther; } - /** - * Convert form values and state into a user profile update - * data package. - * - * Some notes about the user profile service here. - * - * First, unlike the call to fetch the profile, which is made to the - * user profile "bff" service, this call is directly to the user_profile service. - * I suspect this is due to the fact that the user profile refactor - * which converted from JS/knockout to TS/react was initially for a viewer, - * and later the scope was expanded to cover editing, but time constraints or - * simply the quite long duration of that project (6 mos or so iirc) required - * shortcuts. - * - * So the rules for submitting updates to the user profile service are ineffect here. - * - * So the user profile service is essentially a lightly validated passthrough to - * mongodb. - * - * The "user" field serves two purposes. It is used to verify that the - * profile being updated has the same username as the username associated with the token. - * And it is used to update the realname and thumbnail (unused) fields. - * - * The "profile" field is used to update the user profile data. The service ensures that the entire - * profile object is not overwritten, only the top level properties. That is, it creates an update object - * in which each field name is "profile.PROP" where prop is a top level profile field. See the UserProfileProfile - * type, but the fields are metadata, userdata, synced, preferences, plugins, and surveydata. - * Of these, all that we are interested in are: - * - userdata - the actual user-controlled display fields for the profile - * - plugins - contains plugin-level preferences - we use this to set the user profile orcid display opt-in/out. - * - * Note that each of these must be provided IN THEIR ENTIRETY, due to the fact that the the user profile - * service does not accept a dotted field path. To this end, the best strategy is to fetch the user profile - * first, then apply any changes to userdata and plugin preferences, then send just those two back in - * an update object. - * - * Needless to say, this is not great, but this service has been hardly touched in nearly 10 years. - * - * @param allValues - */ - - // Okay, here is one way to model the form values (in our case). - // export type FormUpdate = Record | Array>>; - - // or this - - - function formToUpdate(allValues: unknown): UserProfileUpdate { - - if (typeof allValues !== 'object' || allValues === null) { - throw new Error('The update is not an object'); - } - - // Blind Trust activated - const formUpdate = allValues as unknown as FormData - - - // Yes, I know. But we need full deep copy, and structuredClone has not been - // around very long in 2023. - const userdata = JSON.parse(JSON.stringify(props.profileView.profile.userdata)) as UserProfileUserdata; - - // Okay, this is a bit of a cheat, using Required, otherwise the optional keys are - // not recognized. - // TODO: make or find a better KeyOfType implementation. - // const simpleUserdataFields: Array, string | null | Array>> = [ - // 'avatarOption', - // 'gravatarDefault', - // 'jobTitle', - // 'jobTitleOther', - // 'department', - // 'organization', - // 'country', - // 'state', - // 'city', - // 'postalCode', - // 'fundingSource', - // 'researchStatement', - // 'researchInterests' - // ] - - // const simpleFormFields: Array, string | null | Array>> = [ - // 'avatarOption', - // 'gravatarDefault', - // 'jobTitle', - // 'jobTitleOther', - // 'department', - // 'organization', - // 'country', - // 'state', - // 'city', - // 'postalCode', - // 'fundingSource', - // 'researchStatement', - // 'researchInterests' - // ] - - - - // const nestedArrayFields = [ - // { - // name: 'affiliations', - // fields: ['title', 'organization', 'started', 'ended'] - // } - // ] - - // These fields are "required". This is self-discipline, as the user profile - // service doesn't care. But the form requires these fields. - userdata.avatarOption = formUpdate.avatarOption; - - if (!formUpdate.gravatarDefault) { - delete userdata.gravatarDefault; - } else { - userdata.gravatarDefault = formUpdate.gravatarDefault; - } - - - if (!formUpdate.organization) { - delete userdata.organization; - } else { - userdata.organization = formUpdate.organization; - } - - if (!formUpdate.department) { - delete userdata.department; - } else { - userdata.department = formUpdate.department; - } - - if (!formUpdate.city) { - delete userdata.city; - } else { - userdata.city = formUpdate.city; - } - - if (!formUpdate.state) { - delete userdata.state; - } else { - userdata.state = formUpdate.state; - } - - - if (!formUpdate.postalCode) { - delete userdata.postalCode; - } else { - userdata.postalCode = formUpdate.postalCode; - } - - - if (!formUpdate.country) { - delete userdata.country; - } else { - userdata.country = formUpdate.country; - } - - - if (!formUpdate.researchStatement) { - delete userdata.researchStatement; - } else { - userdata.researchStatement = formUpdate.researchStatement; - } - - - if (formUpdate.researchInterests && formUpdate.researchInterests.length > 0) { - userdata.researchInterests = formUpdate.researchInterests; - } else { - delete userdata.researchInterests; - } - - - if (!formUpdate.researchInterestsOther) { - delete userdata.researchInterestsOther; - } else { - userdata.researchInterestsOther = formUpdate.researchInterestsOther; - } - - if (!formUpdate.jobTitle) { - delete userdata.jobTitle; - } else { - userdata.jobTitle = formUpdate.jobTitle; - } - - if (!formUpdate.jobTitleOther) { - delete userdata.jobTitleOther; - } else { - userdata.jobTitleOther = formUpdate.jobTitleOther; - } - - if (!formUpdate.fundingSource) { - delete userdata.fundingSource; - } else { - userdata.fundingSource = formUpdate.fundingSource; - } - - if (formUpdate.affiliations && formUpdate.affiliations.length > 0) { - // should we do more here? There is no simply way to reflect changes - // in the affiliations array, other than, e.g., using all keys to form - // a row identifier. In the end, probably not worth it as the form - // values translate literally into the profile values. - userdata.affiliations = formUpdate.affiliations.map(({ title, organization, started, ended }) => { - const affiliation: UserProfileAffiliation = { - title, organization, started: parseInt(started, 10) - } - if (ended && ended.length) { - affiliation.ended = parseInt(ended); - } - return affiliation; - }) - } else { - delete userdata.affiliations; - } - - - - // TODO: figure this out later. - // for (const field of simpleUserdataFields) { - // if (Object.prototype.hasOwnProperty.call(allValues, field)) { - // if (typeof profileField === 'string' && typeof formUpdate[field] === 'string') { - // userdata[field] = formUpdate[field]; - // } - - // } - // } - - // First we must assert the general structure. - - // Then we can pluck out the fields, one by one. - // Not sure how defensive we should be here. I think if we - // are careful to sync this code with the form's initial values - // we do not need to do things like check if the property is - // available... - - // PREFERENCES - - const preferences = props.profileView.profile.preferences || {}; - - // TODO: remove if orcid is not linked. - if (typeof formUpdate.showORCIDId === 'boolean') { - if (hasOwnProperty(preferences, 'showORCIDId')) { - preferences.showORCIDId = { - ...preferences.showORCIDId, - value: formUpdate.showORCIDId, - updatedAt: Date.now() - } - } else { - preferences.showORCIDId = { - value: formUpdate.showORCIDId, - createdAt: Date.now(), - updatedAt: Date.now() - } - } - } else if (preferences.showORCIDId) { - // Handles case of a user without orcid link - this - // form field will be undefined. - delete preferences.showORCIDId; - } + if (!formUpdate.fundingSource) { + delete userdata.fundingSource; + } else { + userdata.fundingSource = formUpdate.fundingSource; + } - const update: UserProfileUpdate = { - user: props.profileView.user, - profile: { - userdata, - preferences - } + if (formUpdate.affiliations && formUpdate.affiliations.length > 0) { + // should we do more here? There is no simply way to reflect changes + // in the affiliations array, other than, e.g., using all keys to form + // a row identifier. In the end, probably not worth it as the form + // values translate literally into the profile values. + userdata.affiliations = formUpdate.affiliations.map(({ title, organization, started, ended }) => { + const affiliation: UserProfileAffiliation = { + title, + organization, + started: parseInt(started, 10), + }; + if (ended && ended.length) { + affiliation.ended = parseInt(ended); } - - return update + return affiliation; + }); + } else { + delete userdata.affiliations; } - function onFieldsChange(_: Array, allFields: Array) { - const { isValid, isTouched } = checkForm(allFields); - setIsFormValid(isValid); - setIsFormTouched(isTouched); + // TODO: figure this out later. + // for (const field of simpleUserdataFields) { + // if (Object.prototype.hasOwnProperty.call(allValues, field)) { + // if (typeof profileField === 'string' && typeof formUpdate[field] === 'string') { + // userdata[field] = formUpdate[field]; + // } + + // } + // } + + // First we must assert the general structure. + + // Then we can pluck out the fields, one by one. + // Not sure how defensive we should be here. I think if we + // are careful to sync this code with the form's initial values + // we do not need to do things like check if the property is + // available... + + // PREFERENCES + + const preferences = props.profileView.profile.preferences || {}; + + // TODO: remove if orcid is not linked. + if (typeof formUpdate.showORCIDId === 'boolean') { + if (hasOwnProperty(preferences, 'showORCIDId')) { + preferences.showORCIDId = { + ...preferences.showORCIDId, + value: formUpdate.showORCIDId, + updatedAt: Date.now(), + }; + } else { + preferences.showORCIDId = { + value: formUpdate.showORCIDId, + createdAt: Date.now(), + updatedAt: Date.now(), + }; + } + } else if (preferences.showORCIDId) { + // Handles case of a user without orcid link - this + // form field will be undefined. + delete preferences.showORCIDId; } - function renderOrganizations() { - - const message =
    -

    Organizations are not editable in your profile.

    -

    Please visit the Organizations page to manage your Organization memberships.

    -
    - return - } + const update: UserProfileUpdate = { + user: props.profileView.user, + profile: { + userdata, + preferences, + }, + }; + + return update; + } + + function onFieldsChange(_: Array, allFields: Array) { + const { isValid, isTouched } = checkForm(allFields); + setIsFormValid(isValid); + setIsFormTouched(isTouched); + } + + function renderOrganizations() { + const message = ( +
    +

    Organizations are not editable in your profile.

    +

    + Please visit the + + Organizations page + {' '} + to manage your Organization memberships. +

    +
    + ); + return ; + } - function onFormLoad() { - const { isValid } = checkForm(); - setIsFormValid(isValid); - } + function onFormLoad() { + const { isValid } = checkForm(); + setIsFormValid(isValid); + } - function renderIdentityEditor() { - return
    -
    Identity
    - - - - - - - {renderORCIDRow()} - -
    - Username - - {props.profileView.user.username} -
    + function renderIdentityEditor() { + return ( +
    +
    + Identity
    - } - - function renderIdentity() { - return renderIdentityEditor(); - } - - const { - profile: { - userdata: { - researchInterests, researchInterestsOther, jobTitle, jobTitleOther, department, organization, country, state, city, postalCode, - fundingSource, researchStatement, affiliations: rawAffiliations, avatarOption, gravatarDefault - }, - preferences - } - } = props.profileView - - // Some adjustments. - - // Needs to be boolean for the control; defaults to false if not present - const showORCIDId = preferences ? (preferences['showORCIDId']?.value ? true : false) : false; - - // Needs to be string for the input control. - const affiliations = typeof rawAffiliations === 'undefined' ? [] : rawAffiliations - .filter(({ started, title, organization }) => { - return (title && title.length && organization && organization.length && - started); - }) - .map(({ - started, ended, title, organization - }) => { + + + + + + + {renderORCIDRow()} + +
    Username + + {props.profileView.user.username} + +
    +
    + ); + } + + function renderIdentity() { + return renderIdentityEditor(); + } + + const { + profile: { + userdata: { + researchInterests, + researchInterestsOther, + jobTitle, + jobTitleOther, + department, + organization, + country, + state, + city, + postalCode, + fundingSource, + researchStatement, + affiliations: rawAffiliations, + avatarOption, + gravatarDefault, + }, + preferences, + }, + } = props.profileView; + + // Some adjustments. + + // Needs to be boolean for the control; defaults to false if not present + const showORCIDId = preferences ? (preferences['showORCIDId']?.value ? true : false) : false; + + // Needs to be string for the input control. + const affiliations = + typeof rawAffiliations === 'undefined' + ? [] + : rawAffiliations + .filter(({ started, title, organization }) => { + return title && title.length && organization && organization.length && started; + }) + .map(({ started, ended, title, organization }) => { const affiliation: FormDataAffiliation = { - title, organization, - started: String(started) - } + title, + organization, + started: String(started), + }; if (ended) { - affiliation.ended = String(ended); + affiliation.ended = String(ended); } return affiliation; + }); - }); - - affiliations.sort((a: FormDataAffiliation, b: FormDataAffiliation) => { - const startedSort = parseInt(a.started, 10) - parseInt(b.started, 10); - if (startedSort !== 0) { - return startedSort; - } - - const endedSort = (() => { - if (!a.ended) { - return -1; - } - if (!b.ended) { - return 1; - } - return parseInt(a.ended, 10) - parseInt(b.ended, 10); - })(); - - if (endedSort !== 0) { - return endedSort; - } - - const titleSort = a.title.localeCompare(b.title); - if (titleSort !== 0) { - return titleSort; - } + affiliations.sort((a: FormDataAffiliation, b: FormDataAffiliation) => { + const startedSort = parseInt(a.started, 10) - parseInt(b.started, 10); + if (startedSort !== 0) { + return startedSort; + } - return a.organization.localeCompare(b.organization); - }); + const endedSort = (() => { + if (!a.ended) { + return -1; + } + if (!b.ended) { + return 1; + } + return parseInt(a.ended, 10) - parseInt(b.ended, 10); + })(); + + if (endedSort !== 0) { + return endedSort; + } - const initialValues = { - researchInterests, researchInterestsOther, jobTitle, jobTitleOther, - department, organization, country, state, city, postalCode, - fundingSource, researchStatement, affiliations, avatarOption, gravatarDefault, showORCIDId + const titleSort = a.title.localeCompare(b.title); + if (titleSort !== 0) { + return titleSort; } - return ( - <> - {contextHolder} -
    -
    - {renderControls()} -
    -
    -
    - - - + return a.organization.localeCompare(b.organization); + }); + + const initialValues = { + researchInterests, + researchInterestsOther, + jobTitle, + jobTitleOther, + department, + organization, + country, + state, + city, + postalCode, + fundingSource, + researchStatement, + affiliations, + avatarOption, + gravatarDefault, + showORCIDId, + }; + + return ( + <> + {contextHolder} +
    +
    + {renderControls()} +
    + {/* Padding below to fix antd rows with gutters. */} +
    + + + + + + {props.profileView.user.realname} + + } + /> + + + +
    {renderIdentity()}
    + {renderAvatar()} +
    +
    + {/*
    {renderIdentity()}
    {renderAvatar()} - - - - + */} + + + + Research Interests + {renderResearchInterests()} + + {/* {renderResearchInterests()} - - - - + */} + + + + KBase Organizations + {renderOrganizations()} + + {/* {renderOrganizations()} - - -
    - - - + */} + + + + + + {renderUserNutshell()} + + {/* {renderUserNutshell()} - - - - + */} + + + + Research or Personal Statement + {renderResearchStatement()} + + {/* {renderResearchStatement()} - - - - + */} + + + + Affiliations + {renderAffiliations()} + + {/* {renderAffiliations()} - - - - -
    -
    - - ); + */} + +
    + +
    +
    + + ); } export default Profile; diff --git a/vite-app/src/apps/UserProfile/Profile/ProfileViewer.tsx b/vite-app/src/apps/UserProfile/Profile/ProfileViewer.tsx index 0bcbe33d..ac42398f 100644 --- a/vite-app/src/apps/UserProfile/Profile/ProfileViewer.tsx +++ b/vite-app/src/apps/UserProfile/Profile/ProfileViewer.tsx @@ -16,14 +16,13 @@ import { Tooltip } from 'antd'; import Link from 'antd/es/typography/Link'; +import Well from 'components/Well'; import { image } from 'components/images'; import DOMPurify from 'dompurify'; import { AsyncProcessStatus } from 'lib/AsyncProcess'; -import { changeHash2 } from 'lib/navigation'; +import { navigate2 } from 'lib/navigation'; import { marked } from 'marked'; -import { v4 as uuidv4 } from 'uuid'; import { UserProfileAffiliation } from '../API'; -import Area from './Area'; import Orgs from './Orgs/controller'; import './Profile.css'; import { ORCIDState, OrgsState, ProfileView } from './controller'; @@ -33,7 +32,6 @@ export interface ProfileProps { profileView: ProfileView; orcidState: ORCIDState; orgsState: OrgsState; - uiOrigin: string; checkORCID: (username: string) => void; fetchProfile: (username: string) => void; toggleEditing: () => void; @@ -214,7 +212,7 @@ function ProfileViewer(props: ProfileProps) { marked.use({ breaks: true }); - const content = DOMPurify.sanitize(marked.parse(researchStatement)); + const content = DOMPurify.sanitize(marked.parse(researchStatement, {async: false}) as string); statement =
    ; } @@ -344,92 +342,23 @@ function ProfileViewer(props: ProfileProps) {
    } - function onORCIDLink() { - // open window, without much or any window decoration. - const eventId = uuidv4(); - // const url = new URL(`${document.location.origin}#orcidlink/link`); - // TODO: for better ergonomics in development, should be able to get the - // kbase environment host from the config... - - const url = new URL(props.uiOrigin); - // const url = new URL(window.location.href); - url.hash = '#orcidlink/link'; - - // TODO: if this works, we can give the window a unique uuid name when the app loads. - window.name = "FOOBAR"; - - // {id: string} is the ReturnFromWindow type expected by ORCIDLink. - const origin = window.location.origin; - // const origin = "https://ci.kbase.us"; - url.searchParams.set('ui_options', "hide-ui"); - url.searchParams.set('return_link', JSON.stringify({ - type: 'window', - origin, - id: eventId, - label: 'User Profile' - })); - const newWindow = window.open(url.toString(), '_blank', "popup,width=1079,height=960"); - if (newWindow === null) { - // what to do? - // return - console.error('Cannot open new window for linking'); - return; - } - const handleEvent = ({ data }: MessageEvent) => { - if (typeof data === 'object' && data !== null) { - const { id } = data; - if (eventId === id) { - // this.evaluate(); - // do something here... - props.checkORCID(props.profileView.user.username); - props.fetchProfile(props.profileView.user.username); - if (newWindow) { - newWindow.close(); - window.removeEventListener('message', handleEvent); - } - } - } - }; - window.addEventListener('message', handleEvent); - } + function onORCIDLink() { + const params: Record = {}; - function getLinkingLink() { - const linkingURL = new URL(`${props.uiOrigin}/#orcidlink/link`); - const returnURL = (() => { - if (window.parent) { - return new URL(window.parent.location.href); - } else { - return new URL(window.location.href); - } - })(); + const returnURL = new URL(window.location.href); const returnLink = { - type: 'link', url: returnURL.toString(), label: 'User Profile' } - linkingURL.searchParams.set('return_link', JSON.stringify(returnLink)); - const hash = linkingURL.hash; - const query = linkingURL.search; - return `${hash}${query}` - } + params.return_link = JSON.stringify(returnLink); - function onORCIDLink2() { - // const onOk = () => { - // window.location.href = getLinkingLink(); - // } - - // Modal.confirm({ - // title: 'Proceed to ORCID Link', - // onOk, - // content: <> - //

    - // In order to create your ORCID Link, your browser will leave this page, then return - // to it when you have completed the linking process. - //

    - // - // }); - changeHash2(window.location.href = getLinkingLink()); + navigate2({ + path: 'orcidlink/link', + type: 'kbaseui', + params, + newWindow: false + }); } function renderControls() { @@ -457,28 +386,14 @@ function ProfileViewer(props: ProfileProps) { let button; - // const orcidLinkButton = (() => { - // if (props.orcidState.status === AsyncProcessStatus.SUCCESS) { - // if (props.orcidState.value.orcidId) { - // return; - // } - // return - // - // - // } - // })(); const orcidLinkButton2 = (() => { if (props.orcidState.status === AsyncProcessStatus.SUCCESS) { if (props.orcidState.value.orcidId) { return; } return - } @@ -487,11 +402,9 @@ function ProfileViewer(props: ProfileProps) { - {/* {orcidLinkButton} */} {orcidLinkButton2} {warnings} ; @@ -678,43 +591,91 @@ function ProfileViewer(props: ProfileProps) {
    {renderControls()}
    -
    - + {/* Padding below to fix antd rows with gutters. */} +
    - + + + {props.profileView.user.realname} + + +
    + {renderIdentityView()} +
    + {renderAvatar()} +
    +
    + {/*
    {renderIdentityView()}
    {renderAvatar()} - + */} - + + + Research Interests + + + {renderResearchInterests()} + + + {/* {renderResearchInterests()} - + */} - - + + + + KBase Organizations + + + + + + {/* - + */}
    - + + + {renderUserNutshell()} + + + {/* {renderUserNutshell()} - + */} - + + + Research or Personal Statement + + + {renderResearchStatement()} + + + {/* {renderResearchStatement()} - + */} - - + + + + Affiliations + + + {renderAffiliations()} + + + {/* {renderAffiliations()} - + */}
    diff --git a/vite-app/src/apps/UserProfile/Profile/controller.tsx b/vite-app/src/apps/UserProfile/Profile/controller.tsx index 22e65fdb..075ee119 100644 --- a/vite-app/src/apps/UserProfile/Profile/controller.tsx +++ b/vite-app/src/apps/UserProfile/Profile/controller.tsx @@ -1,8 +1,9 @@ import { ErrorCode } from "apps/ORCIDLink/lib/ORCIDLinkClient"; import ErrorMessage from "components/ErrorMessage"; import Loading from "components/Loading"; -import { AuthenticationStateAuthenticated } from "contexts/Auth"; +import { AuthenticationStateAuthenticated } from "contexts/EuropaContext"; import { AsyncProcess, AsyncProcessStatus } from "lib/AsyncProcess"; +// import { JSONRPC20Exception } from "lib/kb_lib/comm/JSONRPC20/JSONRPC20"; import { JSONRPC20Exception } from "lib/kb_lib/comm/JSONRPC20/JSONRPC20"; import ORCIDLinkAPI, { InfoResult } from "lib/kb_lib/comm/coreServices/ORCIDLInk"; import { Component } from "react"; @@ -33,7 +34,7 @@ export type ORCIDState = AsyncProcess; export interface Org { name: string; - url: string; + id: string; logoURL?: string; } @@ -84,6 +85,8 @@ export default class ProfileController extends Component { return { name, - url: "#orgs/" + id, + id, logoURL: custom.logourl, }; }); @@ -439,7 +442,6 @@ export default class ProfileController extends Component; label?: string + hasFeedback?: boolean; required: boolean; } @@ -66,6 +67,7 @@ export default class Organization extends React.Component { componentDidMount(): void { - this.props.setTitle('User Profile - IN PROGRESS'); + this.props.setTitle('User Profile'); } renderUserSearch() { @@ -36,13 +35,13 @@ export default class UserProfile extends Component + children: }] + return (
    ); } -} \ No newline at end of file +} diff --git a/vite-app/src/apps/UserProfile/types.ts b/vite-app/src/apps/UserProfile/types.ts index 4d7bd746..41d3440e 100644 --- a/vite-app/src/apps/UserProfile/types.ts +++ b/vite-app/src/apps/UserProfile/types.ts @@ -7,8 +7,6 @@ export interface JSONObject { [x: string]: JSONValue; } - - export enum ValidationStatus { NONE, SUCCESS, diff --git a/vite-app/src/apps/UserProfile/utils.ts b/vite-app/src/apps/UserProfile/utils.ts index 92a60f79..6271e675 100644 --- a/vite-app/src/apps/UserProfile/utils.ts +++ b/vite-app/src/apps/UserProfile/utils.ts @@ -33,4 +33,4 @@ export function hasOwnProperty(value: unknown, property: string): boolean { return false; } return (Object.prototype.hasOwnProperty.call(value, property)) -} \ No newline at end of file +} diff --git a/vite-app/src/apps/gallery/index.tsx b/vite-app/src/apps/gallery/index.tsx index 454fcb48..633eb288 100644 --- a/vite-app/src/apps/gallery/index.tsx +++ b/vite-app/src/apps/gallery/index.tsx @@ -1,5 +1,5 @@ import { RouteProps } from "components/Router2"; -import { AuthenticationState } from "contexts/Auth"; +import { AuthenticationState } from "contexts/EuropaContext"; import { Component } from "react"; import Nav from "react-bootstrap/esm/Nav"; import { Config } from "types/config"; @@ -33,7 +33,7 @@ export default class Gallery extends Component { } renderBody() { - switch (this.props.params.get('name') || 'home') { + switch (this.props.match.params.get('name') || 'home') { case 'home': return this.renderHome(); case 'alertmessage': @@ -46,7 +46,7 @@ export default class Gallery extends Component { render() { return
    -