diff --git a/asset-manifest.json b/asset-manifest.json index 5bdd0ec..9b5237b 100644 --- a/asset-manifest.json +++ b/asset-manifest.json @@ -1,8 +1,8 @@ { "files": { "main.css": "/free-programming-books-search/static/css/main.be0a7d61.chunk.css", - "main.js": "/free-programming-books-search/static/js/main.c2bca8c9.chunk.js", - "main.js.map": "/free-programming-books-search/static/js/main.c2bca8c9.chunk.js.map", + "main.js": "/free-programming-books-search/static/js/main.9034130b.chunk.js", + "main.js.map": "/free-programming-books-search/static/js/main.9034130b.chunk.js.map", "runtime-main.js": "/free-programming-books-search/static/js/runtime-main.a9bb282d.js", "runtime-main.js.map": "/free-programming-books-search/static/js/runtime-main.a9bb282d.js.map", "static/js/2.0771d3bc.chunk.js": "/free-programming-books-search/static/js/2.0771d3bc.chunk.js", @@ -19,6 +19,6 @@ "static/js/runtime-main.a9bb282d.js", "static/js/2.0771d3bc.chunk.js", "static/css/main.be0a7d61.chunk.css", - "static/js/main.c2bca8c9.chunk.js" + "static/js/main.9034130b.chunk.js" ] } \ No newline at end of file diff --git a/index.html b/index.html index ad57385..1e1756f 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -free-programming-books | Freely available programming books
\ No newline at end of file +free-programming-books | Freely available programming books
\ No newline at end of file diff --git a/static/js/main.9034130b.chunk.js b/static/js/main.9034130b.chunk.js new file mode 100644 index 0000000..2a6517c --- /dev/null +++ b/static/js/main.9034130b.chunk.js @@ -0,0 +1,2 @@ +(this.webpackJsonpfpb_search_page=this.webpackJsonpfpb_search_page||[]).push([[0],{28:function(e,t,r){},49:function(e,t,r){"use strict";r.r(t);var n=r(1),o=r.n(n),c=r(20),a=r.n(c),s=(r(28),r(21)),i=r(5),l=r(4),h=r(2),b=r(11),j=r.n(b),u=r(22),d=r.n(u),m=r(23),g=r(0);var f=function(e){var t,r=e.changeParameter,o=e.data,c=Object(n.useState)([]),a=Object(h.a)(c,2),s=a[0],i=a[1],l=Object(n.useState)(""),b=Object(h.a)(l,2),j=b[0],u=b[1],d=Object(n.useState)(!1),m=Object(h.a)(d,2),f=m[0],O=m[1],p=function(e){r("lang.code",e.target.value),u(e.target.value)};Object(n.useEffect)((function(){if(o){var e=[{code:"en",name:"English"}];o.children[0].children.forEach((function(t){"string"===typeof t.language.name&&t.language.name.length>0&&"en"!==t.language.code&&e.push(t.language)})),e.sort((function(e,t){return e.name>t.name})),i(e)}}),[o]),t=s&&s.map((function(e){return function(e){return Object(g.jsx)("div",{children:Object(g.jsxs)("label",{children:[Object(g.jsx)("input",{type:"radio",className:"lang",value:e.code,onChange:p,checked:e.code==j},e.code),e.name]})})}(e)}));var x=Object(g.jsxs)("form",{className:"filters",children:[Object(g.jsxs)("label",{children:[Object(g.jsx)("input",{type:"radio",className:"sect-select",value:"",onChange:p,checked:""==j},"all"),"All Languages"]}),t]});return Object(g.jsxs)("div",{className:"langFilters",children:[Object(g.jsxs)("div",{className:"filterHeader",children:[Object(g.jsx)("h3",{children:"Filter by Language"}),Object(g.jsx)("button",{onClick:function(){return O(!f)},children:f?"-":"+"})]}),f?x:""]})};var O=function(e){return Object(g.jsx)("form",{onSubmit:function(e){e.preventDefault()},name:"searchBar",className:"searchbar",children:Object(g.jsx)("input",{autoComplete:"off",type:"text",name:"searchTerm",placeholder:"Search Book or Author",className:"searchterm",onChange:function(t){e.changeParameter("searchTerm",t.target.value)}})})};var p=function(e){var t=e.data;return Object(g.jsx)("li",{className:"result",children:Object(g.jsxs)("a",{href:t.url,target:"_blank",rel:"noreferrer",children:["(",t.lang.code,") ",t.title,t.author?" by ".concat(t.author):""]})})};var x=function(){return Object(g.jsxs)("section",{children:[Object(g.jsx)("br",{}),Object(g.jsx)("h1",{id:"list-of-free-learning-resources-in-many-languages",children:"List of Free Learning Resources In Many Languages"}),Object(g.jsx)("div",{align:"center"}),Object(g.jsx)("h2",{id:"intro",children:"Intro"}),Object(g.jsxs)("p",{children:["This list was originally a clone of"," ",Object(g.jsx)("a",{href:"https://web.archive.org/web/20140606191453/http://stackoverflow.com/questions/194812/list-of-freely-available-programming-books/392926",children:"StackOverflow - List of Freely Available Programming Books"})," ","with contributions from Karan Bhangui and George Stocker."]}),Object(g.jsxs)("p",{children:["The list was moved to GitHub by Victor Felder for collaborative updating and maintenance. It has grown to become one of ",Object(g.jsx)("a",{href:"https://octoverse.github.com/",children:"GitHub\u2019s most popular repositories"}),", with 221,000+ stars, 6,900+ commits, 1,900+ contributors, and 47,100+ forks."]}),Object(g.jsxs)("p",{children:["The ",Object(g.jsx)("a",{href:"https://ebookfoundation.org",children:"Free Ebook Foundation"})," now administers the repo, a not-for-profit organization devoted to promoting the creation, distribution, archiving, and sustainability of free ebooks."," ",Object(g.jsx)("a",{href:"https://ebookfoundation.org/contributions.html",children:"Donations"})," to the Free Ebook Foundation are tax-deductible in the US."]}),Object(g.jsx)("h2",{id:"how-to-contribute",children:"How To Contribute"}),Object(g.jsxs)("p",{children:["Please read ",Object(g.jsx)("a",{href:"/free-programming-books/docs/CONTRIBUTING.html",children:"CONTRIBUTING"}),". If you\u2019re new to GitHub,"," ",Object(g.jsx)("a",{href:"/free-programming-books/docs/HOWTO.html",children:"welcome"}),"! Remember to abide by our"," ",Object(g.jsx)("a",{href:"/free-programming-books/docs/CODE_OF_CONDUCT.html",children:"Code of Conduct"})," too. (",Object(g.jsx)("a",{href:"/free-programming-books/docs/#translations",children:"translations"})," also available)"]}),Object(g.jsx)("h2",{id:"how-to-share",children:"How to Share"}),Object(g.jsxs)("ul",{children:[Object(g.jsx)("li",{children:Object(g.jsx)("a",{href:"http://twitter.com/intent/tweet?text=https://github.com/EbookFoundation/free-programming-books%0AFree%20Programming%20Books",children:"Share on Twitter"})}),Object(g.jsx)("li",{children:Object(g.jsx)("a",{href:"https://www.facebook.com/share.php?u=https%3A%2F%2Fgithub.com%2FEbookFoundation%2Ffree-programming-books&p%5Bimages%5D%5B0%5D=&p%5Btitle%5D=Free%20Programming%20Books&p%5Bsummary%5D=",children:"Share on Facebook"})}),Object(g.jsx)("li",{children:Object(g.jsx)("a",{href:"http://www.linkedin.com/shareArticle?mini=true&url=https://github.com/EbookFoundation/free-programming-books&title=Free%20Programming%20Books&summary=&source=",children:"Share on LinkedIn"})}),Object(g.jsx)("li",{children:Object(g.jsx)("a",{href:"https://t.me/share/url?url=https://github.com/EbookFoundation/free-programming-books",children:"Share on Telegram"})})]}),Object(g.jsx)("h2",{id:"translations",children:"Translations"}),Object(g.jsx)("p",{children:"Volunteers have translated many of our Contributing, How-to, and Code of Conduct documents into languages covered by our lists."}),Object(g.jsxs)("ul",{children:[Object(g.jsxs)("li",{children:["English",Object(g.jsxs)("ul",{children:[Object(g.jsx)("li",{children:Object(g.jsx)("a",{href:"/free-programming-books/docs/CODE_OF_CONDUCT.html",children:"Code of Conduct"})}),Object(g.jsx)("li",{children:Object(g.jsx)("a",{href:"/free-programming-books/docs/CONTRIBUTING.html",children:"Contributing"})}),Object(g.jsx)("li",{children:Object(g.jsx)("a",{href:"/free-programming-books/docs/HOWTO.html",children:"How-to"})})]})]}),Object(g.jsxs)("li",{children:["\u2026"," ",Object(g.jsx)("em",{children:Object(g.jsx)("a",{href:"/free-programming-books/docs/#translations",children:"More languages"})})," ","\u2026"]})]}),Object(g.jsxs)("p",{children:["You might notice that there are"," ",Object(g.jsx)("a",{href:"/free-programming-books/docs/#translations",children:"some missing translations here"})," - perhaps you would like to help out by"," ",Object(g.jsx)("a",{href:"/free-programming-books/docs/CONTRIBUTING.html#help-out-by-contributing-a-translation",children:"contributing a translation"}),"?"]}),Object(g.jsx)("h2",{id:"license",children:"License"}),Object(g.jsxs)("p",{children:["Each file included in this repository is licensed under the"," ",Object(g.jsx)("a",{href:"/free-programming-books/LICENSE",children:"CC BY License"}),"."]})]})},k=(r.p,r.p,null);function v(e){var t=[],r=[];return e.children[0].children.forEach((function(e){e.sections.forEach((function(n){r.includes(n.section)||r.push(n.section),n.entries.forEach((function(r){t.push({author:r.author,title:r.title,url:r.url,lang:e.language,section:n.section})})),n.subsections.forEach((function(r){r.entries.forEach((function(o){t.push({author:o.author,title:o.title,url:o.url,lang:e.language,section:n.section,subsection:r.section})}))}))}))})),{arr:t,sections:r}}var w=function(){var e=Object(n.useState)(void 0),t=Object(h.a)(e,2),r=t[0],o=t[1],c=Object(n.useState)([]),a=Object(h.a)(c,2),b=a[0],u=a[1],w=Object(n.useState)([]),F=Object(h.a)(w,2),E=(F[0],F[1]),C=Object(n.useState)(!0),y=Object(h.a)(C,2),S=y[0],T=y[1],N=Object(n.useState)({searchTerm:""}),B=Object(h.a)(N,2),I=B[0],L=B[1],H=Object(n.useState)([]),_=Object(h.a)(H,2),P=_[0],D=_[1],A=Object(n.useState)([]),G=Object(h.a)(A,2),R=(G[0],G[1],Object(n.useState)(!0)),U=Object(h.a)(R,2),M=(U[0],U[1],Object(n.useState)("")),V=Object(h.a)(M,2),J=V[0],W=(V[1],null),Y=function(e,t){L(Object(l.a)(Object(l.a)({},I),{},Object(i.a)({},e,t)))};return Object(n.useEffect)((function(){function e(){return(e=Object(s.a)(j.a.mark((function e(){var t,r,n,c,a,s,i;return j.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,T(!0),e.next=4,d.a.get("https://raw.githubusercontent.com/FreeEbookFoundationBot/free-programming-books-json/main/fpb.json");case 4:t=e.sent,o(t.data),r=v(t.data),n=r.arr,c=r.sections,u(n),E(c),e.next=17;break;case 11:e.prev=11,e.t0=e.catch(0),o(k),a=v(k),s=a.arr,i=a.sections,E(i),u(s);case 17:T(!1);case 18:case"end":return e.stop()}}),e,null,[[0,11]])})))).apply(this,arguments)}!function(){e.apply(this,arguments)}()}),[]),Object(n.useEffect)((function(){if(b){for(var e=new m.a(b,{useExtendedSearch:!0,findAllMatches:!0,shouldSort:!0,includeScore:!0,threshold:.2,keys:["author","title","lang.code","section"]}),t=[],r=[],n=0,o=Object.entries(I);n {\r\n changeParameter(\"lang.code\", e.target.value);\r\n setSelected(e.target.value);\r\n };\r\n\r\n useEffect(\r\n // run whenever data changes\r\n () => {\r\n if (data) {\r\n let langArray = [{ code: \"en\", name: \"English\" }];\r\n data.children[0].children.forEach((document) => {\r\n if (typeof document.language.name === \"string\" && document.language.name.length > 0) {\r\n //make sure the language is valid and not blank\r\n //console.log(\"LANGUAGE: \" + document.language.name)\r\n if (document.language.code !== \"en\") {\r\n // used to ensure only one English is listed\r\n langArray.push(document.language);\r\n }\r\n }\r\n });\r\n langArray.sort((a, b) => a.name > b.name);\r\n setLanguages(langArray);\r\n }\r\n },\r\n [data]\r\n );\r\n\r\n const createOption = (language) => {\r\n return (\r\n
\r\n \r\n
\r\n );\r\n };\r\n\r\n options =\r\n languages &&\r\n languages.map((language) => {\r\n return createOption(language);\r\n });\r\n\r\n let filterList = (\r\n
\r\n \r\n {options}\r\n
\r\n );\r\n\r\n return (\r\n
\r\n
\r\n

Filter by Language

\r\n \r\n
\r\n {showFilters ? filterList : \"\"}\r\n
\r\n );\r\n}\r\n\r\nexport default LangFilters;\r\n","import React from \"react\";\r\n\r\nfunction SearchBar(props) {\r\n const handleChange = (e) => {\r\n props.changeParameter(\"searchTerm\", e.target.value);\r\n };\r\n\r\n return (\r\n {\r\n e.preventDefault();\r\n }}\r\n name=\"searchBar\"\r\n className=\"searchbar\"\r\n >\r\n \r\n \r\n );\r\n}\r\n\r\nexport default SearchBar;\r\n","import React from \"react\";\r\n\r\nfunction SearchResult({ data }) {\r\n return (\r\n
  • \r\n \r\n ({data.lang.code}) {data.title}{data.author ? ` by ${data.author}` : \"\"}\r\n \r\n
  • \r\n );\r\n}\r\n\r\nexport default SearchResult;\r\n","import React from \"react\";\r\n\r\nfunction Default() {\r\n return (\r\n
    \r\n
    \r\n\r\n

    List of Free Learning Resources In Many Languages

    \r\n\r\n
    \r\n {/*

    \"Awesome\" */}\r\n {/* \"License:

    */}\r\n
    \r\n\r\n

    Intro

    \r\n\r\n

    \r\n This list was originally a clone of{\" \"}\r\n \r\n StackOverflow - List of Freely Available Programming Books\r\n {\" \"}\r\n with contributions from Karan Bhangui and George Stocker.\r\n

    \r\n\r\n

    \r\n The list was moved to GitHub by Victor Felder for collaborative updating and maintenance. It has grown to become\r\n one of GitHub’s most popular repositories, with 221,000+ stars,\r\n 6,900+ commits, 1,900+ contributors, and 47,100+ forks.\r\n

    \r\n\r\n

    \r\n The Free Ebook Foundation now administers the repo, a not-for-profit\r\n organization devoted to promoting the creation, distribution, archiving, and sustainability of free ebooks.{\" \"}\r\n Donations to the Free Ebook Foundation are\r\n tax-deductible in the US.\r\n

    \r\n\r\n

    How To Contribute

    \r\n\r\n

    \r\n Please read CONTRIBUTING. If you’re new to GitHub,{\" \"}\r\n welcome! Remember to abide by our{\" \"}\r\n Code of Conduct too. (\r\n translations also available)\r\n

    \r\n\r\n

    How to Share

    \r\n\r\n \r\n\r\n

    Translations

    \r\n\r\n

    \r\n Volunteers have translated many of our Contributing, How-to, and Code of Conduct documents into languages\r\n covered by our lists.\r\n

    \r\n\r\n \r\n\r\n

    \r\n You might notice that there are{\" \"}\r\n some missing translations here - perhaps you would like\r\n to help out by{\" \"}\r\n \r\n contributing a translation\r\n \r\n ?\r\n

    \r\n\r\n

    License

    \r\n\r\n

    \r\n Each file included in this repository is licensed under the{\" \"}\r\n CC BY License.\r\n

    \r\n
    \r\n );\r\n}\r\n\r\nexport default Default;\r\n","import React, { useState, useEffect } from \"react\";\r\nimport axios from \"axios\";\r\nimport Fuse from \"fuse.js\";\r\n\r\nimport LangFilters from \"./components/LangFilters\";\r\nimport SectDropdown from \"./components/SectDropdown\";\r\nimport SearchBar from \"./components/SearchBar\";\r\nimport SearchResult from \"./components/SearchResult\";\r\nimport LightSwitch from \"./components/LightSwitch\";\r\nimport Default from \"./components/Default\";\r\n\r\nimport SunImg from \"./img/sun.png\";\r\nimport MoonImg from \"./img/moon.png\";\r\n\r\nconst fpb = null;\r\n\r\n// eslint-disable-next-line\r\nfunction makeBook(author, hLang, cLang, title, url) {\r\n //returns a struct with basic book info (author, human language, computer language, book title, url)\r\n return {\r\n author: author,\r\n hLang: hLang, //human language\r\n cLang: cLang, //computer language\r\n title: title,\r\n url: url,\r\n };\r\n}\r\n\r\n// eslint-disable-next-line\r\nfunction forEachBook(func, json) {\r\n //Runs func on each section, entry, and book in json, which is a list of entries\r\n if (typeof func !== \"function\") {\r\n // eslint-disable-next-line\r\n throw \"ERROR in forEachBook: parameter not a fucntion\";\r\n }\r\n\r\n for (const hLang in json) {\r\n //for each human language\r\n if (Array.isArray(hLang.sections)) {\r\n //check if sections is an array\r\n hLang.sections.forEach(\r\n (\r\n cLang //for each computer lanuage\r\n ) => {\r\n if (Array.isArray(cLang.entries)) {\r\n //verify is entries is an array\r\n cLang.entries.forEach(\r\n (\r\n book //for each book\r\n ) => {\r\n if (typeof book === \"object\") {\r\n //verify that book is an object\r\n func(json[hLang], cLang, book); //run the function\r\n }\r\n }\r\n );\r\n }\r\n }\r\n );\r\n }\r\n }\r\n}\r\n\r\n// Sorts search results by their score\r\n// eslint-disable-next-line\r\nfunction sortByScore(results) {\r\n results.sort(function (a, b) {\r\n return a.score - b.score;\r\n });\r\n return results;\r\n}\r\n\r\nfunction jsonToArray(json) {\r\n let arr = [];\r\n let sections = [];\r\n json.children[0].children.forEach((document) => {\r\n document.sections.forEach((section) => {\r\n if (!sections.includes(section.section)) sections.push(section.section);\r\n section.entries.forEach((entry) => {\r\n arr.push({\r\n author: entry.author,\r\n title: entry.title,\r\n url: entry.url,\r\n lang: document.language,\r\n section: section.section,\r\n });\r\n });\r\n section.subsections.forEach((subsection) => {\r\n subsection.entries.forEach((entry) => {\r\n arr.push({\r\n author: entry.author,\r\n title: entry.title,\r\n url: entry.url,\r\n lang: document.language,\r\n section: section.section,\r\n subsection: subsection.section,\r\n });\r\n });\r\n });\r\n });\r\n });\r\n return { arr: arr, sections: sections };\r\n}\r\n\r\nfunction App() {\r\n const [data, setData] = useState(undefined); // keeps the state of the json\r\n const [dataArray, setDataArray] = useState([]); // put everything into one array. uses more memory, but search is faster and less complex\r\n // eslint-disable-next-line\r\n const [index, setIndex] = useState([]); // used for \"table of contents\". currently unused\r\n const [loading, setLoading] = useState(true); // Determines whether to show spinner\r\n const [searchParams, setSearchParams] = useState({ searchTerm: \"\" });\r\n const [searchResults, setSearchResults] = useState([]);\r\n const [sectionResults, setSectionResults] = useState([]);\r\n const [lightMode, setLightMode] = useState(true);\r\n\r\n // eslint-disable-next-line\r\n const [error, setError] = useState(\"\");\r\n\r\n let resultsList = null; // the html string containing the search results\r\n let sectionResultsList = null;\r\n\r\n const changeParameter = (param, value) => {\r\n // Lets a child component set the value of the search term\r\n setSearchParams({ ...searchParams, [param]: value });\r\n };\r\n\r\n // fetches data the first time the page renders\r\n useEffect(() => {\r\n async function fetchData() {\r\n try {\r\n setLoading(true);\r\n let result = await axios.get(\r\n \"https://raw.githubusercontent.com/FreeEbookFoundationBot/free-programming-books-json/main/fpb.json\"\r\n );\r\n setData(result.data);\r\n let { arr, sections } = jsonToArray(result.data);\r\n setDataArray(arr);\r\n setIndex(sections);\r\n } catch (e) {\r\n // setError(\"Couldn't get data. Please try again later\")\r\n setData(fpb);\r\n let { arr, sections } = jsonToArray(fpb);\r\n setIndex(sections);\r\n setDataArray(arr);\r\n }\r\n setLoading(false);\r\n }\r\n fetchData();\r\n }, []);\r\n\r\n // fires when searchTerm changes\r\n // Finds most relevant title or author\r\n // THIS IS THE MAIN SEARCH FUNCTION\r\n useEffect(() => {\r\n if (dataArray) {\r\n const fuseOptions = {\r\n useExtendedSearch: true, // see fuse.js documentation\r\n findAllMatches: true, //continue searching after first match\r\n shouldSort: true, // sort by proximity score\r\n includeScore: true, // includes score in results\r\n threshold: 0.2, // threshold for fuzzy-search,\r\n keys: [\"author\", \"title\", \"lang.code\", \"section\"],\r\n };\r\n\r\n // create new fuse given the array of books and the fuse options from above\r\n let fuse = new Fuse(dataArray, fuseOptions);\r\n let andQuery = []; // for filters that MUST be matched, like language\r\n let orQuery = []; // filters where any may be matched, like author or title\r\n\r\n // for each search param\r\n for (const [key, value] of Object.entries(searchParams)) {\r\n if (value === null || value === \"\") continue;\r\n if (key === \"lang.code\" || key === \"section\") {\r\n // the '^' means it must be an exact match at the beginning\r\n // this is because lang.code and section are strict filters \r\n andQuery.push({ [key]: `^${value}` });\r\n }\r\n if(key === \"searchTerm\") {\r\n orQuery.push({ \"author\": value});\r\n orQuery.push({ \"title\": value});\r\n }\r\n }\r\n // Nest the 'or' query inside the 'and' query\r\n // Necessary step, a quirk with fuse.js\r\n andQuery.push({$or: orQuery})\r\n // Perform the search\r\n let result = fuse.search({\r\n $and: andQuery,\r\n });\r\n // filter to top results\r\n result = result.slice(0, 40);\r\n\r\n // Goes through the list of results\r\n let relevantLists = [];\r\n result.forEach((entry) => {\r\n // Checks if a new entry has already been made with the given programming language and human language.\r\n let obj = relevantLists.find(\r\n (o) => o.item.section === entry.item.section && o.item.lang.code === entry.item.lang.code\r\n );\r\n if (!obj && entry.item.lang.code) {\r\n let langCode = entry.item.lang.code;\r\n let section = entry.item.subsection ? entry.item.subsection : entry.item.section;\r\n // English is split into the subjects and langs file. The parser flags which type of entry it is to use here\r\n if (langCode === \"en\") {\r\n if (entry.item.lang.isSubject) {\r\n langCode = \"subjects\";\r\n } else {\r\n langCode = \"langs\";\r\n }\r\n }\r\n\r\n let id = section;\r\n \r\n // Some ids are in HTML tags, so this will extract that id to form proper links\r\n if (id.includes(\" {\r\n // let section = entry.item.section;\r\n // if (!sResults.includes(section)) sResults.push(section);\r\n // });\r\n // setSectionResults(sResults);\r\n }\r\n }, [searchParams, dataArray]);\r\n\r\n if (loading) {\r\n // if still fetching resource\r\n return

    Loading...

    ;\r\n }\r\n if (error) {\r\n return

    Error: {error}

    ;\r\n }\r\n if (searchParams.searchTerm && searchResults.length !== 0) {\r\n resultsList =\r\n searchResults &&\r\n searchResults.map((entry) => {\r\n return ;\r\n });\r\n // Getting rid of the section results UI renders this irrelevant\r\n // sectionResultsList =\r\n // sectionResults &&\r\n // sectionResults.map((section) => {\r\n // return (\r\n // {\r\n // changeParameter(\"section\", section);\r\n // }}\r\n // >\r\n // {section}\r\n // \r\n // );\r\n // });\r\n }\r\n return (\r\n
    \r\n
    \r\n

    \r\n \r\n free-programming-books\r\n \r\n

    \r\n\r\n

    \r\n {\" \"}\r\n Freely available programming books\r\n

    \r\n\r\n

    \r\n \r\n View the Project on GitHub EbookFoundation/free-programming-books\r\n \r\n

    \r\n

    \r\n Does a link not work?\r\n
    \r\n \r\n Report an error on GitHub\r\n \r\n

    \r\n\r\n
    \r\n \r\n {/* Filters */}\r\n \r\n {/* Keeping sections commented out just in case */}\r\n {/* */}\r\n {/* {sectionResultsList &&

    Suggestions based on your search

    }\r\n
    {sectionResultsList}
    */}\r\n
    \r\n
    \r\n\r\n
    \r\n {resultsList ? (\r\n
    \r\n
    \r\n

    Search Results

    \r\n
      {resultsList}
    \r\n
    \r\n ) : searchParams.searchTerm ? (\r\n
    \r\n
    \r\n

    No results found.

    \r\n
    \r\n ) : (\r\n \r\n )}\r\n
    \r\n\r\n \r\n
    \r\n );\r\n}\r\n\r\nexport default App;\r\n","export default __webpack_public_path__ + \"static/media/sun.d499a97b.png\";","export default __webpack_public_path__ + \"static/media/moon.6ad80c47.png\";","const reportWebVitals = onPerfEntry => {\r\n if (onPerfEntry && onPerfEntry instanceof Function) {\r\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\r\n getCLS(onPerfEntry);\r\n getFID(onPerfEntry);\r\n getFCP(onPerfEntry);\r\n getLCP(onPerfEntry);\r\n getTTFB(onPerfEntry);\r\n });\r\n }\r\n};\r\n\r\nexport default reportWebVitals;\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './App.css';\r\nimport App from './App';\r\nimport reportWebVitals from './reportWebVitals';\r\n\r\nReactDOM.render(\r\n \r\n \r\n ,\r\n document.getElementById('root')\r\n);\r\n\r\n// If you want to start measuring performance in your app, pass a function\r\n// to log results (for example: reportWebVitals(console.log))\r\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\r\nreportWebVitals();\r\n"],"sourceRoot":""} \ No newline at end of file diff --git a/static/js/main.c2bca8c9.chunk.js b/static/js/main.c2bca8c9.chunk.js deleted file mode 100644 index 16e3bcf..0000000 --- a/static/js/main.c2bca8c9.chunk.js +++ /dev/null @@ -1,2 +0,0 @@ -(this.webpackJsonpfpb_search_page=this.webpackJsonpfpb_search_page||[]).push([[0],{28:function(e,t,r){},49:function(e,t,r){"use strict";r.r(t);var n=r(1),o=r.n(n),c=r(20),a=r.n(c),s=(r(28),r(21)),i=r(5),l=r(4),h=r(2),b=r(11),j=r.n(b),u=r(22),d=r.n(u),g=r(23),m=r(0);var f=function(e){var t,r=e.changeParameter,o=e.data,c=Object(n.useState)([]),a=Object(h.a)(c,2),s=a[0],i=a[1],l=Object(n.useState)(""),b=Object(h.a)(l,2),j=b[0],u=b[1],d=Object(n.useState)(!1),g=Object(h.a)(d,2),f=g[0],O=g[1],p=function(e){r("lang.code",e.target.value),u(e.target.value)};Object(n.useEffect)((function(){if(o){var e=[{code:"en",name:"English"}];o.children[0].children.forEach((function(t){"string"===typeof t.language.name&&t.language.name.length>0&&"en"!==t.language.code&&e.push(t.language)})),e.sort((function(e,t){return e.name>t.name})),i(e)}}),[o]),t=s&&s.map((function(e){return function(e){return Object(m.jsx)("div",{children:Object(m.jsxs)("label",{children:[Object(m.jsx)("input",{type:"radio",className:"lang",value:e.code,onChange:p,checked:e.code==j},e.code),e.name]})})}(e)}));var x=Object(m.jsxs)("form",{class:"filters",children:[Object(m.jsxs)("label",{children:[Object(m.jsx)("input",{type:"radio",className:"sect-select",value:"",onChange:p,checked:""==j}),"All Languages"]}),t]});return Object(m.jsxs)("div",{className:"langFilters",children:[Object(m.jsxs)("div",{className:"filterHeader",children:[Object(m.jsx)("h3",{children:"Filter by Language"}),Object(m.jsx)("button",{onClick:function(){return O(!f)},children:f?"-":"+"})]}),f?x:""]})};var O=function(e){return Object(m.jsx)("form",{onSubmit:function(e){e.preventDefault()},name:"searchBar",className:"searchbar",children:Object(m.jsx)("input",{autoComplete:"off",type:"text",name:"searchTerm",placeholder:"Search Book or Author",className:"searchterm",onChange:function(t){e.changeParameter("title",t.target.value)}})})};var p=function(e){var t=e.data;return Object(m.jsx)("li",{class:"result",children:Object(m.jsxs)("a",{href:t.url,target:"_blank",rel:"noreferrer",children:["(",t.lang.code,") ",t.title,t.author?" by ".concat(t.author):""]})})};var x=function(){return Object(m.jsxs)("section",{children:[Object(m.jsx)("br",{}),Object(m.jsx)("h1",{id:"list-of-free-learning-resources-in-many-languages",children:"List of Free Learning Resources In Many Languages"}),Object(m.jsx)("div",{align:"center"}),Object(m.jsx)("h2",{id:"intro",children:"Intro"}),Object(m.jsxs)("p",{children:["This list was originally a clone of"," ",Object(m.jsx)("a",{href:"https://web.archive.org/web/20140606191453/http://stackoverflow.com/questions/194812/list-of-freely-available-programming-books/392926",children:"StackOverflow - List of Freely Available Programming Books"})," ","with contributions from Karan Bhangui and George Stocker."]}),Object(m.jsxs)("p",{children:["The list was moved to GitHub by Victor Felder for collaborative updating and maintenance. It has grown to become one of ",Object(m.jsx)("a",{href:"https://octoverse.github.com/",children:"GitHub\u2019s most popular repositories"}),", with 221,000+ stars, 6,900+ commits, 1,900+ contributors, and 47,100+ forks."]}),Object(m.jsxs)("p",{children:["The ",Object(m.jsx)("a",{href:"https://ebookfoundation.org",children:"Free Ebook Foundation"})," now administers the repo, a not-for-profit organization devoted to promoting the creation, distribution, archiving, and sustainability of free ebooks."," ",Object(m.jsx)("a",{href:"https://ebookfoundation.org/contributions.html",children:"Donations"})," to the Free Ebook Foundation are tax-deductible in the US."]}),Object(m.jsx)("h2",{id:"how-to-contribute",children:"How To Contribute"}),Object(m.jsxs)("p",{children:["Please read ",Object(m.jsx)("a",{href:"/free-programming-books/docs/CONTRIBUTING.html",children:"CONTRIBUTING"}),". If you\u2019re new to GitHub,"," ",Object(m.jsx)("a",{href:"/free-programming-books/docs/HOWTO.html",children:"welcome"}),"! Remember to abide by our"," ",Object(m.jsx)("a",{href:"/free-programming-books/docs/CODE_OF_CONDUCT.html",children:"Code of Conduct"})," too. (",Object(m.jsx)("a",{href:"/free-programming-books/docs/#translations",children:"translations"})," also available)"]}),Object(m.jsx)("h2",{id:"how-to-share",children:"How to Share"}),Object(m.jsxs)("ul",{children:[Object(m.jsx)("li",{children:Object(m.jsx)("a",{href:"http://twitter.com/intent/tweet?text=https://github.com/EbookFoundation/free-programming-books%0AFree%20Programming%20Books",children:"Share on Twitter"})}),Object(m.jsx)("li",{children:Object(m.jsx)("a",{href:"https://www.facebook.com/share.php?u=https%3A%2F%2Fgithub.com%2FEbookFoundation%2Ffree-programming-books&p%5Bimages%5D%5B0%5D=&p%5Btitle%5D=Free%20Programming%20Books&p%5Bsummary%5D=",children:"Share on Facebook"})}),Object(m.jsx)("li",{children:Object(m.jsx)("a",{href:"http://www.linkedin.com/shareArticle?mini=true&url=https://github.com/EbookFoundation/free-programming-books&title=Free%20Programming%20Books&summary=&source=",children:"Share on LinkedIn"})}),Object(m.jsx)("li",{children:Object(m.jsx)("a",{href:"https://t.me/share/url?url=https://github.com/EbookFoundation/free-programming-books",children:"Share on Telegram"})})]}),Object(m.jsx)("h2",{id:"translations",children:"Translations"}),Object(m.jsx)("p",{children:"Volunteers have translated many of our Contributing, How-to, and Code of Conduct documents into languages covered by our lists."}),Object(m.jsxs)("ul",{children:[Object(m.jsxs)("li",{children:["English",Object(m.jsxs)("ul",{children:[Object(m.jsx)("li",{children:Object(m.jsx)("a",{href:"/free-programming-books/docs/CODE_OF_CONDUCT.html",children:"Code of Conduct"})}),Object(m.jsx)("li",{children:Object(m.jsx)("a",{href:"/free-programming-books/docs/CONTRIBUTING.html",children:"Contributing"})}),Object(m.jsx)("li",{children:Object(m.jsx)("a",{href:"/free-programming-books/docs/HOWTO.html",children:"How-to"})})]})]}),Object(m.jsxs)("li",{children:["\u2026"," ",Object(m.jsx)("em",{children:Object(m.jsx)("a",{href:"/free-programming-books/docs/#translations",children:"More languages"})})," ","\u2026"]})]}),Object(m.jsxs)("p",{children:["You might notice that there are"," ",Object(m.jsx)("a",{href:"/free-programming-books/docs/#translations",children:"some missing translations here"})," - perhaps you would like to help out by"," ",Object(m.jsx)("a",{href:"/free-programming-books/docs/CONTRIBUTING.html#help-out-by-contributing-a-translation",children:"contributing a translation"}),"?"]}),Object(m.jsx)("h2",{id:"license",children:"License"}),Object(m.jsxs)("p",{children:["Each file included in this repository is licensed under the"," ",Object(m.jsx)("a",{href:"/free-programming-books/LICENSE",children:"CC BY License"}),"."]})]})},k=(r.p,r.p,null);function v(e){var t=[],r=[];return e.children[0].children.forEach((function(e){e.sections.forEach((function(n){r.includes(n.section)||r.push(n.section),n.entries.forEach((function(r){t.push({author:r.author,title:r.title,url:r.url,lang:e.language,section:n.section})})),n.subsections.forEach((function(r){r.entries.forEach((function(o){t.push({author:o.author,title:o.title,url:o.url,lang:e.language,section:n.section,subsection:r.section})}))}))}))})),{arr:t,sections:r}}var w=function(){var e=Object(n.useState)(void 0),t=Object(h.a)(e,2),r=t[0],o=t[1],c=Object(n.useState)([]),a=Object(h.a)(c,2),b=a[0],u=a[1],w=Object(n.useState)([]),F=Object(h.a)(w,2),E=(F[0],F[1]),C=Object(n.useState)(!0),y=Object(h.a)(C,2),S=y[0],T=y[1],N=Object(n.useState)({title:""}),B=Object(h.a)(N,2),I=B[0],L=B[1],H=Object(n.useState)([]),_=Object(h.a)(H,2),P=_[0],D=_[1],A=Object(n.useState)([]),G=Object(h.a)(A,2),R=(G[0],G[1],Object(n.useState)(!0)),U=Object(h.a)(R,2),M=(U[0],U[1],Object(n.useState)("")),V=Object(h.a)(M,2),J=V[0],W=(V[1],null),Y=function(e,t){L(Object(l.a)(Object(l.a)({},I),{},Object(i.a)({},e,t)))};return Object(n.useEffect)((function(){function e(){return(e=Object(s.a)(j.a.mark((function e(){var t,r,n,c,a,s,i;return j.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,T(!0),e.next=4,d.a.get("https://raw.githubusercontent.com/FreeEbookFoundationBot/free-programming-books-json/main/fpb.json");case 4:t=e.sent,o(t.data),r=v(t.data),n=r.arr,c=r.sections,console.log(n),u(n),E(c),e.next=18;break;case 12:e.prev=12,e.t0=e.catch(0),o(k),a=v(k),s=a.arr,i=a.sections,E(i),u(s);case 18:T(!1);case 19:case"end":return e.stop()}}),e,null,[[0,12]])})))).apply(this,arguments)}!function(){e.apply(this,arguments)}()}),[]),Object(n.useEffect)((function(){if(b){for(var e=new g.a(b,{useExtendedSearch:!0,findAllMatches:!0,shouldSort:!0,includeScore:!0,threshold:.2,keys:["title","lang.code","section"]}),t=[],r=0,n=Object.entries(I);r {\r\n changeParameter(\"lang.code\", e.target.value);\r\n setSelected(e.target.value);\r\n };\r\n\r\n useEffect(\r\n // run whenever data changes\r\n () => {\r\n if (data) {\r\n let langArray = [{ code: \"en\", name: \"English\" }];\r\n data.children[0].children.forEach((document) => {\r\n if (typeof document.language.name === \"string\" && document.language.name.length > 0) {\r\n //make sure the language is valid and not blank\r\n //console.log(\"LANGUAGE: \" + document.language.name)\r\n if (document.language.code !== \"en\") {\r\n // used to ensure only one English is listed\r\n langArray.push(document.language);\r\n }\r\n }\r\n });\r\n langArray.sort((a, b) => a.name > b.name);\r\n setLanguages(langArray);\r\n }\r\n },\r\n [data]\r\n );\r\n\r\n const createOption = (language) => {\r\n return (\r\n
    \r\n \r\n
    \r\n );\r\n };\r\n\r\n options =\r\n languages &&\r\n languages.map((language) => {\r\n return createOption(language);\r\n });\r\n\r\n let filterList = (\r\n
    \r\n \r\n {options}\r\n
    \r\n );\r\n\r\n return (\r\n
    \r\n
    \r\n

    Filter by Language

    \r\n \r\n
    \r\n {showFilters ? filterList : \"\"}\r\n
    \r\n );\r\n}\r\n\r\nexport default LangFilters;\r\n","import React from \"react\";\r\n\r\nfunction SearchBar(props) {\r\n const handleChange = (e) => {\r\n props.changeParameter(\"title\", e.target.value);\r\n };\r\n\r\n return (\r\n {\r\n e.preventDefault();\r\n }}\r\n name=\"searchBar\"\r\n className=\"searchbar\"\r\n >\r\n \r\n \r\n );\r\n}\r\n\r\nexport default SearchBar;\r\n","import React from \"react\";\r\n\r\nfunction SearchResult({ data }) {\r\n return (\r\n
  • \r\n \r\n ({data.lang.code}) {data.title}{data.author ? ` by ${data.author}` : \"\"}\r\n \r\n
  • \r\n );\r\n}\r\n\r\nexport default SearchResult;\r\n","import React from \"react\";\r\n\r\nfunction Default() {\r\n return (\r\n
    \r\n
    \r\n\r\n

    List of Free Learning Resources In Many Languages

    \r\n\r\n
    \r\n {/*

    \"Awesome\" */}\r\n {/* \"License:

    */}\r\n
    \r\n\r\n

    Intro

    \r\n\r\n

    \r\n This list was originally a clone of{\" \"}\r\n \r\n StackOverflow - List of Freely Available Programming Books\r\n {\" \"}\r\n with contributions from Karan Bhangui and George Stocker.\r\n

    \r\n\r\n

    \r\n The list was moved to GitHub by Victor Felder for collaborative updating and maintenance. It has grown to become\r\n one of GitHub’s most popular repositories, with 221,000+ stars,\r\n 6,900+ commits, 1,900+ contributors, and 47,100+ forks.\r\n

    \r\n\r\n

    \r\n The Free Ebook Foundation now administers the repo, a not-for-profit\r\n organization devoted to promoting the creation, distribution, archiving, and sustainability of free ebooks.{\" \"}\r\n Donations to the Free Ebook Foundation are\r\n tax-deductible in the US.\r\n

    \r\n\r\n

    How To Contribute

    \r\n\r\n

    \r\n Please read CONTRIBUTING. If you’re new to GitHub,{\" \"}\r\n welcome! Remember to abide by our{\" \"}\r\n Code of Conduct too. (\r\n translations also available)\r\n

    \r\n\r\n

    How to Share

    \r\n\r\n \r\n\r\n

    Translations

    \r\n\r\n

    \r\n Volunteers have translated many of our Contributing, How-to, and Code of Conduct documents into languages\r\n covered by our lists.\r\n

    \r\n\r\n \r\n\r\n

    \r\n You might notice that there are{\" \"}\r\n some missing translations here - perhaps you would like\r\n to help out by{\" \"}\r\n \r\n contributing a translation\r\n \r\n ?\r\n

    \r\n\r\n

    License

    \r\n\r\n

    \r\n Each file included in this repository is licensed under the{\" \"}\r\n CC BY License.\r\n

    \r\n
    \r\n );\r\n}\r\n\r\nexport default Default;\r\n","import React, { useState, useEffect } from \"react\";\r\nimport axios from \"axios\";\r\nimport Fuse from \"fuse.js\";\r\n\r\nimport LangFilters from \"./components/LangFilters\";\r\nimport SectDropdown from \"./components/SectDropdown\";\r\nimport SearchBar from \"./components/SearchBar\";\r\nimport SearchResult from \"./components/SearchResult\";\r\nimport LightSwitch from \"./components/LightSwitch\";\r\nimport Default from \"./components/Default\";\r\n\r\nimport SunImg from \"./img/sun.png\";\r\nimport MoonImg from \"./img/moon.png\";\r\n\r\nconst fpb = null;\r\n\r\n// eslint-disable-next-line\r\nfunction makeBook(author, hLang, cLang, title, url) {\r\n //returns a struct with basic book info (author, human language, computer language, book title, url)\r\n return {\r\n author: author,\r\n hLang: hLang, //human language\r\n cLang: cLang, //computer language\r\n title: title,\r\n url: url,\r\n };\r\n}\r\n\r\n// eslint-disable-next-line\r\nfunction forEachBook(func, json) {\r\n //Runs func on each section, entry, and book in json, which is a list of entries\r\n if (typeof func !== \"function\") {\r\n // eslint-disable-next-line\r\n throw \"ERROR in forEachBook: parameter not a fucntion\";\r\n }\r\n\r\n for (const hLang in json) {\r\n //for each human language\r\n if (Array.isArray(hLang.sections)) {\r\n //check if sections is an array\r\n hLang.sections.forEach(\r\n (\r\n cLang //for each computer lanuage\r\n ) => {\r\n if (Array.isArray(cLang.entries)) {\r\n //verify is entries is an array\r\n cLang.entries.forEach(\r\n (\r\n book //for each book\r\n ) => {\r\n if (typeof book === \"object\") {\r\n //verify that book is an object\r\n func(json[hLang], cLang, book); //run the function\r\n }\r\n }\r\n );\r\n }\r\n }\r\n );\r\n }\r\n }\r\n}\r\n\r\n// Sorts search results by their score\r\n// eslint-disable-next-line\r\nfunction sortByScore(results) {\r\n results.sort(function (a, b) {\r\n return a.score - b.score;\r\n });\r\n return results;\r\n}\r\n\r\nfunction jsonToArray(json) {\r\n let arr = [];\r\n let sections = [];\r\n json.children[0].children.forEach((document) => {\r\n document.sections.forEach((section) => {\r\n if (!sections.includes(section.section)) sections.push(section.section);\r\n section.entries.forEach((entry) => {\r\n arr.push({\r\n author: entry.author,\r\n title: entry.title,\r\n url: entry.url,\r\n lang: document.language,\r\n section: section.section,\r\n });\r\n });\r\n section.subsections.forEach((subsection) => {\r\n subsection.entries.forEach((entry) => {\r\n arr.push({\r\n author: entry.author,\r\n title: entry.title,\r\n url: entry.url,\r\n lang: document.language,\r\n section: section.section,\r\n subsection: subsection.section,\r\n });\r\n });\r\n });\r\n });\r\n });\r\n return { arr: arr, sections: sections };\r\n}\r\n\r\nfunction App() {\r\n const [data, setData] = useState(undefined); // keeps the state of the json\r\n const [dataArray, setDataArray] = useState([]); // put everything into one array. uses more memory, but search is faster and less complex\r\n // eslint-disable-next-line\r\n const [index, setIndex] = useState([]); // used for \"table of contents\". currently unused\r\n const [loading, setLoading] = useState(true); // Determines whether to show spinner\r\n const [searchParams, setSearchParams] = useState({ title: \"\" });\r\n const [searchResults, setSearchResults] = useState([]);\r\n const [sectionResults, setSectionResults] = useState([]);\r\n const [lightMode, setLightMode] = useState(true);\r\n\r\n // eslint-disable-next-line\r\n const [error, setError] = useState(\"\");\r\n\r\n let resultsList = null; // the html string containing the search results\r\n let sectionResultsList = null;\r\n\r\n const changeParameter = (param, value) => {\r\n // Lets a child component set the value of the search term\r\n setSearchParams({ ...searchParams, [param]: value });\r\n };\r\n\r\n // fetches data the first time the page renders\r\n useEffect(() => {\r\n async function fetchData() {\r\n try {\r\n setLoading(true);\r\n let result = await axios.get(\r\n \"https://raw.githubusercontent.com/FreeEbookFoundationBot/free-programming-books-json/main/fpb.json\"\r\n );\r\n setData(result.data);\r\n let { arr, sections } = jsonToArray(result.data);\r\n console.log(arr);\r\n setDataArray(arr);\r\n setIndex(sections);\r\n } catch (e) {\r\n // setError(\"Couldn't get data. Please try again later\")\r\n setData(fpb);\r\n let { arr, sections } = jsonToArray(fpb);\r\n setIndex(sections);\r\n setDataArray(arr);\r\n }\r\n setLoading(false);\r\n }\r\n fetchData();\r\n }, []);\r\n\r\n // fires when searchTerm changes\r\n // THIS IS THE MAIN SEARCH FUNCTION CURRENTLY\r\n useEffect(() => {\r\n if (dataArray) {\r\n // Finds most relevant titles\r\n const fuseOptions = {\r\n useExtendedSearch: true,\r\n findAllMatches: true,\r\n shouldSort: true,\r\n includeScore: true,\r\n threshold: 0.2,\r\n keys: [\"title\", \"lang.code\", \"section\"],\r\n };\r\n\r\n let fuse = new Fuse(dataArray, fuseOptions);\r\n let query = [];\r\n for (const [key, value] of Object.entries(searchParams)) {\r\n if (value === null || value === \"\") continue;\r\n if (key === \"lang.code\") {\r\n query.push({ \"lang.code\": `^${value}` });\r\n continue;\r\n }\r\n if (key === \"section\") {\r\n query.push({ section: `^${value}` });\r\n continue;\r\n }\r\n query.push({ [key]: value });\r\n }\r\n let result = fuse.search({\r\n $and: query,\r\n });\r\n result = result.slice(0, 40);\r\n\r\n // Goes through the list of results\r\n let relevantLists = [];\r\n result.forEach((entry) => {\r\n // Checks if a new entry has already been made with the given programming language and human language.\r\n let obj = relevantLists.find(\r\n (o) => o.item.section === entry.item.section && o.item.lang.code === entry.item.lang.code\r\n );\r\n if (!obj && entry.item.lang.code) {\r\n let langCode = entry.item.lang.code;\r\n let section = entry.item.section;\r\n // English is split into the subjects and langs file. The parser flags which type of entry it is to use here\r\n if (langCode === \"en\") {\r\n if (entry.item.lang.isSubject) {\r\n langCode = \"subjects\";\r\n } else {\r\n langCode = \"langs\";\r\n }\r\n }\r\n\r\n let id = entry.item.section;\r\n \r\n // Some ids are in HTML tags, so this will extract that id to form proper links\r\n if (id.includes(\" {\r\n // let section = entry.item.section;\r\n // if (!sResults.includes(section)) sResults.push(section);\r\n // });\r\n // setSectionResults(sResults);\r\n }\r\n }, [searchParams, dataArray]);\r\n\r\n if (loading) {\r\n // if still fetching resource\r\n return

    Loading...

    ;\r\n }\r\n if (error) {\r\n return

    Error: {error}

    ;\r\n }\r\n\r\n if (searchParams.title && searchResults.length !== 0) {\r\n resultsList =\r\n searchResults &&\r\n searchResults.map((entry) => {\r\n return ;\r\n });\r\n // Getting rid of the section results UI renders this irrelevant\r\n // sectionResultsList =\r\n // sectionResults &&\r\n // sectionResults.map((section) => {\r\n // return (\r\n // {\r\n // changeParameter(\"section\", section);\r\n // }}\r\n // >\r\n // {section}\r\n // \r\n // );\r\n // });\r\n }\r\n return (\r\n
    \r\n
    \r\n

    \r\n \r\n free-programming-books\r\n \r\n

    \r\n\r\n

    \r\n {\" \"}\r\n Freely available programming books\r\n

    \r\n\r\n

    \r\n \r\n View the Project on GitHub EbookFoundation/free-programming-books\r\n \r\n

    \r\n

    \r\n Does a link not work?\r\n
    \r\n \r\n Report an error on GitHub\r\n \r\n

    \r\n\r\n
    \r\n \r\n {/* Filters */}\r\n \r\n {/* Keeping sections commented out just in case */}\r\n {/* */}\r\n {/* {sectionResultsList &&

    Suggestions based on your search

    }\r\n
    {sectionResultsList}
    */}\r\n
    \r\n
    \r\n\r\n
    \r\n {resultsList ? (\r\n
    \r\n
    \r\n

    Search Results

    \r\n
      {resultsList}
    \r\n
    \r\n ) : searchParams.title ? (\r\n
    \r\n
    \r\n

    No results found.

    \r\n
    \r\n ) : (\r\n \r\n )}\r\n
    \r\n\r\n \r\n
    \r\n );\r\n}\r\n\r\nexport default App;\r\n","export default __webpack_public_path__ + \"static/media/sun.d499a97b.png\";","export default __webpack_public_path__ + \"static/media/moon.6ad80c47.png\";","const reportWebVitals = onPerfEntry => {\r\n if (onPerfEntry && onPerfEntry instanceof Function) {\r\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\r\n getCLS(onPerfEntry);\r\n getFID(onPerfEntry);\r\n getFCP(onPerfEntry);\r\n getLCP(onPerfEntry);\r\n getTTFB(onPerfEntry);\r\n });\r\n }\r\n};\r\n\r\nexport default reportWebVitals;\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './App.css';\r\nimport App from './App';\r\nimport reportWebVitals from './reportWebVitals';\r\n\r\nReactDOM.render(\r\n \r\n \r\n ,\r\n document.getElementById('root')\r\n);\r\n\r\n// If you want to start measuring performance in your app, pass a function\r\n// to log results (for example: reportWebVitals(console.log))\r\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\r\nreportWebVitals();\r\n"],"sourceRoot":""} \ No newline at end of file