diff --git a/src/app/helpers/books.ts b/src/app/helpers/books.ts index c0f814e58..060983490 100644 --- a/src/app/helpers/books.ts +++ b/src/app/helpers/books.ts @@ -8,6 +8,11 @@ export type Book = { subjects: string[]; title: string; content_warning_text: string; + assignable_book?: boolean; + kindle_link?: string; + has_faculty_resources?: boolean; + has_student_resources?: boolean; + }; const statesToInclude = ['live', 'new_edition_available', 'coming_soon']; diff --git a/src/app/pages/errata-form/errata-form-context.js b/src/app/pages/errata-form/errata-form-context.tsx similarity index 53% rename from src/app/pages/errata-form/errata-form-context.js rename to src/app/pages/errata-form/errata-form-context.tsx index b8a98093a..718edd4f6 100644 --- a/src/app/pages/errata-form/errata-form-context.js +++ b/src/app/pages/errata-form/errata-form-context.tsx @@ -1,30 +1,51 @@ import React, {useState} from 'react'; import buildContext from '~/components/jsx-helpers/build-context'; import fetchBooks from '~/models/books'; +import {type Book} from '~/helpers/books'; import {useLocation} from 'react-router-dom'; import {useDataFromPromise, useDataFromSlug} from '~/helpers/page-data-utils'; +type ContextValue = { + selectedBook: Book | null; + books: Book[] | null | undefined; + hasError: string | null; + setHasError: (error: string | null) => void; + hideErrors: boolean; + submitting: boolean; + validateBeforeSubmitting: (event: React.FormEvent) => void; + searchParams: URLSearchParams; + title: string | null; + setTitle: (title: string) => void; +}; + function useSearchParams() { const {search} = useLocation(); return React.useMemo(() => new window.URLSearchParams(search), [search]); } -function useContextValue() { +function useContextValue(): ContextValue { const searchParams = useSearchParams(); - const initialTitle = React.useMemo(() => searchParams.get('book'), [searchParams]); - const [title, setTitle] = useState(initialTitle); + const initialTitle = React.useMemo( + () => searchParams.get('book'), + [searchParams] + ); + const [title, setTitle] = useState(initialTitle); const books = useDataFromPromise(fetchBooks); const selectedBook = React.useMemo( - () => books?.find((b) => b.title === title) || {}, + () => books?.find((b) => b.title === title) || null, [books, title] ); - const bookInfo = useDataFromSlug(selectedBook.slug) || selectedBook; - const [hasError, setHasError] = useState('You have not completed the form'); + const bookInfo = + useDataFromSlug(selectedBook ? selectedBook.slug : null) || + selectedBook; + const [hasError, setHasError] = useState( + 'You have not completed the form' + ); const [hideErrors, setHideErrors] = useState(true); const [submitting, setSubmitting] = useState(false); const validateBeforeSubmitting = React.useCallback( - (event) => { + (event: React.FormEvent) => { event.preventDefault(); setHideErrors(false); if (!hasError) { @@ -37,7 +58,8 @@ function useContextValue() { return { selectedBook: bookInfo, books, - hasError, setHasError, + hasError, + setHasError, hideErrors, submitting, validateBeforeSubmitting, @@ -49,7 +71,4 @@ function useContextValue() { const {useContext, ContextProvider} = buildContext({useContextValue}); -export { - useContext as default, - ContextProvider as ErrataFormContextProvider -}; +export {useContext as default, ContextProvider as ErrataFormContextProvider}; diff --git a/src/app/pages/errata-form/errata-form.js b/src/app/pages/errata-form/errata-form.tsx similarity index 71% rename from src/app/pages/errata-form/errata-form.js rename to src/app/pages/errata-form/errata-form.tsx index fb3bc1713..4ad9739af 100644 --- a/src/app/pages/errata-form/errata-form.js +++ b/src/app/pages/errata-form/errata-form.tsx @@ -1,11 +1,17 @@ import React from 'react'; import Form from './form/form'; import FormSelect from '~/components/form-select/form-select'; -import useErrataFormContext, {ErrataFormContextProvider} from './errata-form-context'; +import useErrataFormContext, { + ErrataFormContextProvider +} from './errata-form-context'; import useUserContext from '~/contexts/user'; import linkHelper from '~/helpers/link'; import './errata-form.scss'; +type Book = { + title: string; +}; + function ErrataForm() { const {title} = useErrataFormContext(); @@ -26,22 +32,29 @@ function ErrataForm() { function TitleSelector() { const {books, setTitle} = useErrataFormContext(); const options = React.useMemo( - () => books?.map((book) => ({label: book.title, value: book.title})), + () => + books?.map((book: Book) => ({ + label: book.title, + value: book.title + })), [books] ); return (

- It looks like you got referred here but they didn't tell us what - book you were looking at. + It looks like you got referred here but they didn't tell us + what book you were looking at.

+ label="What book were you in, again?" + options={options ?? []} + />
); } @@ -64,7 +77,13 @@ export default function EnsureLoggedIn() {
You need to be logged in to submit errata
- Log in + + Log in +
); diff --git a/src/app/pages/errata-form/form/ErrorLocationSelector/ErrorLocationSelector.js b/src/app/pages/errata-form/form/ErrorLocationSelector/ErrorLocationSelector.js deleted file mode 100644 index 541bbd822..000000000 --- a/src/app/pages/errata-form/form/ErrorLocationSelector/ErrorLocationSelector.js +++ /dev/null @@ -1,60 +0,0 @@ -import React, {useState, useRef, useEffect} from 'react'; -import useErrataFormContext from '../../errata-form-context'; -import managedInvalidMessage from '../InvalidMessage'; -import TocSelector from './toc-selector'; -import './ErrorLocationSelector.scss'; - -function AdditionalLocationInput({value='', readOnly=false, updateValue, required=true}) { - const inputRef = useRef(); - const [InvalidMessage, updateInvalidMessage] = managedInvalidMessage(inputRef); - const syncValue = React.useCallback( - (event) => updateValue(event.target.value), - [updateValue] - ); - - useEffect(updateInvalidMessage, [required, updateInvalidMessage]); - - return ( - -
Additional location information, if applicable
- - -
- ); -} - -function DefaultValue({defaultValue}) { - return ( - - ); -} - -function NotDefaultValue({defaultValue}) { - const [tocV, updateTocV] = useState(); - const [addlV, updateAddlV] = useState(defaultValue); - const required = () => !tocV && !addlV; - - return ( - - - - - ); -} - -export default function ErrorLocationSelector() { - const {searchParams} = useErrataFormContext(); - const defaultValue = searchParams.get('location'); - const readOnly = defaultValue && searchParams.get('source'); - const Input = (readOnly) ? DefaultValue : NotDefaultValue; - - return ( - - ); -} diff --git a/src/app/pages/errata-form/form/ErrorLocationSelector/ErrorLocationSelector.tsx b/src/app/pages/errata-form/form/ErrorLocationSelector/ErrorLocationSelector.tsx new file mode 100644 index 000000000..75a08bdbe --- /dev/null +++ b/src/app/pages/errata-form/form/ErrorLocationSelector/ErrorLocationSelector.tsx @@ -0,0 +1,92 @@ +import React, {useState, useRef, useEffect} from 'react'; +import useErrataFormContext from '../../errata-form-context'; +import managedInvalidMessage from '../InvalidMessage'; +import TocSelector from './toc-selector'; +import './ErrorLocationSelector.scss'; + +type AdditionalLocationInputProps = { + value?: string; + readOnly?: boolean; + updateValue?: (value: string) => void; + required?: boolean; +}; + +type InputComponentProps = { + defaultValue: string | null; +}; + +function AdditionalLocationInput({ + value, + readOnly = false, + updateValue, + required = true +}: AdditionalLocationInputProps) { + const inputRef = useRef(null); + const [InvalidMessage, updateInvalidMessage] = + managedInvalidMessage(inputRef); + const syncValue = React.useCallback( + (event: React.ChangeEvent) => + updateValue?.(event.target.value), + [updateValue] + ); + + useEffect(updateInvalidMessage, [required, updateInvalidMessage]); + + return ( + + + + + + ); +} + +function DefaultValue({defaultValue}: InputComponentProps) { + return ( + + ); +} + +function NotDefaultValue({defaultValue}: InputComponentProps) { + const [tocV, updateTocV] = useState(); + const [addlV, updateAddlV] = useState(defaultValue || ''); + const required = () => !tocV && !addlV; + + return ( + + + + + ); +} + +export default function ErrorLocationSelector() { + const {searchParams} = useErrataFormContext(); + const defaultValue = searchParams.get('location'); + const readOnly = defaultValue && searchParams.get('source'); + const Input = readOnly ? DefaultValue : NotDefaultValue; + + return ; +} diff --git a/src/app/pages/errata-form/form/ErrorLocationSelector/test-data.js b/src/app/pages/errata-form/form/ErrorLocationSelector/test-data.ts similarity index 100% rename from src/app/pages/errata-form/form/ErrorLocationSelector/test-data.js rename to src/app/pages/errata-form/form/ErrorLocationSelector/test-data.ts diff --git a/src/app/pages/errata-form/form/ErrorLocationSelector/toc-selector.js b/src/app/pages/errata-form/form/ErrorLocationSelector/toc-selector.js deleted file mode 100644 index d546c290d..000000000 --- a/src/app/pages/errata-form/form/ErrorLocationSelector/toc-selector.js +++ /dev/null @@ -1,148 +0,0 @@ -import React, {useState, useRef, useEffect, useMemo} from 'react'; -import useErrataFormContext from '../../errata-form-context'; -import managedInvalidMessage from '../InvalidMessage'; -import bookToc from '~/models/book-toc'; -import {htmlToText} from '~/helpers/data'; -// For LOCAL TESTING when you can't reach Rex; there is another testing section below -// import testData from './test-data'; - -function treeEntry(title, indentLevel, parent, isChapter) { - const value = parent ? `${parent}:${title}` : title; - const expandedValue = value - .replace(/(^|:)(\d+ )/, (_, before, num) => `${before}Chapter ${num}`) - .replace(/(:)(\d+\.\d+)/, (_, before, num) => `${before}Section ${num}`) - .replace(/:(?=\S)/g, ': '); - - return { - title, - indentLevel, - parent, - value, - expandedValue, - isChapter - }; -} - -function flattenTree(contents, indentLevel=0, parent='') { - return contents.map((entry) => { - const title = htmlToText(entry.title); - const isChapter = Boolean(entry.contents); - const thisEntry = treeEntry(title, indentLevel, parent, isChapter); - - return [thisEntry] - .concat(entry.contents ? flattenTree(entry.contents, indentLevel+1, thisEntry.value) : []); - }).flat(); -} - -function ChapterOption({entry, chapterFilter, updateChapterFilter}) { - const expanded = chapterFilter === entry.value; - const onClick = () => { - const value = expanded ? entry.parent : entry.value; - - updateChapterFilter(value); - }; - - return ( - - ); -} - -function PageOption({entry}) { - return ( - - ); -} - -function ChapterOrPageOption(passThruOptions) { - const {entry} = passThruOptions; - - return ( - entry.isChapter && !entry.parent ? - : - - ); -} - -function useTocTree(slug, chapterFilter) { - const [tree, updateTree] = useState([]); - const filteredTree = useMemo( - () => { - if (!chapterFilter) { - return tree.filter((entry) => !entry.parent); - } - return tree.filter((entry) => - !entry.parent || - entry.value.startsWith(chapterFilter)); - }, - [tree, chapterFilter] - ); - - useEffect(() => { - if (slug) { - bookToc(slug) - .then((contents) => updateTree(flattenTree(contents))); - // FOR TESTING - // .catch(() => { - // console.info('caught...using testdata', testData); - // updateTree(flattenTree(testData.tree.contents)); - // }); - } - }, [slug]); - - return filteredTree; -} - -export default function TocSelector({required=true, updateValue}) { - const {selectedBook} = useErrataFormContext(); - const inputRef = useRef(); - const [InvalidMessage, updateInvalidMessage] = managedInvalidMessage(inputRef); - const [chapterFilter, updateChapterFilter] = useState(); - const filteredTree = useTocTree(selectedBook.slug, chapterFilter); - const deselect = React.useCallback( - () => { - inputRef.current.value = null; - updateValue(null); - }, - [updateValue] - ); - const onChange = React.useCallback( - ({target: {value}}) => updateValue(value), - [updateValue] - ); - - useEffect(updateInvalidMessage, [required, updateInvalidMessage]); - - return ( - -
Where in the book did you find the error?
- - - -
- ); -} diff --git a/src/app/pages/errata-form/form/ErrorLocationSelector/toc-selector.tsx b/src/app/pages/errata-form/form/ErrorLocationSelector/toc-selector.tsx new file mode 100644 index 000000000..529c3b2f0 --- /dev/null +++ b/src/app/pages/errata-form/form/ErrorLocationSelector/toc-selector.tsx @@ -0,0 +1,205 @@ +import React, {useState, useRef, useEffect, useMemo} from 'react'; +import useErrataFormContext from '../../errata-form-context'; +import managedInvalidMessage from '../InvalidMessage'; +import bookToc from '~/models/book-toc'; +import {assertNotNull, htmlToText} from '~/helpers/data'; +// For LOCAL TESTING when you can't reach Rex; there is another testing section below +// import testData from './test-data'; + +type TreeEntry = { + title: string; + indentLevel: number; + parent: string; + value: string; + expandedValue: string; + isChapter: boolean; +}; + +type TocContent = { + title: string; + contents?: TocContent[]; +}; + +type ChapterOptionProps = { + entry: TreeEntry; + chapterFilter: string | undefined; + updateChapterFilter: (value: string) => void; +}; + +type PageOptionProps = { + entry: TreeEntry; +}; + +type TocSelectorProps = { + required: boolean; + updateValue: (value: string | null) => void; +}; + +function treeEntry( + title: string, + indentLevel: number, + parent: string, + isChapter: boolean +): TreeEntry { + const value = parent ? `${parent}:${title}` : title; + const expandedValue = value + .replace(/(^|:)(\d+ )/, (_, before, num) => `${before}Chapter ${num}`) + .replace(/(:)(\d+\.\d+)/, (_, before, num) => `${before}Section ${num}`) + .replace(/:(?=\S)/g, ': '); + + return { + title, + indentLevel, + parent, + value, + expandedValue, + isChapter + }; +} + +function flattenTree( + contents: TocContent[], + indentLevel = 0, + parent = '' +): TreeEntry[] { + return contents + .map((entry) => { + const title = htmlToText(entry.title); + const isChapter = Boolean(entry.contents); + const thisEntry = treeEntry(title, indentLevel, parent, isChapter); + + return [thisEntry].concat( + entry.contents + ? flattenTree( + entry.contents, + indentLevel + 1, + thisEntry.value + ) + : [] + ); + }) + .flat(); +} + +function ChapterOption({ + entry, + chapterFilter, + updateChapterFilter +}: ChapterOptionProps) { + const expanded = chapterFilter === entry.value; + const onClick = () => { + const value = expanded ? entry.parent : entry.value; + + updateChapterFilter(value); + }; + + return ( + + ); +} + +function PageOption({entry}: PageOptionProps) { + return ( + + ); +} + +function ChapterOrPageOption(passThruOptions: ChapterOptionProps) { + const {entry} = passThruOptions; + + return entry.isChapter && !entry.parent ? ( + + ) : ( + + ); +} + +function useTocTree( + slug: string | undefined, + chapterFilter: string | undefined +) { + const [tree, updateTree] = useState([]); + const filteredTree = useMemo(() => { + if (!chapterFilter) { + return tree.filter((entry) => !entry.parent); + } + return tree.filter( + (entry) => !entry.parent || entry.value.startsWith(chapterFilter) + ); + }, [tree, chapterFilter]); + + useEffect(() => { + if (slug) { + bookToc(slug).then((contents: TocContent[]) => + updateTree(flattenTree(contents)) + ); + // FOR TESTING + // .catch(() => { + // console.info('caught...using testdata', testData); + // updateTree(flattenTree(testData.tree.contents)); + // }); + } + }, [slug]); + + return filteredTree; +} + +export default function TocSelector({required, updateValue}: TocSelectorProps) { + const {selectedBook} = useErrataFormContext(); + const inputRef = useRef(null); + const [InvalidMessage, updateInvalidMessage] = + managedInvalidMessage(inputRef); + const [chapterFilter, updateChapterFilter] = useState(); + const slug = selectedBook ? selectedBook.slug : undefined; + const filteredTree = useTocTree(slug, chapterFilter); + const deselect = React.useCallback(() => { + assertNotNull(inputRef.current).value = ''; + updateValue(null); + }, [updateValue]); + const onChange = React.useCallback( + ({target: {value}}: React.ChangeEvent) => + updateValue(value), + [updateValue] + ); + + useEffect(updateInvalidMessage, [required, updateInvalidMessage]); + + return ( + + + + + + + ); +} diff --git a/src/app/pages/errata-form/form/ErrorSourceSelector.js b/src/app/pages/errata-form/form/ErrorSourceSelector.js deleted file mode 100644 index e68922e98..000000000 --- a/src/app/pages/errata-form/form/ErrorSourceSelector.js +++ /dev/null @@ -1,136 +0,0 @@ -import React, {useState, useRef, useMemo} from 'react'; -import useErrataFormContext from '../errata-form-context'; -import managedInvalidMessage from './InvalidMessage'; -import getFields from '~/models/errata-fields'; - -const sourceNames = { -}; - -const resourcePromise = getFields('resources') - .then((resources) => resources.map((entry) => entry.field)); - -function OtherSourceInput() { - const inputRef = useRef(); - const [InvalidMessage, updateInvalidMessage] = managedInvalidMessage(inputRef); - - return ( -
- - -
- ); -} - -const subnotes = {'Textbook': 'includes print, PDF, and web view'}; - -function Subnote({sType}) { - return ( -
- {sType} - { - (sType in subnotes) && -
{subnotes[sType]}
- } -
- ); -} - -function LabeledButton({selectedSource, sType, onChange, radioRef}) { - const checked = selectedSource === sType; - const showOtherInput = checked && selectedSource === 'Other'; - - return ( - - ); -} - -function filterForBook(bookInfo) { - // eslint-disable-next-line complexity - return function (type) { - if (type.startsWith('Assignable')) { - return bookInfo.assignable_book; - } - if (type.startsWith('Kindle')) { - return Boolean(bookInfo.kindle_link); - } - if (type === 'Instructor solution manual') { - return bookInfo.book_faculty_resources?.find( - (r) => (/^Instructor (Solution|Answer)/).test(r.resource_heading) - ); - } - if (type === 'Student solution manual') { - return bookInfo.book_student_resources?.find( - (r) => (/^Student (Solution|Answer)/).test(r.resource_heading) - ); - } - return true; - }; -} - -function useSourceTypes() { - const {searchParams, selectedBook} = useErrataFormContext(); - const source = searchParams.get('source'); - const initialSource = source && sourceNames[source.toLowerCase()]; - const [sourceTypes, updateSourceTypes] = useState([]); - const filteredSourceTypes = useMemo( - () => sourceTypes.filter(filterForBook(selectedBook)), - [sourceTypes, selectedBook] - ); - const [selectedSource, updateSelectedSource] = useState(initialSource); - const onChange = React.useCallback( - ({target: {value}}) => updateSelectedSource(value), - [] - ); - - React.useEffect( - () => resourcePromise.then(updateSourceTypes), - [selectedBook] - ); - - return {sourceTypes: filteredSourceTypes, selectedSource, onChange}; -} - -export default function ErrorSourceSelector() { - const radioRef = useRef(); - const {sourceTypes, onChange, selectedSource} = useSourceTypes(); - const [RadioInvalidMessage, updateRadioInvalidMessage] = managedInvalidMessage(radioRef); - - React.useEffect( - updateRadioInvalidMessage, - [sourceTypes, selectedSource, updateRadioInvalidMessage] - ); - - return ( - -
In which source did you find this error?
-
- - { - sourceTypes.map((sType, index) => ( - - )) - } -
-
- ); -} diff --git a/src/app/pages/errata-form/form/ErrorSourceSelector.tsx b/src/app/pages/errata-form/form/ErrorSourceSelector.tsx new file mode 100644 index 000000000..dc5c64143 --- /dev/null +++ b/src/app/pages/errata-form/form/ErrorSourceSelector.tsx @@ -0,0 +1,156 @@ +import React, {useState, useRef, useMemo} from 'react'; +import useErrataFormContext from '../errata-form-context'; +import {type Book} from '~/helpers/books'; +import managedInvalidMessage from './InvalidMessage'; +import getFields from '~/models/errata-fields'; + +type SourceSelectorProps = { + selectedSource: string | null; + sType: string; + onChange: (event: React.ChangeEvent) => void; + radioRef?: React.RefObject; +}; + +type SubnoteProps = { + sType: string; +}; + +const resourcePromise = getFields('resources').then( + (resources: {field: string}[]) => resources.map((entry) => entry.field) +); + +function OtherSourceInput() { + const inputRef = useRef(null); + const [InvalidMessage, updateInvalidMessage] = + managedInvalidMessage(inputRef); + + return ( +
+ + +
+ ); +} + +const subnotes: Record = { + Textbook: 'includes print, PDF, and web view' +}; + +function Subnote({sType}: SubnoteProps) { + return ( +
+ {sType} + {sType in subnotes && ( +
{subnotes[sType]}
+ )} +
+ ); +} + +function LabeledButton({ + selectedSource, + sType, + onChange, + radioRef +}: SourceSelectorProps) { + const checked = selectedSource === sType; + const showOtherInput = checked && selectedSource === 'Other'; + + return ( + + ); +} + +function filterForBook(bookInfo: Book) { + return function (type: string) { + if (type.startsWith('Assignable')) { + return bookInfo.assignable_book; + } + if (type.startsWith('Kindle')) { + return Boolean(bookInfo.kindle_link); + } + if (type === 'Instructor solution manual') { + return bookInfo.has_faculty_resources; + } + if (type === 'Student solution manual') { + return bookInfo.has_student_resources; + } + return true; + }; +} + +function useSourceTypes() { + const {selectedBook} = useErrataFormContext(); + const [sourceTypes, updateSourceTypes] = useState([]); + const filteredSourceTypes = useMemo( + () => sourceTypes.filter(filterForBook(selectedBook ?? ({} as Book))), + [sourceTypes, selectedBook] + ); + const [selectedSource, updateSelectedSource] = useState( + null + ); + const onChange = React.useCallback( + ({target: {value}}: React.ChangeEvent) => + updateSelectedSource(value), + [] + ); + + React.useEffect(() => { + resourcePromise.then(updateSourceTypes); + }, [selectedBook]); + + return {sourceTypes: filteredSourceTypes, selectedSource, onChange}; +} + +export default function ErrorSourceSelector() { + const radioRef = useRef(null); + const {sourceTypes, onChange, selectedSource} = useSourceTypes(); + const [RadioInvalidMessage, updateRadioInvalidMessage] = + managedInvalidMessage(radioRef); + + React.useEffect(updateRadioInvalidMessage, [ + sourceTypes, + selectedSource, + updateRadioInvalidMessage + ]); + + return ( + +
+ In which source did you find this error? +
+
+ + {sourceTypes.map((sType, index) => ( + + ))} +
+
+ ); +} diff --git a/src/app/pages/errata-form/form/ErrorTypeSelector.js b/src/app/pages/errata-form/form/ErrorTypeSelector.js deleted file mode 100644 index 6efcc195b..000000000 --- a/src/app/pages/errata-form/form/ErrorTypeSelector.js +++ /dev/null @@ -1,74 +0,0 @@ -import React, {useState, useRef} from 'react'; -import managedInvalidMessage from './InvalidMessage'; - -function OtherErrorInput() { - const inputRef = useRef(); - const [InvalidMessage, updateInvalidMessage] = managedInvalidMessage(inputRef); - - return ( -
- - -
- ); -} - -export default function ErrorTypeSelector() { - const errorTypes = [ - 'Broken link', - 'Incorrect answer, calculation, or solution', - 'General/pedagogical suggestion or question', - 'Other factual inaccuracy in content', - 'Typo', - 'Other' - ]; - const inputRef = useRef(); - const [InvalidMessage, updateInvalidMessage] = managedInvalidMessage(inputRef); - const [selectedError, updateSelectedError] = useState(); - const helpBoxVisible = selectedError === 'Other' ? 'visible' : 'not-visible'; - const onChange = React.useCallback( - (event) => { - updateSelectedError(event.target.value); - updateInvalidMessage(); - }, - [updateSelectedError, updateInvalidMessage] - ); - - return ( - -
Select the type of error below.
-
- - { - errorTypes.map((eType) => - - ) - } -
-
- Need help logging in or have general questions? Contact Support at - support@openstax.org. -
-
- ); -} diff --git a/src/app/pages/errata-form/form/ErrorTypeSelector.tsx b/src/app/pages/errata-form/form/ErrorTypeSelector.tsx new file mode 100644 index 000000000..b8e1b0869 --- /dev/null +++ b/src/app/pages/errata-form/form/ErrorTypeSelector.tsx @@ -0,0 +1,79 @@ +import React, {useState, useRef} from 'react'; +import managedInvalidMessage from './InvalidMessage'; + +function OtherErrorInput() { + const inputRef = useRef(null); + const [InvalidMessage, updateInvalidMessage] = + managedInvalidMessage(inputRef); + + return ( +
+ + +
+ ); +} + +export default function ErrorTypeSelector() { + const errorTypes = [ + 'Broken link', + 'Incorrect answer, calculation, or solution', + 'General/pedagogical suggestion or question', + 'Other factual inaccuracy in content', + 'Typo', + 'Other' + ]; + const inputRef = useRef(null); + const [InvalidMessage, updateInvalidMessage] = + managedInvalidMessage(inputRef); + const [selectedError, updateSelectedError] = useState(); + const helpBoxVisible = + selectedError === 'Other' ? 'visible' : 'not-visible'; + const onChange = React.useCallback( + (event: React.ChangeEvent) => { + updateSelectedError(event.target.value); + updateInvalidMessage(); + }, + [updateSelectedError, updateInvalidMessage] + ); + + return ( + +
Select the type of error below.
+
+ + {errorTypes.map((eType) => ( + + ))} +
+
+ + Need help logging in or have general questions? Contact + Support at{' '} + + support@openstax.org. +
+
+ ); +} diff --git a/src/app/pages/errata-form/form/FileUploader.js b/src/app/pages/errata-form/form/FileUploader.tsx similarity index 53% rename from src/app/pages/errata-form/form/FileUploader.js rename to src/app/pages/errata-form/form/FileUploader.tsx index ee9f3bdc8..4aadcc23b 100644 --- a/src/app/pages/errata-form/form/FileUploader.js +++ b/src/app/pages/errata-form/form/FileUploader.tsx @@ -3,11 +3,15 @@ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faTimes} from '@fortawesome/free-solid-svg-icons/faTimes'; import cn from 'classnames'; -export function FileButton({name}) { +type FileButtonProps = { + name: string; +}; + +export function FileButton({name}: FileButtonProps) { const [filePath, updateFilePath] = useState(''); const empty = filePath === ''; - function setFile(event) { + function setFile(event: React.ChangeEvent) { updateFilePath(event.target.value.replace(/.*\\/, '')); } @@ -26,19 +30,28 @@ export function FileButton({name}) { return (
-
); } diff --git a/src/app/pages/errata-form/form/InvalidMessage.js b/src/app/pages/errata-form/form/InvalidMessage.tsx similarity index 56% rename from src/app/pages/errata-form/form/InvalidMessage.js rename to src/app/pages/errata-form/form/InvalidMessage.tsx index 2293c24ce..060324251 100644 --- a/src/app/pages/errata-form/form/InvalidMessage.js +++ b/src/app/pages/errata-form/form/InvalidMessage.tsx @@ -7,26 +7,27 @@ import React, {useState, useEffect} from 'react'; * It is important that the ref item exist when the message item is created */ -function InvalidMessage({message}) { - return ( - {message} - ); +type InvalidMessageProps = { + message: string; +}; + +function InvalidMessage({message}: InvalidMessageProps) { + return {message}; } -export default function (inputRef) { +export default function ( + inputRef: React.RefObject< + HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement + > +): [() => React.JSX.Element, () => void] { const [message, updateMessage] = useState(''); const updateFromRef = () => { if (inputRef.current) { updateMessage(inputRef.current.validationMessage); - } else { - console.warn('No current ref', inputRef); } }; useEffect(updateFromRef, [inputRef]); - return [ - () => , - updateFromRef - ]; + return [() => , updateFromRef]; } diff --git a/src/app/pages/errata-form/form/form.scss b/src/app/pages/errata-form/form/form.scss index 65e7f6398..4b1d7bebf 100644 --- a/src/app/pages/errata-form/form/form.scss +++ b/src/app/pages/errata-form/form/form.scss @@ -41,7 +41,7 @@ color: text-color(helper); } - label { + label:not(.question) { align-items: center; color: text-color(helper); display: flex; diff --git a/src/app/pages/errata-form/form/form.js b/src/app/pages/errata-form/form/form.tsx similarity index 60% rename from src/app/pages/errata-form/form/form.js rename to src/app/pages/errata-form/form/form.tsx index 049b645d0..e29912bbc 100644 --- a/src/app/pages/errata-form/form/form.js +++ b/src/app/pages/errata-form/form/form.tsx @@ -12,44 +12,61 @@ import {useNavigate} from 'react-router-dom'; import cn from 'classnames'; import './form.scss'; +type ApiResponse = { + id?: string; + submitted_by_account_id?: string[]; +}; + const postEndpoint = `${$.apiOriginAndOldPrefix}/errata/`; function ErrorExplanationBox() { - const inputRef = useRef(); - const [InvalidMessage, updateInvalidMessage] = managedInvalidMessage(inputRef); + const inputRef = useRef(null); + const [InvalidMessage, updateInvalidMessage] = + managedInvalidMessage(inputRef); return ( -
Tell us in detail about the error and your suggestion.
+
Please limit to one error per submission and include a suggested resolution if possible. If you have several to report, please - contact us at errata@openstax.org. + contact us at{' '} + errata@openstax.org.
+ id="error-detail" + maxLength={4000} + name="detail" + ref={inputRef} + onChange={updateInvalidMessage} + required + >
); } function SubmitButton() { - const {hasError, submitting, validateBeforeSubmitting} = useErrataFormContext(); + const {hasError, submitting, validateBeforeSubmitting} = + useErrataFormContext(); return (
{hasError &&
{hasError}
}
); } -const semesters = [ +const semesters: [string, string, string][] = [ ['March', 'October', 'spring'], ['November', 'February', 'fall'] ]; @@ -61,12 +78,12 @@ function RevisionSchedule() { return (
- Errata received from {start} through {end} will be fixed - in the online format for the {semester} semester. + Errata received from {start} through {end} will be + fixed in the online format for the {semester} semester.
- PDF versions of OpenStax textbooks are only updated once a year, prior - to the fall semester, if there are substantial errata updates to the - book that year. + PDF versions of OpenStax textbooks are only updated once a year, + prior to the fall semester, if there are substantial errata updates + to the book that year.
); } @@ -74,16 +91,24 @@ function RevisionSchedule() { function FormFields() { const {selectedBook} = useErrataFormContext(); const {accountId: submittedBy} = useUserContext(); + const id = selectedBook ? selectedBook.id : ''; return ( - - + + -
Please add a screenshot or any other file that helps explain the error.
+
+ Please add a screenshot or any other file that helps explain the + error. +
@@ -95,32 +120,34 @@ function FormFields() { // Safari cannot handle empty files; Edge cannot manipulate FormData // so we remove the file inputs that have no values -function removeEmptyFileWidgets(formEl) { - const fileInputs = Array.from(formEl.querySelectorAll('[type="file"]')); +function removeEmptyFileWidgets(formEl: HTMLFormElement) { + const fileInputs = Array.from( + formEl.querySelectorAll('[type="file"]') + ); const fiParents = fileInputs.map((el) => el.parentNode); fileInputs.forEach((el) => { if (el.value === '') { - el.parentNode.removeChild(el); + el.parentNode?.removeChild(el); } }); fileInputs.forEach((el, index) => { - el.setAttribute('name', `file_${index+1}`); + el.setAttribute('name', `file_${index + 1}`); }); // Return a function to put them back return () => { fileInputs.forEach((el, i) => { - fiParents[i].appendChild(el); + fiParents[i]?.appendChild(el); }); }; } function useBannedDialog() { - const [bannedText, setBannedText] = useState(); + const [bannedText, setBannedText] = useState(); const navigate = useNavigate(); const handleSubmissionResponse = React.useCallback( - (json) => { + (json: ApiResponse) => { if (json.id) { navigate(`/confirmation/errata?id=${json.id}`); } else if (json.submitted_by_account_id) { @@ -141,7 +168,8 @@ function useBannedDialog() { function BannedDialog() { return ( setBannedText(null)} + isOpen={Boolean(bannedText)} + onPutAway={() => setBannedText(undefined)} title="Errata submission rejected" >
{bannedText}
@@ -149,44 +177,39 @@ function useBannedDialog() { ); } - return [BannedDialog, handleSubmissionResponse]; + return [BannedDialog, handleSubmissionResponse] as const; } export default function ErrataForm() { const {hideErrors, submitting, setHasError} = useErrataFormContext(); const [BannedDialog, handleSubmissionResponse] = useBannedDialog(); - const formRef = useRef(); + const formRef = useRef(null); function validate() { - const invalid = formRef.current.querySelector(':invalid'); + const invalid = formRef.current?.querySelector(':invalid'); setHasError(invalid ? 'You have not completed the form.' : null); } React.useEffect(() => { - if (submitting) { + if (submitting && formRef.current) { const formEl = formRef.current; const putFileWidgetsBack = removeEmptyFileWidgets(formEl); const formData = new window.FormData(formEl); // Programmatically post the form - fetch( - postEndpoint, - { - method: 'POST', - body: formData - } - ) + fetch(postEndpoint, { + method: 'POST', + body: formData + }) .then((r) => r.json()) - .catch((err) => {throw new Error(`Posting errata form data: ${err}`);}) - .then( - handleSubmissionResponse, - (fetchError) => { - setHasError(`Submit failed: ${fetchError}.`); - putFileWidgetsBack(); - } - ) - ; + .catch((err) => { + throw new Error(`Posting errata form data: ${err}`); + }) + .then(handleSubmissionResponse, (fetchError: Error) => { + setHasError(`Submit failed: ${fetchError}.`); + putFileWidgetsBack(); + }); } }, [submitting, setHasError, handleSubmissionResponse]); @@ -194,10 +217,12 @@ export default function ErrataForm() {
diff --git a/test/helpers/fetch-mocker.js b/test/helpers/fetch-mocker.js index e9601677d..172859fe6 100644 --- a/test/helpers/fetch-mocker.js +++ b/test/helpers/fetch-mocker.js @@ -34,6 +34,7 @@ import pressData from '../src/data/press'; import pressArticleData from '../src/data/press-article'; import researchData from '../src/data/research'; import renewalData from '../src/data/renewal'; +import resourcesData from '../src/data/resources'; import rolesData from '../src/data/roles'; import salesforceData from '../src/data/salesforce'; import salesforcePartnerData from '../src/data/salesforce-partners'; @@ -52,7 +53,8 @@ import archiveData from '../src/data/archive'; // eslint-disable-next-line no-undef global.fetch = jest.fn().mockImplementation((...args) => { const isAdoption = (/pages\/adoption-form/).test(args[0]); - const isAlgebra = (/v2\/pages\/39/).test(args[0]); + // 81 is Astronomy, but we don't much care what the content is + const isAlgebra = (/v2\/pages\/(39|81)/).test(args[0]); const isAllBooks = (/book_subjects/).test(args[0]); const isAmazonBlurb = args[0].endsWith('snippets/amazonbookblurb/'); const isBiology = (/v2\/pages\/207/).test(args[0]); @@ -90,6 +92,7 @@ global.fetch = jest.fn().mockImplementation((...args) => { const isPressArticle = (/api\/press\/[a-z]/).test(args[0]); const isRenewal = args[0].includes('renewal?account_uuid'); const isResearch = args[0].includes('pages/research'); + const isResources = args[0].endsWith('errata-fields/?field=resources'); const isRoles = (/snippets\/roles/).test(args[0]); const isSchools = (/salesforce\/schools/).test(args[0]); const isSearchCollection = args[0].includes('/search/?collection='); @@ -186,6 +189,8 @@ global.fetch = jest.fn().mockImplementation((...args) => { payload = booksForAnalyticsData; } else if (isRenewal) { payload = renewalData; + } else if (isResources) { + payload = resourcesData; } else if (isRoles) { payload = rolesData; } else if (isSchools) { diff --git a/test/src/data/astronomy-toc.json b/test/src/data/astronomy-toc.json new file mode 100644 index 000000000..7376a8900 --- /dev/null +++ b/test/src/data/astronomy-toc.json @@ -0,0 +1,3323 @@ +{ + "title": "Astronomy 2e", + "revised": "2025-07-16T14:51:35+00:00", + "tree": { + "id": "4c29f9e5-a53d-42c0-bdb5-091990527d79@24525b6", + "title": "Astronomy 2e", + "contents": [ + { + "id": "b795b4f7-3318-4419-a338-8f5eeb0874ee@", + "title": "Preface", + "toc_type": "book-content", + "toc_target_type": "preface", + "slug": "preface" + }, + { + "id": "7a834c01-a9a2-5697-a1cf-0f59df8b56ca@24525b6", + "title": "Chapter 1\n \nScience and the Universe: A Brief Tour", + "toc_type": "chapter", + "contents": [ + { + "id": "ff8e6ee8-8a50-4756-b95e-c3b8e803622b@", + "title": "Introduction", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "1-introduction" + }, + { + "id": "7f11b6c9-3774-45f2-89e7-65c0196f6c29@", + "title": "1.1 The Nature of Astronomy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "1-1-the-nature-of-astronomy" + }, + { + "id": "c2150b0b-4881-42c7-83b2-ad766c79d36a@", + "title": "1.2 The Nature of Science", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "1-2-the-nature-of-science" + }, + { + "id": "8b5ce726-e912-4fcd-aacf-e35aaafb9839@", + "title": "1.3 The Laws of Nature", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "1-3-the-laws-of-nature" + }, + { + "id": "6d1abd05-a7d8-44c0-acd0-b5b97b3f771b@", + "title": "1.4 Numbers in Astronomy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "1-4-numbers-in-astronomy" + }, + { + "id": "72f7108d-f806-4f54-80ac-eed5976266e2@", + "title": "1.5 Consequences of Light Travel Time", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "1-5-consequences-of-light-travel-time" + }, + { + "id": "206e426a-3d8f-4832-80dd-189b03869a34@", + "title": "1.6 A Tour of the Universe", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "1-6-a-tour-of-the-universe" + }, + { + "id": "abd4b491-1fd8-418f-8a46-c0c9f96df944@", + "title": "1.7 The Universe on the Large Scale", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "1-7-the-universe-on-the-large-scale" + }, + { + "id": "15fa90be-da2d-48d6-bae9-f3b84d1d3960@", + "title": "1.8 The Universe of the Very Small", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "1-8-the-universe-of-the-very-small" + }, + { + "id": "bc9a9cec-f111-457a-8360-f3dfcdbfa410@", + "title": "1.9 A Conclusion and a Beginning", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "1-9-a-conclusion-and-a-beginning" + }, + { + "id": "b509e547-2c22-5620-9896-032cf5ffd458@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "1-for-further-exploration" + } + ], + "slug": "1-science-and-the-universe-a-brief-tour" + }, + { + "id": "e56bf2dc-f872-57c9-865a-8442ca8ebe0e@24525b6", + "title": "Chapter 2\n \nObserving the Sky: The Birth of Astronomy", + "toc_type": "chapter", + "contents": [ + { + "id": "5669c796-2b05-4a8f-96ac-85939b9b32af@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "2-thinking-ahead" + }, + { + "id": "8c5081ca-2ce9-44b9-8491-bfa4d6948d6e@", + "title": "2.1 The Sky Above", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "2-1-the-sky-above" + }, + { + "id": "3eb6f7c7-5832-4824-b71b-2fa5c5859cb6@", + "title": "2.2 Ancient Astronomy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "2-2-ancient-astronomy" + }, + { + "id": "3e7849d9-bda2-4f03-8517-953f63735a69@", + "title": "2.3 Astrology and Astronomy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "2-3-astrology-and-astronomy" + }, + { + "id": "0fa12f98-6991-469f-9e81-e518d4b1507b@", + "title": "2.4 The Birth of Modern Astronomy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "2-4-the-birth-of-modern-astronomy" + }, + { + "id": "1d5e084d-726a-5f29-90e3-b8320f12a954@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "2-key-terms" + }, + { + "id": "d12fe360-e8e0-5690-af42-30f17b29cb3d@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "2-summary" + }, + { + "id": "e24ee7bd-d21b-5af6-a665-f2934ef40c38@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "2-for-further-exploration" + }, + { + "id": "e5b6912f-7333-57c8-b7af-c93673a27487@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "2-collaborative-group-activities" + }, + { + "id": "c26fda6f-94bf-5036-90c8-172398909927@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "bf884580-f8b4-5cac-83be-71d8be3b7a38@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "2-review-questions" + }, + { + "id": "942be1a5-3d38-5106-9294-bc821ded82f7@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "2-thought-questions" + }, + { + "id": "b54556fb-cfc3-5575-ac76-78f763cde267@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "2-figuring-for-yourself" + } + ], + "slug": "2-exercises" + } + ], + "slug": "2-observing-the-sky-the-birth-of-astronomy" + }, + { + "id": "fe49f25b-bf43-577a-b1f0-2efb1830b6c5@24525b6", + "title": "Chapter 3\n \nOrbits and Gravity", + "toc_type": "chapter", + "contents": [ + { + "id": "e2171dce-08e7-4d5d-9f87-ae6d454b6831@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "3-thinking-ahead" + }, + { + "id": "47523a07-81ed-49ea-907c-775a77830d8f@", + "title": "3.1 The Laws of Planetary Motion", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "3-1-the-laws-of-planetary-motion" + }, + { + "id": "8dc7024f-0626-4a47-9ddb-34ecd15db2f6@", + "title": "3.2 Newton’s Great Synthesis", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "3-2-newtons-great-synthesis" + }, + { + "id": "b601e378-6e52-49c0-a085-29e17a7763bc@", + "title": "3.3 Newton’s Universal Law of Gravitation", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "3-3-newtons-universal-law-of-gravitation" + }, + { + "id": "e2c6b1d7-f6ec-4586-9648-770769fb9b34@", + "title": "3.4 Orbits in the Solar System", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "3-4-orbits-in-the-solar-system" + }, + { + "id": "b5a9fa3d-f23f-4c86-9ed9-50bfc39fd05b@", + "title": "3.5 Motions of Satellites and Spacecraft", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "3-5-motions-of-satellites-and-spacecraft" + }, + { + "id": "2b0e50b7-cacc-4a71-8f1b-6b3151fa8219@", + "title": "3.6 Gravity with More Than Two Bodies", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "3-6-gravity-with-more-than-two-bodies" + }, + { + "id": "4848f68c-234e-56ef-af32-f32662b23a3f@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "3-key-terms" + }, + { + "id": "6a236ece-02df-53bd-89a7-f1dd3c3a69db@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "3-summary" + }, + { + "id": "e7f667c6-c2fd-543b-88b4-0d0d04254e96@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "3-for-further-exploration" + }, + { + "id": "281cb692-f479-53cf-a654-25fa863a0e37@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "3-collaborative-group-activities" + }, + { + "id": "67310f45-7bc0-5fa1-a043-cd9404ebb711@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "189047a9-c2a9-5cc6-9b4c-13b792ee0a48@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "3-review-questions" + }, + { + "id": "1154892f-55a9-5e47-8080-6a7916fb2b0f@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "3-thought-questions" + }, + { + "id": "f306f90d-c4ce-57f2-9e85-9c65c99eefa3@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "3-figuring-for-yourself" + } + ], + "slug": "3-exercises" + } + ], + "slug": "3-orbits-and-gravity" + }, + { + "id": "394032b3-ade7-5a91-b373-7a7bb9da439d@24525b6", + "title": "Chapter 4\n \nEarth, Moon, and Sky", + "toc_type": "chapter", + "contents": [ + { + "id": "1620756f-04bc-4173-b549-e693ce6e573f@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "4-thinking-ahead" + }, + { + "id": "2137756f-bba9-4571-b15d-d99af6911ce8@", + "title": "4.1 Earth and Sky", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "4-1-earth-and-sky" + }, + { + "id": "1fa4ebbd-7de6-4b35-8b96-1ea6538d10f7@", + "title": "4.2 The Seasons", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "4-2-the-seasons" + }, + { + "id": "ff0d0421-83f7-42ce-a604-e3820ebafd76@", + "title": "4.3 Keeping Time", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "4-3-keeping-time" + }, + { + "id": "b1642146-c688-4668-abcb-897b128aefe6@", + "title": "4.4 The Calendar", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "4-4-the-calendar" + }, + { + "id": "4fd1d099-cf07-41a5-ac1a-236f3d2db0eb@", + "title": "4.5 Phases and Motions of the Moon", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "4-5-phases-and-motions-of-the-moon" + }, + { + "id": "c309faea-c9aa-4070-89a6-efbba3482901@", + "title": "4.6 Ocean Tides and the Moon", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "4-6-ocean-tides-and-the-moon" + }, + { + "id": "e6b95fa8-0f58-47c0-b3fa-cb82c29696d9@", + "title": "4.7 Eclipses of the Sun and Moon", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "4-7-eclipses-of-the-sun-and-moon" + }, + { + "id": "1e730129-9750-5236-be77-415ec42c777f@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "4-key-terms" + }, + { + "id": "50e253f2-9b38-5b67-82f7-9f5f5e01c474@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "4-summary" + }, + { + "id": "f76807e5-aadb-5440-83b3-7cef84e8f21e@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "4-for-further-exploration" + }, + { + "id": "abe57d4e-e592-54a3-b05f-3ce24f4aff18@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "4-collaborative-group-activities" + }, + { + "id": "b7a8461e-89d6-55e7-b942-e3bf8401d55a@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "19efc8be-1fef-5e02-837d-a59b2da0f3b1@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "4-review-questions" + }, + { + "id": "e064665e-04c3-586e-9096-ce1cb70db09a@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "4-thought-questions" + }, + { + "id": "078c6c60-e701-5fc6-8472-45fc6b91939f@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "4-figuring-for-yourself" + } + ], + "slug": "4-exercises" + } + ], + "slug": "4-earth-moon-and-sky" + }, + { + "id": "a0851e84-08ff-5c47-b1d2-f3f005a5f8d3@24525b6", + "title": "Chapter 5\n \nRadiation and Spectra", + "toc_type": "chapter", + "contents": [ + { + "id": "bc5ce180-f2b3-4469-a882-22bf96435c99@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "5-thinking-ahead" + }, + { + "id": "badbbab4-54ea-49f8-834b-4762fc4b7e35@", + "title": "5.1 The Behavior of Light", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "5-1-the-behavior-of-light" + }, + { + "id": "15eec1a9-5e3c-4e2b-abac-8cd61748d4a0@", + "title": "5.2 The Electromagnetic Spectrum", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "5-2-the-electromagnetic-spectrum" + }, + { + "id": "1f92a120-370a-4547-b14e-a3df3ce6f083@", + "title": "5.3 Spectroscopy in Astronomy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "5-3-spectroscopy-in-astronomy" + }, + { + "id": "22d9d199-7c88-418f-92bd-6cb72d0e1a53@", + "title": "5.4 The Structure of the Atom", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "5-4-the-structure-of-the-atom" + }, + { + "id": "9d3d546b-fc92-410c-a9cc-5e084fdb4b62@", + "title": "5.5 Formation of Spectral Lines", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "5-5-formation-of-spectral-lines" + }, + { + "id": "9d6442f2-71bf-4ed3-9a37-1723bb846e0e@", + "title": "5.6 The Doppler Effect", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "5-6-the-doppler-effect" + }, + { + "id": "45103869-56cc-5290-a01c-4589dbb92bd4@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "5-key-terms" + }, + { + "id": "3fdb800c-d358-58ce-97d3-332101c926f9@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "5-summary" + }, + { + "id": "ac348c37-facc-5204-9ea3-33f8360a2641@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "5-for-further-exploration" + }, + { + "id": "3d2901ff-5e44-53d2-a035-5b920a406e15@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "5-collaborative-group-activities" + }, + { + "id": "973b05ee-31c8-5340-8342-a9f3a312bd56@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "9fbdcef4-4417-5477-b51b-dded5adedc8a@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "5-review-questions" + }, + { + "id": "af242728-c240-5845-8615-f0f37b36cdd1@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "5-thought-questions" + }, + { + "id": "c41b30a6-cbc9-5948-9ee2-2f0f2915b457@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "5-figuring-for-yourself" + } + ], + "slug": "5-exercises" + } + ], + "slug": "5-radiation-and-spectra" + }, + { + "id": "dbe10943-90e9-548f-bef4-6eb660614908@24525b6", + "title": "Chapter 6\n \nAstronomical Instruments", + "toc_type": "chapter", + "contents": [ + { + "id": "bd9d6fca-fd83-4112-9379-482f40364ae7@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "6-thinking-ahead" + }, + { + "id": "7c547388-eced-47de-80c9-4826b072356e@", + "title": "6.1 Telescopes", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "6-1-telescopes" + }, + { + "id": "cbd1efb7-998a-4672-9337-ba9ecf4f8a8d@", + "title": "6.2 Telescopes Today", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "6-2-telescopes-today" + }, + { + "id": "558682b0-2683-4513-a52e-beddbd32e4b5@", + "title": "6.3 Visible-Light Detectors and Instruments", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "6-3-visible-light-detectors-and-instruments" + }, + { + "id": "99df183c-aa08-41b0-b02e-bb641d304cb9@", + "title": "6.4 Radio Telescopes", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "6-4-radio-telescopes" + }, + { + "id": "ae35cefe-bf23-40b0-97a8-d174c341e5d8@", + "title": "6.5 Observations outside Earth’s Atmosphere", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "6-5-observations-outside-earths-atmosphere" + }, + { + "id": "f9b9b592-b963-46ef-92bf-2feb6c600154@", + "title": "6.6 The Future of Large Telescopes", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "6-6-the-future-of-large-telescopes" + }, + { + "id": "64294cdd-006f-57dd-b017-d00b533d9286@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "6-key-terms" + }, + { + "id": "909579e0-cfb9-5e44-8c9e-19e436e21ba8@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "6-summary" + }, + { + "id": "230ef1dc-e60f-519e-bd57-eb79d71780ea@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "6-for-further-exploration" + }, + { + "id": "c7756378-900b-52f0-84cf-4a81c3909247@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "6-collaborative-group-activities" + }, + { + "id": "a2b557bd-95e2-5ee6-8827-87f72023e787@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "f81a1d22-93c5-57a8-8881-c8f98ed43cd1@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "6-review-questions" + }, + { + "id": "082d1f66-6f3b-516f-b96b-997ee8a49a39@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "6-thought-questions" + }, + { + "id": "25eec6f7-dc13-5740-9061-e61b73bf70fa@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "6-figuring-for-yourself" + } + ], + "slug": "6-exercises" + } + ], + "slug": "6-astronomical-instruments" + }, + { + "id": "0bee6f60-b380-524f-8781-4778b16dd702@24525b6", + "title": "Chapter 7\n \nOther Worlds: An Introduction to the Solar System", + "toc_type": "chapter", + "contents": [ + { + "id": "0bb91d10-14bd-49f7-ae1c-d97d421465b6@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "7-thinking-ahead" + }, + { + "id": "c9239bd9-a44b-4187-a3f9-d0a5511b45e4@", + "title": "7.1 Overview of Our Planetary System", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "7-1-overview-of-our-planetary-system" + }, + { + "id": "89bccab6-a207-484d-95ac-e59f72e0a4f8@", + "title": "7.2 Composition and Structure of Planets", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "7-2-composition-and-structure-of-planets" + }, + { + "id": "9e21231f-4dd5-4589-87a4-f0abd02bde90@", + "title": "7.3 Dating Planetary Surfaces", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "7-3-dating-planetary-surfaces" + }, + { + "id": "777e7e4d-3bf1-4488-b693-d43f89c58994@", + "title": "7.4 Origin of the Solar System", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "7-4-origin-of-the-solar-system" + }, + { + "id": "41d86913-b0ee-5bcb-a096-c48c2128ade3@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "7-key-terms" + }, + { + "id": "703f5a6e-46c4-5ba0-abe0-36f917d24c3d@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "7-summary" + }, + { + "id": "44040322-e902-5bd1-aa34-0f78bd003da1@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "7-for-further-exploration" + }, + { + "id": "dc293ed0-c6e9-59bc-ace0-4dfc31c9c7f5@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "7-collaborative-group-activities" + }, + { + "id": "29cd75a0-6cbe-535d-a196-558d8ce4c470@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "cac74f3d-01eb-52d3-94ac-02ce58cd63db@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "7-review-questions" + }, + { + "id": "8408f298-1313-54ee-b85c-fe3c5cb0905a@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "7-thought-questions" + }, + { + "id": "3c297860-bb8c-536b-b2d6-7ff39013e76e@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "7-figuring-for-yourself" + } + ], + "slug": "7-exercises" + } + ], + "slug": "7-other-worlds-an-introduction-to-the-solar-system" + }, + { + "id": "f55f2c11-f37f-53f9-8693-d53b4611f2d0@24525b6", + "title": "Chapter 8\n \nEarth as a Planet", + "toc_type": "chapter", + "contents": [ + { + "id": "05a1c8d2-7400-4b6a-ada6-c3179952f725@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "8-thinking-ahead" + }, + { + "id": "7c4fae08-3cc6-4e08-9ee0-12158c0f3071@", + "title": "8.1 The Global Perspective", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "8-1-the-global-perspective" + }, + { + "id": "06448fca-ae6c-4146-a3e1-b13d8c765c63@", + "title": "8.2 Earth’s Crust", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "8-2-earths-crust" + }, + { + "id": "c5fa6993-c0ee-45f0-ab80-c983b0677452@", + "title": "8.3 Earth’s Atmosphere", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "8-3-earths-atmosphere" + }, + { + "id": "f9261cd1-436c-498c-aa22-b81749400913@", + "title": "8.4 Life, Chemical Evolution, and Climate Change", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "8-4-life-chemical-evolution-and-climate-change" + }, + { + "id": "b90e376a-c576-4e98-88fc-de2b19526a40@", + "title": "8.5 Cosmic Influences on the Evolution of Earth", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "8-5-cosmic-influences-on-the-evolution-of-earth" + }, + { + "id": "68c114b9-eb8e-55f2-8a77-c6d7061d7482@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "8-key-terms" + }, + { + "id": "7e1a7949-e011-51ca-9d7a-3ddbeeeed1c1@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "8-summary" + }, + { + "id": "67713eb9-4cc8-56a5-8e30-64b25f3529e9@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "8-for-further-exploration" + }, + { + "id": "135ce91b-37d2-5fcb-b46d-56cd0baea009@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "8-collaborative-group-activities" + }, + { + "id": "1f0684c4-1165-5c0c-85ae-947bdf071e81@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "13a07c5b-a9e3-5c02-8411-81427dcfb583@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "8-review-questions" + }, + { + "id": "dd9f8118-1801-58a0-8738-b6f9d73ae983@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "8-thought-questions" + }, + { + "id": "477a1fcc-2d06-5bfb-b6e1-c7220a5a4d16@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "8-figuring-for-yourself" + } + ], + "slug": "8-exercises" + } + ], + "slug": "8-earth-as-a-planet" + }, + { + "id": "39f2b3fe-9ecb-5e52-a91b-c5bb843af093@24525b6", + "title": "Chapter 9\n \nCratered Worlds", + "toc_type": "chapter", + "contents": [ + { + "id": "f5930002-07c4-4bec-8e25-f3ad35de6963@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "9-thinking-ahead" + }, + { + "id": "fa6f6f04-2ea7-4c0a-b792-565198157034@", + "title": "9.1 General Properties of the Moon", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "9-1-general-properties-of-the-moon" + }, + { + "id": "eea4b9d8-6b59-4040-90e8-fead7b28668b@", + "title": "9.2 The Lunar Surface", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "9-2-the-lunar-surface" + }, + { + "id": "07ca43bf-5858-4ac3-aa7a-d1fd7992fffe@", + "title": "9.3 Impact Craters", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "9-3-impact-craters" + }, + { + "id": "f11291b8-079b-49fa-a302-4139c51133f9@", + "title": "9.4 The Origin of the Moon", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "9-4-the-origin-of-the-moon" + }, + { + "id": "c4fdaa69-9e6a-436c-a27a-d7e2cf95e45c@", + "title": "9.5 Mercury", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "9-5-mercury" + }, + { + "id": "43b954f4-f0e3-5b5b-8818-e6c07c464391@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "9-key-terms" + }, + { + "id": "4d6aab28-4a1d-53af-9630-834c3d61bbe6@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "9-summary" + }, + { + "id": "232b4c9e-030a-59be-b0a3-1124c3989a16@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "9-for-further-exploration" + }, + { + "id": "38d0acbe-c050-5c95-b7f6-633128fd7ee3@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "9-collaborative-group-activities" + }, + { + "id": "2ceed067-bcb8-53ad-a2a8-70fde1b7660d@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "5fa50daf-30c1-5e02-a08b-b56ff04c0b80@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "9-review-questions" + }, + { + "id": "2e6f82ba-56f4-5700-93e5-be3a4f1d3c05@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "9-thought-questions" + }, + { + "id": "2bc53836-6b9a-54ce-a207-313e888a18d6@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "9-figuring-for-yourself" + } + ], + "slug": "9-exercises" + } + ], + "slug": "9-cratered-worlds" + }, + { + "id": "34b2195c-cdf9-571f-b3f2-625f9d175f9e@24525b6", + "title": "Chapter 10\n \nEarthlike Planets: Venus and Mars", + "toc_type": "chapter", + "contents": [ + { + "id": "bd3a9cb6-eecc-42fb-9626-6bc145004074@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "10-thinking-ahead" + }, + { + "id": "c76a2699-5934-4efd-b059-3213342d048c@", + "title": "10.1 The Nearest Planets: An Overview", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "10-1-the-nearest-planets-an-overview" + }, + { + "id": "e10c1a16-d06c-4057-8813-29ae446efe94@", + "title": "10.2 The Geology of Venus", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "10-2-the-geology-of-venus" + }, + { + "id": "41d0c477-4230-42e8-a1b0-ba1317d9b909@", + "title": "10.3 The Massive Atmosphere of Venus", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "10-3-the-massive-atmosphere-of-venus" + }, + { + "id": "93c3c498-3673-4622-bdb2-7db24243affa@", + "title": "10.4 The Geology of Mars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "10-4-the-geology-of-mars" + }, + { + "id": "d163b409-95d7-49e2-a04c-9dcd5e373719@", + "title": "10.5 Water and Life on Mars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "10-5-water-and-life-on-mars" + }, + { + "id": "db6df2ee-5f21-4089-b8b8-df88a87480e9@", + "title": "10.6 Divergent Planetary Evolution", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "10-6-divergent-planetary-evolution" + }, + { + "id": "9969772a-e0fa-5bde-aac1-f41c43567ccf@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "10-key-terms" + }, + { + "id": "e0e9166b-91b2-5446-9567-7e135e6a2573@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "10-summary" + }, + { + "id": "8dcbd0a4-8449-58dd-ad02-86f84e085191@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "10-for-further-exploration" + }, + { + "id": "e9cb534d-6f30-569d-b318-85e1dfa72151@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "10-collaborative-group-activities" + }, + { + "id": "4d84197b-07a2-57e8-b0ce-a3138f076d49@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "79bee2b6-021c-543d-8686-304d26ea7732@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "10-review-questions" + }, + { + "id": "92c96bdf-c2fa-5994-83a3-7a02b96ee531@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "10-thought-questions" + }, + { + "id": "f130004d-c7bd-544d-9ecd-e93ac8957b43@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "10-figuring-for-yourself" + } + ], + "slug": "10-exercises" + } + ], + "slug": "10-earthlike-planets-venus-and-mars" + }, + { + "id": "aa45d25e-fb6e-5120-ae56-cbd62c21d815@24525b6", + "title": "Chapter 11\n \nThe Giant Planets", + "toc_type": "chapter", + "contents": [ + { + "id": "24137f9b-61e6-48d5-8ea1-e6fe7fc644d3@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "11-thinking-ahead" + }, + { + "id": "d9cfd957-5241-4611-abff-426e7b4f7a0c@", + "title": "11.1 Exploring the Outer Planets", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "11-1-exploring-the-outer-planets" + }, + { + "id": "139674ba-d381-46a3-b07e-50d0fca52b12@", + "title": "11.2 The Giant Planets", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "11-2-the-giant-planets" + }, + { + "id": "8215f9ce-0a31-4c2e-a6de-bbd5931d229a@", + "title": "11.3 Atmospheres of the Giant Planets", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "11-3-atmospheres-of-the-giant-planets" + }, + { + "id": "5883744c-25a3-5d03-a5f7-1d992312307a@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "11-key-terms" + }, + { + "id": "ac350723-8733-56de-a7dd-8a9b6c45926d@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "11-summary" + }, + { + "id": "3d16efb7-b2ef-5366-920e-dd4aedc5e40c@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "11-for-further-exploration" + }, + { + "id": "176d2cf7-2a5e-5e2b-a888-00276d8b2292@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "11-collaborative-group-activities" + }, + { + "id": "c2291d65-07c0-59e6-ac23-7e19b3fd1bc3@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "66f15fd3-ae24-5a6e-86bd-fd11f22e9934@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "11-review-questions" + }, + { + "id": "84e4ec2b-6ec5-5e6f-b248-82ab77d0d42b@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "11-thought-questions" + }, + { + "id": "eba8a0a9-3b27-5049-a92d-42181436b9c9@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "11-figuring-for-yourself" + } + ], + "slug": "11-exercises" + } + ], + "slug": "11-the-giant-planets" + }, + { + "id": "6a13f500-919f-58ed-8650-cda1ae28d36c@24525b6", + "title": "Chapter 12\n \nRings, Moons, and Pluto", + "toc_type": "chapter", + "contents": [ + { + "id": "760cf33c-7669-4f5f-a68e-e74a63d3731f@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "12-thinking-ahead" + }, + { + "id": "a03c22a2-3d5b-4ffc-a773-71bf1c98b7f0@", + "title": "12.1 Ring and Moon Systems Introduced", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "12-1-ring-and-moon-systems-introduced" + }, + { + "id": "0bf21b5e-5915-4804-b7a9-ef67fef5c7e8@", + "title": "12.2 The Galilean Moons of Jupiter", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "12-2-the-galilean-moons-of-jupiter" + }, + { + "id": "bdc41f58-f869-444a-b939-9c73c0a48d15@", + "title": "12.3 Titan and Triton", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "12-3-titan-and-triton" + }, + { + "id": "6e41304f-cdf5-4a3a-b5f1-0fd49bd85023@", + "title": "12.4 Pluto and Charon", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "12-4-pluto-and-charon" + }, + { + "id": "8b8a7842-b3fd-4fda-aa7a-8fa137a1dc42@", + "title": "12.5 Planetary Rings (and Enceladus)", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "12-5-planetary-rings-and-enceladus" + }, + { + "id": "751a867d-468f-5d74-8701-7bac8ded8408@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "12-key-terms" + }, + { + "id": "81ae8c53-8cc3-5d14-b713-8f7975e18068@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "12-summary" + }, + { + "id": "ded490db-11f2-5e36-9ded-d9d1ac792c7e@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "12-for-further-exploration" + }, + { + "id": "262989c3-345c-5065-b1b5-8251d54cb9fc@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "12-collaborative-group-activities" + }, + { + "id": "4a150f1e-089f-5d34-9aa9-c3cfc3d63204@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "0be2ec3a-150f-55a9-9e47-55a22fc6bd6a@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "12-review-questions" + }, + { + "id": "a1102f2e-5c1a-5252-971d-437f4348e671@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "12-thought-questions" + }, + { + "id": "983e393d-310c-545e-8f85-1f1b575db409@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "12-figuring-for-yourself" + } + ], + "slug": "12-exercises" + } + ], + "slug": "12-rings-moons-and-pluto" + }, + { + "id": "827a1bea-4053-5a07-bad5-97f7a478419f@24525b6", + "title": "Chapter 13\n \nComets and Asteroids: Debris of the Solar System", + "toc_type": "chapter", + "contents": [ + { + "id": "46f47a00-a325-4985-a7e2-92ac70b2483a@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "13-thinking-ahead" + }, + { + "id": "721b4675-43e5-47fc-95ed-0eb06cc49d36@", + "title": "13.1 Asteroids", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "13-1-asteroids" + }, + { + "id": "b1750def-8849-4ae6-87d0-b7a993fc2c24@", + "title": "13.2 Asteroids and Planetary Defense", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "13-2-asteroids-and-planetary-defense" + }, + { + "id": "0adc3d85-995c-427e-a4d1-c90b6161f1e4@", + "title": "13.3 The “Long-Haired” Comets", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "13-3-the-long-haired-comets" + }, + { + "id": "9aca755b-b169-427f-b460-894e739504b5@", + "title": "13.4 The Origin and Fate of Comets and Related Objects", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "13-4-the-origin-and-fate-of-comets-and-related-objects" + }, + { + "id": "ee20a483-c518-52c7-84dd-53c5d50955cb@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "13-key-terms" + }, + { + "id": "5443c78b-2d01-5c95-b4dc-b0c776a1a3c5@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "13-summary" + }, + { + "id": "0300c939-9813-5e39-85b6-8c66604a684f@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "13-for-further-exploration" + }, + { + "id": "0a696104-1fce-503f-9d81-044bfe13970c@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "13-collaborative-group-activities" + }, + { + "id": "3014d24d-6820-5c7b-9618-c93a16542225@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "84f017eb-f4f2-52ae-bfd0-6e34cef464f6@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "13-review-questions" + }, + { + "id": "6968b908-3f74-57cc-a5ec-5b8ada55a38c@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "13-thought-questions" + }, + { + "id": "d40e20dc-212e-58d7-9b1c-33ba7d0f89bf@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "13-figuring-for-yourself" + } + ], + "slug": "13-exercises" + } + ], + "slug": "13-comets-and-asteroids-debris-of-the-solar-system" + }, + { + "id": "cf144e92-a507-5a2f-b2c8-8ca58cd6244f@24525b6", + "title": "Chapter 14\n \nCosmic Samples and the Origin of the Solar System", + "toc_type": "chapter", + "contents": [ + { + "id": "821ee95d-a7c5-44fc-9a15-c6aadaaa8b51@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "14-thinking-ahead" + }, + { + "id": "399c3a6d-5dba-4317-9e4d-51ac95c86e5a@", + "title": "14.1 Meteors", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "14-1-meteors" + }, + { + "id": "b8fcd786-2d2e-415f-8ce8-a61442d8e6b9@", + "title": "14.2 Meteorites: Stones from Heaven", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "14-2-meteorites-stones-from-heaven" + }, + { + "id": "d3960789-d139-4c88-870e-982093388aa6@", + "title": "14.3 Formation of the Solar System", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "14-3-formation-of-the-solar-system" + }, + { + "id": "32d4a7d0-c061-4fd7-a687-d698a04da5e4@", + "title": "14.4 Comparison with Other Planetary Systems", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "14-4-comparison-with-other-planetary-systems" + }, + { + "id": "06733e8f-49db-4a2f-bbe0-0d949d4949a8@", + "title": "14.5 Planetary Evolution", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "14-5-planetary-evolution" + }, + { + "id": "f2c38a67-5254-5a4b-b12b-c92bff5622ff@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "14-key-terms" + }, + { + "id": "801aa218-797e-5ea8-9f39-e9ca8d63ea0a@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "14-summary" + }, + { + "id": "3596165c-86f0-553e-a80c-b10c00418288@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "14-for-further-exploration" + }, + { + "id": "97da3361-f782-544d-ac17-dc54abb290d5@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "14-collaborative-group-activities" + }, + { + "id": "889ff650-7a6d-53ca-9f2b-a5be358e2459@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "9206a42b-f983-5d6b-bf37-e88cfa424f33@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "14-review-questions" + }, + { + "id": "dd3a14c6-5063-559d-ba97-8740a218dc6f@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "14-thought-questions" + }, + { + "id": "e6715fba-bde3-585b-ba59-73d60ff49ab1@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "14-figuring-for-yourself" + } + ], + "slug": "14-exercises" + } + ], + "slug": "14-cosmic-samples-and-the-origin-of-the-solar-system" + }, + { + "id": "ba9f2785-dc8e-55ce-92b3-f065cfdc9d96@24525b6", + "title": "Chapter 15\n \nThe Sun: A Garden-Variety Star", + "toc_type": "chapter", + "contents": [ + { + "id": "da30e85d-e625-4c76-bd12-77270b8d4f9b@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "15-thinking-ahead" + }, + { + "id": "97449e6c-5612-433b-9586-c078970c1a2e@", + "title": "15.1 The Structure and Composition of the Sun", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "15-1-the-structure-and-composition-of-the-sun" + }, + { + "id": "f4a8969d-bbef-4f5d-a2ef-fa45a3625aa4@", + "title": "15.2 The Solar Cycle", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "15-2-the-solar-cycle" + }, + { + "id": "a20c81bb-271c-4862-b4a8-4bda31bb3a2a@", + "title": "15.3 Solar Activity above the Photosphere", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "15-3-solar-activity-above-the-photosphere" + }, + { + "id": "2c84c2af-e198-435e-8402-bdb41fab1954@", + "title": "15.4 Space Weather", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "15-4-space-weather" + }, + { + "id": "6456a9eb-3668-5088-9816-89fdc720a7fe@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "15-key-terms" + }, + { + "id": "b1a77d95-741c-5978-b853-7557efd21766@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "15-summary" + }, + { + "id": "166a26ce-c73f-5a12-af84-a8df475832c4@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "15-for-further-exploration" + }, + { + "id": "7cfb20d9-d915-5d4e-8a4b-923194389713@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "15-collaborative-group-activities" + }, + { + "id": "a8e295bc-4a0a-5eb0-9d23-34c64a97b39e@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "5eca84ce-de5b-5611-990a-8becf80b1690@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "15-review-questions" + }, + { + "id": "532db4b5-f4e3-5adb-9058-235f91804b87@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "15-thought-questions" + }, + { + "id": "a068ca83-8623-5858-896b-feea89c1663a@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "15-figuring-for-yourself" + } + ], + "slug": "15-exercises" + } + ], + "slug": "15-the-sun-a-garden-variety-star" + }, + { + "id": "a0b64668-264d-5856-b581-6cb222a70f35@24525b6", + "title": "Chapter 16\n \nThe Sun: A Nuclear Powerhouse", + "toc_type": "chapter", + "contents": [ + { + "id": "3e4a13f1-3aeb-4fe2-b9f5-dc354139c29f@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "16-thinking-ahead" + }, + { + "id": "0ac646fb-3bf3-498e-a911-c80b917508a4@", + "title": "16.1 Sources of Sunshine: Thermal and Gravitational Energy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "16-1-sources-of-sunshine-thermal-and-gravitational-energy" + }, + { + "id": "48c2dc44-40da-465e-b524-0adefbbc1490@", + "title": "16.2 Mass, Energy, and the Theory of Relativity", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "16-2-mass-energy-and-the-theory-of-relativity" + }, + { + "id": "808fd050-635a-4043-9f03-612a5a799c78@", + "title": "16.3 The Solar Interior: Theory", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "16-3-the-solar-interior-theory" + }, + { + "id": "29321b1a-92b6-46a1-8647-2322d31a2426@", + "title": "16.4 The Solar Interior: Observations", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "16-4-the-solar-interior-observations" + }, + { + "id": "d0c0d984-378a-5626-b12b-32e99365878c@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "16-key-terms" + }, + { + "id": "3bacf7ce-950b-5790-bc13-a37a92242dfe@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "16-summary" + }, + { + "id": "bf2d3b85-46de-55e6-bc81-97f1d701623d@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "16-for-further-exploration" + }, + { + "id": "663a2148-7506-5ebe-8447-c9daa5e72aa5@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "16-collaborative-group-activities" + }, + { + "id": "9de9020e-0782-5a4c-96f5-e42f27ea47c8@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "ab693c4c-e517-5a06-86fc-a31c90207a73@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "16-review-questions" + }, + { + "id": "4517f013-95d5-5c26-8a1e-112b033ab135@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "16-thought-questions" + }, + { + "id": "d8e4e089-a21b-52e1-82fc-920c8a001af0@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "16-figuring-for-yourself" + } + ], + "slug": "16-exercises" + } + ], + "slug": "16-the-sun-a-nuclear-powerhouse" + }, + { + "id": "4e1f1bf5-35f2-5fbb-88fd-1ac88d77c732@24525b6", + "title": "Chapter 17\n \nAnalyzing Starlight", + "toc_type": "chapter", + "contents": [ + { + "id": "9d28d6da-b855-4cfe-b629-54620023f99c@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "17-thinking-ahead" + }, + { + "id": "c2e301e8-00d7-40aa-adc6-5074e1780167@", + "title": "17.1 The Brightness of Stars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "17-1-the-brightness-of-stars" + }, + { + "id": "ae03b328-30e7-4be5-a3fb-f1ea6f56407e@", + "title": "17.2 Colors of Stars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "17-2-colors-of-stars" + }, + { + "id": "d1261637-6e72-43d8-be82-54d3e5a3d1e0@", + "title": "17.3 The Spectra of Stars (and Brown Dwarfs)", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "17-3-the-spectra-of-stars-and-brown-dwarfs" + }, + { + "id": "167aaaa5-7530-49bd-b110-21d10d7cd56b@", + "title": "17.4 Using Spectra to Measure Stellar Radius, Composition, and Motion", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "17-4-using-spectra-to-measure-stellar-radius-composition-and-motion" + }, + { + "id": "88205381-f8d1-54b0-8a72-b8b3ae25a1e3@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "17-key-terms" + }, + { + "id": "097df605-c1ea-55fe-b3ce-8f7e2830b75f@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "17-summary" + }, + { + "id": "d29cc47f-de03-5a77-824e-98bbc9014e01@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "17-for-further-exploration" + }, + { + "id": "0e05a553-20a1-5b14-aa22-55227e3e6749@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "17-collaborative-group-activities" + }, + { + "id": "95354a5c-41eb-5710-8c10-62f030cf5f36@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "40f2b0f0-e7fe-5326-8f4c-acd8ce8ef3d2@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "17-review-questions" + }, + { + "id": "14740931-bc9d-5ace-a0de-a97922f5274c@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "17-thought-questions" + }, + { + "id": "527fedf7-a2f4-5b02-ac43-2f1ce798b4f1@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "17-figuring-for-yourself" + } + ], + "slug": "17-exercises" + } + ], + "slug": "17-analyzing-starlight" + }, + { + "id": "feb2f4f4-5fce-590f-8a4c-8f879d306b22@24525b6", + "title": "Chapter 18\n \nThe Stars: A Celestial Census", + "toc_type": "chapter", + "contents": [ + { + "id": "810ba736-3e15-48e2-9491-cf0f401611c3@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "18-thinking-ahead" + }, + { + "id": "f6dd7bbd-c01f-4c46-b50c-851f6fdedd2e@", + "title": "18.1 A Stellar Census", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "18-1-a-stellar-census" + }, + { + "id": "7eb90491-5946-4150-9c21-38c946124a55@", + "title": "18.2 Measuring Stellar Masses", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "18-2-measuring-stellar-masses" + }, + { + "id": "7b355f77-984b-4af1-b188-97ddeb9e658b@", + "title": "18.3 Diameters of Stars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "18-3-diameters-of-stars" + }, + { + "id": "11581e86-b3c6-45ea-bd3e-0d55a8f12ab8@", + "title": "18.4 The H–R Diagram", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "18-4-the-h-r-diagram" + }, + { + "id": "ca417f24-20d5-5db8-aa06-47ecb5b5337f@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "18-key-terms" + }, + { + "id": "257f91ab-4f86-5678-b6fd-626c33a8c625@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "18-summary" + }, + { + "id": "5b616c97-75ae-576d-b7f6-fc51ffc3d803@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "18-for-further-exploration" + }, + { + "id": "24f74dcc-098e-50e6-8cf1-3cfacb5081f0@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "18-collaborative-group-activities" + }, + { + "id": "d0c42095-ca7a-55fe-a507-921c278f256b@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "a615a27f-d0ff-5328-a49d-0c06d6140d2f@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "18-review-questions" + }, + { + "id": "896598be-427e-5031-ac8a-9f411e70580c@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "18-thought-questions" + }, + { + "id": "76bc7bc4-a224-5422-a638-c13643d92348@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "18-figuring-for-yourself" + } + ], + "slug": "18-exercises" + } + ], + "slug": "18-the-stars-a-celestial-census" + }, + { + "id": "497cd12d-b0c3-51bf-a184-9e05e14d9c8e@24525b6", + "title": "Chapter 19\n \nCelestial Distances", + "toc_type": "chapter", + "contents": [ + { + "id": "1ee1ae44-9a8c-439f-b39d-c385ef80ca3f@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "19-thinking-ahead" + }, + { + "id": "495b1319-ab2a-46be-a216-f98692a0eb14@", + "title": "19.1 Fundamental Units of Distance", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "19-1-fundamental-units-of-distance" + }, + { + "id": "e7866b9e-59bd-4e63-a285-58320ddaf41c@", + "title": "19.2 Surveying the Stars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "19-2-surveying-the-stars" + }, + { + "id": "bdd59622-7b70-46bd-948f-3651c94d230b@", + "title": "19.3 Variable Stars: One Key to Cosmic Distances", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "19-3-variable-stars-one-key-to-cosmic-distances" + }, + { + "id": "6956e36d-e32e-4e3d-83d8-ca2a23a411d4@", + "title": "19.4 The H–R Diagram and Cosmic Distances", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "19-4-the-h-r-diagram-and-cosmic-distances" + }, + { + "id": "ce0a3b20-d659-544f-be83-6e77a65e69c2@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "19-key-terms" + }, + { + "id": "03e3eaa0-feab-55e7-a77b-4e71fac2eb65@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "19-summary" + }, + { + "id": "27e9dec1-54f7-5d23-b959-724e2c8a06b8@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "19-for-further-exploration" + }, + { + "id": "b5dc5b9a-8380-58a6-a318-bec37596fde1@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "19-collaborative-group-activities" + }, + { + "id": "4d618b53-b25e-56f6-a63c-88f282c77ed2@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "741eecab-1f0c-58d5-bf3f-7fd8a40c046d@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "19-review-questions" + }, + { + "id": "cc3e5d3a-4286-57df-b77c-ff6be961b807@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "19-thought-questions" + }, + { + "id": "ef7880d8-9a61-5bcf-911f-8736919891d0@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "19-figuring-for-yourself" + } + ], + "slug": "19-exercises" + } + ], + "slug": "19-celestial-distances" + }, + { + "id": "9da9b4a6-4def-5b76-9dac-039e0a8d7a69@24525b6", + "title": "Chapter 20\n \nBetween the Stars: Gas and Dust in Space", + "toc_type": "chapter", + "contents": [ + { + "id": "73158c18-de2f-4a95-b9cf-3ac65c11cbe0@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "20-thinking-ahead" + }, + { + "id": "0e4c42c9-c91a-4c41-9ad1-116621dae208@", + "title": "20.1 The Interstellar Medium", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "20-1-the-interstellar-medium" + }, + { + "id": "d202bcaf-7f29-43c8-953d-e716c4785ad2@", + "title": "20.2 Interstellar Gas", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "20-2-interstellar-gas" + }, + { + "id": "9e1d113d-c083-451f-806a-31b3c54b4a05@", + "title": "20.3 Cosmic Dust", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "20-3-cosmic-dust" + }, + { + "id": "a90879d1-ee17-4595-9d79-8e75038891bf@", + "title": "20.4 Cosmic Rays", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "20-4-cosmic-rays" + }, + { + "id": "ed257b38-6523-4a4d-a227-24223f6753bc@", + "title": "20.5 The Life Cycle of Cosmic Material", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "20-5-the-life-cycle-of-cosmic-material" + }, + { + "id": "e5591420-f150-4160-8b4a-42087b79794b@", + "title": "20.6 Interstellar Matter around the Sun", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "20-6-interstellar-matter-around-the-sun" + }, + { + "id": "994d9837-0441-5cf4-8ddd-b484fc2d892b@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "20-key-terms" + }, + { + "id": "d66a9927-e3d2-5d11-9574-fce93f368e9c@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "20-summary" + }, + { + "id": "80647693-4dd6-591c-8b51-8da29be074eb@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "20-for-further-exploration" + }, + { + "id": "7fc9ccc9-acbf-504e-9698-5784653738c8@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "20-collaborative-group-activities" + }, + { + "id": "5d864583-87cb-5748-8986-d7c6f7fd2e31@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "670064b4-33bd-5f03-b4cf-852a1779dced@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "20-review-questions" + }, + { + "id": "e3280c98-5fcd-59c5-b34e-d02a87fdd7aa@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "20-thought-questions" + }, + { + "id": "90b7c114-d88a-59eb-ac33-d2d826606282@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "20-figuring-for-yourself" + } + ], + "slug": "20-exercises" + } + ], + "slug": "20-between-the-stars-gas-and-dust-in-space" + }, + { + "id": "f2c3ffff-256c-5d33-88d3-9b5759d134b0@24525b6", + "title": "Chapter 21\n \nThe Birth of Stars and the Discovery of Planets outside the Solar System", + "toc_type": "chapter", + "contents": [ + { + "id": "a4d25617-b0da-4fe3-8542-322122f7e7d3@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "21-thinking-ahead" + }, + { + "id": "d0564568-2e7f-4a39-9252-57b7f53c75d4@", + "title": "21.1 Star Formation", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "21-1-star-formation" + }, + { + "id": "c80b855e-bbb9-49a4-89ca-cceaa1621efd@", + "title": "21.2 The H–R Diagram and the Study of Stellar Evolution", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "21-2-the-h-r-diagram-and-the-study-of-stellar-evolution" + }, + { + "id": "e24426f1-be17-4920-9461-8d7d449257df@", + "title": "21.3 Evidence That Planets Form around Other Stars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "21-3-evidence-that-planets-form-around-other-stars" + }, + { + "id": "c86ab422-c09c-4b54-810c-f1432eb3c342@", + "title": "21.4 Planets beyond the Solar System: Search and Discovery", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "21-4-planets-beyond-the-solar-system-search-and-discovery" + }, + { + "id": "fa826ec8-d865-4fc5-bbc6-b7643788d709@", + "title": "21.5 Exoplanets Everywhere: What We Are Learning", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "21-5-exoplanets-everywhere-what-we-are-learning" + }, + { + "id": "b6b6db26-7ae7-4735-a8da-988c26104485@", + "title": "21.6 New Perspectives on Planet Formation", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "21-6-new-perspectives-on-planet-formation" + }, + { + "id": "f4a4ae6f-5597-52f8-9e71-549ecebbcad2@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "21-key-terms" + }, + { + "id": "cbf08b5e-4094-5a43-a70d-02b59a732a31@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "21-summary" + }, + { + "id": "4ab44299-c350-5db4-8382-1ff41e49ed01@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "21-for-further-exploration" + }, + { + "id": "27464d3b-a232-545a-928d-8d157e05ff1d@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "21-collaborative-group-activities" + }, + { + "id": "4852f557-cab2-50ad-903d-4f44dbfb3cc6@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "fa50cfee-b017-543e-8ff9-0ef57dbb3764@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "21-review-questions" + }, + { + "id": "76a8cf10-692d-58bc-8348-6ee0498b828f@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "21-thought-questions" + }, + { + "id": "33bfb46d-a5e6-5b7c-a660-de2e59f34678@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "21-figuring-for-yourself" + } + ], + "slug": "21-exercises" + } + ], + "slug": "21-the-birth-of-stars-and-the-discovery-of-planets-outside-the-solar-system" + }, + { + "id": "19044b53-b381-5840-b2e7-3517e304a71a@24525b6", + "title": "Chapter 22\n \nStars from Adolescence to Old Age", + "toc_type": "chapter", + "contents": [ + { + "id": "46b88c58-3f68-469e-98f0-ed46bc80f5a1@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "22-thinking-ahead" + }, + { + "id": "8a6e3d45-44dc-48f6-8973-d6f95fbcc318@", + "title": "22.1 Evolution from the Main Sequence to Red Giants", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "22-1-evolution-from-the-main-sequence-to-red-giants" + }, + { + "id": "22c8446c-af88-4319-9a18-fe03a51bd297@", + "title": "22.2 Star Clusters", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "22-2-star-clusters" + }, + { + "id": "94219738-96dc-47ef-b1e0-03c9044e8ac6@", + "title": "22.3 Checking Out the Theory", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "22-3-checking-out-the-theory" + }, + { + "id": "780466d0-053e-4f7f-adbd-b0d0dac5c99b@", + "title": "22.4 Further Evolution of Stars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "22-4-further-evolution-of-stars" + }, + { + "id": "a75aea70-4fb6-4d2e-9c29-7d29b55b93ce@", + "title": "22.5 The Evolution of More Massive Stars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "22-5-the-evolution-of-more-massive-stars" + }, + { + "id": "4dc35307-7f92-5f80-bafe-5c425415d940@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "22-key-terms" + }, + { + "id": "9ea0ec75-0219-58db-ae3e-3841a81fb5ed@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "22-summary" + }, + { + "id": "2ce536e8-c640-503f-9bd1-f4bb05aac25d@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "22-for-further-exploration" + }, + { + "id": "0a281ade-2a97-51cb-9fda-6b9c8eaa947f@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "22-collaborative-group-activities" + }, + { + "id": "657daccd-9cd7-5f59-b757-02b1f7c31060@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "eb31344f-3d4a-54ad-a7e4-5d5442dc3f33@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "22-review-questions" + }, + { + "id": "a1c78acc-8234-5de8-833d-aac0010fccdf@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "22-thought-questions" + }, + { + "id": "e71a3ca1-8a9a-568d-8a14-e942836c823d@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "22-figuring-for-yourself" + } + ], + "slug": "22-exercises" + } + ], + "slug": "22-stars-from-adolescence-to-old-age" + }, + { + "id": "009b1392-bfa6-5821-9bbe-eff449bc4c9a@24525b6", + "title": "Chapter 23\n \nThe Death of Stars", + "toc_type": "chapter", + "contents": [ + { + "id": "8e460daa-be2b-47de-9d38-ab4c21865a8a@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "23-thinking-ahead" + }, + { + "id": "915e3fbb-30e8-464d-ad0f-5a756d205ea7@", + "title": "23.1 The Death of Low-Mass Stars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "23-1-the-death-of-low-mass-stars" + }, + { + "id": "ecaa1a98-d696-4822-b88c-1b8e29502ef6@", + "title": "23.2 Evolution of Massive Stars: An Explosive Finish", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "23-2-evolution-of-massive-stars-an-explosive-finish" + }, + { + "id": "a567ba98-3507-49d5-893c-c05cd42eefa5@", + "title": "23.3 Supernova Observations", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "23-3-supernova-observations" + }, + { + "id": "bfeda56d-0942-4640-9f37-619d208eb106@", + "title": "23.4 Pulsars and the Discovery of Neutron Stars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "23-4-pulsars-and-the-discovery-of-neutron-stars" + }, + { + "id": "3a787454-c556-4633-895a-ff762fbd2b72@", + "title": "23.5 The Evolution of Binary Star Systems", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "23-5-the-evolution-of-binary-star-systems" + }, + { + "id": "979ea345-05c5-4720-ae29-212ffb3b6ecd@", + "title": "23.6 The Mystery of the Gamma-Ray Bursts", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "23-6-the-mystery-of-the-gamma-ray-bursts" + }, + { + "id": "a6a9561d-a717-5fe0-94e3-61251587ddbf@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "23-key-terms" + }, + { + "id": "cd03cf4b-2990-5ec5-aa2b-29e12e54bc7f@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "23-summary" + }, + { + "id": "11f0d91c-53c9-5d31-8614-ea549bf4b2a2@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "23-for-further-exploration" + }, + { + "id": "f97929a8-b88f-5d5e-a316-d19e29a8ddf1@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "23-collaborative-group-activities" + }, + { + "id": "ffabc844-acf3-5752-a818-86a39ea25073@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "4dd8af71-40b9-57a7-ad3c-8f6800931748@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "23-review-questions" + }, + { + "id": "6c083955-14b0-53fb-a43b-e46bebe6e519@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "23-thought-questions" + }, + { + "id": "653362da-ed7c-5c27-98e9-d5001cf1b63c@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "23-figuring-for-yourself" + } + ], + "slug": "23-exercises" + } + ], + "slug": "23-the-death-of-stars" + }, + { + "id": "1ab4309b-5308-5eae-a566-e3cea6a84260@24525b6", + "title": "Chapter 24\n \nBlack Holes and Curved Spacetime", + "toc_type": "chapter", + "contents": [ + { + "id": "c58084cd-93fa-48ba-82a5-8bc44de393ed@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "24-thinking-ahead" + }, + { + "id": "87febba0-f4df-4096-b9f6-a13ed65deb0f@", + "title": "24.1 Introducing General Relativity", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "24-1-introducing-general-relativity" + }, + { + "id": "3ce9d47d-1953-4522-ad16-0a8c17b4cf92@", + "title": "24.2 Spacetime and Gravity", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "24-2-spacetime-and-gravity" + }, + { + "id": "340339c0-3b54-44c0-929a-7fe8b575a8a2@", + "title": "24.3 Tests of General Relativity", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "24-3-tests-of-general-relativity" + }, + { + "id": "e42a160d-33cd-413f-ba2e-d23601880762@", + "title": "24.4 Time in General Relativity", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "24-4-time-in-general-relativity" + }, + { + "id": "366e559d-50aa-4678-b615-bc6f4f06e5cc@", + "title": "24.5 Black Holes", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "24-5-black-holes" + }, + { + "id": "0eb920e0-9e34-4761-b92a-369b0a40ae70@", + "title": "24.6 Evidence for Black Holes", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "24-6-evidence-for-black-holes" + }, + { + "id": "b59bbcd2-3e7d-4bf0-8f2d-e2ef9265be3a@", + "title": "24.7 Gravitational Wave Astronomy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "24-7-gravitational-wave-astronomy" + }, + { + "id": "29b10d46-33e0-508e-afef-4d74683fa5ef@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "24-key-terms" + }, + { + "id": "3caa9650-7edc-57cf-88b5-23343b499b7c@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "24-summary" + }, + { + "id": "f1bc374d-f58f-5a95-9144-f81fae834cc8@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "24-for-further-exploration" + }, + { + "id": "dbda5721-647d-557f-ad1b-e159f3b05489@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "24-collaborative-group-activities" + }, + { + "id": "9eb85f79-2727-539a-bef1-7bc297a5ad72@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "2655c71b-b0b8-5fa9-8152-01786bba960e@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "24-review-questions" + }, + { + "id": "1c43497c-8604-5d9a-ade9-240ee3178888@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "24-thought-questions" + }, + { + "id": "9d00c01b-5b3f-527f-876b-57501d36a54f@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "24-figuring-for-yourself" + } + ], + "slug": "24-exercises" + } + ], + "slug": "24-black-holes-and-curved-spacetime" + }, + { + "id": "d4f64924-3241-59a1-8b91-767141ad52ac@24525b6", + "title": "Chapter 25\n \nThe Milky Way Galaxy", + "toc_type": "chapter", + "contents": [ + { + "id": "cfa5edb3-71c8-4593-bcef-efbc4dc2d162@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "25-thinking-ahead" + }, + { + "id": "80c08cb8-b0ca-49a2-bbb9-87ed85d23745@", + "title": "25.1 The Architecture of the Galaxy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "25-1-the-architecture-of-the-galaxy" + }, + { + "id": "e5ae30bd-bea0-482e-aa8d-9031fe0a6de5@", + "title": "25.2 Spiral Structure", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "25-2-spiral-structure" + }, + { + "id": "3637e692-0455-46d1-a76d-d5a8a0d48e5c@", + "title": "25.3 The Mass of the Galaxy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "25-3-the-mass-of-the-galaxy" + }, + { + "id": "5bea3219-4ed3-4eba-99a7-8ccd6a723fba@", + "title": "25.4 The Center of the Galaxy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "25-4-the-center-of-the-galaxy" + }, + { + "id": "42d678ee-f4eb-4208-be35-17206525601f@", + "title": "25.5 Stellar Populations in the Galaxy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "25-5-stellar-populations-in-the-galaxy" + }, + { + "id": "f84ec82d-1a65-48ac-af23-44256b829a73@", + "title": "25.6 The Formation of the Galaxy", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "25-6-the-formation-of-the-galaxy" + }, + { + "id": "ef40ac9d-e8d0-57fb-8ba0-0cf704b6ec26@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "25-key-terms" + }, + { + "id": "63582b1e-74fc-5aac-bb7e-d7cccba6971e@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "25-summary" + }, + { + "id": "5e72fbbd-a368-56bd-a025-b7b7801ec348@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "25-for-further-exploration" + }, + { + "id": "87c70239-2b35-5085-beb9-ad470f17cc37@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "25-collaborative-group-activities" + }, + { + "id": "363929df-2999-57bb-a394-a1c8e6c0acf1@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "5691e613-db9d-529c-b092-0943d7eca099@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "25-review-questions" + }, + { + "id": "a3754aed-6890-5b14-82b7-a2cc9686fe8c@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "25-thought-questions" + }, + { + "id": "cc425769-e9a5-50fe-9de2-17f2bfe44436@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "25-figuring-for-yourself" + } + ], + "slug": "25-exercises" + } + ], + "slug": "25-the-milky-way-galaxy" + }, + { + "id": "aa5a3b3a-d69d-5dc7-a6c3-f7f6a64c8a7f@24525b6", + "title": "Chapter 26\n \nGalaxies", + "toc_type": "chapter", + "contents": [ + { + "id": "1db87beb-ec02-4a18-8f7b-fe500224ba2d@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "26-thinking-ahead" + }, + { + "id": "7207bf03-f431-490f-af15-d053f957dddd@", + "title": "26.1 The Discovery of Galaxies", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "26-1-the-discovery-of-galaxies" + }, + { + "id": "2301b05b-62ca-4212-9e3d-b68715f001bf@", + "title": "26.2 Types of Galaxies", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "26-2-types-of-galaxies" + }, + { + "id": "d46dc34b-84fa-4abc-8716-e237f6a71142@", + "title": "26.3 Properties of Galaxies", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "26-3-properties-of-galaxies" + }, + { + "id": "0fd5bc48-a4a5-4876-83a3-68ea812a662a@", + "title": "26.4 The Extragalactic Distance Scale", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "26-4-the-extragalactic-distance-scale" + }, + { + "id": "eea58296-1089-4e4d-8805-b0dc4fddea2e@", + "title": "26.5 The Expanding Universe", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "26-5-the-expanding-universe" + }, + { + "id": "4cfa89d9-5804-594d-b2e6-1dc4493e6ed7@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "26-key-terms" + }, + { + "id": "421c45d7-8c22-5df6-a8e5-c391ab8ca185@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "26-summary" + }, + { + "id": "0d3f6db3-9095-5935-abf7-96bb6e9fd5b6@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "26-for-further-exploration" + }, + { + "id": "e3d66161-3404-52e6-b1ec-960e49811056@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "26-collaborative-group-activities" + }, + { + "id": "4c739aa3-a3af-55ff-b09f-c36d83bde70a@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "e46812a6-2df1-5f13-a38f-630ec6b20557@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "26-review-questions" + }, + { + "id": "b0d7257b-5143-5fb5-9ed0-9bcd58fa8fa2@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "26-thought-questions" + }, + { + "id": "2950b113-2153-5eb6-84d8-829e3df746be@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "26-figuring-for-yourself" + } + ], + "slug": "26-exercises" + } + ], + "slug": "26-galaxies" + }, + { + "id": "fdf8cf8a-1b11-54d2-9e7a-09c42db035b9@24525b6", + "title": "Chapter 27\n \nActive Galaxies, Quasars, and Supermassive Black Holes", + "toc_type": "chapter", + "contents": [ + { + "id": "c1576760-aaaf-4663-ac75-4b81891a0cf3@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "27-thinking-ahead" + }, + { + "id": "976cd1d5-fa37-4496-b3fa-c1bc770bdadd@", + "title": "27.1 Quasars", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "27-1-quasars" + }, + { + "id": "79e546fb-e10c-4604-9cd4-6d64d9535f8c@", + "title": "27.2 Supermassive Black Holes: What Quasars Really Are", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "27-2-supermassive-black-holes-what-quasars-really-are" + }, + { + "id": "6abf3134-2c1b-4e20-a4cd-f91360777a8b@", + "title": "27.3 Quasars as Probes of Evolution in the Universe", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "27-3-quasars-as-probes-of-evolution-in-the-universe" + }, + { + "id": "db953b77-bb82-5d0d-bbc5-f6766d2835ec@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "27-key-terms" + }, + { + "id": "50e8e223-ad29-58bf-97d2-7a92e4582e2e@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "27-summary" + }, + { + "id": "93026b74-2ccd-53ee-ad9b-5e137c203a7d@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "27-for-further-exploration" + }, + { + "id": "7b052f40-5897-52f2-bb46-614a0b76c4d1@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "27-collaborative-group-activities" + }, + { + "id": "d14f133c-8715-5945-8ab7-90101b92bd65@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "90dabfb1-5dbf-5a2c-ab12-b7fd81eda98d@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "27-review-questions" + }, + { + "id": "5f141414-ae50-5925-a59f-af539d6a7bc2@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "27-thought-questions" + }, + { + "id": "84f2d243-0179-58bc-a9b9-a5c7bf2ce011@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "27-figuring-for-yourself" + } + ], + "slug": "27-exercises" + } + ], + "slug": "27-active-galaxies-quasars-and-supermassive-black-holes" + }, + { + "id": "1b8159d9-44c1-5cef-820a-94aa75f933cd@24525b6", + "title": "Chapter 28\n \nThe Evolution and Distribution of Galaxies", + "toc_type": "chapter", + "contents": [ + { + "id": "d7f7bff9-fe26-4af6-bb4c-b2869541c71a@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "28-thinking-ahead" + }, + { + "id": "1e224c17-74f4-4082-988d-13dc5475aeda@", + "title": "28.1 Observations of Distant Galaxies", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "28-1-observations-of-distant-galaxies" + }, + { + "id": "06b43416-8559-4c50-b870-e9fda268bf4e@", + "title": "28.2 Galaxy Mergers and Active Galactic Nuclei", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "28-2-galaxy-mergers-and-active-galactic-nuclei" + }, + { + "id": "09cab279-1255-4465-b14a-ca893103f2e8@", + "title": "28.3 The Distribution of Galaxies in Space", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "28-3-the-distribution-of-galaxies-in-space" + }, + { + "id": "b063470e-4c67-4956-ac8b-aa08510a414f@", + "title": "28.4 The Challenge of Dark Matter", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "28-4-the-challenge-of-dark-matter" + }, + { + "id": "0553dc16-7f85-4d2b-b6d4-aea5dc9dc4ed@", + "title": "28.5 The Formation and Evolution of Galaxies and Structure in the Universe", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "28-5-the-formation-and-evolution-of-galaxies-and-structure-in-the-universe" + }, + { + "id": "bf968821-6f45-5540-8580-917d0014491c@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "28-key-terms" + }, + { + "id": "d5682f8a-cfb8-5094-88a8-587d93694e8f@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "28-summary" + }, + { + "id": "0f885ff5-0a57-5f25-9f82-779309f64ffc@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "28-for-further-exploration" + }, + { + "id": "620bb949-fa90-5bb8-bf5d-fa6367d2d588@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "28-collaborative-group-activities" + }, + { + "id": "5fb08c71-c8db-55d7-bd0b-95827f6257e9@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "55f9a2f8-0ea7-555b-a185-9f75b05b73f7@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "28-review-questions" + }, + { + "id": "8753e1cd-ddc6-5d32-a86e-39a18e656595@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "28-thought-questions" + }, + { + "id": "6062cbac-ddcf-53da-af22-ad651e4a7522@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "28-figuring-for-yourself" + } + ], + "slug": "28-exercises" + } + ], + "slug": "28-the-evolution-and-distribution-of-galaxies" + }, + { + "id": "ce79f7c3-429d-5bb7-9661-181282131a9c@24525b6", + "title": "Chapter 29\n \nThe Big Bang", + "toc_type": "chapter", + "contents": [ + { + "id": "c4987953-c1a0-4df4-8d01-1d0df7ae228f@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "29-thinking-ahead" + }, + { + "id": "81ac6512-f327-4a65-b2f7-ffa9e2b14302@", + "title": "29.1 The Age of the Universe", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "29-1-the-age-of-the-universe" + }, + { + "id": "df0a1d5f-b241-42e4-843f-57fbd3c5c1f1@", + "title": "29.2 A Model of the Universe", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "29-2-a-model-of-the-universe" + }, + { + "id": "aa165ae9-6681-4297-94e1-c013f7cf15fc@", + "title": "29.3 The Beginning of the Universe", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "29-3-the-beginning-of-the-universe" + }, + { + "id": "2d06b339-8230-4298-a7e7-72771b1a40a9@", + "title": "29.4 The Cosmic Microwave Background", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "29-4-the-cosmic-microwave-background" + }, + { + "id": "6a24271c-6c9f-4178-92a5-b5e2234f13cf@", + "title": "29.5 What Is the Universe Really Made Of?", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "29-5-what-is-the-universe-really-made-of" + }, + { + "id": "0ff79f0f-13c3-4e5b-8f86-24a52fc009b4@", + "title": "29.6 The Inflationary Universe", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "29-6-the-inflationary-universe" + }, + { + "id": "0cb5d17a-1dff-44d4-af38-803d675f303c@", + "title": "29.7 The Anthropic Principle", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "29-7-the-anthropic-principle" + }, + { + "id": "1c536721-7310-56cb-b6bf-a324dc3a56b8@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "29-key-terms" + }, + { + "id": "25ce4e91-85a4-5442-bfaa-91c3f8a3e1e0@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "29-summary" + }, + { + "id": "b29c0a00-b577-5fbf-9add-5b51b076ab6a@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "29-for-further-exploration" + }, + { + "id": "afb23ddb-dcd6-55ce-8c70-2ae2714ee3f0@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "29-collaborative-group-activities" + }, + { + "id": "7ffbee66-b6dd-59a9-911b-f03f65df739e@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "cc267582-f1e5-51dd-b5ed-d9ed8c86f731@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "29-review-questions" + }, + { + "id": "77c7de85-0fd0-5878-81d8-3c1de81be57e@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "29-thought-questions" + }, + { + "id": "e927dd39-8779-5afa-b40c-65ed3e854667@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "29-figuring-for-yourself" + } + ], + "slug": "29-exercises" + } + ], + "slug": "29-the-big-bang" + }, + { + "id": "6d7c0907-8bd7-531c-b99d-b9e2d10a5b3f@24525b6", + "title": "Chapter 30\n \nLife in the Universe", + "toc_type": "chapter", + "contents": [ + { + "id": "7ac95c9e-6713-43a4-adf8-c8285882caaa@", + "title": "Thinking Ahead", + "toc_type": "book-content", + "toc_target_type": "intro", + "slug": "30-thinking-ahead" + }, + { + "id": "f302e4d4-b5fd-41bc-8d19-99dcb7e819a2@", + "title": "30 The Cosmic Context for Life", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "30-1-the-cosmic-context-for-life" + }, + { + "id": "6e5659bc-b570-4cc3-8078-1eb4acd3b8fc@", + "title": "30.2 Astrobiology", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "30-2-astrobiology" + }, + { + "id": "be446a6a-8a98-4999-9ee3-e830ec801ed2@", + "title": "30.3 Searching for Life beyond Earth", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "30-3-searching-for-life-beyond-earth" + }, + { + "id": "71ee00eb-d39d-437c-9a85-9a8db4309fe3@", + "title": "30.4 The Search for Extraterrestrial Intelligence", + "toc_type": "book-content", + "toc_target_type": "numbered-section", + "slug": "30-4-the-search-for-extraterrestrial-intelligence" + }, + { + "id": "76853ba6-8909-563f-a331-922d6088b270@24525b6", + "title": "Key Terms", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "30-key-terms" + }, + { + "id": "084049c3-342c-57d8-8aa1-fa7a9a4f6665@24525b6", + "title": "Summary", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "30-summary" + }, + { + "id": "0eaf4ab1-6832-5d1c-a8e9-169487b2a337@24525b6", + "title": "For Further Exploration", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "30-for-further-exploration" + }, + { + "id": "e67b2ba5-dbf5-5266-895c-1bd350187e36@24525b6", + "title": "Collaborative Group Activities", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "30-collaborative-group-activities" + }, + { + "id": "17f99b7f-6d0c-5884-8aa7-d27f40d03702@24525b6", + "title": "Exercises", + "toc_type": "sub-book-tree", + "contents": [ + { + "id": "2a80add4-220b-5813-8f61-b11d1d5bbf7b@24525b6", + "title": "Review Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "30-review-questions" + }, + { + "id": "9a05fb9c-85f5-5f4a-905f-b6f810d2b77c@24525b6", + "title": "Thought Questions", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "30-thought-questions" + }, + { + "id": "1b04756d-f897-525d-9c35-fb93e7fcff43@24525b6", + "title": "Figuring for Yourself", + "toc_type": "book-content", + "toc_target_type": "composite-page", + "slug": "30-figuring-for-yourself" + } + ], + "slug": "30-exercises" + } + ], + "slug": "30-life-in-the-universe" + }, + { + "id": "4a274b24-cc3d-4264-b5c5-7527026d831e@", + "title": "Appendix A How to Study for an Introductory Astronomy Class", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "a-how-to-study-for-an-introductory-astronomy-class" + }, + { + "id": "5828cbfc-03c0-436c-8efe-264a5de96b94@", + "title": "Appendix B Astronomy Websites, Images, and Apps", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "b-astronomy-websites-images-and-apps" + }, + { + "id": "b51ff343-f72e-4d3d-b1ff-d91fc7b22490@", + "title": "Appendix C Scientific Notation", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "c-scientific-notation" + }, + { + "id": "fde24489-0317-41c9-83ee-eb6de6224ea0@", + "title": "Appendix D Units Used in Science", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "d-units-used-in-science" + }, + { + "id": "73d49c7c-b8ec-4bb4-a3e8-2fdf9acdf2b3@", + "title": "Appendix E Some Useful Constants for Astronomy", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "e-some-useful-constants-for-astronomy" + }, + { + "id": "b88f5bbe-31c9-4a24-8920-0c55689a6142@", + "title": "Appendix F Physical and Orbital Data for the Planets", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "f-physical-and-orbital-data-for-the-planets" + }, + { + "id": "bc5da890-ed3e-44f7-a950-26bd9074ca62@", + "title": "Appendix G Selected Moons of the Planets", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "g-selected-moons-of-the-planets" + }, + { + "id": "24e32afd-b542-4ca3-a516-455a66ac7900@", + "title": "Appendix H Future Total Eclipses", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "h-future-total-eclipses" + }, + { + "id": "d648a9b8-e2a5-4b2d-8979-1a075cb91899@", + "title": "Appendix I The Nearest Stars, Brown Dwarfs, and White Dwarfs", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "i-the-nearest-stars-brown-dwarfs-and-white-dwarfs" + }, + { + "id": "ab019339-b032-49cc-93e8-7e46f704a554@", + "title": "Appendix J The Brightest Twenty Stars", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "j-the-brightest-twenty-stars" + }, + { + "id": "55ecd3c3-0cdc-482c-8e2f-ec853554054d@", + "title": "Appendix K The Chemical Elements", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "k-the-chemical-elements" + }, + { + "id": "0e15f0fc-0d77-4a0b-8b70-cfdffc87b73f@", + "title": "Appendix L The Constellations", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "l-the-constellations" + }, + { + "id": "f97dbe3b-b6e5-45c1-a243-a0afa8c7b95e@", + "title": "Appendix M Star Chart and Sky Event Resources", + "toc_type": "book-content", + "toc_target_type": "appendix", + "slug": "m-star-chart-and-sky-event-resources" + }, + { + "id": "6d5a1a4f-46ab-51f0-8387-cc7bbe5f0041@24525b6", + "title": "Index", + "toc_type": "book-content", + "toc_target_type": "index", + "slug": "index" + } + ], + "slug": "astronomy-2e" + }, + "slug": "astronomy-2e", + "id": "4c29f9e5-a53d-42c0-bdb5-091990527d79", + "version": "24525b6", + "license": { + "url": "http://creativecommons.org/licenses/by/4.0/", + "name": "Creative Commons Attribution License" + }, + "language": "en", + "content": "\n \n Table of Contents\n \n \n \n\n", + "repo_schema_version": 1, + "style_name": "astronomy", + "style_href": "../resources/styles/webview-generic.css" +} diff --git a/test/src/data/books.js b/test/src/data/books.js index 46e50c34f..8359ccc8c 100644 --- a/test/src/data/books.js +++ b/test/src/data/books.js @@ -32,7 +32,7 @@ export default { "books": [ { "id": 39, - "slug": "books/college-algebra", + "slug": "v2/pages/39", "book_state": "live", "title": "College Algebra", "subjects": [ diff --git a/test/src/data/resources.js b/test/src/data/resources.js new file mode 100644 index 000000000..62ee002ff --- /dev/null +++ b/test/src/data/resources.js @@ -0,0 +1,34 @@ +export default [ + { + field: 'Textbook', + verbose: 'Textbook' + }, + { + field: 'iBooks version', + verbose: 'iBooks version' + }, + { + field: 'Instructor solution manual', + verbose: 'Instructor solution manual' + }, + { + field: 'Student solution manual', + verbose: 'Student solution manual' + }, + { + field: 'Kindle', + verbose: 'Kindle' + }, + { + field: 'Study guide in online view', + verbose: 'Study guide in online view' + }, + { + field: 'Assignable', + verbose: 'Assignable' + }, + { + field: 'Other', + verbose: 'Other' + } +]; diff --git a/test/src/pages/errata/errata-form.test.tsx b/test/src/pages/errata/errata-form.test.tsx new file mode 100644 index 000000000..798e441bc --- /dev/null +++ b/test/src/pages/errata/errata-form.test.tsx @@ -0,0 +1,258 @@ +import React from 'react'; +import {render, screen, waitFor} from '@testing-library/preact'; +import userEvent from '@testing-library/user-event'; +import ErrataForm from '~/pages/errata-form/errata-form'; +import * as UC from '~/contexts/user'; +import MemoryRouter from '~/../../test/helpers/future-memory-router'; +import rexReleaseData from '~/../../test/src/data/astronomy-toc.json'; + +const mockUseUserContext = jest.spyOn(UC, 'default'); +const mockRexRelease = jest.fn().mockReturnValue(rexReleaseData); + +jest.mock('~/models/rex-release', () => ({ + __esModule: true, + default: () => mockRexRelease() +})); + +function Component({bookTitle = 'some-title'}) { + return ( + + + + ); +} + +const user = userEvent.setup(); + +jest.setTimeout(12000); + +describe('errata-form', () => { + it('renders; shows other source input when Other source selected', async () => { + mockUseUserContext.mockReturnValue({ + // @ts-expect-error incomplete structure + uuid: 1 + }); + render(); + await waitFor(() => + expect(screen.getAllByRole('radio', {name: 'Other'}).length).toBe(2) + ); + + const r = screen.getAllByRole('radio', {name: 'Other'}); + + expect(r.length).toBe(2); + await user.click(r[0]); + await screen.findByRole('textbox', {name: 'other error type'}); + await user.click(r[1]); + await screen.findByRole('textbox', {name: 'other source'}); + await user.click(screen.getByRole('button', {name: 'Submit'})); + }); + it('tells them to log in if they are not', () => { + // @ts-expect-error incomplete structure + mockUseUserContext.mockReturnValue({}); + render(); + screen.getByText('You need to be logged in to submit errata'); + }); + it('shows title selector if no title comes in', async () => { + mockUseUserContext.mockReturnValue({ + // @ts-expect-error incomplete structure + uuid: 1 + }); + render(); + screen.getByText('What book were you in, again?'); + await user.click(await screen.findByRole('combobox')); + const options = await screen.findAllByRole('option'); + + await user.click(options[0]); + }); + it('handles file uploader', async () => { + // This covers the revision schedule Nov-Feb + jest.useFakeTimers(); + jest.setSystemTime(new Date('2024-01-07')); + render(); + jest.useRealTimers(); + screen.getByText('November'); + screen.getByText('February'); + await user.click( + (await screen.findAllByRole('button', {name: 'Add file'}))[0] + ); + const fileInput = document.querySelector( + 'input[name="file_1"]' + ) as HTMLInputElement; + const mockFile = new File(['mock content'], 'mock-file.txt', { + type: 'text/plain' + }); + + await userEvent.upload(fileInput, mockFile); + await user.click(screen.getByRole('button', {name: 'Clear file'})); + }); + it('handles location parameter and toc selection', async () => { + // This covers the revision schedule Mar-Oct + jest.useFakeTimers(); + jest.setSystemTime(new Date('2024-04-07')); + render(); + jest.useRealTimers(); + screen.getByText('March'); + screen.getByText('October'); + const locationInput = (await screen.findByRole('textbox', { + name: 'Additional location information, if applicable' + })) as HTMLInputElement; + + expect(locationInput.value).toBe('somewhere'); + // exercise syncValue code in ErrorLocationSelector + await user.type(locationInput, ' else'); + screen.getByText('Where in the book did you find the error?'); + // exercise toc-selector + const select = screen.getByRole('listbox'); + const chapter = screen.getByRole('option', { + name: '+ Chapter 2 Observing the Sky: The Birth of Astronomy' + }); + + await user.click(chapter); + expect(chapter.textContent?.substring(0, 1)).toBe('–'); + const selection = screen.getByRole('option', { + name: 'Thinking Ahead' + }); + + await user.selectOptions(select, selection.value); + expect(select.value).toBe(selection.value); + await user.click(screen.getByRole('button', {name: 'Deselect'})); + expect(select.value).toBe(''); + // Deselect is ok when nothing is selected + await user.click(screen.getByRole('button', {name: 'Deselect'})); + await user.click(chapter); + expect(chapter.textContent?.substring(0, 1)).toBe('+'); + }); + it('displays no toc selector when source+location are specified', async () => { + render( + + ); + expect( + ( + (await screen.findByRole('textbox', { + name: 'Additional location information, if applicable' + })) as HTMLInputElement + ).value + ).toBe('somewhere'); + expect( + screen.queryByText('Where in the book did you find the error?') + ).toBeNull(); + }); + it('checks errors and sets submitting (errata-form-context)', async () => { + render( + + ); + await user.click(screen.getByRole('radio', {name: 'Typo'})); + await user.click( + screen.getByRole('radio', { + name: 'Textbook includes print, PDF, and web view' + }) + ); + await userEvent.type( + screen.getByRole('textbox', { + name: 'Tell us in detail about the error and your suggestion.' + }), + 'some text' + ); + + const saveFetch = global.fetch; + + global.fetch = jest.fn().mockRejectedValue('intentional fail'); + await user.click(screen.getByRole('button', {name: 'Submit'})); + expect(global.fetch).toHaveBeenCalled(); + global.fetch = saveFetch; + }); + it('unpacks json from submission response with id', async () => { + render( + + ); + await user.click(screen.getByRole('radio', {name: 'Typo'})); + await user.click( + screen.getByRole('radio', { + name: 'Textbook includes print, PDF, and web view' + }) + ); + await userEvent.type( + screen.getByRole('textbox', { + name: 'Tell us in detail about the error and your suggestion.' + }), + 'some text' + ); + + const saveFetch = global.fetch; + + global.fetch = jest.fn().mockResolvedValue({ + json: () => ({ + id: 1 + }) + }); + await user.click(screen.getByRole('button', {name: 'Submit'})); + expect(global.fetch).toHaveBeenCalled(); + global.fetch = saveFetch; + }); + it('unpacks json from submission response with no id', async () => { + render( + + ); + await user.click(screen.getByRole('radio', {name: 'Typo'})); + await user.click( + screen.getByRole('radio', { + name: 'Textbook includes print, PDF, and web view' + }) + ); + await userEvent.type( + screen.getByRole('textbox', { + name: 'Tell us in detail about the error and your suggestion.' + }), + 'some text' + ); + + const saveFetch = global.fetch; + + global.fetch = jest.fn().mockResolvedValue({ + json: () => ({ + submitted_by_account_id: [2] // eslint-disable-line camelcase + }) + }); + await user.click(screen.getByRole('button', {name: 'Submit'})); + expect(global.fetch).toHaveBeenCalled(); + // The banned dialog displays + screen.getByRole('dialog'); + await user.click(screen.getByRole('button', {name: 'close'})); + global.fetch = saveFetch; + }); + it('unpacks json from submission response with no id or submitted-by id', async () => { + render( + + ); + await user.click(screen.getByRole('radio', {name: 'Typo'})); + await user.click( + screen.getByRole('radio', { + name: 'Textbook includes print, PDF, and web view' + }) + ); + await userEvent.type( + screen.getByRole('textbox', { + name: 'Tell us in detail about the error and your suggestion.' + }), + 'some text' + ); + + const fileInput = document.querySelector( + 'input[name="file_1"]' + ) as HTMLInputElement; + const mockFile = new File(['mock content'], 'mock-file.txt', { + type: 'text/plain' + }); + + await userEvent.upload(fileInput, mockFile); + + const saveFetch = global.fetch; + + global.fetch = jest.fn().mockResolvedValue({ + json: () => ({}) + }); + await user.click(screen.getByRole('button', {name: 'Submit'})); + expect(global.fetch).toHaveBeenCalled(); + global.fetch = saveFetch; + }); +});