From eb10cd1e5d1473989bf3d2e2de1bce0d51634ed3 Mon Sep 17 00:00:00 2001 From: Advait Bhat Date: Fri, 4 Sep 2026 21:38:55 -0700 Subject: [PATCH 01/10] Replace Jekyll with a static React website and document completion roadmap --- .github/workflows/check.yml | 23 + .github/workflows/deploy.yml | 35 + .gitignore | 28 +- .nvmrc | 1 + AGENTS.md | 9 + CLAUDE.md | 1 + CODEBASE.md | 14 + Gemfile | 2 - README.md | 75 +- _config.yml | 50 - _data/alumni.yml | 23 - _data/news.yml | 6 - _data/sponsors.yml | 14 - _includes/about.md | 1 - _includes/analytics.html | 10 - _includes/contact.md | 4 - _includes/footer.html | 17 - _includes/group.md | 55 - _includes/head.html | 15 - _includes/header.html | 39 - _includes/interests.md | 4 - _includes/news.html | 12 - _includes/sponsors.html | 7 - _layouts/default.html | 14 - _layouts/gridlay.html | 6 - _layouts/homelay.html | 15 - _layouts/page.html | 14 - _layouts/piclay.html | 7 - _layouts/post.html | 15 - _layouts/publications.html | 6 - _layouts/research.html | 6 - _layouts/team.html | 7 - _layouts/textlay.html | 6 - _pages/404.md | 10 - _pages/_home_pretty.md | 74 - _pages/aboutwebsite.md | 50 - _pages/allnews.md | 14 - _pages/home.md | 17 - _pages/idiofid.md | 35 - _pages/openings.md | 10 - _pages/pictures.md | 10 - _pages/publications.md | 103 - _pages/research.md | 17 - _pages/team.md | 9 - _people/advaitbhat.md | 13 - _people/antoniasaravanou.md | 10 - _people/ashishsharma.md | 12 - _people/bretnestor.md | 10 - _people/deniznazarova.md | 14 - _people/galenweld.md | 11 - _people/innalin.md | 9 - _people/jinasuh.md | 13 - _people/joyhe-yueya.md | 10 - _people/kengu.md | 9 - _people/margaretli.md | 12 - _people/melihyilmaz.md | 10 - _people/mickelliu.md | 13 - _people/mikemerrill.md | 10 - _people/remydeshayes.md | 9 - _people/timalthoff.md | 9 - _people/vinayakgupta.md | 10 - _people/xinyizhou.md | 9 - _planning/MODERN_STACK_OPTIONS.md | 111 + _planning/NEXT_STEPS.md | 137 + _planning/WEBSITE_SPEC.md | 166 ++ _planning/migration-report.json | 10 + _plugins/markdown.rb | 23 - _publications/Gu2022UnderstandingAS.md | 10 - _publications/Weld_Glenski_Althoff_2021.md | 39 - _publications/althoff2014ask.md | 10 - _publications/althoff2015donor.md | 13 - _publications/althoff2016counseling.md | 12 - _publications/althoff2016onlineappendix.md | 13 - _publications/althoff2016pokemon.md | 19 - _publications/althoff2017large.md | 12 - _publications/althoff2017onlineactions.md | 11 - _publications/althoff2017population.md | 14 - _publications/althoff2018psychomotor.md | 15 - _publications/althoff2022diet.md | 15 - _publications/althoffModeration.md | 12 - _publications/althoffPocketskills.md | 13 - _publications/althoffTalklifeEngagement.md | 11 - _publications/gordonactivity2019.md | 37 - _publications/gu2024blade.md | 8 - _publications/gu2024how_analysts.md | 8 - _publications/gu2024how_understand.md | 8 - _publications/hicks2022leveraging.md | 15 - _publications/kurashima2018tipas.md | 14 - _publications/lin-etal-2022-gendered.md | 35 - _publications/lin2024imbue.md | 8 - _publications/liupaths2020.md | 35 - _publications/merrill2024language.md | 8 - .../merrillHomekit2020BenchmarkTime2023.md | 38 - ...llSelfsupervisedPretrainingTransfer2023.md | 31 - _publications/merrill_multiverse_2021.md | 36 - _publications/mezlini2021estimating.md | 13 - _publications/miner2022computational.md | 17 - _publications/sefidgarpassively2020.md | 42 - _publications/shameli2017gamification.md | 14 - _publications/sharma2020computational.md | 14 - _publications/sharma2021facilitating.md | 21 - _publications/sharma2023human.md | 16 - _publications/sharma2024computational.md | 8 - _publications/sharma2024facilitating.md | 8 - _publications/suh2020populationscale.md | 15 - .../suhDisparateImpactsOnline2022.md | 34 - .../weld2022adjusting_confounders.md | 11 - _publications/weld2022community_values.md | 11 - _publications/weld2024making.md | 8 - _publications/xu2022GLOBEM.md | 19 - _publications/xu2023globemimwut.md | 19 - _publications/xuleveraging2019.md | 47 - _publications/zech2023mhatsengagement.md | 13 - _publications/zhou2024correcting.md | 8 - _sass/_bootstrap.scss | 58 - _sass/bootstrap/_alerts.scss | 73 - _sass/bootstrap/_badges.scss | 68 - _sass/bootstrap/_bootswatch.scss | 523 ---- _sass/bootstrap/_breadcrumbs.scss | 28 - _sass/bootstrap/_button-groups.scss | 244 -- _sass/bootstrap/_buttons.scss | 168 -- _sass/bootstrap/_carousel.scss | 270 -- _sass/bootstrap/_close.scss | 36 - _sass/bootstrap/_code.scss | 69 - _sass/bootstrap/_component-animations.scss | 37 - _sass/bootstrap/_dropdowns.scss | 216 -- _sass/bootstrap/_forms.scss | 617 ----- _sass/bootstrap/_glyphicons.scss | 307 --- _sass/bootstrap/_grid.scss | 84 - _sass/bootstrap/_input-groups.scss | 171 -- _sass/bootstrap/_jumbotron.scss | 54 - _sass/bootstrap/_labels.scss | 66 - _sass/bootstrap/_list-group.scss | 130 - _sass/bootstrap/_media.scss | 66 - _sass/bootstrap/_mixins.scss | 40 - _sass/bootstrap/_modals.scss | 150 -- _sass/bootstrap/_navbar.scss | 662 ----- _sass/bootstrap/_navs.scss | 242 -- _sass/bootstrap/_normalize.scss | 424 --- _sass/bootstrap/_pager.scss | 54 - _sass/bootstrap/_pagination.scss | 89 - _sass/bootstrap/_panels.scss | 271 -- _sass/bootstrap/_popovers.scss | 131 - _sass/bootstrap/_print.scss | 101 - _sass/bootstrap/_progress-bars.scss | 87 - _sass/bootstrap/_responsive-embed.scss | 35 - _sass/bootstrap/_responsive-utilities.scss | 179 -- _sass/bootstrap/_scaffolding.scss | 161 -- _sass/bootstrap/_tables.scss | 234 -- _sass/bootstrap/_theme.scss | 291 -- _sass/bootstrap/_thumbnails.scss | 38 - _sass/bootstrap/_tooltip.scss | 101 - _sass/bootstrap/_type.scss | 298 --- _sass/bootstrap/_utilities.scss | 55 - _sass/bootstrap/_variables copy.scss | 874 ------ _sass/bootstrap/_variables.scss | 870 ------ _sass/bootstrap/_wells.scss | 29 - _sass/bootstrap/mixins/_alerts.scss | 14 - .../bootstrap/mixins/_background-variant.scss | 12 - _sass/bootstrap/mixins/_border-radius.scss | 18 - _sass/bootstrap/mixins/_buttons.scss | 65 - _sass/bootstrap/mixins/_center-block.scss | 7 - _sass/bootstrap/mixins/_clearfix.scss | 22 - _sass/bootstrap/mixins/_forms.scss | 88 - _sass/bootstrap/mixins/_gradients.scss | 58 - _sass/bootstrap/mixins/_grid-framework.scss | 81 - _sass/bootstrap/mixins/_grid.scss | 122 - _sass/bootstrap/mixins/_hide-text.scss | 21 - _sass/bootstrap/mixins/_image.scss | 33 - _sass/bootstrap/mixins/_labels.scss | 12 - _sass/bootstrap/mixins/_list-group.scss | 32 - _sass/bootstrap/mixins/_nav-divider.scss | 10 - .../bootstrap/mixins/_nav-vertical-align.scss | 9 - _sass/bootstrap/mixins/_opacity.scss | 8 - _sass/bootstrap/mixins/_pagination.scss | 24 - _sass/bootstrap/mixins/_panels.scss | 24 - _sass/bootstrap/mixins/_progress-bar.scss | 10 - _sass/bootstrap/mixins/_reset-filter.scss | 8 - _sass/bootstrap/mixins/_reset-text.scss | 18 - _sass/bootstrap/mixins/_resize.scss | 6 - .../mixins/_responsive-visibility.scss | 21 - _sass/bootstrap/mixins/_size.scss | 10 - _sass/bootstrap/mixins/_tab-focus.scss | 9 - _sass/bootstrap/mixins/_table-row.scss | 28 - _sass/bootstrap/mixins/_text-emphasis.scss | 12 - _sass/bootstrap/mixins/_text-overflow.scss | 8 - _sass/bootstrap/mixins/_vendor-prefixes.scss | 222 -- add_person.py | 116 - add_pub.py | 165 -- app/aboutwebsite/page.jsx | 3 + app/allnews/page.jsx | 1 + app/globals.css | 18 + app/idiofid/page.jsx | 3 + app/join/page.jsx | 8 + app/layout.jsx | 22 + app/news/page.jsx | 6 + app/not-found.jsx | 3 + app/page.jsx | 19 + app/people/[id]/page.jsx | 14 + app/pictures/page.jsx | 3 + app/publications/[id]/page.jsx | 19 + app/publications/page.jsx | 7 + app/research/page.jsx | 3 + app/robots.js | 2 + app/sitemap.js | 3 + app/team/page.jsx | 13 + app/vacancies/page.jsx | 1 + bdata.bib | 90 - biblib/__init__.py | 1 - biblib/algo.py | 485 ---- biblib/bib.py | 496 ---- biblib/messages.py | 126 - biblib/test.py | 327 --- components/navigation.jsx | 8 + components/page-heading.jsx | 3 + components/paper-card.jsx | 13 + components/publication-explorer.jsx | 17 + content/alumni.json | 49 + content/news.json | 17 + content/people.json | 472 ++++ content/publications.json | 1664 ++++++++++++ content/sponsors.json | 30 + css/main.scss | 254 -- js/bootstrap.js | 2363 ----------------- js/bootstrap.min.js | 7 - js/jquery.min.js | 2 - js/npm.js | 13 - js/popper.min.js | 184 -- js/scripts.js | 1 - jsconfig.json | 3 + lib/content.js | 19 + lib/publications.mjs | 19 + next.config.mjs | 7 + package-lock.json | 2176 +++++++++++++++ package.json | 18 + public/.nojekyll | 0 .../downloads}/GeneralPostdoc_2019_v01.pdf | Bin {downloads => public/downloads}/PD.pdf | Bin {downloads => public/downloads}/PHD1.pdf | Bin {downloads => public/downloads}/PHD2.pdf | Bin .../downloads}/PPMS_PhD_2019_v01.pdf | Bin .../fonts}/Proxima-Nova-Regular.otf | Bin {fonts => public/fonts}/Proxima-Nova-Thin.otf | Bin .../fonts}/glyphicons-halflings-regular.eot | Bin .../fonts}/glyphicons-halflings-regular.svg | 0 .../fonts}/glyphicons-halflings-regular.ttf | Bin .../fonts}/glyphicons-halflings-regular.woff | Bin .../fonts}/glyphicons-halflings-regular.woff2 | Bin {images => public/images}/Group05022015.jpg | Bin .../images}/Group05022015_red.jpg | Bin {images => public/images}/Group2015.png | Bin {images => public/images}/Group2015_red.jpg | Bin {images => public/images}/Logos_h.jpg | Bin {images => public/images}/News_M2PG.png | Bin {images => public/images}/News_Maarten.png | Bin {images => public/images}/bio-photo.jpg | Bin {images => public/images}/dummy.png | Bin {images => public/images}/favicon.ico | Bin {images => public/images}/logo1.png | Bin {images => public/images}/logo2.png | Bin .../images}/logopic/Logo_Bdata.png | Bin .../images}/logopic/Logo_Bdata_text_below.png | Bin .../images}/mm-browser-mockups.png | Bin .../images}/mm-layout-examples.png | Bin {images => public/images}/newspic/Contest.jpg | Bin .../images}/newspic/DomeNews.png | Bin .../images}/newspic/LCposter.jpg | Bin {images => public/images}/newspic/NewsNP.png | Bin {images => public/images}/newspic/SFnews.png | Bin .../images}/newspic/Saphireheadline.jpeg | Bin .../images}/newspic/SmartTip.png | Bin {images => public/images}/newspic/amp.PNG | Bin .../images}/newspic/doohee_prize.png | Bin {images => public/images}/newspic/order.png | Bin .../images}/newspic/scesprizes.jpg | Bin .../picpic/Gallery/20150918_145800.jpg | Bin .../images}/picpic/Gallery/DSC_0030.jpg | Bin .../images}/picpic/Gallery/DSC_0051.jpg | Bin .../images}/picpic/Gallery/DSC_0116.jpg | Bin .../images}/picpic/Gallery/DSC_0119.jpg | Bin .../images}/picpic/Gallery/DSC_0128.jpg | Bin .../images}/picpic/Gallery/DSC_0139.jpg | Bin .../images}/picpic/Gallery/DSC_0366.JPG | Bin .../images}/picpic/Gallery/DSC_0368.JPG | Bin .../images}/picpic/Gallery/DSC_0636.jpg | Bin .../images}/picpic/Gallery/DSC_0683.jpg | Bin .../images}/picpic/Gallery/DSC_0696.jpg | Bin .../images}/picpic/Gallery/DSC_0757.jpg | Bin .../images}/picpic/Gallery/Group05022015.jpg | Bin .../images}/picpic/Gallery/IMG_4334.jpg | Bin .../images}/picpic/Gallery/IMG_4376.jpg | Bin .../images}/picpic/Gallery/tamagochi.jpg | Bin .../images}/picpic/Gallery/tmp2-2.jpg | Bin .../images}/picpic/WebpageCornell.jpg | Bin .../images}/picpic/WebpageCornell_red.jpg | Bin .../images}/picpic/WebpageETH.jpg | Bin .../images}/picpic/WebpageETH_red.jpg | Bin .../images}/picpic/WebpageLeiden.jpg | Bin .../images}/picpic/WebpageLeiden2.jpg | Bin .../images}/picpic/WebpageLeiden_red.jpg | Bin .../images}/picpic/WebpageSTA.jpg | Bin .../images}/picpic/WebpageSTA_red.jpg | Bin {images => public/images}/pubpic/DomePub.png | Bin {images => public/images}/pubpic/Fano.png | Bin .../images}/pubpic/Mott_phase_sep.jpg | Bin {images => public/images}/pubpic/PbSpub.png | Bin {images => public/images}/pubpic/Pub_327.png | Bin {images => public/images}/pubpic/Pub_BCl.png | Bin .../images}/pubpic/Pub_CeCoIn5.png | Bin {images => public/images}/pubpic/Pub_FP.png | Bin {images => public/images}/pubpic/Pub_HFSC.png | Bin .../images}/pubpic/Pub_LiFeAs.png | Bin {images => public/images}/pubpic/Pub_M2PG.png | Bin {images => public/images}/pubpic/Pub_hBN.png | Bin .../images}/pubpic/Pub_nemat1.png | Bin .../images}/pubpic/Pub_nemat2b.png | Bin .../images}/pubpic/SCAUweb copy.jpg | Bin {images => public/images}/pubpic/SCAUweb.jpg | Bin {images => public/images}/pubpic/SFpub.png | Bin {images => public/images}/pubpic/STS_news.png | Bin {images => public/images}/pubpic/SmartPub.png | Bin .../images}/pubpic/TBG_ARPES.png | Bin {images => public/images}/pubpic/TBG_SL.png | Bin {images => public/images}/pubpic/TIBB.png | Bin {images => public/images}/pubpic/YSR.png | Bin {images => public/images}/pubpic/dummy.png | Bin .../images}/respic/layers_fft.gif | Bin .../images}/respic/layers_fft.jpg | Bin .../images}/respic/layers_fft_red.gif | Bin .../images}/respic/layers_real.gif | Bin .../images}/respic/layers_real.jpg | Bin .../images}/respic/layers_real_red.gif | Bin .../images}/slider7001400/FabSCAU.jpg | Bin .../images}/slider7001400/Group2015_red.jpg | Bin .../images}/slider7001400/Logos_h.jpg | Bin .../images}/slider7001400/MottMap.jpg | Bin .../images}/slider7001400/NoiseCover2.jpg | Bin .../images}/slider7001400/STS.jpg | Bin .../images}/slider7001400/SaphireSTM2.jpg | Bin .../images}/slider7001400/SmartTipSide.jpg | Bin .../images}/slider7001400/cake_web.jpg | Bin .../images}/slider7001400/dinner2.jpg | Bin .../images}/slider7001400/dinner3.jpg | Bin .../images}/slider7001400/groupDinner.jpg | Bin .../images}/slider7001400/lab.jpg | Bin .../images}/slider7001400/logos.jpg | Bin .../images}/slider7001400/tamagochi.jpg | Bin .../images}/slider7001400/topo214.png | Bin .../images}/teampic/CV_Photo4.jpg | Bin .../images}/teampic/DSC_1032.JPG | Bin .../images}/teampic/Damianos.jpg | Bin {images => public/images}/teampic/Doohee2.jpg | Bin {images => public/images}/teampic/Freek.jpg | Bin {images => public/images}/teampic/Jacky.jpg | Bin {images => public/images}/teampic/Jiasen.png | Bin {images => public/images}/teampic/Kees.jpg | Bin {images => public/images}/teampic/Koen.jpg | Bin {images => public/images}/teampic/Maarten.png | Bin {images => public/images}/teampic/Milan.jpg | Bin .../images}/teampic/Photo Vincent.jpg | Bin .../images}/teampic/Photo_Irene.jpg | Bin {images => public/images}/teampic/Ram.png | Bin {images => public/images}/teampic/Vitaly.JPG | Bin .../images}/teampic/Webfoto_HS2.jpg | Bin {images => public/images}/teampic/hugo.jpg | Bin {images => public/images}/teampic/irene.jpg | Bin {images => public/images}/teampic/rock.jpg | Bin {images => public/images}/teampic/tjeruk.jpg | Bin {images => public/images}/teampic/verdoes.jpg | Bin .../images}/teampic/website_pic_willem.jpg | Bin .../resources}/headshots/advait.jpeg | Bin .../resources}/headshots/antoniasaravanou.jpg | Bin .../resources}/headshots/ashishsharma.png | Bin .../resources}/headshots/bretnestor.jpg | Bin public/resources/headshots/cl.png | Bin 0 -> 11954 bytes .../resources}/headshots/deniz.jpeg | Bin .../resources}/headshots/dubs.png | Bin public/resources/headshots/galenweld.png | Bin 0 -> 1418981 bytes .../resources/headshots/galenweldphd.png | Bin .../resources}/headshots/innalin.jpg | Bin .../resources}/headshots/jinasuh.jpg | Bin .../resources}/headshots/joyhe-yueya.jpg | Bin .../resources}/headshots/kengu.jpg | Bin .../resources}/headshots/margaretli.png | Bin .../resources}/headshots/melihyilmaz.png | Bin .../resources}/headshots/mickelliu.png | Bin .../resources}/headshots/mikemerrill.jpeg | Bin .../resources}/headshots/remydeshayes.png | Bin public/resources/headshots/rongwu.png | Bin 0 -> 1143133 bytes .../resources}/headshots/tim.png | Bin .../resources}/headshots/timalthoff.jpg | Bin .../resources}/headshots/vinayakgupta.png | Bin .../resources}/headshots/xinyizhou.jpg | Bin public/resources/headshots/yasaman.png | Bin 0 -> 1609229 bytes .../resources/headshots/yasamansefidgar.png | Bin 0 -> 1609229 bytes .../pubpdfs/Gu2022UnderstandingAS.pdf | Bin .../pubpdfs/Weld_Glenski_Althoff_2021.pdf | Bin .../resources}/pubpdfs/althoff2014ask.pdf | Bin .../resources}/pubpdfs/althoff2015donor.pdf | Bin .../pubpdfs/althoff2016counseling.pdf | Bin .../pubpdfs/althoff2016onlineappendix.pdf | Bin .../resources}/pubpdfs/althoff2016pokemon.pdf | Bin .../resources}/pubpdfs/althoff2017large.pdf | Bin .../pubpdfs/althoff2017onlineactions.pdf | Bin .../pubpdfs/althoff2017population.pdf | Bin .../pubpdfs/althoff2018psychomotor.pdf | Bin .../resources}/pubpdfs/althoff2022diet.pdf | Bin .../resources}/pubpdfs/althoffModeration.pdf | Bin .../pubpdfs/althoffPocketskills.pdf | Bin .../pubpdfs/althoffTalklifeEngagement.pdf | Bin .../resources}/pubpdfs/gordonactivity2019.pdf | Bin .../guBLADEBenchmarkingLanguage2024a.pdf | Bin .../pubpdfs/guHowDoAnalystsUnderstand2024.pdf | Bin .../pubpdfs/guHowDoDataAnalysts2024.pdf | Bin .../pubpdfs/hicks2022leveraging.pdf | Bin .../resources}/pubpdfs/kurashima2018tipas.pdf | Bin .../pubpdfs/lander1966counterexample.pdf | Bin .../pubpdfs/lin-etal-2022-gendered.pdf | Bin .../resources}/pubpdfs/linIMBUE2024.pdf | Bin .../resources}/pubpdfs/liupaths2020.pdf | Bin .../merrillHomekit2020BenchmarkTime2023.pdf | Bin .../merrillLanguageModelsStill2024.pdf | Bin ...lSelfsupervisedPretrainingTransfer2023.pdf | Bin .../merrillTransformingWearableData2024a.pdf | Bin .../pubpdfs/merrill_multiverse_2021.pdf | Bin .../pubpdfs/mezlini2021estimating.pdf | Bin .../pubpdfs/miner2022computational.pdf | Bin .../pubpdfs/sefidgarpassively2020.pdf | Bin .../pubpdfs/shameli2017gamification.pdf | Bin .../pubpdfs/sharma2020computational.pdf | Bin .../pubpdfs/sharma2021facilitating.pdf | Bin .../resources}/pubpdfs/sharma2023human.pdf | Bin .../pubpdfs/sharma2024computational.pdf | Bin .../sharmaFacilitatingSelf-Guided2024.pdf | Bin .../pubpdfs/suh2020populationscale.pdf | Bin .../pubpdfs/suhDisparateImpactsOnline2022.pdf | Bin .../pubpdfs/tanAreLanguageModels2024.pdf | Bin .../resources}/pubpdfs/tseng2016ubicomp.pdf | Bin .../pubpdfs/weld2022adjusting_confounders.pdf | Bin .../pubpdfs/weld2022community_values.pdf | Bin .../weldMakingOnlineCommunities2024.pdf | Bin .../resources}/pubpdfs/xu2022GLOBEM.pdf | Bin .../resources}/pubpdfs/xu2023globemimwut.pdf | Bin .../resources}/pubpdfs/xuleveraging2019.pdf | Bin .../pubpdfs/zech2023mhatsengagement.pdf | Bin .../zhouCorrectingMisinformation2024.pdf | Bin .../resources}/spons/adobe.jpg | Bin {resources => public/resources}/spons/ai2.png | Bin .../resources}/spons/gates.png | Bin {resources => public/resources}/spons/msr.gif | Bin {resources => public/resources}/spons/nih.png | Bin {resources => public/resources}/spons/nsf.png | Bin {resources => public/resources}/spons/onr.png | Bin .../thumbnails/Gu2022UnderstandingAS.png | Bin .../thumbnails/Weld_Glenski_Althoff_2021.jpg | Bin .../resources}/thumbnails/althoff2014ask.png | Bin .../thumbnails/althoff2015donor.png | Bin .../thumbnails/althoff2016counseling.png | Bin .../thumbnails/althoff2016onlineappendix.png | Bin .../thumbnails/althoff2016pokemon.png | Bin .../thumbnails/althoff2017large.png | Bin .../thumbnails/althoff2017onlineactions.png | Bin .../thumbnails/althoff2017population.png | Bin .../thumbnails/althoff2018psychomotor.png | Bin .../resources}/thumbnails/althoff2022diet.png | Bin .../thumbnails/althoffModeration.png | Bin .../thumbnails/althoffPocketskills.png | Bin .../thumbnails/althoffTalklifeEngagement.png | Bin .../thumbnails/gordonactivity2019.png | Bin .../resources}/thumbnails/guBLADE.png | Bin .../thumbnails/guHowDoDataAnalysts.png | Bin .../guHowDoDataAnalystsUnderstand.png | Bin .../thumbnails/hicks2022leveraging.png | Bin .../thumbnails/kurashima2018tipas.pdf | Bin .../thumbnails/kurashima2018tipas.png | Bin .../thumbnails/lander1966counterexample.png | Bin .../thumbnails/lin-etal-2022-gendered.png | Bin .../resources}/thumbnails/linIMBUE.png | Bin .../resources}/thumbnails/liupaths2020.png | Bin .../merrillHomekit2020BenchmarkTime2023.png | Bin .../thumbnails/merrillLanguageModels.png | Bin ...lSelfsupervisedPretrainingTransfer2023.png | Bin .../thumbnails/merrillTransforming.png | Bin .../thumbnails/merrill_multiverse_2021.png | Bin .../thumbnails/mezlini2021estimating.png | Bin .../thumbnails/miner2022computational.png | Bin .../thumbnails/sefidgarpassively2020.png | Bin .../thumbnails/shameli2017gamification.png | Bin .../thumbnails/sharma2020computational.png | Bin .../thumbnails/sharma2021facilitating.png | Bin .../resources}/thumbnails/sharma2023human.png | Bin .../thumbnails/sharmaComputational.png | Bin .../thumbnails/sharmafacilitating.png | Bin .../thumbnails/suh2020populationscale.png | Bin .../suhDisparateImpactsOnline2022.png | Bin .../thumbnails/tseng2016ubicomp.jpeg | Bin .../weld2022adjusting_confounders.JPG | Bin .../thumbnails/weld2022community_values.jpg | Bin .../resources}/thumbnails/weldmaking.png | Bin .../resources}/thumbnails/xu2022GLOBEM.png | Bin .../thumbnails/xu2023globemimwut.png | Bin .../thumbnails/xuleveraging2019.png | Bin .../thumbnails/zech2023mhatsengagement.png | Bin .../thumbnails/zhouCorrectingMis.png | Bin scripts/README.md | 21 + scripts/prepare_publication.py | 66 + scripts/validate-content.mjs | 23 + split_bibtex.py | 43 - tests/publications.test.mjs | 28 + tests/test_prepare_publication.py | 26 + tim_bib/althoff2014ask.bib | 8 - tim_bib/althoff2014howtoaskforafavor.bib | 10 - tim_bib/althoff2015donor.bib | 12 - tim_bib/althoff2016counseling.bib | 9 - tim_bib/althoff2016neurips.bib | 8 - tim_bib/althoff2016onlineappendix.bib | 11 - tim_bib/althoff2016pokemon.bib | 16 - tim_bib/althoff2016pokemonold.bib | 9 - tim_bib/althoff2017harnessing.bib | 10 - tim_bib/althoff2017large.bib | 9 - tim_bib/althoff2017onlineactions.bib | 7 - tim_bib/althoff2017population.bib | 10 - tim_bib/althoff2018psychomotor.bib | 11 - tim_bib/althoffmoderation.bib | 9 - tim_bib/althoffpocketskills.bib | 10 - tim_bib/althoffrisescience.bib | 8 - tim_bib/althofftalklifeengagement.bib | 9 - tim_bib/kurashima2018tipas.bib | 12 - tim_bib/kurashima2018tipasdeprecated.bib | 11 - tim_bib/shameli2017gamification.bib | 13 - utils.py | 35 - 531 files changed, 5399 insertions(+), 16419 deletions(-) create mode 100644 .github/workflows/check.yml create mode 100644 .github/workflows/deploy.yml create mode 100644 .nvmrc create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 CODEBASE.md delete mode 100644 Gemfile delete mode 100644 _config.yml delete mode 100644 _data/alumni.yml delete mode 100644 _data/news.yml delete mode 100644 _data/sponsors.yml delete mode 100644 _includes/about.md delete mode 100644 _includes/analytics.html delete mode 100644 _includes/contact.md delete mode 100644 _includes/footer.html delete mode 100644 _includes/group.md delete mode 100644 _includes/head.html delete mode 100644 _includes/header.html delete mode 100644 _includes/interests.md delete mode 100644 _includes/news.html delete mode 100644 _includes/sponsors.html delete mode 100644 _layouts/default.html delete mode 100644 _layouts/gridlay.html delete mode 100644 _layouts/homelay.html delete mode 100644 _layouts/page.html delete mode 100644 _layouts/piclay.html delete mode 100644 _layouts/post.html delete mode 100644 _layouts/publications.html delete mode 100644 _layouts/research.html delete mode 100644 _layouts/team.html delete mode 100644 _layouts/textlay.html delete mode 100755 _pages/404.md delete mode 100644 _pages/_home_pretty.md delete mode 100644 _pages/aboutwebsite.md delete mode 100644 _pages/allnews.md delete mode 100644 _pages/home.md delete mode 100644 _pages/idiofid.md delete mode 100644 _pages/openings.md delete mode 100644 _pages/pictures.md delete mode 100644 _pages/publications.md delete mode 100644 _pages/research.md delete mode 100644 _pages/team.md delete mode 100644 _people/advaitbhat.md delete mode 100644 _people/antoniasaravanou.md delete mode 100644 _people/ashishsharma.md delete mode 100644 _people/bretnestor.md delete mode 100644 _people/deniznazarova.md delete mode 100644 _people/galenweld.md delete mode 100644 _people/innalin.md delete mode 100644 _people/jinasuh.md delete mode 100644 _people/joyhe-yueya.md delete mode 100644 _people/kengu.md delete mode 100644 _people/margaretli.md delete mode 100644 _people/melihyilmaz.md delete mode 100644 _people/mickelliu.md delete mode 100644 _people/mikemerrill.md delete mode 100644 _people/remydeshayes.md delete mode 100644 _people/timalthoff.md delete mode 100644 _people/vinayakgupta.md delete mode 100644 _people/xinyizhou.md create mode 100644 _planning/MODERN_STACK_OPTIONS.md create mode 100644 _planning/NEXT_STEPS.md create mode 100644 _planning/WEBSITE_SPEC.md create mode 100644 _planning/migration-report.json delete mode 100644 _plugins/markdown.rb delete mode 100644 _publications/Gu2022UnderstandingAS.md delete mode 100644 _publications/Weld_Glenski_Althoff_2021.md delete mode 100644 _publications/althoff2014ask.md delete mode 100644 _publications/althoff2015donor.md delete mode 100644 _publications/althoff2016counseling.md delete mode 100644 _publications/althoff2016onlineappendix.md delete mode 100644 _publications/althoff2016pokemon.md delete mode 100644 _publications/althoff2017large.md delete mode 100644 _publications/althoff2017onlineactions.md delete mode 100644 _publications/althoff2017population.md delete mode 100644 _publications/althoff2018psychomotor.md delete mode 100644 _publications/althoff2022diet.md delete mode 100644 _publications/althoffModeration.md delete mode 100644 _publications/althoffPocketskills.md delete mode 100644 _publications/althoffTalklifeEngagement.md delete mode 100644 _publications/gordonactivity2019.md delete mode 100644 _publications/gu2024blade.md delete mode 100644 _publications/gu2024how_analysts.md delete mode 100644 _publications/gu2024how_understand.md delete mode 100644 _publications/hicks2022leveraging.md delete mode 100644 _publications/kurashima2018tipas.md delete mode 100644 _publications/lin-etal-2022-gendered.md delete mode 100644 _publications/lin2024imbue.md delete mode 100644 _publications/liupaths2020.md delete mode 100644 _publications/merrill2024language.md delete mode 100644 _publications/merrillHomekit2020BenchmarkTime2023.md delete mode 100644 _publications/merrillSelfsupervisedPretrainingTransfer2023.md delete mode 100644 _publications/merrill_multiverse_2021.md delete mode 100644 _publications/mezlini2021estimating.md delete mode 100644 _publications/miner2022computational.md delete mode 100644 _publications/sefidgarpassively2020.md delete mode 100644 _publications/shameli2017gamification.md delete mode 100644 _publications/sharma2020computational.md delete mode 100644 _publications/sharma2021facilitating.md delete mode 100644 _publications/sharma2023human.md delete mode 100644 _publications/sharma2024computational.md delete mode 100644 _publications/sharma2024facilitating.md delete mode 100644 _publications/suh2020populationscale.md delete mode 100644 _publications/suhDisparateImpactsOnline2022.md delete mode 100644 _publications/weld2022adjusting_confounders.md delete mode 100644 _publications/weld2022community_values.md delete mode 100644 _publications/weld2024making.md delete mode 100644 _publications/xu2022GLOBEM.md delete mode 100644 _publications/xu2023globemimwut.md delete mode 100644 _publications/xuleveraging2019.md delete mode 100644 _publications/zech2023mhatsengagement.md delete mode 100644 _publications/zhou2024correcting.md delete mode 100644 _sass/_bootstrap.scss delete mode 100644 _sass/bootstrap/_alerts.scss delete mode 100644 _sass/bootstrap/_badges.scss delete mode 100644 _sass/bootstrap/_bootswatch.scss delete mode 100644 _sass/bootstrap/_breadcrumbs.scss delete mode 100644 _sass/bootstrap/_button-groups.scss delete mode 100644 _sass/bootstrap/_buttons.scss delete mode 100644 _sass/bootstrap/_carousel.scss delete mode 100644 _sass/bootstrap/_close.scss delete mode 100644 _sass/bootstrap/_code.scss delete mode 100644 _sass/bootstrap/_component-animations.scss delete mode 100644 _sass/bootstrap/_dropdowns.scss delete mode 100644 _sass/bootstrap/_forms.scss delete mode 100644 _sass/bootstrap/_glyphicons.scss delete mode 100644 _sass/bootstrap/_grid.scss delete mode 100644 _sass/bootstrap/_input-groups.scss delete mode 100644 _sass/bootstrap/_jumbotron.scss delete mode 100644 _sass/bootstrap/_labels.scss delete mode 100644 _sass/bootstrap/_list-group.scss delete mode 100644 _sass/bootstrap/_media.scss delete mode 100644 _sass/bootstrap/_mixins.scss delete mode 100644 _sass/bootstrap/_modals.scss delete mode 100644 _sass/bootstrap/_navbar.scss delete mode 100644 _sass/bootstrap/_navs.scss delete mode 100644 _sass/bootstrap/_normalize.scss delete mode 100644 _sass/bootstrap/_pager.scss delete mode 100644 _sass/bootstrap/_pagination.scss delete mode 100644 _sass/bootstrap/_panels.scss delete mode 100644 _sass/bootstrap/_popovers.scss delete mode 100644 _sass/bootstrap/_print.scss delete mode 100644 _sass/bootstrap/_progress-bars.scss delete mode 100644 _sass/bootstrap/_responsive-embed.scss delete mode 100644 _sass/bootstrap/_responsive-utilities.scss delete mode 100644 _sass/bootstrap/_scaffolding.scss delete mode 100644 _sass/bootstrap/_tables.scss delete mode 100644 _sass/bootstrap/_theme.scss delete mode 100644 _sass/bootstrap/_thumbnails.scss delete mode 100644 _sass/bootstrap/_tooltip.scss delete mode 100644 _sass/bootstrap/_type.scss delete mode 100644 _sass/bootstrap/_utilities.scss delete mode 100644 _sass/bootstrap/_variables copy.scss delete mode 100644 _sass/bootstrap/_variables.scss delete mode 100644 _sass/bootstrap/_wells.scss delete mode 100644 _sass/bootstrap/mixins/_alerts.scss delete mode 100644 _sass/bootstrap/mixins/_background-variant.scss delete mode 100644 _sass/bootstrap/mixins/_border-radius.scss delete mode 100644 _sass/bootstrap/mixins/_buttons.scss delete mode 100644 _sass/bootstrap/mixins/_center-block.scss delete mode 100644 _sass/bootstrap/mixins/_clearfix.scss delete mode 100644 _sass/bootstrap/mixins/_forms.scss delete mode 100644 _sass/bootstrap/mixins/_gradients.scss delete mode 100644 _sass/bootstrap/mixins/_grid-framework.scss delete mode 100644 _sass/bootstrap/mixins/_grid.scss delete mode 100644 _sass/bootstrap/mixins/_hide-text.scss delete mode 100644 _sass/bootstrap/mixins/_image.scss delete mode 100644 _sass/bootstrap/mixins/_labels.scss delete mode 100644 _sass/bootstrap/mixins/_list-group.scss delete mode 100644 _sass/bootstrap/mixins/_nav-divider.scss delete mode 100644 _sass/bootstrap/mixins/_nav-vertical-align.scss delete mode 100644 _sass/bootstrap/mixins/_opacity.scss delete mode 100644 _sass/bootstrap/mixins/_pagination.scss delete mode 100644 _sass/bootstrap/mixins/_panels.scss delete mode 100644 _sass/bootstrap/mixins/_progress-bar.scss delete mode 100644 _sass/bootstrap/mixins/_reset-filter.scss delete mode 100644 _sass/bootstrap/mixins/_reset-text.scss delete mode 100644 _sass/bootstrap/mixins/_resize.scss delete mode 100644 _sass/bootstrap/mixins/_responsive-visibility.scss delete mode 100644 _sass/bootstrap/mixins/_size.scss delete mode 100644 _sass/bootstrap/mixins/_tab-focus.scss delete mode 100644 _sass/bootstrap/mixins/_table-row.scss delete mode 100644 _sass/bootstrap/mixins/_text-emphasis.scss delete mode 100644 _sass/bootstrap/mixins/_text-overflow.scss delete mode 100644 _sass/bootstrap/mixins/_vendor-prefixes.scss delete mode 100644 add_person.py delete mode 100644 add_pub.py create mode 100644 app/aboutwebsite/page.jsx create mode 100644 app/allnews/page.jsx create mode 100644 app/globals.css create mode 100644 app/idiofid/page.jsx create mode 100644 app/join/page.jsx create mode 100644 app/layout.jsx create mode 100644 app/news/page.jsx create mode 100644 app/not-found.jsx create mode 100644 app/page.jsx create mode 100644 app/people/[id]/page.jsx create mode 100644 app/pictures/page.jsx create mode 100644 app/publications/[id]/page.jsx create mode 100644 app/publications/page.jsx create mode 100644 app/research/page.jsx create mode 100644 app/robots.js create mode 100644 app/sitemap.js create mode 100644 app/team/page.jsx create mode 100644 app/vacancies/page.jsx delete mode 100644 bdata.bib delete mode 100644 biblib/__init__.py delete mode 100644 biblib/algo.py delete mode 100644 biblib/bib.py delete mode 100644 biblib/messages.py delete mode 100644 biblib/test.py create mode 100644 components/navigation.jsx create mode 100644 components/page-heading.jsx create mode 100644 components/paper-card.jsx create mode 100644 components/publication-explorer.jsx create mode 100644 content/alumni.json create mode 100644 content/news.json create mode 100644 content/people.json create mode 100644 content/publications.json create mode 100644 content/sponsors.json delete mode 100644 css/main.scss delete mode 100644 js/bootstrap.js delete mode 100644 js/bootstrap.min.js delete mode 100644 js/jquery.min.js delete mode 100644 js/npm.js delete mode 100644 js/popper.min.js delete mode 100644 js/scripts.js create mode 100644 jsconfig.json create mode 100644 lib/content.js create mode 100644 lib/publications.mjs create mode 100644 next.config.mjs create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/.nojekyll rename {downloads => public/downloads}/GeneralPostdoc_2019_v01.pdf (100%) rename {downloads => public/downloads}/PD.pdf (100%) rename {downloads => public/downloads}/PHD1.pdf (100%) rename {downloads => public/downloads}/PHD2.pdf (100%) rename {downloads => public/downloads}/PPMS_PhD_2019_v01.pdf (100%) rename {fonts => public/fonts}/Proxima-Nova-Regular.otf (100%) rename {fonts => public/fonts}/Proxima-Nova-Thin.otf (100%) rename {fonts => public/fonts}/glyphicons-halflings-regular.eot (100%) rename {fonts => public/fonts}/glyphicons-halflings-regular.svg (100%) rename {fonts => public/fonts}/glyphicons-halflings-regular.ttf (100%) rename {fonts => public/fonts}/glyphicons-halflings-regular.woff (100%) rename {fonts => public/fonts}/glyphicons-halflings-regular.woff2 (100%) rename {images => public/images}/Group05022015.jpg (100%) rename {images => public/images}/Group05022015_red.jpg (100%) rename {images => public/images}/Group2015.png (100%) rename {images => public/images}/Group2015_red.jpg (100%) rename {images => public/images}/Logos_h.jpg (100%) rename {images => public/images}/News_M2PG.png (100%) rename {images => public/images}/News_Maarten.png (100%) rename {images => public/images}/bio-photo.jpg (100%) rename {images => public/images}/dummy.png (100%) rename {images => public/images}/favicon.ico (100%) rename {images => public/images}/logo1.png (100%) rename {images => public/images}/logo2.png (100%) rename {images => public/images}/logopic/Logo_Bdata.png (100%) rename {images => public/images}/logopic/Logo_Bdata_text_below.png (100%) rename {images => public/images}/mm-browser-mockups.png (100%) rename {images => public/images}/mm-layout-examples.png (100%) rename {images => public/images}/newspic/Contest.jpg (100%) rename {images => public/images}/newspic/DomeNews.png (100%) rename {images => public/images}/newspic/LCposter.jpg (100%) rename {images => public/images}/newspic/NewsNP.png (100%) rename {images => public/images}/newspic/SFnews.png (100%) rename {images => public/images}/newspic/Saphireheadline.jpeg (100%) rename {images => public/images}/newspic/SmartTip.png (100%) rename {images => public/images}/newspic/amp.PNG (100%) rename {images => public/images}/newspic/doohee_prize.png (100%) rename {images => public/images}/newspic/order.png (100%) rename {images => public/images}/newspic/scesprizes.jpg (100%) rename {images => public/images}/picpic/Gallery/20150918_145800.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0030.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0051.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0116.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0119.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0128.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0139.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0366.JPG (100%) rename {images => public/images}/picpic/Gallery/DSC_0368.JPG (100%) rename {images => public/images}/picpic/Gallery/DSC_0636.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0683.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0696.jpg (100%) rename {images => public/images}/picpic/Gallery/DSC_0757.jpg (100%) rename {images => public/images}/picpic/Gallery/Group05022015.jpg (100%) rename {images => public/images}/picpic/Gallery/IMG_4334.jpg (100%) rename {images => public/images}/picpic/Gallery/IMG_4376.jpg (100%) rename {images => public/images}/picpic/Gallery/tamagochi.jpg (100%) rename {images => public/images}/picpic/Gallery/tmp2-2.jpg (100%) rename {images => public/images}/picpic/WebpageCornell.jpg (100%) rename {images => public/images}/picpic/WebpageCornell_red.jpg (100%) rename {images => public/images}/picpic/WebpageETH.jpg (100%) rename {images => public/images}/picpic/WebpageETH_red.jpg (100%) rename {images => public/images}/picpic/WebpageLeiden.jpg (100%) rename {images => public/images}/picpic/WebpageLeiden2.jpg (100%) rename {images => public/images}/picpic/WebpageLeiden_red.jpg (100%) rename {images => public/images}/picpic/WebpageSTA.jpg (100%) rename {images => public/images}/picpic/WebpageSTA_red.jpg (100%) rename {images => public/images}/pubpic/DomePub.png (100%) rename {images => public/images}/pubpic/Fano.png (100%) rename {images => public/images}/pubpic/Mott_phase_sep.jpg (100%) rename {images => public/images}/pubpic/PbSpub.png (100%) rename {images => public/images}/pubpic/Pub_327.png (100%) rename {images => public/images}/pubpic/Pub_BCl.png (100%) rename {images => public/images}/pubpic/Pub_CeCoIn5.png (100%) rename {images => public/images}/pubpic/Pub_FP.png (100%) rename {images => public/images}/pubpic/Pub_HFSC.png (100%) rename {images => public/images}/pubpic/Pub_LiFeAs.png (100%) rename {images => public/images}/pubpic/Pub_M2PG.png (100%) rename {images => public/images}/pubpic/Pub_hBN.png (100%) rename {images => public/images}/pubpic/Pub_nemat1.png (100%) rename {images => public/images}/pubpic/Pub_nemat2b.png (100%) rename {images => public/images}/pubpic/SCAUweb copy.jpg (100%) rename {images => public/images}/pubpic/SCAUweb.jpg (100%) rename {images => public/images}/pubpic/SFpub.png (100%) rename {images => public/images}/pubpic/STS_news.png (100%) rename {images => public/images}/pubpic/SmartPub.png (100%) rename {images => public/images}/pubpic/TBG_ARPES.png (100%) rename {images => public/images}/pubpic/TBG_SL.png (100%) rename {images => public/images}/pubpic/TIBB.png (100%) rename {images => public/images}/pubpic/YSR.png (100%) rename {images => public/images}/pubpic/dummy.png (100%) rename {images => public/images}/respic/layers_fft.gif (100%) rename {images => public/images}/respic/layers_fft.jpg (100%) rename {images => public/images}/respic/layers_fft_red.gif (100%) rename {images => public/images}/respic/layers_real.gif (100%) rename {images => public/images}/respic/layers_real.jpg (100%) rename {images => public/images}/respic/layers_real_red.gif (100%) rename {images => public/images}/slider7001400/FabSCAU.jpg (100%) rename {images => public/images}/slider7001400/Group2015_red.jpg (100%) rename {images => public/images}/slider7001400/Logos_h.jpg (100%) rename {images => public/images}/slider7001400/MottMap.jpg (100%) rename {images => public/images}/slider7001400/NoiseCover2.jpg (100%) rename {images => public/images}/slider7001400/STS.jpg (100%) rename {images => public/images}/slider7001400/SaphireSTM2.jpg (100%) rename {images => public/images}/slider7001400/SmartTipSide.jpg (100%) rename {images => public/images}/slider7001400/cake_web.jpg (100%) rename {images => public/images}/slider7001400/dinner2.jpg (100%) rename {images => public/images}/slider7001400/dinner3.jpg (100%) rename {images => public/images}/slider7001400/groupDinner.jpg (100%) rename {images => public/images}/slider7001400/lab.jpg (100%) rename {images => public/images}/slider7001400/logos.jpg (100%) rename {images => public/images}/slider7001400/tamagochi.jpg (100%) rename {images => public/images}/slider7001400/topo214.png (100%) rename {images => public/images}/teampic/CV_Photo4.jpg (100%) rename {images => public/images}/teampic/DSC_1032.JPG (100%) rename {images => public/images}/teampic/Damianos.jpg (100%) rename {images => public/images}/teampic/Doohee2.jpg (100%) rename {images => public/images}/teampic/Freek.jpg (100%) rename {images => public/images}/teampic/Jacky.jpg (100%) rename {images => public/images}/teampic/Jiasen.png (100%) rename {images => public/images}/teampic/Kees.jpg (100%) rename {images => public/images}/teampic/Koen.jpg (100%) rename {images => public/images}/teampic/Maarten.png (100%) rename {images => public/images}/teampic/Milan.jpg (100%) rename {images => public/images}/teampic/Photo Vincent.jpg (100%) rename {images => public/images}/teampic/Photo_Irene.jpg (100%) rename {images => public/images}/teampic/Ram.png (100%) rename {images => public/images}/teampic/Vitaly.JPG (100%) rename {images => public/images}/teampic/Webfoto_HS2.jpg (100%) rename {images => public/images}/teampic/hugo.jpg (100%) rename {images => public/images}/teampic/irene.jpg (100%) rename {images => public/images}/teampic/rock.jpg (100%) rename {images => public/images}/teampic/tjeruk.jpg (100%) rename {images => public/images}/teampic/verdoes.jpg (100%) rename {images => public/images}/teampic/website_pic_willem.jpg (100%) rename {resources => public/resources}/headshots/advait.jpeg (100%) rename {resources => public/resources}/headshots/antoniasaravanou.jpg (100%) rename {resources => public/resources}/headshots/ashishsharma.png (100%) rename {resources => public/resources}/headshots/bretnestor.jpg (100%) create mode 100644 public/resources/headshots/cl.png rename {resources => public/resources}/headshots/deniz.jpeg (100%) rename {resources => public/resources}/headshots/dubs.png (100%) create mode 100644 public/resources/headshots/galenweld.png rename resources/headshots/galenweld.png => public/resources/headshots/galenweldphd.png (100%) rename {resources => public/resources}/headshots/innalin.jpg (100%) rename {resources => public/resources}/headshots/jinasuh.jpg (100%) rename {resources => public/resources}/headshots/joyhe-yueya.jpg (100%) rename {resources => public/resources}/headshots/kengu.jpg (100%) rename {resources => public/resources}/headshots/margaretli.png (100%) rename {resources => public/resources}/headshots/melihyilmaz.png (100%) rename {resources => public/resources}/headshots/mickelliu.png (100%) rename {resources => public/resources}/headshots/mikemerrill.jpeg (100%) rename {resources => public/resources}/headshots/remydeshayes.png (100%) create mode 100644 public/resources/headshots/rongwu.png rename {resources => public/resources}/headshots/tim.png (100%) rename {resources => public/resources}/headshots/timalthoff.jpg (100%) rename {resources => public/resources}/headshots/vinayakgupta.png (100%) rename {resources => public/resources}/headshots/xinyizhou.jpg (100%) create mode 100644 public/resources/headshots/yasaman.png create mode 100644 public/resources/headshots/yasamansefidgar.png rename {resources => public/resources}/pubpdfs/Gu2022UnderstandingAS.pdf (100%) rename {resources => public/resources}/pubpdfs/Weld_Glenski_Althoff_2021.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2014ask.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2015donor.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2016counseling.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2016onlineappendix.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2016pokemon.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2017large.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2017onlineactions.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2017population.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2018psychomotor.pdf (100%) rename {resources => public/resources}/pubpdfs/althoff2022diet.pdf (100%) rename {resources => public/resources}/pubpdfs/althoffModeration.pdf (100%) rename {resources => public/resources}/pubpdfs/althoffPocketskills.pdf (100%) rename {resources => public/resources}/pubpdfs/althoffTalklifeEngagement.pdf (100%) rename {resources => public/resources}/pubpdfs/gordonactivity2019.pdf (100%) rename {resources => public/resources}/pubpdfs/guBLADEBenchmarkingLanguage2024a.pdf (100%) rename {resources => public/resources}/pubpdfs/guHowDoAnalystsUnderstand2024.pdf (100%) rename {resources => public/resources}/pubpdfs/guHowDoDataAnalysts2024.pdf (100%) rename {resources => public/resources}/pubpdfs/hicks2022leveraging.pdf (100%) rename {resources => public/resources}/pubpdfs/kurashima2018tipas.pdf (100%) rename {resources => public/resources}/pubpdfs/lander1966counterexample.pdf (100%) rename {resources => public/resources}/pubpdfs/lin-etal-2022-gendered.pdf (100%) rename {resources => public/resources}/pubpdfs/linIMBUE2024.pdf (100%) rename {resources => public/resources}/pubpdfs/liupaths2020.pdf (100%) rename {resources => public/resources}/pubpdfs/merrillHomekit2020BenchmarkTime2023.pdf (100%) rename {resources => public/resources}/pubpdfs/merrillLanguageModelsStill2024.pdf (100%) rename {resources => public/resources}/pubpdfs/merrillSelfsupervisedPretrainingTransfer2023.pdf (100%) rename {resources => public/resources}/pubpdfs/merrillTransformingWearableData2024a.pdf (100%) rename {resources => public/resources}/pubpdfs/merrill_multiverse_2021.pdf (100%) rename {resources => public/resources}/pubpdfs/mezlini2021estimating.pdf (100%) rename {resources => public/resources}/pubpdfs/miner2022computational.pdf (100%) rename {resources => public/resources}/pubpdfs/sefidgarpassively2020.pdf (100%) rename {resources => public/resources}/pubpdfs/shameli2017gamification.pdf (100%) rename {resources => public/resources}/pubpdfs/sharma2020computational.pdf (100%) rename {resources => public/resources}/pubpdfs/sharma2021facilitating.pdf (100%) rename {resources => public/resources}/pubpdfs/sharma2023human.pdf (100%) rename {resources => public/resources}/pubpdfs/sharma2024computational.pdf (100%) rename {resources => public/resources}/pubpdfs/sharmaFacilitatingSelf-Guided2024.pdf (100%) rename {resources => public/resources}/pubpdfs/suh2020populationscale.pdf (100%) rename {resources => public/resources}/pubpdfs/suhDisparateImpactsOnline2022.pdf (100%) rename {resources => public/resources}/pubpdfs/tanAreLanguageModels2024.pdf (100%) rename {resources => public/resources}/pubpdfs/tseng2016ubicomp.pdf (100%) rename {resources => public/resources}/pubpdfs/weld2022adjusting_confounders.pdf (100%) rename {resources => public/resources}/pubpdfs/weld2022community_values.pdf (100%) rename {resources => public/resources}/pubpdfs/weldMakingOnlineCommunities2024.pdf (100%) rename {resources => public/resources}/pubpdfs/xu2022GLOBEM.pdf (100%) rename {resources => public/resources}/pubpdfs/xu2023globemimwut.pdf (100%) rename {resources => public/resources}/pubpdfs/xuleveraging2019.pdf (100%) rename {resources => public/resources}/pubpdfs/zech2023mhatsengagement.pdf (100%) rename {resources => public/resources}/pubpdfs/zhouCorrectingMisinformation2024.pdf (100%) rename {resources => public/resources}/spons/adobe.jpg (100%) rename {resources => public/resources}/spons/ai2.png (100%) rename {resources => public/resources}/spons/gates.png (100%) rename {resources => public/resources}/spons/msr.gif (100%) rename {resources => public/resources}/spons/nih.png (100%) rename {resources => public/resources}/spons/nsf.png (100%) rename {resources => public/resources}/spons/onr.png (100%) rename {resources => public/resources}/thumbnails/Gu2022UnderstandingAS.png (100%) rename {resources => public/resources}/thumbnails/Weld_Glenski_Althoff_2021.jpg (100%) rename {resources => public/resources}/thumbnails/althoff2014ask.png (100%) rename {resources => public/resources}/thumbnails/althoff2015donor.png (100%) rename {resources => public/resources}/thumbnails/althoff2016counseling.png (100%) rename {resources => public/resources}/thumbnails/althoff2016onlineappendix.png (100%) rename {resources => public/resources}/thumbnails/althoff2016pokemon.png (100%) rename {resources => public/resources}/thumbnails/althoff2017large.png (100%) rename {resources => public/resources}/thumbnails/althoff2017onlineactions.png (100%) rename {resources => public/resources}/thumbnails/althoff2017population.png (100%) rename {resources => public/resources}/thumbnails/althoff2018psychomotor.png (100%) rename {resources => public/resources}/thumbnails/althoff2022diet.png (100%) rename {resources => public/resources}/thumbnails/althoffModeration.png (100%) rename {resources => public/resources}/thumbnails/althoffPocketskills.png (100%) rename {resources => public/resources}/thumbnails/althoffTalklifeEngagement.png (100%) rename {resources => public/resources}/thumbnails/gordonactivity2019.png (100%) rename {resources => public/resources}/thumbnails/guBLADE.png (100%) rename {resources => public/resources}/thumbnails/guHowDoDataAnalysts.png (100%) rename {resources => public/resources}/thumbnails/guHowDoDataAnalystsUnderstand.png (100%) rename {resources => public/resources}/thumbnails/hicks2022leveraging.png (100%) rename {resources => public/resources}/thumbnails/kurashima2018tipas.pdf (100%) rename {resources => public/resources}/thumbnails/kurashima2018tipas.png (100%) rename {resources => public/resources}/thumbnails/lander1966counterexample.png (100%) rename {resources => public/resources}/thumbnails/lin-etal-2022-gendered.png (100%) rename {resources => public/resources}/thumbnails/linIMBUE.png (100%) rename {resources => public/resources}/thumbnails/liupaths2020.png (100%) rename {resources => public/resources}/thumbnails/merrillHomekit2020BenchmarkTime2023.png (100%) rename {resources => public/resources}/thumbnails/merrillLanguageModels.png (100%) rename {resources => public/resources}/thumbnails/merrillSelfsupervisedPretrainingTransfer2023.png (100%) rename {resources => public/resources}/thumbnails/merrillTransforming.png (100%) rename {resources => public/resources}/thumbnails/merrill_multiverse_2021.png (100%) rename {resources => public/resources}/thumbnails/mezlini2021estimating.png (100%) rename {resources => public/resources}/thumbnails/miner2022computational.png (100%) rename {resources => public/resources}/thumbnails/sefidgarpassively2020.png (100%) rename {resources => public/resources}/thumbnails/shameli2017gamification.png (100%) rename {resources => public/resources}/thumbnails/sharma2020computational.png (100%) rename {resources => public/resources}/thumbnails/sharma2021facilitating.png (100%) rename {resources => public/resources}/thumbnails/sharma2023human.png (100%) rename {resources => public/resources}/thumbnails/sharmaComputational.png (100%) rename {resources => public/resources}/thumbnails/sharmafacilitating.png (100%) rename {resources => public/resources}/thumbnails/suh2020populationscale.png (100%) rename {resources => public/resources}/thumbnails/suhDisparateImpactsOnline2022.png (100%) rename {resources => public/resources}/thumbnails/tseng2016ubicomp.jpeg (100%) rename {resources => public/resources}/thumbnails/weld2022adjusting_confounders.JPG (100%) rename {resources => public/resources}/thumbnails/weld2022community_values.jpg (100%) rename {resources => public/resources}/thumbnails/weldmaking.png (100%) rename {resources => public/resources}/thumbnails/xu2022GLOBEM.png (100%) rename {resources => public/resources}/thumbnails/xu2023globemimwut.png (100%) rename {resources => public/resources}/thumbnails/xuleveraging2019.png (100%) rename {resources => public/resources}/thumbnails/zech2023mhatsengagement.png (100%) rename {resources => public/resources}/thumbnails/zhouCorrectingMis.png (100%) create mode 100644 scripts/README.md create mode 100644 scripts/prepare_publication.py create mode 100644 scripts/validate-content.mjs delete mode 100644 split_bibtex.py create mode 100644 tests/publications.test.mjs create mode 100644 tests/test_prepare_publication.py delete mode 100644 tim_bib/althoff2014ask.bib delete mode 100644 tim_bib/althoff2014howtoaskforafavor.bib delete mode 100644 tim_bib/althoff2015donor.bib delete mode 100644 tim_bib/althoff2016counseling.bib delete mode 100644 tim_bib/althoff2016neurips.bib delete mode 100644 tim_bib/althoff2016onlineappendix.bib delete mode 100644 tim_bib/althoff2016pokemon.bib delete mode 100644 tim_bib/althoff2016pokemonold.bib delete mode 100644 tim_bib/althoff2017harnessing.bib delete mode 100644 tim_bib/althoff2017large.bib delete mode 100644 tim_bib/althoff2017onlineactions.bib delete mode 100644 tim_bib/althoff2017population.bib delete mode 100644 tim_bib/althoff2018psychomotor.bib delete mode 100644 tim_bib/althoffmoderation.bib delete mode 100644 tim_bib/althoffpocketskills.bib delete mode 100644 tim_bib/althoffrisescience.bib delete mode 100644 tim_bib/althofftalklifeengagement.bib delete mode 100644 tim_bib/kurashima2018tipas.bib delete mode 100644 tim_bib/kurashima2018tipasdeprecated.bib delete mode 100644 tim_bib/shameli2017gamification.bib delete mode 100644 utils.py diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..9aafbda --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,23 @@ +name: Check website +on: + pull_request: + workflow_dispatch: +permissions: + contents: read +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + - run: npm ci + - run: npm test + - run: python3 -m unittest discover -s tests -p 'test_*.py' + - run: npm run build + - uses: actions/upload-artifact@v4 + with: + name: website-preview + path: out diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..d40269d --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,35 @@ +# Manual until the lab approves switching production to React. +# After the first approved deployment, add a push trigger for master if desired. +name: Deploy React website +on: + workflow_dispatch: +permissions: + contents: read + pages: write + id-token: write +concurrency: + group: pages + cancel-in-progress: false +jobs: + deploy: + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + - run: npm ci + - run: npm test + - run: python3 -m unittest discover -s tests -p 'test_*.py' + - run: npm run build + - uses: actions/configure-pages@v5 + - uses: actions/upload-pages-artifact@v3 + with: + path: out + - name: Deploy + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index c0d8a9b..8f6ca00 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,12 @@ -_site/* -_theme_packages/* - -Thumbs.db +node_modules/ +.next/ +out/ +_review/ .DS_Store +__pycache__/ +*.pyc +.env* +!.env.example -!.gitkeep - -.rbenv-version -.rvmrc - -.sass-cache -.jekyll-metadata -.jekyll-cache - -biblib/__pycache__ - -Gemfile.lock - -__pycache__ \ No newline at end of file +# Machine-local pre-migration recovery inventory +_planning/migration-backup.json diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..a45fd52 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..643577d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,9 @@ + + +# This is NOT the Next.js you know + +This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices. + +This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean. + + diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/CODEBASE.md b/CODEBASE.md new file mode 100644 index 0000000..c79a1c9 --- /dev/null +++ b/CODEBASE.md @@ -0,0 +1,14 @@ +# Codebase map + +- `app/`: Next.js routes, metadata and plain CSS; exported as static HTML. +- `components/`: reusable React navigation, paper cards and publication filters. +- `content/`: editable JSON datasets. These are the source of truth for the public website. +- `lib/`: content access, filtering and citation formatting. +- `public/`: original assets at their historical URL paths. +- `scripts/validate-content.mjs`: content and asset checks, run before every build. +- `scripts/prepare_publication.py`: DOI lookup that creates a local review proposal. +- `tests/`: focused publication filtering, citation and proposal tests. +- `.github/workflows/`: pull-request checks and a manual production deployment. +- `_planning/`: inventory, migration report and future maintenance specification. + +See README.md for commands and contribution instructions. There is no Jekyll or Ruby build path. diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 37f5eaa..0000000 --- a/Gemfile +++ /dev/null @@ -1,2 +0,0 @@ -source 'https://rubygems.org' -gem 'github-pages', group: :jekyll_plugins diff --git a/README.md b/README.md index 9e9de97..200e3dc 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,67 @@ -# Behavioral Data Science Site +# Behavioral Data Science website -This is the website of our academic research group at UW CSE. It is based on the template provided by the [Allan Lab at Leiden University](https://www.allanlab.org/aboutwebsite.html). +A static React website built with Next.js and plain CSS. Content is stored in JSON; the optional DOI helper uses Python's standard library. No Ruby, Jekyll, database, or application server is needed in production. -## Modifying this Site -This website is powered by [Jekyll](https://jekyllrb.com/) and some Bootstrap. To work on the site, clone this repo. If you want to preview your changes before committing them (recommended) you will need to install Jekyll and run a local server in your root directory with `jekyll serve`. +## Run locally -### Jerkyll Installation M1 Mac -If you are having trouble installing Jerkyll on your m1 mac check out this [script](https://github.com/monfresh/laptop) which automatically installs it for you. +Use Node 24 LTS (`nvm use` if you use nvm): -### Worked for Ken 04192023 M1 Mac -Ran the below in the root project folder +```sh +npm ci +npm run dev ``` -gem install bundler jekyl -bundle install -bundle exec jekyll serve + +Open the URL printed by Next.js (normally http://127.0.0.1:3000). + +## Build and check + +```sh +npm test +python3 -m unittest discover -s tests -p 'test_*.py' +npm run build +npm run preview ``` -### Adding a Member -Run `python add_person.py` from the root directory, and follow the prompts as they come up. +The build validates the content and referenced assets, then exports static files into `out/`. Stop the development server before starting the static preview because both default to port 3000. + +## Update content + +| What to edit | Where | +| --- | --- | +| Publications | `content/publications.json` | +| People, roles, status and interests | `content/people.json` | +| Alumni from the original site | `content/alumni.json` | +| News, newest date first | `content/news.json` | +| Sponsors | `content/sponsors.json` | +| Page layout and text | `app/` | +| Shared interface components | `components/` | +| All styling | `app/globals.css` | +| Images, PDFs and downloads | `public/` | + +See `scripts/README.md` for a DOI metadata helper and the review workflow. Keep stable IDs when editing existing records: they determine page URLs. Ordinary papers do not require a thumbnail or local PDF. Do not modify the `legacy` metadata unless correcting an import; it preserves original bibliographic details. + +People's archive publications are matched from stored author names, not live author identities. Check ambiguous names when adding records. The future discovery service will require verified author IDs and membership dates. + +## Review and deploy + +Create a branch and pull request. The check workflow runs content validation, tests and the production build, then saves the exported site as a downloadable artifact. Review the content and preview before merging. + +The React deployment workflow is **manual-only** until the lab approves the production switch. In the GitHub repository, set Pages → Source to GitHub Actions, then run “Deploy React website” after approval. It deploys `out/` at the existing organization site address. No production settings were changed during local migration. Once the lab wants automatic deployment, add a `push` trigger for `master`. + +Do not push the migration to the production branch while the old Pages branch-based Jekyll deployment remains enabled. Use a PR and coordinate the Pages source switch with the first React deployment. + +## Migration and remaining work + +See [Next steps and GitHub issues](_planning/NEXT_STEPS.md) for the current delivery plan and completion criteria. + +All 47 publication records, 21 people records, 12 legacy alumni entries, three news records, seven sponsors and original asset files were preserved. Old route names remain available, including `/team/`, `/publications/`, `/allnews/`, `/vacancies/` and `/idiofid/`. A duplicated PDF path in the old GLOBEM entry was repaired. -### Adding a publication -Use `add_pub.py` from the root directory. +The existing dataset still needs a roster review and publication/award backfill. No new papers, honors or current job titles were inferred. The IdioFID form retains its existing Google Apps Script endpoint; a signup was not submitted during migration. -### Adding a News Item -News items should be manually edited in the `_data/news.yml` collection. +The migration backup location and inventory are recorded in `_planning/migration-backup.json`. It includes the pre-migration legacy source and staged/unstaged Git patches. Generated Jekyll output and installed Ruby dependencies were not archived. Git's existing commit history is intact. -### Contibuting your changes -Since the site is hosted with github pages, anything in the master branch is live (in production). When you make changes, create a new branch and make a pull request [(tutorial here)](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request). If there aren't any common problems then maybe soon anyone from bdata will be able to merge with master, but for now we'll limit it. +**Weekly automatic discovery is not enabled yet.** The DOI helper only prepares local proposals. The next phase is a verified author roster, source discovery, deduplication, one weekly review batch, and independent missed-run monitoring. Private reviewer notes, credentials and signup addresses must stay out of this public repository. -Copyright Allan Lab. Code released under the MIT License. +## Credits +The original website was based on the Allan Lab at Leiden University template. Its content and historical assets are retained with their existing attribution. The current implementation uses React and Next.js. diff --git a/_config.yml b/_config.yml deleted file mode 100644 index bee9f20..0000000 --- a/_config.yml +++ /dev/null @@ -1,50 +0,0 @@ -# Welcome to Jekyll! -# -# This config file is meant for settings that affect your whole blog, values -# which you are expected to set up once and rarely need to edit after that. -# For technical reasons, this file is *NOT* reloaded automatically when you use -# 'jekyll serve'. If you change this file, please restart the server process. - -# Site settings -title: Behavioral Data Dcience -email: althoff@cs.washinton.edu -description: > # this means to ignore newlines until "baseurl:" - Behavioral Data Science @ UW CSE. -baseurl: "" -url: "" - - -RESOURCES_PATH: resources -include: - - .htaccess - - _pages - -collections: - - people - - publications - - pubpdfs - -sass: - sass_dir: _sass - -# Conversion -markdown: kramdown -highlighter: rouge -lsi: false -excerpt_separator: "\n\n" -incremental: false - - - -# Markdown Processing -kramdown: - input: GFM - hard_wrap: false - auto_ids: true - footnote_nr: 1 - entity_output: as_char - toc_levels: 1..6 - smart_quotes: lsquo,rsquo,ldquo,rdquo - enable_coderay: false - parse_block_html: true # default for kramdown is false. This will enable using Markdown links - diff --git a/_data/alumni.yml b/_data/alumni.yml deleted file mode 100644 index 9073886..0000000 --- a/_data/alumni.yml +++ /dev/null @@ -1,23 +0,0 @@ -- name: Mike Merrill, PhD Student - site: https://mikemerrill.io -- name: Chris Rytting, Postdoc - site: https://chrisrytting.github.io/ -- name: Ashish Sharma, PhD Student - site: https://ash-shar.github.io/ -- name: Vinayak Gupta, Postdoc - site: https://gvinayak.github.io/ -- name: Antonia Saravanou, Visiting Researcher - site: https://antonia42.github.io/ -- name: Bret Nestor, Postdoc - site: http://www.cs.toronto.edu/~bretnestor/ -- name: Jina Suh, PhD Student, Fall 2018 - Winter 2023 - site: https://www.microsoft.com/en-us/research/people/jinsuh/ -- name: Jacopo Mocellin, Visiting Master's Student, Spring 2022 -- name: Ethan Hsu, Visiting Master's Student, Summer 2021 - Winter 2022 - site: https://ethan5437.github.io/ -- name: Joy He-Yueya, Bachelor's Student Research Assistant, Fall 2019 - Spring 2021 - site: https://joyheyueya.github.io/ -- name: Remy Deshayes, Visiting Master's Student, Summer 2020 - Fall 2020 - site: https://remydeshayes.github.io/ -- name: Ge Zhang, Visiting Bachelor's Student, Fall 2019 - Fall 2020 - site: https://gezhangrp.com/ diff --git a/_data/news.yml b/_data/news.yml deleted file mode 100644 index 76f84e5..0000000 --- a/_data/news.yml +++ /dev/null @@ -1,6 +0,0 @@ -- date: September 2nd 2020 - headline: "Welcome to our new PhD Students Inna and Ken!" -- date: June 10th 2021 - headline: "Tim, Inna, Ashish, and Galen win 4 Best Paper awards at WWW, ICWSM, and NLP4IF!" -- date: November 2nd 2020 - headline: "Our fancy site is live!" diff --git a/_data/sponsors.yml b/_data/sponsors.yml deleted file mode 100644 index 03d5c1d..0000000 --- a/_data/sponsors.yml +++ /dev/null @@ -1,14 +0,0 @@ -- path: /spons/adobe.jpg - name: Adobe -- path: /spons/ai2.png - name: AI2 -- path: /spons/gates.png - name: The Bill and Melinda Gates Foundation -- path: /spons/msr.gif - name: Microsoft Research -- path: /spons/nih.png - name: The National Institutes of Health -- path: /spons/nsf.png - name: The National Science Foundation -- path: /spons/onr.png - name: The Office of Naval Research \ No newline at end of file diff --git a/_includes/about.md b/_includes/about.md deleted file mode 100644 index 2c06704..0000000 --- a/_includes/about.md +++ /dev/null @@ -1 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Turpis tincidunt id aliquet risus feugiat in ante metus. Lacus vel facilisis volutpat est velit egestas dui id ornare. Sed enim ut sem viverra aliquet eget. \ No newline at end of file diff --git a/_includes/analytics.html b/_includes/analytics.html deleted file mode 100644 index 833e7a8..0000000 --- a/_includes/analytics.html +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/_includes/contact.md b/_includes/contact.md deleted file mode 100644 index 6905bab..0000000 --- a/_includes/contact.md +++ /dev/null @@ -1,4 +0,0 @@ -- Email: mikeam@cs.washington.edu -- [📚 Google Scholar](https://scholar.google.com/citations?user=lK6SO9IAAAAJ&hl=en) -- [🐦 Twitter](https://twitter.com/Mike_A_Merrill) -- [📄 CV](./resources/Mike_Merrill_CV.pdf) \ No newline at end of file diff --git a/_includes/footer.html b/_includes/footer.html deleted file mode 100644 index bc6063c..0000000 --- a/_includes/footer.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - diff --git a/_includes/group.md b/_includes/group.md deleted file mode 100644 index d25fbdd..0000000 --- a/_includes/group.md +++ /dev/null @@ -1,55 +0,0 @@ -# Our Group - - - -
- -{% assign sorted_people = site.people | sort: 'priority' | where:"is_visiting","false" | where: 'inactive', nil%} -{% for member in sorted_people %} -{% unless member.inactive %} -
-
- - -#### [{{ member.name }}]({{member.site}}) - -{{ member.title }} - -
- -
-{% endunless %} -{% endfor %} - -
- -{% assign sorted_visitors = site.people | sort: 'priority' | where:"is_visiting","true" | where: 'inactive', nil%} -{% if sorted_vistors %} -## Current Visitors -
- -{% for member in sorted_visitors %} - -
-
- - -#### [{{ member.name }}]({{member.site}}) - -{{ member.title }} - -
-
-{% endfor %} - -
-{% endif %} -## Alumni - - \ No newline at end of file diff --git a/_includes/head.html b/_includes/head.html deleted file mode 100644 index a1c9ec8..0000000 --- a/_includes/head.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - {% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %} - - - - - -{% if jekyll.environment == 'production' %} -{% include analytics.html %} -{% endif %} - - diff --git a/_includes/header.html b/_includes/header.html deleted file mode 100644 index 9cb9786..0000000 --- a/_includes/header.html +++ /dev/null @@ -1,39 +0,0 @@ - diff --git a/_includes/interests.md b/_includes/interests.md deleted file mode 100644 index 2b9bc22..0000000 --- a/_includes/interests.md +++ /dev/null @@ -1,4 +0,0 @@ -- Data Science -- Human Wellbeing -- Behavior -- Yoyos \ No newline at end of file diff --git a/_includes/news.html b/_includes/news.html deleted file mode 100644 index 2fb6bd9..0000000 --- a/_includes/news.html +++ /dev/null @@ -1,12 +0,0 @@ - -
-

News

- -{% for article in site.data.news limit:9 %} -{{ article.date }} -

{{ article.headline }}

-{% endfor %} - -

... see all News

- -
diff --git a/_includes/sponsors.html b/_includes/sponsors.html deleted file mode 100644 index cee54a4..0000000 --- a/_includes/sponsors.html +++ /dev/null @@ -1,7 +0,0 @@ - -
- {% for img in site.data.sponsors %} - - {% endfor %} -
- \ No newline at end of file diff --git a/_layouts/default.html b/_layouts/default.html deleted file mode 100644 index cd96ba4..0000000 --- a/_layouts/default.html +++ /dev/null @@ -1,14 +0,0 @@ - - - {% include head.html %} - - - {% include header.html %} - -
-
{{ content }}
-
- - {% include footer.html %} - - diff --git a/_layouts/gridlay.html b/_layouts/gridlay.html deleted file mode 100644 index 4560794..0000000 --- a/_layouts/gridlay.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -layout: default ---- -
- {{ content }} -
diff --git a/_layouts/homelay.html b/_layouts/homelay.html deleted file mode 100644 index ea6c165..0000000 --- a/_layouts/homelay.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -layout: default ---- - -
-

Welcome to the Behavioral Data Science Lab

- - {{ content }} -
-
- - -

Support From

- {% include sponsors.html %} -
diff --git a/_layouts/page.html b/_layouts/page.html deleted file mode 100644 index ce233ad..0000000 --- a/_layouts/page.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -layout: default ---- -
- -
-

{{ page.title }}

-
- -
- {{ content }} -
- -
diff --git a/_layouts/piclay.html b/_layouts/piclay.html deleted file mode 100644 index 3a7ddca..0000000 --- a/_layouts/piclay.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: default ---- - -
- {{ content }} -
diff --git a/_layouts/post.html b/_layouts/post.html deleted file mode 100644 index 3a0fb52..0000000 --- a/_layouts/post.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -layout: default ---- -
- -
-

{{ page.title }}

- -
- -
- {{ content }} -
- -
diff --git a/_layouts/publications.html b/_layouts/publications.html deleted file mode 100644 index ac4e92c..0000000 --- a/_layouts/publications.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -layout: default ---- -
- {{ content }} -
diff --git a/_layouts/research.html b/_layouts/research.html deleted file mode 100644 index 1fb65e7..0000000 --- a/_layouts/research.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -layout: default ---- -
- {{ content }} -
diff --git a/_layouts/team.html b/_layouts/team.html deleted file mode 100644 index c17f2ce..0000000 --- a/_layouts/team.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: default ---- -
- {{ content }} -
- diff --git a/_layouts/textlay.html b/_layouts/textlay.html deleted file mode 100644 index a2bbf5e..0000000 --- a/_layouts/textlay.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -layout: default ---- -
- {{ content }} -
diff --git a/_pages/404.md b/_pages/404.md deleted file mode 100755 index cd29c19..0000000 --- a/_pages/404.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Page Not Found" -layout: default -excerpt: "Page not found. We didn't predict this behavior." -sitemap: false -permalink: /404.html ---- - -Sorry, but the page you were trying to view does not exist. - diff --git a/_pages/_home_pretty.md b/_pages/_home_pretty.md deleted file mode 100644 index 0037a03..0000000 --- a/_pages/_home_pretty.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: "Behavioral Data Science - Home" -layout: homelay -excerpt: "Behavioral Data Science @ UW" -sitemap: false -permalink: / ---- - -We are a research group at the [Paul G. Allen School of Computer Science of Engineering](http://cs.washington.edu). Our aim is to explore and understand behavioral through the lense of data science. - - - - - - - -To this end, we .... COPY THAT MAKES US LOOK GOOD - - **We are looking for passionate new PhD students, Postdocs, and Master students to join the team** [(more info)]({{ site.url }}{{ site.baseurl }}/vacancies) **!** - - -We are grateful for funding from... WHO FUNDS US. - -
- - - - -
diff --git a/_pages/aboutwebsite.md b/_pages/aboutwebsite.md deleted file mode 100644 index bd18ba1..0000000 --- a/_pages/aboutwebsite.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "About the website" -layout: textlay -excerpt: "About the website." -sitemap: false -permalink: /aboutwebsite.html ---- - -# Use this website as a template for your academic research group - -This website is powered by [Jekyll](https://jekyllrb.com) and uses some [Bootstrap](http://www.getbootstrap.com) and [Bootswatch](http://www.bootswatch.com). We tried to make it simple yet adaptable, so that it is easy for you to re-use it for your purpose. - -### Getting started -All pages are written in [markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) for easy editing, and [Jekyll](https://jekyllrb.com) uses Liquid for the data-driven pages. The publicaion list, news items, and group members are stored as `.yml` data sheets (plain text) in the `_data folder`, so that one can update the website easily. The pages are in the `_pages` folder. Updating and maintaining is easy using [Github](http://www.github.com) (not worldpress-easy, but there are other advantages (see e.g. [this](https://www.taniarascia.com/make-a-static-website-with-jekyll/), or [this](http://www.webdesignerdepot.com/2015/11/jekyll-against-the-rest-of-the-world/)). [Jekyll](https://jekyllrb.com) takes all the markdown and data files, and creates beautiful `html` files in the `_site` folder. - -If you never used [Jekyll](https://jekyllrb.com), read the [wikipedia article](https://en.wikipedia.org/wiki/Jekyll_(software)) article and check out [their website](https://jekyllrb.com). Same for [Github](http://www.github.com), which will host your first website draft. - -Create and open a github account, go to [our repository](https://github.com/allanlab/allanlab), and click 'fork'. This is now your copy of the website, and you can change and adapt it as you want. You don't have to link to us or mention us (but of course we appreciate it). Then change the name of the repository to "your_username" and the name of the branch to "gh-pages". Your website is now automatically published under *your_username.github.io/your_username/*. Except that it probably still looks like our website. - -To modify the webpage, you can either do everything on on github.com (go to a file, click "edit", then "commit", "push"), or install [Jekyll](https://jekyllrb.com) on your computer and play with your local copy that you sync with the branch on github.com. The former is much easier in the beginning, but a bit less convenient once you start rewriting everythint. To get it to work on your computer (and to learn a bit more about [Jekyll](https://jekyllrb.com)), [here](https://www.taniarascia.com/make-a-static-website-with-jekyll/) and [here](https://scotch.io/tutorials/getting-started-with-jekyll-plus-a-free-bootstrap-3-starter-theme) are tutorials on how to use it and how set it up locally. Also, consider using the [Github desktop app](http://www.desktop.github.com), I found it helpful. - -### Customization -Now let's make this *your* website. - -First, go to the `news.ylm`, `publist.ylm`, and `team.ylm` files in the `_data` folder and insert your own data into the data fields. Watch out: [Jekyll](https://jekyllrb.com) is quite strict about extra or missing spaces etc. Adhere to the format. In the beginning, test each change: commit, push, and check the published website. - -For publications, you can add a "1" in the highlight field, then it will be featured prominently. You can add important news items (red, "news1"), and less important news items (blue, "news2"). - -For the news items, just keep adding them. The first 10 will be displayed on the 'home' page. - -For the `team.ylm` file - -Next, change the content of all files in the `_pages` folder. To change the title in the homepage, go to `homelay.html` in the `_layout` folder. - -Lastly, change the footer and perhaps header appropriately (in `_include`). - -You might also want to change the style or theme. I imported style files (in sass) from Bootstrap/Bootwatch, you can replace them with your own (in the `_sass directory`). For small changes, just work on the override stuff in the `main.sass` file in the `CSS` folder. Or change some variables in the `_variables.sass` file, like the background color etc. - -As said, [Jekyll](https://jekyllrb.com) takes all the markdown and data files, and creates beautiful `html` files in the `_site` folder.In the end, either upload these files to your server, or buy yourself a domain and check the instructions on github on how to host it there. - -### Copyright / credit - -You can use this template as you please. You don't have to link to us or mention us (but of course we appreciate it). We also welcome it if you send us an email with a link to your website, perhaps we'll publish a list here at some point. - -Comments welcome. - -Code released under the MIT License. - - - diff --git a/_pages/allnews.md b/_pages/allnews.md deleted file mode 100644 index 5ff3475..0000000 --- a/_pages/allnews.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: "News" -layout: textlay -excerpt: "Behavioral Data Science @ UW CSE" -sitemap: false -permalink: /allnews.html ---- - -# News - -{% for article in site.data.news %} -

{{ article.date }}
-{{ article.headline }}

-{% endfor %} diff --git a/_pages/home.md b/_pages/home.md deleted file mode 100644 index 8f23d9d..0000000 --- a/_pages/home.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: "Behavioral Data Science - Home" -layout: homelay -excerpt: "Behavioral Data Science @ UW" -sitemap: false -permalink: / ---- - -We are a research group at the [Paul G. Allen School of Computer Science of Engineering](http://cs.washington.edu). Our aim is to explore and understand behavior through the lens of data science. - -The Behavioral Data Science Group develops computational methods that leverage large-scale behavioral data to extract actionable insights about our lives, health and happiness through combining techniques from data science, social network analysis, and natural language processing. We currently work on research related to mental health, misinformation online, scientific reproducibility, and informing the COVID-19 response. - -We have a [postdoc position](https://docs.google.com/document/d/1h44Gz1wOMx6QhHUWv9QFB3Jnrn-JzEMPHC0WZhPMEqU/edit#) available. - -We are also looking for PhD students, especially in but not limited to deep learning, causal inference, data science and mobile health. If you're interested please apply to the UW Allen School. Go Dawgs! - -{% include group.md %} diff --git a/_pages/idiofid.md b/_pages/idiofid.md deleted file mode 100644 index 7496958..0000000 --- a/_pages/idiofid.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: "Idiographic Fidelity Benchmark – Updates" -layout: textlay -excerpt: "Notification page for the Idiographic Fidelity Benchmark release." -sitemap: false -permalink: /idiofid/ ---- - -# Idiographic Fidelity Benchmark – Attitude (IdioFid-A) - -IdioFid-A is a benchmark for evaluating how well AI agents can infer a specific person’s attitudes from their real social media history. Leave your email to get a one-time notification when the benchmark, dataset, and code are public. - -
-
- -
- - -
-
We’ll only email about this benchmark.
-
- - -
diff --git a/_pages/openings.md b/_pages/openings.md deleted file mode 100644 index 2ab2d93..0000000 --- a/_pages/openings.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Behavioral Data Science - Vacancies" -layout: textlay -excerpt: "Openings" -sitemap: false -permalink: /vacancies ---- - -# Open positions -WRITE ABOUT OPEN POSITIONS HERE diff --git a/_pages/pictures.md b/_pages/pictures.md deleted file mode 100644 index 6760ea7..0000000 --- a/_pages/pictures.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Behavioral Data Science - Pictures" -layout: piclay -excerpt: "Behavioral Data Science -- Pictures" -permalink: /pictures/ ---- - -# Pictures -This page could contain pictures (once we're all together again!) - diff --git a/_pages/publications.md b/_pages/publications.md deleted file mode 100644 index 5968115..0000000 --- a/_pages/publications.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "Behavioral Data Science - Publications" -layout: gridlay -excerpt: "Behavioral Data Science -- Publications." -sitemap: false -permalink: /publications/ ---- - - -# Publications - -## Group highlights -(For a full list see [below](#full-list)) - -{% assign highlights = site.publications | where_exp:"pub","pub.highlight>=1"%} - -
- -{% for pub in highlights %} - -{% if pub.journal %} - {% assign venue = pub.journal %} -{% elsif pub.booktitle %} - {% assign venue = pub.booktitle %} -{% else %} - {% assign venue = "BLANK" %} -{% endif %} - -
-
- -
-
-{{ pub.title }} -
-

{{ pub.author }} - -
{{venue}} {{ pub.year}} -{% if pub.award %} -🏆 {{ pub.award }} -{% endif %} -

-

{{ pub.description }}

-

- {% if pub.pdf %}[PDF] {% endif %}{% if pub.code %}[CODE] {% endif %} -

-
-
-
- -{% endfor %} - -
- -## Full List - -
-{% assign sorted_pubs = site.publications | sort: 'year' | reverse %} -{% for pub in sorted_pubs %} - - -{% if pub.journal %} - {% assign venue = pub.journal %} -{% elsif pub.booktitle %} - {% assign venue = pub.booktitle %} -{% else %} - {% assign venue = "BLANK" %} -{% endif %} - - -
-
- -
-
-{{ pub.title }} -
-

{{ pub.author }} -
{{venue}} {{ pub.year}} -{% if pub.award %} -🏆 {{ pub.award }} -{% endif %} - -

- -{% if pub.pdf %} -[PDF] -{% endif %} -
-
-
- -{% endfor %} - -
diff --git a/_pages/research.md b/_pages/research.md deleted file mode 100644 index ed6875c..0000000 --- a/_pages/research.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: "Behavioral Data Science - Research" -layout: textlay -excerpt: "Behavioral Data Science -- Research" -sitemap: false -permalink: /research/ ---- - -# Research - -This page would contain a more detailed description of our research. - -![]({{ site.url }}{{ site.baseurl }}/images/respic/layers_real.jpg){: style="width: 300px; float: right; border: 10px"} - - -![]({{ site.url }}{{ site.baseurl }}/images/respic/layers_fft.jpg){: style="width: 300px; float: left; border: 10px"} - diff --git a/_pages/team.md b/_pages/team.md deleted file mode 100644 index f19fa97..0000000 --- a/_pages/team.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: "Behavioral Data Science - Team" -layout: gridlay -excerpt: "Behavioral Data Science: Team members" -sitemap: false -permalink: /team/ ---- - -{% include group.md %} diff --git a/_people/advaitbhat.md b/_people/advaitbhat.md deleted file mode 100644 index 2094eb5..0000000 --- a/_people/advaitbhat.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -headshot: advait.jpeg -is_visiting: false -name: Advait Bhat -priority: 4 -research_areas: - - Human-AI Interaction - - Human-Computer Interaction - - Natural Language Processing - - Computational Social Science -site: https://advaitmb.com/ -title: PhD Student ---- \ No newline at end of file diff --git a/_people/antoniasaravanou.md b/_people/antoniasaravanou.md deleted file mode 100644 index a0d9dc8..0000000 --- a/_people/antoniasaravanou.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -headshot: antoniasaravanou.jpg -is_visiting: false -name: Antonia Saravanou -priority: 5 -research_areas: null -site: https://antonia42.github.io/ -title: Visiting Researcher -inactive: true ---- \ No newline at end of file diff --git a/_people/ashishsharma.md b/_people/ashishsharma.md deleted file mode 100644 index 7b78b52..0000000 --- a/_people/ashishsharma.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -headshot: ashishsharma.png -is_visiting: false -name: Ashish Sharma -priority: 5 -research_areas: - - NLP - - Computational Social Science -site: https://ash-shar.github.io/ -title: PhD Student -inactive: true ---- diff --git a/_people/bretnestor.md b/_people/bretnestor.md deleted file mode 100644 index c8e0722..0000000 --- a/_people/bretnestor.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -headshot: bretnestor.jpg -is_visiting: false -name: Bret Nestor -priority: 5 -research_areas: null -site: http://www.cs.toronto.edu/~bretnestor/ -title: Postdoc -inactive: true ---- \ No newline at end of file diff --git a/_people/deniznazarova.md b/_people/deniznazarova.md deleted file mode 100644 index c015427..0000000 --- a/_people/deniznazarova.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -headshot: deniz.jpeg -is_visiting: false -name: Deniz Nazarova -priority: 4 -research_areas: - - AI in Therapy - - NLP - - Multilingual NLP - - AI Bias - - HCI -site: https://gonzoden.github.io/ -title: PhD Student ---- \ No newline at end of file diff --git a/_people/galenweld.md b/_people/galenweld.md deleted file mode 100644 index 7387d00..0000000 --- a/_people/galenweld.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -headshot: galenweld.png -is_visiting: false -name: Galen Weld -priority: 5 -research_areas: -- causal inference -- ' online communities' -site: https://galenweld.com/ -title: PhD Student ---- diff --git a/_people/innalin.md b/_people/innalin.md deleted file mode 100644 index 3e8bc9e..0000000 --- a/_people/innalin.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -headshot: innalin.jpg -is_visiting: false -name: Inna Lin -priority: 5 -research_areas: null -site: https://innawy.github.io -title: PhD Student ---- diff --git a/_people/jinasuh.md b/_people/jinasuh.md deleted file mode 100644 index 1b1a05c..0000000 --- a/_people/jinasuh.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -headshot: jinasuh.jpg -is_visiting: false -name: Jina Suh -priority: 4 -research_areas: - - Human-Centered Data Science - - Human-Centered Design - - Human-Centered AI -site: https://www.microsoft.com/en-us/research/people/jinsuh/ -title: PhD -inactive: true ---- diff --git a/_people/joyhe-yueya.md b/_people/joyhe-yueya.md deleted file mode 100644 index 94c1ae8..0000000 --- a/_people/joyhe-yueya.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -headshot: joyhe-yueya.jpg -is_visiting: false -name: Joy He-Yueya -priority: 8 -research_areas: null -site: https://joyheyueya.github.io -title: Bachelor's Student -inactive: true ---- \ No newline at end of file diff --git a/_people/kengu.md b/_people/kengu.md deleted file mode 100644 index ac3c431..0000000 --- a/_people/kengu.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -headshot: kengu.jpg -is_visiting: false -name: Ken Gu -priority: 5 -research_areas: null -site: https://kenqgu.com/ -title: PhD Student ---- \ No newline at end of file diff --git a/_people/margaretli.md b/_people/margaretli.md deleted file mode 100644 index 0b0d048..0000000 --- a/_people/margaretli.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -headshot: margaretli.png -is_visiting: false -name: Margaret Li -priority: 5 -research_areas: -- NLP -- Dialogue -- ML -site: https://margs.li -title: PhD Student ---- \ No newline at end of file diff --git a/_people/melihyilmaz.md b/_people/melihyilmaz.md deleted file mode 100644 index ef50439..0000000 --- a/_people/melihyilmaz.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -headshot: melihyilmaz.png -is_visiting: false -name: Melih Yilmaz -priority: 5 -research_areas: null -site: null -title: PhD Student -inactive: true ---- \ No newline at end of file diff --git a/_people/mickelliu.md b/_people/mickelliu.md deleted file mode 100644 index 783b1bb..0000000 --- a/_people/mickelliu.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -headshot: mickelliu.png -is_visiting: false -name: Mickel Liu -priority: 4 -research_areas: - - Agent Alignment - - Multi-Agent Systems - - Large Language Models - - Reinforcement Learning -site: https://mickel-liu.github.io/ -title: PhD Student ---- \ No newline at end of file diff --git a/_people/mikemerrill.md b/_people/mikemerrill.md deleted file mode 100644 index bbe32c8..0000000 --- a/_people/mikemerrill.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -headshot: mikemerrill.jpeg -is_visiting: false -name: Mike Merrill -priority: 5 -research_areas: null -site: https://mikemerrill.io -title: PhD Student -inactive: true ---- \ No newline at end of file diff --git a/_people/remydeshayes.md b/_people/remydeshayes.md deleted file mode 100644 index dd395dc..0000000 --- a/_people/remydeshayes.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -headshot: remydeshayes.png -is_visiting: true -name: Remy Deshayes -priority: 7 -research_areas: null -site: https://remydeshayes.github.io/ -title: Master's Student ---- diff --git a/_people/timalthoff.md b/_people/timalthoff.md deleted file mode 100644 index f463d86..0000000 --- a/_people/timalthoff.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -headshot: timalthoff.jpg -is_visiting: false -name: Tim Althoff -priority: 2 -research_areas: null -site: http://www.timalthoff.com/ -title: Assistant Professor ---- \ No newline at end of file diff --git a/_people/vinayakgupta.md b/_people/vinayakgupta.md deleted file mode 100644 index edbbc60..0000000 --- a/_people/vinayakgupta.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -headshot: vinayakgupta.png -is_visiting: false -name: Vinayak Gupta -priority: 5 -research_areas: null -site: https://gvinayak.github.io/ -title: Postdoc -inactive: true ---- diff --git a/_people/xinyizhou.md b/_people/xinyizhou.md deleted file mode 100644 index f6da3fa..0000000 --- a/_people/xinyizhou.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -headshot: xinyizhou.jpg -is_visiting: false -name: Xinyi Zhou -priority: 3 -research_areas: null -site: https://xinyizhou.xyz/ -title: Postdoc ---- \ No newline at end of file diff --git a/_planning/MODERN_STACK_OPTIONS.md b/_planning/MODERN_STACK_OPTIONS.md new file mode 100644 index 0000000..ee8c6c3 --- /dev/null +++ b/_planning/MODERN_STACK_OPTIONS.md @@ -0,0 +1,111 @@ +# Modern website tooling assessment + +**Historical audit/research:** See [NEXT_STEPS.md](NEXT_STEPS.md) for the current React implementation roadmap and issue tracker. Earlier Jekyll/Astro recommendations and delivery phases below are superseded. + +**Selected stack:** React + Next.js, plain CSS, JSON/Markdown content, Python maintenance helpers, and GitHub Pages. The React migration is implemented locally; automated weekly discovery and production deployment remain pending. Earlier framework comparisons below are historical research. +Research memo, September 4, 2026. Proposals only; no packages installed, site rebuilt, services connected, or hosting changed. Based on the existing feature spec, repository audit, and a dedicated research sub-agent's findings. + +## Recommended direction + +**Preference update:** The user prioritizes a simple, familiar stack that future lab members can maintain and has not accepted Astro. The Astro recommendation below is retained as a researched option, not a selected stack. Reassess Jekyll modernization for Git-comfortable maintainers and managed WordPress for editors who need a graphical interface. React/Next.js is an alternative if maintainers already know React, but familiarity alone does not reduce its dependency and build requirements. + +Rebuild the public website with **Astro and TypeScript**, store approved people/paper/award records as schema-validated content in Git, add **Pagefind** for search, and build a separate **Python ingestion service** that proposes **one GitHub pull request per weekly review batch**. Keep GitHub Pages as the production host initially. Add a browser-based content editor only if the reviewers need it. + +This replaces the old presentation stack while preserving the repository, public address, assets, citation links and editorial history. The automation service handles content collection; changing the page framework alone will not keep papers or awards current. + +## Current dependencies and build environment + +Verified from source: + +- `Gemfile.lock`: `github-pages` 231, pinning Jekyll 3.9.5. +- Loaded Bootstrap asset: 3.3.6. +- `_includes/footer.html` loads jQuery 1.11.3 from a CDN. A separate jQuery 3.3.1 asset exists locally; it is not the footer's loaded version. +- Markdown/YAML collections and manually maintained BibTeX helpers. +- No tracked custom `.github` workflows in the audited commit. +- Host tools: Node 23.6.1, Python 3.12.4, system Ruby 2.6.10. These are local tool versions, not a claim about GitHub's deployment runtime. + +For the new build, pin a supported Node LTS release with the package lockfile. Node's current release table lists 24 as LTS and 23 as end of life. Do not build on the host's default Node 23 simply because it is already installed. [Node releases](https://nodejs.org/en/about/previous-releases) + +## Framework comparison + +| Option | Fit for this lab | Tradeoff | Recommendation | +| --- | --- | --- | --- | +| Astro + TypeScript | Public research site with structured collections, generated profiles, papers, projects and selective interactive UI. | Templates and content references need migration; weekly review and discovery remain custom work. | Preferred rebuild. | +| Next.js | Stronger fit if the product becomes a substantial signed-in application with a custom dashboard and server-side features. | More runtime/application concerns when using server features; static export cannot provide those features by itself. | Choose only if the editorial application becomes a central requirement. | +| Modernize existing Jekyll | Retain existing templates and add search/import/review independently. | Least migration, but retains Liquid/Ruby tooling and requires deliberate theme cleanup. | Valid lower-effort alternative. | + +Astro provides typed content schemas and relationships between collections. Its official migration guide covers translating Jekyll content/templates, and its deployment guide supports static output on GitHub Pages. These capabilities are a good fit for the existing Markdown/YAML source. [Content collections](https://docs.astro.build/en/guides/content-collections/), [Jekyll migration](https://docs.astro.build/en/guides/migrate-to-astro/from-jekyll/), [GitHub Pages deployment](https://docs.astro.build/en/guides/deploy/github/) + +Use a maintained stable release verified at implementation time, rather than targeting an unverified newest patch. Record runtime compatibility in the project and CI configuration. + +Next.js documents the features unavailable in [static export mode](https://nextjs.org/docs/pages/guides/static-exports). Jekyll remains a maintained option; the older version pinned here should not be confused with the entire framework being obsolete. [Jekyll documentation](https://jekyllrb.com/docs/github-pages/) + +## Feature-to-tool mapping + +| Needed capability | Proposed tool | What it supplies | What we still build/configure | +| --- | --- | --- | --- | +| Fast, responsive public pages | Astro, TypeScript, modern CSS | Page generation, components, typed data access. | Lab visual design, navigation, layout, mobile behavior. | +| People, papers, projects, awards | Astro content collections + Markdown/YAML/JSON | Schemas, validation and content references. | Lab schema, migration, author identity mapping, cross-linked views. | +| Search and filters | Pagefind | Static search index, browser UI/API, metadata facets. | Person/year/topic/venue metadata, index boundaries, result design and empty states. | +| Weekly review | GitHub PRs and required checks | Diffs, review history, branches, controlled merging. | Importer-generated batch, evidence summary, edits/rejections/defer actions, rejection memory. | +| Browser-based manual editing | Optional Decap CMS | Forms over Git content and an editorial workflow. | Authentication, content schemas and previews. Its per-entry workflow is distinct from our multi-record batch. | +| Paper discovery | OpenAlex or Semantic Scholar; Crossref; arXiv | Publication metadata, author lookup, DOI/preprint records. | Identity verification, lab-relevance policy, deduplication, version linkage and reconciliation. | +| Awards and news | Source feeds/pages plus member submissions | Raw evidence and announcements. | Selected sources, extraction, exact recipients/award category, human approval. | +| Deployment | GitHub Actions + GitHub Pages | Build and publish approved static output. | CI checks, permissions, old-route preservation, rollback, separate review previews if desired. | +| Scheduled maintenance | Actions plus independent health check, or lab-owned external scheduler | Job execution. | Source state, retries, missed-run detection, owner and notification destination. | +| Quality | Playwright + axe-core, schema checks, link checks | Browser assertions and automated accessibility checks. | Meaningful interaction tests, redirects, manual keyboard/visual review, content correctness tests. | +| Release notifications | Preserve existing IdioFID integration initially | Existing signup flow. | Verify ownership, operation and whether it should be replaced; keep addresses outside the public content repository. | + +Pagefind indexes rendered HTML and ships a static search bundle, so it does not require a hosted search database. The site must emit searchable content and filter metadata correctly. [Pagefind](https://pagefind.app/) + +Playwright documents axe-core integration, while noting that automated checks cannot detect every accessibility problem. Include manual keyboard navigation and responsive review. [Accessibility testing](https://playwright.dev/docs/accessibility-testing) + +## Editing tools: the distinction that matters + +The user has chosen a weekly batch reviewed before publication. Start with a bot-generated GitHub PR that covers the entire batch, plus a readable change summary. This aligns with the current repository and needs no separate CMS account. + +Decap CMS is a candidate for convenient manual edits to people, news or opportunities. Its editorial mode creates a PR for each unpublished entry; it does not implement a weekly batch spanning multiple papers, people and awards. Keep those two paths explicit and do not promise that installing a CMS supplies the ingestion/reconciliation system. Direct saving is the default, so configure editorial mode if using Decap. [Decap editorial workflow](https://decapcms.org/docs/editorial-workflows/) + +A hosted CMS becomes worthwhile if nontechnical editors need a richer shared workspace and the lab accepts another service, access configuration and possible recurring costs. It should replace the relevant editing path rather than create competing authoritative copies of publication data. + +Decap's [GitHub backend](https://decapcms.org/docs/github-backend/) requires an OAuth server/service and repository push access for editors. [Keystatic GitHub mode](https://keystatic.com/docs/github-mode) is another credible Git-backed editing option, but introduces a GitHub App, secrets and collaborator access. Choose at most one editor after the pilot rather than layering several onto the same records. + +## External service choices + +- OpenAlex is the recommended first discovery provider. Current documentation describes a free API key with a daily usage allowance, so budget and instrument queries rather than assuming unlimited access. [Pricing](https://help.openalex.org/access/pricing/), [example costs](https://help.openalex.org/access/example-costs/) +- Crossref supports DOI metadata lookup without signup. Use it to normalize publisher records. [REST API](https://www.crossref.org/documentation/retrieve-metadata/rest-api/) +- Semantic Scholar is a secondary coverage option; verify access and rate limits when configuring it. [API](https://www.semanticscholar.org/product/api) +- Healthchecks.io is a candidate for independent detection of missed jobs; an existing lab monitor can fill the same role. [How monitoring works](https://healthchecks.io/docs/) +- Cloudflare Pages can provide branch previews if needed. Preview access must be configured deliberately, and per-file asset limits matter for existing PDFs. [Preview deployments](https://developers.cloudflare.com/pages/configuration/preview-deployments/), [platform limits](https://developers.cloudflare.com/pages/platform/limits/) + +These services need separate setup where chosen. The recommended public site and search can remain static; recurring costs are most likely to arise from optional editing, preview, monitoring, API or AI services. Assess quotas using a real import batch before committing to paid plans. + +## Hosting, previews and reliability + +Keep the existing `behavioral-data.github.io` address and Git repository. GitHub Pages can host Astro output, so framework migration does not require a production hosting migration. Preserve all existing routes and PDF links with a tested migration map. + +GitHub Pages production deployment and per-PR previews are separate requirements. Start with local previews or CI build artifacts; if reviewers need clickable previews for every batch, configure a preview service explicitly and check access. Public-repository branches and PR descriptions are public even when unpublished on the production website. Private submissions and reviewer notes need separate storage. + +GitHub scheduled jobs can be disabled after 60 days without repository activity. Add a missed-run monitor independent of the scheduled job, or use an external lab-owned scheduler. No-content-change runs must still record health somewhere appropriate. [GitHub workflow inactivity](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/disable-and-enable-workflows) + +When implementing the bot, test automated PR checks and deployment triggers end to end. GitHub documents special behavior for events created by `GITHUB_TOKEN`, including approval requirements for some automated PR workflows. Select explicit dispatch or a suitably scoped GitHub App when needed; do not assume all generated events trigger downstream checks. [Workflow triggering](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow) + +## Available implementation capabilities + +This workspace already has code/file editing, Git and GitHub tooling, current-web research, Python and Node runtimes, and built-in browser inspection. Additional project dependencies would be installed only during implementation. + +Sites building/hosting tools are also available for deployment previews and hosted applications. Their local documentation supports static output and Cloudflare Workers-backed capabilities, with managed database/object-storage options. The current repository has no Sites hosting configuration; those capabilities are alternatives, not an existing production integration. A separate hosted editor could use such a runtime if needed, but the public site does not currently need a database. + +No extra plugin is necessary to evaluate or start the rebuild. Hosted CMS access, scholarly API credentials, preview hosting, and lab-owned scheduling must be configured when selected; availability of a development tool does not imply those external accounts are connected. + +## Scope of custom work + +The largest custom component is the content maintenance pipeline: verified roster IDs, historical membership rules, merging preprints and final versions, field-level overrides, award evidence, suppression of rejected candidates, and a readable weekly review batch. A framework, CMS or AI service does not supply these lab-specific rules automatically. + +Preserve the existing papers, photos, PDFs, verified editorial text and repository history. Replace the Bootstrap/jQuery presentation layer, modernize the build tooling, and migrate records with count/link checks. Avoid adding a database, visitor accounts, a large React application, or AI-based search until a concrete requirement justifies them. + +## Proposed first implementation milestone + +The framework choice remains open under the simplicity preference above; the following Astro milestone is conditional, not authorized implementation. + +Build a local Astro proof of concept containing the homepage, one member profile, a searchable publication archive, one paper page, and a sample weekly review batch. Use existing content and a mock import fixture; establish that approve/reject and duplicate handling work before enabling live scheduled imports. Pin runtime/dependencies, preserve public URLs, and compare against the spec before replacing the live site. diff --git a/_planning/NEXT_STEPS.md b/_planning/NEXT_STEPS.md new file mode 100644 index 0000000..cd47cab --- /dev/null +++ b/_planning/NEXT_STEPS.md @@ -0,0 +1,137 @@ +# Completing the new lab website + +Current implementation: React + Next.js, plain CSS, JSON content, optional Python helpers, and static export for GitHub Pages. Jekyll has been removed. The initial migration preserves 47 papers, 21 people records, 12 legacy alumni entries, three news items, seven sponsors, and the original assets. The UI uses original lab prose and branding with minimal functional labels. + +This is the current implementation roadmap. WEBSITE_SPEC.md and MODERN_STACK_OPTIONS.md retain the earlier audit and research history; this document supersedes their old stack and delivery recommendations. + +## Decisions already made + +- Keep the website barebones. Use original prose; obtain approval for factual corrections or new wording. +- Keep the stack familiar and simple: React/Next.js, plain CSS, structured files, Python where helpful, GitHub Pages. +- Review one weekly batch before publishing. Automatic publication is not enabled or planned for this phase. +- Keep the production switch separate from migration development. The existing live website is unchanged. + +## Delivery order + +Start roster verification and original-content review together. Then backfill publications and awards, finish browser/route/signup checks, and obtain approval for the Pages switch. Discovery and the weekly review pilot can proceed after the roster and content model are reliable; they need not block a reviewed static-site launch. + +Before starting the maintenance pilot, settle preprint inclusion, lab-work attribution, primary/backup reviewers, provider access, and the lab-owned scheduler. These decisions are acceptance work in the issues, not reasons to delay creating the branch. + +## Work items + +### 1. Verify the lab roster and publication attribution rules + +Phase: Before launch. Dependencies: none. + +The imported roster has 21 people records plus 12 legacy alumni entries. These are historical records, not a verified current membership list. Profile publications currently use name matching. + +- [ ] Have a lab maintainer confirm current members, alumni, visitors, roles, websites, headshots, ordering, and membership dates; reconcile duplicate alumni representations. +- [ ] Record verified scholarly author IDs and aliases with source links; do not resolve identities from names alone. +- [ ] Decide whether preprints are included and how pre-joining, post-departure, and continuing-collaboration work should be attributed. +- [ ] Add explicit internal person links to reviewed publications and use those on profiles instead of relying on name matching. +- [ ] Validate the new fields and check ambiguous names, visitors, and alumni against reviewed examples. + +Done when the roster and attribution policy are approved and each profile lists the intended lab work. + +### 2. Backfill missing publications and reconcile existing metadata + +Phase: Before launch. Dependencies: 1. + +The migrated archive contains 47 papers spanning 2014–2024. It needs a verified backfill, beginning with 2025 onward and then older omissions. + +- [ ] Reconcile publications for every verified member and relevant alumnus against authoritative author records, publisher pages, and personal bibliographies. +- [ ] Submit candidates for human review with sources, lab-author links, ordered authors, dates, venue, DOI/arXiv IDs, and publication state. +- [ ] Reconcile preprint/published versions and existing duplicates while retaining stable URLs and editorial descriptions. +- [ ] Add available PDF, code, dataset, and project links; ordinary papers must not require a local PDF or thumbnail. +- [ ] Verify current highlights with the lab; preserve original prose unless a replacement is explicitly approved. + +Done when an agreed bibliography has been reconciled, omissions or conflicts are recorded, and approved papers appear consistently in the archive and profiles. + +### 3. Verify and backfill awards and news with shared records + +Phase: Before launch. Dependencies: 1, 2. + +The current site imports three news items and three paper award fields. It has no verified general honors collection. + +- [ ] Collect missing paper awards, individual honors, and lab news from conference/award organizations, UW announcements, or member-submitted evidence. +- [ ] Add structured award records with exact title, awarding body, date, recipients, optional paper link, and source URL. +- [ ] Review the original award fields and news entries; migrate without changing their meaning or duplicating announcements. +- [ ] Render approved awards consistently on relevant paper/profile pages and the news/awards view from shared records. +- [ ] Require approval for new wording; do not generate promotional summaries or infer awards from citations. + +Done when the lab approves the initial backfill and editing one award updates all associated views. + +### 4. Review original page content, recruitment, sponsors, and barebones layout + +Phase: Before launch. Dependencies: none. + +The React draft intentionally uses original site prose and logos. Some original claims are old, including recruiting availability and research themes. Research, pictures, and about-website routes currently have only titles. + +- [ ] Ask the lab to verify the existing overview, postdoc document, PhD guidance, affiliation, and seven sponsor entries. +- [ ] Remove or explicitly approve corrections to stale claims; add no new prose or taglines without approval. +- [ ] Decide whether empty routes should remain, be hidden, or redirect; retain necessary template attribution in repository documentation. +- [ ] Add an owner and review/expiry date for opportunities and other time-sensitive content. +- [ ] Confirm page order, original logo variants, highlight selection, and which archive sections belong on the homepage. + +Done when the lab has approved the minimal content and navigation and no unverified current opening is advertised. + +### 5. Complete browser, accessibility, route, and signup checks + +Phase: Before launch. Dependencies: 4. + +Production builds, content validation, unit tests, and an internal exported-link check pass locally. Comprehensive browser and integration QA is still pending. + +- [ ] Exercise desktop/mobile layouts, original logos, keyboard navigation, focus, contrast, headings, alt text, and zoom in the built-in browser. +- [ ] Check publication search, combined filters, reset/empty states, profiles, awards, and missing optional assets. +- [ ] Build a legacy URL inventory from the original site and verify every required page/download. Include /team/, /publications/, /allnews/, /vacancies, /idiofid/, /aboutwebsite.html, and linked PDFs; add redirects or exported aliases for gaps. +- [ ] Check canonical URLs, sitemap, robots, favicon, social/search metadata, and 404 behavior on a static Pages-like server. +- [ ] Confirm ownership of the IdioFid Google Apps Script endpoint and coordinate one authorized test signup; verify the response without storing addresses in the repository. +- [ ] Add durable automated checks for actual regressions found, especially URL preservation and content relationships. + +Done when launch-critical routes and interactions pass, the signup flow is verified, and remaining nonblocking defects are recorded. + +### 6. Implement publication discovery, normalization, and deduplication + +Phase: Maintenance pilot. Dependencies: 1, 2. + +scripts/prepare_publication.py currently prepares a local proposal from one Crossref DOI. It does not discover papers or edit approved content. + +- [ ] Choose one primary scholarly provider after checking current access, coverage, limits, and costs; query verified author IDs. +- [ ] Implement paginated incremental retrieval with lookback, periodic reconciliation, caching, retries, and a request budget. +- [ ] Normalize source IDs and metadata; use exact IDs for deduplication and send fuzzy matches or version conflicts to review. +- [ ] Store candidates and provenance separately from approved content. Preserve manual corrections, rejected candidates, and deferrals across runs. +- [ ] Flag withdrawals, corrections, missing source records, and changed metadata for review; never silently delete approved papers. +- [ ] Test repeat runs, same-name researchers, preprint-to-publication transitions, source failures, and partial results. + +Done when fixture and live pilot runs produce evidence-backed candidates, repeat runs produce no duplicate changes, and no candidate publishes automatically. + +### 7. Create weekly review batches, contributor intake, and monitoring + +Phase: Maintenance pilot. Dependencies: 3, 6. + +The agreed policy is one weekly batch for human review before publication. No scheduled discovery or review automation is enabled yet. + +- [ ] Add a simple member submission path for DOI/URL, award evidence, and profile corrections; GitHub issue forms are sufficient initially. +- [ ] Prepare one review pull request per weekly batch with additions, changed fields, source links, matched people, and conflicts; update an existing batch instead of duplicating it. +- [ ] Support approve/edit/reject/defer and retain those decisions on subsequent imports; keep private reviewer notes and signup addresses outside the public repo. +- [ ] Run content checks and provide a preview/artifact. Publish only after a maintainer approves and merges. +- [ ] Assign primary and backup reviewers and select a lab-owned scheduler and notification destination. +- [ ] Track last successful fetch, review, and deploy; detect missed runs independently and notify on actionable failures or overdue review, staying quiet on no-change runs. +- [ ] Run at least two weekly review cycles and record missed papers, false matches, duplicates, failure recovery, and reviewer time. + +Done when the pilot demonstrates reliable collection and human-reviewed publication, with a documented operating owner. Automatic publication remains out of scope. + +### 8. Launch React on GitHub Pages and document maintainer handoff + +Phase: Launch. Dependencies: 1, 2, 3, 4, 5. + +The migration exports a static Next.js/React site. The existing live site remains on its old deployment; the new Pages workflow is manual-only. + +- [ ] Open and review the migration PR; run CI from a clean checkout with the documented Node version and validate the exported artifact. +- [ ] Confirm the intended production branch/domain and record a known-good rollback revision and deployment procedure. +- [ ] Obtain lab approval for the production switch, coordinate merging with changing Pages Source to GitHub Actions, and run the first React deployment. +- [ ] Verify production routes, PDFs, assets, canonical domain, and signup behavior; confirm the rollback procedure is usable. +- [ ] Enable deployment on approved merges only after the initial switch is verified, if agreed. +- [ ] Give a primary and backup CS PhD maintainer a short runbook covering content edits, preview, validation, deployment, rollback, dependencies, and lab-owned credentials. + +Done when the approved React site is live and a second maintainer can make and roll back an update. The maintenance pilot can follow launch; do not imply that launch alone enables automatic discovery. diff --git a/_planning/WEBSITE_SPEC.md b/_planning/WEBSITE_SPEC.md new file mode 100644 index 0000000..25422d0 --- /dev/null +++ b/_planning/WEBSITE_SPEC.md @@ -0,0 +1,166 @@ +# Behavioral Data Science website: inventory and maintenance spec + +**Historical audit/research:** See [NEXT_STEPS.md](NEXT_STEPS.md) for the current React implementation roadmap and issue tracker. Earlier Jekyll/Astro recommendations and delivery phases below are superseded. + +**Selected stack:** React + Next.js, plain CSS, JSON/Markdown content, Python maintenance helpers, and GitHub Pages. The React migration is implemented locally; automated weekly discovery and production deployment remain pending. Earlier framework comparisons below are historical research. +Draft for discussion, September 4, 2026. This document proposes a system; it does not enable jobs, publish content, or establish a verified current lab roster. + +## Recommendation + +Keep a static website backed by structured content in Git. Add a service that discovers publication candidates, checks identities and duplicates, and prepares a weekly review batch. Members can submit a DOI, paper URL, award announcement, or profile correction through a short form. An editor approves changes once, and the site generates all affected pages from the same records. + +Confirmed user decision: prepare a weekly batch for review before publishing. Automatic publication is a possible later option requiring a separate decision and an explicit, tested matching policy. Continue reviewing awards, affiliation changes, editorial summaries, and ambiguous matches. Automating collection is practical; assuming every external author match or award mention is correct is not. + +The current Jekyll site can support the first version. A visual redesign can follow independently; a framework migration is not required to solve stale content. + +Follow-up tooling research now recommends **Astro + TypeScript + Pagefind** for a full rebuild, with the same separate ingestion and weekly review pipeline. Keeping Jekyll remains the smaller modernization option. See [Modern stack options](MODERN_STACK_OPTIONS.md) for the comparison, feature mapping and service requirements; this is a proposal, not an implemented migration. + +**Latest user constraint:** Prefer a simple, familiar stack that future lab members can maintain. Astro is not selected. Evaluate modernizing Jekyll and managed WordPress alongside mainstream React/Next.js, distinguishing the work of editing content from maintaining code. Weekly human review remains the confirmed publishing policy. + +## Audit scope and baseline + +Inspected the local source, committed source at `d6a7b92de79642aee11c2c5bfe60c94588beae79`, and public home, team, and publication pages. The earlier GitHub check found that commit at remote `master`, dated December 1, 2025, with a successful Pages deployment. No tracked custom `.github` workflows were present in that commit. + +There are significant unpublished local changes. They consolidate navigation into homepage sections, remove the separate team/publication page source files, adjust roster visibility, and reorganize maintenance scripts. They must be reconciled deliberately before implementing the redesign. The local CODEBASE.md still references some deleted pages, so it is not a definitive inventory. + +| Content measure | Committed source | Local working copy | +| --- | --- | --- | +| Publication records | 47, spanning 2014–2024 | 47, spanning 2014–2024 | +| Publications marked as highlights | 5 | 5 | +| Publications with an award field | 3 | 3 | +| People records | 18, including 8 marked inactive | 21, including 11 marked inactive | +| Alumni list entries | 12 | 12 | +| News records | 3; latest dated June 10, 2021 | Same | +| Sponsor entries | 7 | 7 | + +These are record counts, not a verified current membership count. The public team page displays nine people, alongside its alumni list. Publications from 2025 onward are absent from the collection; that establishes a gap in site content, not the complete set of missing papers. A verified bibliography backfill remains to be done. + +## Existing feature inventory + +| Feature | Existing behavior and evidence | Renewal requirement | +| --- | --- | --- | +| Home and lab overview | Introduction, research themes, UW/Allen School affiliation, branding, recruitment copy, people, sponsor logos. `_pages/home.md`, `_layouts/homelay.html`, shared includes. | Refresh editorial text; surface recent papers and news from shared records. | +| Navigation and responsive layout | Published navigation has Home, Team, Publications; Bootstrap mobile menu and grid. Local draft uses homepage anchors. `_includes/header.html`, `css/main.scss`. | Accessible navigation with stable URLs; homepage summaries can coexist with dedicated archive pages. | +| Team directory | Headshots, names, roles, personal websites, priority ordering, inactive filtering. `_people/`, `_includes/group.md`. | One people dataset with verified identities, role history, affiliation dates, research interests, and profile pages. | +| Visitors | Visitor fields and template logic exist. Committed visitor heading condition has a variable typo; local logic has been revised. | Support visitor dates/status without assuming the current section works as intended. | +| Alumni | Separate YAML list with optional website and role/date text. `_data/alumni.yml`. | Derive alumni from people records; retain historical lab contributions. | +| Publications | Full list ordered by year, author/venue/year text, thumbnails, PDFs. `_publications/`; committed `_pages/publications.md`, local `_includes/publications.md`. | Search/filter by person, year, topic, venue, and type; stable paper pages and external IDs. | +| Research highlights | Curated publication selection with descriptive text and optional code links. | Keep editorial selection; avoid requiring a thumbnail or summary for ordinary new papers. | +| Paper awards | Three records have award text displayed as badges. | Structured award records with exact award name, awarding body, year, recipients, linked paper, and evidence. | +| News | Three manual YAML entries and an archive template. The public `/allnews/` route currently shows Page Not Found. Homepage news include is commented out in committed source. The source template renders entries in file order, not sorted by date. | Visible, date-sorted updates generated from approved events; ISO dates and an archive. | +| Recruiting | Home has a postdoc document link and PhD application guidance. `/vacancies` source is placeholder text. | Reviewed opportunities with owner, expiry/review date, and application link. Do not assume existing openings are still active. | +| Research/gallery pages | `/research/` and `/pictures/` sources are placeholders rather than substantive maintained sections. | Publish only when populated; add topic/project pages as content becomes available. | +| Project release signup | `/idiofid/` source describes IdioFid-A and posts an email form to a Google Apps Script endpoint. | Preserve the URL and intended flow, or replace deliberately. Verify endpoint ownership and operation; no form was submitted in this audit. | +| Sponsor recognition | Seven logos from YAML. | Keep editable sponsor records and review dates. | +| Assets and downloads | Local PDFs, publication thumbnails, headshots, logos and other downloads. | Preserve existing linked asset URLs; allow an external paper URL and fallback image. | +| Site metadata and utilities | Titles, descriptions, canonical tag, favicon, custom 404, credits and UW footer. A legacy Universal Analytics snippet is present. | Configure canonical domain and metadata, check indexing/accessibility, decide whether analytics is wanted and validate any replacement. Presence of a snippet does not prove working analytics. | +| Contributor tools | Python person-entry and BibTeX-to-publication helpers; paper helper requires a PDF and thumbnail. Manual YAML news editing. | DOI/URL intake, metadata lookup, optional assets, validation, preview, review history. | +| Hosting and deployment | Jekyll/GitHub Pages; documented branch/PR workflow; latest checked deployment succeeded. | Continue automatic deployment of approved changes, with validation and rollback. | + +Not found in the inspected implementation: publication search/filter controls, automated literature discovery, person-to-paper identity links, a general honors directory, structured project/dataset catalog, editorial review inbox, content freshness monitoring, or an authenticated content editor. + +Public evidence: [home](https://behavioral-data.github.io/), [team](https://behavioral-data.github.io/team/), [publications](https://behavioral-data.github.io/publications/). Built-in browser verification confirmed Home/Team/Publications navigation, a Page Not Found response at `/allnews/`, and a visible email signup at `/idiofid/`. The form was not submitted. This was a content/source audit with focused browser checks, not a comprehensive visual, accessibility or integration QA pass. + +## Proposed visitor experience + +**Version 1:** Home, People, Publications, News & Awards, and Join/Contact. Home shows a concise lab description, selected work, and recent approved updates. People pages collect each member's papers, projects, and honors automatically. Publication cards offer DOI/publisher, preprint/PDF, code, dataset, project page, and BibTeX links where available. Missing optional assets should never block publishing a paper. + +**Later:** Curated research themes and project pages connecting people, papers, code, and datasets; photos if someone owns their upkeep; RSS for public updates. Keep the IdioFID release page and existing external links working throughout migration. + +Use dedicated archive URLs even if the homepage contains all key sections. Preserve `/team/`, `/publications/`, `/allnews/`, `/idiofid/`, and existing PDF links through retained routes or tested redirects. The current local consolidation needs these redirects before deployment. + +## Content model + +| Record | Minimum information | +| --- | --- | +| Person | Stable internal ID, preferred name, aliases, verified ORCID/OpenAlex/Semantic Scholar IDs when available, website, role, membership intervals, active/alumni/visitor state, profile review date. | +| Publication | Internal ID, DOI/arXiv/provider IDs, title, ordered authors with internal person links when verified, venue, dates, preprint/accepted/published state, topic tags, external links, optional thumbnail and curated summary. | +| Award | Exact title, awarding organization, date/year, recipients, optional paper/project, category, source URL and supporting excerpt, approval state. | +| News event | Event type/date, headline/body, related entity IDs, source, editorial state. One event can appear on home, archive, and profile pages. | +| Project | Title, short approved summary, people, papers, code, datasets, release status and external links. | +| Opportunity | Role, application URL, owner, open/closed status, closing or review date. | +| Editorial state | Source observations, last fetched/verified time, field-level overrides, approval/rejection history, and correction/suppression rules. | + +Separate imported observations from approved content and human overrides. An API refresh must not overwrite a corrected name, selected thumbnail, custom description, or rejected candidate. Keep reviewer notes, unpublished submissions, credentials, and signup addresses outside the public repository and generated site. + +## How updates work + +1. **Confirm the roster once.** Verify author IDs using personal/institutional pages and known papers. Track members beyond just the PI. Establish membership dates and how to treat work before joining or after leaving. Proposed default: archive lab-period work; allow explicitly linked continuing collaborations after departure. +2. **Backfill.** Start with 2025–present, then reconcile older omissions. Query every verified member, including alumni needed for lab-period coverage. Import candidates into a review queue; do not label an entire name-search result set as lab work. +3. **Discover weekly.** Use OpenAlex or Semantic Scholar author records for candidates; Crossref for publisher-deposited DOI metadata; arXiv for preprint discovery. Pick one primary provider during the pilot and add another only where measured coverage warrants it. +4. **Normalize and match.** Prefer DOI and arXiv identifiers; preserve author order and publication state. Fuzzy title/author matching raises a review candidate, not an automatic merge. Link a preprint and its published version into one work with version records when evidence supports the relationship. +5. **Prepare a review batch.** Show additions and changed fields, matched lab members, evidence, and conflicts. An editor can approve, edit, reject, or defer. A member can supply a DOI/URL or award source via a short form; the system fills the rest. +6. **Publish once.** Approved records generate every relevant page, publication list, award badge, and optional news event. Use one event per meaningful change; do not create another announcement for a spelling correction or repeated import. +7. **Check health.** Record each source's success/failure, candidate count, last successful sync, last approval, and last deploy. Keep the last good site on failure. Notify the designated owner about failures or overdue review batches; stay quiet on no-change runs. + +```mermaid +flowchart LR + A[Scholarly APIs and member submissions] --> B[Normalize and match identities] + B --> C[Deduplicate and attach evidence] + C --> D[Review batch] + D --> E[Approved content in Git] + E --> F[Build and deploy] + F --> G[Home, people, papers, news and awards] +``` + +### Publication automation policy + +Initially review all additions. Potential later automatic additions require a verified author identity, an approved rule for lab relevance, an exact publication identifier, no duplicate/conflicting record, valid metadata and links, and no prior suppression. Preprints must remain visibly labeled. Name-only matches, ambiguous affiliation dates, author-profile merges, and changed titles/venues go to review. + +Publication dates and membership periods are evidence, not a complete definition of lab contribution: delayed publication and work spanning institutions require an override. Never silently delete a paper because one source no longer returns it. Flag corrections, withdrawals and retractions for review rather than treating them as ordinary metadata refreshes. + +### Awards, news, and people + +Use conference/award organization announcements, UW/Allen School news, and member-submitted evidence as the main inputs. A member's website may suggest a candidate that needs confirmation. Do not assume a literature index has complete coverage of personal honors or best-paper awards. + +AI can extract a draft award record and summarize a source, but an editor checks exact award type, recipients, year and wording. Distinguished paper, honorable mention, best paper and nomination remain distinct. Do not infer awards from citation counts or publish unsupported claims. Generate a linked news entry from an approved award so it only needs entering once. + +Review roster, titles, recruiting and sponsor text each quarter. Automated detection can suggest a change; it should not decide that someone left the lab based on a stale or missing page. + +## Technical and operating choices + +Use the existing Jekyll content collections for the first implementation, Python for ingestion/validation, and GitHub review/build/deployment. Begin with repository-native review to avoid building an admin system prematurely; add a small authenticated editor if reviewers need it. A member submission form should collect only the fields needed to prepare an update. + +Run the weekly workflow through a lab-owned scheduler or include an independent missed-run check. GitHub documents that public-repository schedules can be disabled after 60 days of inactivity, and scheduled runs can be delayed. A quiet lab website must not depend solely on an unchecked GitHub cron job. Select the scheduler and notification channel at implementation time; no monitor has been created by this spec. + +Use pagination, caching, incremental retrieval with a lookback window, occasional full reconciliation, retries/backoff, provider-specific limits, and a request budget. Track source licensing before importing full text or images; prefer metadata and external links. Store API credentials as service secrets, never in the client or public content. Treat fetched HTML and AI-produced text as untrusted input to sanitize and validate. + +Assign a primary maintainer and a backup, use lab-owned service accounts, and document credential renewal and rollback. Target a short weekly editorial review; measure effort during the pilot instead of promising zero maintenance. Exact service costs and access requirements depend on provider and hosting choices and must be checked when selecting them. + +## Delivery phases and acceptance criteria + +**Phase 1 — Reconcile and establish content.** Preserve current local work; agree on page structure and lab-work scope; verify roster/author IDs; normalize existing records; backfill missing papers and awards with sources. Produce a reviewed migration report and route/asset inventory. + +**Phase 2 — Pilot maintenance on the existing site.** Implement discovery, matching, deduplication, submission intake, one review batch, validation, build/deploy, and health tracking. Run at least two weekly review cycles and evaluate missed papers, false matches and editor time. + +**Phase 3 — Redesign.** Build the new visitor experience from approved records, retain redirects, and verify mobile/keyboard behavior, search, metadata and important external links. Add automatic publication only for a matching policy that passes the pilot review. + +Acceptance checks: + +- A reviewer-approved DOI import appears on the publication archive and each linked lab member's page, without manual page edits. +- Reprocessing identical inputs produces no content diff, duplicate news event, or duplicate review request. +- A preprint becoming published updates a linked work; different papers with similar titles remain distinguishable. +- A same-name researcher and a post-departure unrelated paper cannot auto-publish under the default policy. +- A paper with no PDF/thumbnail can publish with valid external links and a usable fallback layout. +- Manual corrections and rejected candidates survive future syncs. +- An award requires evidence and approval; all linked views display the same verified record. +- API errors, missing scheduler runs and deployment failures are visible to an owner; existing published content stays available. +- Approved test-set papers are all present; candidate false positives and unresolved matches are recorded for review. Do not claim exhaustive coverage solely because a sync succeeded. +- Existing public routes and linked PDFs remain reachable, including IdioFID; its signup integration receives a separate authorized functional test. +- A maintainer can undo a bad content change and redeploy using documented instructions. + +## Decisions for discussion + +1. Confirmed: review a weekly batch before publication. Future automatic publication remains undecided. +2. Include preprints alongside published work with clear labels? +3. Define lab work: membership-period work and continuing collaborations, or all work by current members? +4. Who owns weekly review and the quarterly roster check, with whom as backup? +5. Prefer GitHub review initially, or prioritize a web editor for contributors? + +## References for the proposed integrations + +- [OpenAlex authors](https://help.openalex.org/data/authors/): author identities, ORCID links, affiliations derived from works, and author-work lookup. Author identity still needs verification. +- [Semantic Scholar API](https://www.semanticscholar.org/product/api): author/paper metadata and API access; [tutorial](https://webflow.semanticscholar.org/product/api/tutorial) covers author queries and batching. +- [Crossref REST API](https://www.crossref.org/documentation/retrieve-metadata/rest-api/): publisher-deposited bibliographic metadata and DOI lookup. +- [arXiv API manual](https://github.com/arXiv/arxiv-docs/blob/develop/source/help/api/user-manual.md): programmatic preprint discovery. +- [GitHub schedule behavior](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#schedule) and [workflow inactivity](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/disable-and-enable-workflows): scheduling limits and the 60-day inactivity rule. diff --git a/_planning/migration-report.json b/_planning/migration-report.json new file mode 100644 index 0000000..211df0a --- /dev/null +++ b/_planning/migration-report.json @@ -0,0 +1,10 @@ +{ + "people": 21, + "publications": 47, + "news": 3, + "missing_assets": [], + "repairs": [ + "Corrected duplicated resources/pubpdfs prefix in xu2022GLOBEM PDF link." + ], + "asset_copy": "All legacy asset bytes verified before removing original paths." +} diff --git a/_plugins/markdown.rb b/_plugins/markdown.rb deleted file mode 100644 index 727bf40..0000000 --- a/_plugins/markdown.rb +++ /dev/null @@ -1,23 +0,0 @@ -=begin - Jekyll tag to include Markdown text from _includes directory preprocessing with Liquid. - Usage: - {% markdown %} - Dependency: - - kramdown -=end -module Jekyll - class MarkdownTag < Liquid::Tag - def initialize(tag_name, text, tokens) - super - @text = text.strip - end - require "kramdown" - def render(context) - tmpl = File.read File.join Dir.pwd, "_includes", @text - site = context.registers[:site] - tmpl = (Liquid::Template.parse tmpl).render site.site_payload - html = Kramdown::Document.new(tmpl).to_html - end - end -end -Liquid::Template.register_tag('markdown', Jekyll::MarkdownTag) diff --git a/_publications/Gu2022UnderstandingAS.md b/_publications/Gu2022UnderstandingAS.md deleted file mode 100644 index 7e70aa3..0000000 --- a/_publications/Gu2022UnderstandingAS.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -author: Ken Gu, Eunice Jun and Tim Althoff -description: null -highlight: 0 -journal: CHI -pdf: Gu2022UnderstandingAS.pdf -thumbnail: Gu2022UnderstandingAS.png -title: Understanding and Supporting Debugging Workflows in Multiverse Analysis -year: '2023' ---- \ No newline at end of file diff --git a/_publications/Weld_Glenski_Althoff_2021.md b/_publications/Weld_Glenski_Althoff_2021.md deleted file mode 100644 index 6ddd3d6..0000000 --- a/_publications/Weld_Glenski_Althoff_2021.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -abstractnote: As civil discourse increasingly takes place online, misinformation and - the polarization of news shared in online communities have become ever more relevant - concerns with real world harms across our society. Studying online news sharing - at scale is challenging due to the massive volume of content which is shared by - millions of users across thousands of communities. Therefore, existing research - has largely focused on specific communities or specific interventions, such as bans. - However, understanding the prevalence and spread of misinformation and polarization - more broadly, across thousands of online communities, is critical for the development - of governance strategies, interventions, and community design. Here, we conduct - the largest study of news sharing on reddit to date, analyzing more than 550 million - links spanning 4 years. We use non-partisan news source ratings from Media Bias/Fact - Check to annotate links to news sources with their political bias and factualness. - We find that, compared to left-leaning communities, right-leaning communities have - 105% more variance in the political bias of their news sources, and more links to - relatively-more biased sources, on average. We observe that reddit users’ voting - and re-sharing behaviors generally decrease the visibility of extremely biased and - low factual content, which receives 20% fewer upvotes and 30% fewer exposures from - crossposts than more neutral or more factual content. This suggests that reddit - is more resilient to low factual content than Twitter. We show that extremely biased - and low factual content is very concentrated, with 99% of such content being shared - in only 0.5% of communities, giving credence to the recent strategy of community-wide - bans and quarantines. -author: Weld, Galen and Glenski, Maria and Althoff, Tim -description: Studying news shared online is challenging due to the massive volume of content which is shared. In this work, we conduct the largest study of news sharing to date, analyzing more than 550 million links to news articles posted on reddit over four years. Using non-partisan news source ratings of sources' political bias and factualness, we find that up- and down-voting mechanisms generally decrease the visibility of biased and low factual content, and that such content is very concentrated, being mostly shared in only a small fraction of all communities. -highlight: 1 -journal: ICWSM -month: May -number: '1' -pages: 796-807 -pdf: Weld_Glenski_Althoff_2021.pdf -award: Best Paper (Outstanding Analysis) -thumbnail: Weld_Glenski_Althoff_2021.jpg -title: Political Bias and Factualness in News Sharing across more than 100,000 Online - Communities -url: https://ojs.aaai.org/index.php/ICWSM/article/view/18104 -volume: '15' -year: '2021' ---- \ No newline at end of file diff --git a/_publications/althoff2014ask.md b/_publications/althoff2014ask.md deleted file mode 100644 index 8f16bba..0000000 --- a/_publications/althoff2014ask.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -author: Althoff, Tim and Danescu-Niculescu-Mizil, Cristian and Jurafsky, Dan -booktitle: ICWSM -description: '' -highlight: 0 -pdf: althoff2014ask.pdf -thumbnail: althoff2014ask.png -title: 'How to Ask for a Favor: A Case Study on the Success of Altruistic Requests.' -year: '2014' ---- \ No newline at end of file diff --git a/_publications/althoff2015donor.md b/_publications/althoff2015donor.md deleted file mode 100644 index ff612e1..0000000 --- a/_publications/althoff2015donor.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -author: Althoff, Tim and Leskovec, Jure -booktitle: WWW -description: '' -highlight: 0 -optbooktitle: Proceedings of the 24th International Conference on World Wide Web -optorganization: International World Wide Web Conferences Steering Committee -optpages: 34--44 -pdf: althoff2015donor.pdf -thumbnail: althoff2015donor.png -title: 'Donor retention in online crowdfunding communities: A case study of DonorsChoose.org' -year: '2015' ---- \ No newline at end of file diff --git a/_publications/althoff2016counseling.md b/_publications/althoff2016counseling.md deleted file mode 100644 index ca6e863..0000000 --- a/_publications/althoff2016counseling.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -author: Althoff, Tim and Clark, Kevin and Leskovec, Jure -description: '' -highlight: 0 -journal: TACL -optjournal: Transactions of the Association for Computational Linguistics -pdf: althoff2016counseling.pdf -thumbnail: althoff2016counseling.png -title: 'Large-scale Analysis of Counseling Conversations: {An} Application of Natural - Language Processing to Mental Health' -year: '2016' ---- \ No newline at end of file diff --git a/_publications/althoff2016onlineappendix.md b/_publications/althoff2016onlineappendix.md deleted file mode 100644 index 5db51e2..0000000 --- a/_publications/althoff2016onlineappendix.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -author: Althoff, Tim and Horvitz, Eric and White, Ryen W and Zeitzer, Jamie -booktitle: WWW -description: '' -highlight: 0 -note: \url{http://stanford.io/2ejFPhD} -optauthor: Althoff, Tim and others -pdf: althoff2016onlineappendix.pdf -thumbnail: althoff2016onlineappendix.png -title: 'Harnessing the Web for Population-Scale Physiological Sensing: A Case Study - of Sleep and Performance. ' -year: '2017' ---- \ No newline at end of file diff --git a/_publications/althoff2016pokemon.md b/_publications/althoff2016pokemon.md deleted file mode 100644 index 0feceee..0000000 --- a/_publications/althoff2016pokemon.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -author: Althoff, Tim and White, Ryen W and Horvitz, Eric -description: '' -highlight: 0 -journal: JMIR -optday: '06' -optdoi: 10.2196/jmir.6759 -optmonth: Dec -optnote: doi:10.2196/jmir.6759 -optnumber: '12' -optpages: e315 -opttitle: 'Influence of Pokémon Go on Physical Activity: Study and Implications' -opturl: http://www.jmir.org/2016/12/e315/ -optvolume: '18' -pdf: althoff2016pokemon.pdf -thumbnail: althoff2016pokemon.png -title: Influence of Pokémon Go on Physical Activity -year: '2016' ---- \ No newline at end of file diff --git a/_publications/althoff2017large.md b/_publications/althoff2017large.md deleted file mode 100644 index b387b24..0000000 --- a/_publications/althoff2017large.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -author: Althoff, Tim and Sosic, Rok and Hicks, Jennifer L and King, Abby C and Delp, - Scott L and Leskovec, Jure -description: '' -highlight: 0 -journal: Nature -optpublisher: Nature Research -pdf: althoff2017large.pdf -thumbnail: althoff2017large.png -title: Large-scale physical activity data reveal worldwide activity inequality -year: '2017' ---- \ No newline at end of file diff --git a/_publications/althoff2017onlineactions.md b/_publications/althoff2017onlineactions.md deleted file mode 100644 index 3096378..0000000 --- a/_publications/althoff2017onlineactions.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -author: Althoff, Tim and Jindal, Pranav and Leskovec, Jure -booktitle: WSDM -description: '' -highlight: 0 -pdf: althoff2017onlineactions.pdf -thumbnail: althoff2017onlineactions.png -title: 'Online Actions with Offline Impact: How Online Social Networks Influence Online - and Offline User Behavior' -year: '2017' ---- \ No newline at end of file diff --git a/_publications/althoff2017population.md b/_publications/althoff2017population.md deleted file mode 100644 index 2e4e9d4..0000000 --- a/_publications/althoff2017population.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -author: Althoff, Tim -description: '' -highlight: 0 -journal: IEEE Pervasive Computing -number: '4' -pages: 75--79 -pdf: althoff2017population.pdf -publisher: IEEE -thumbnail: althoff2017population.png -title: Population-Scale Pervasive Health -volume: '16' -year: '2017' ---- \ No newline at end of file diff --git a/_publications/althoff2018psychomotor.md b/_publications/althoff2018psychomotor.md deleted file mode 100644 index 27751c5..0000000 --- a/_publications/althoff2018psychomotor.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -author: Althoff, Tim and Horvitz, Eric and White, Ryen W -description: '' -highlight: 0 -journal: 'NPJ Digital Medicine' -optnumber: '1' -optpages: '3' -optpublisher: Nature Publishing Group -optvolume: '1' -pdf: althoff2018psychomotor.pdf -thumbnail: althoff2018psychomotor.png -title: Psychomotor function measured via online activity predicts motor vehicle fatality - risk -year: '2018' ---- \ No newline at end of file diff --git a/_publications/althoff2022diet.md b/_publications/althoff2022diet.md deleted file mode 100644 index 2e72e78..0000000 --- a/_publications/althoff2022diet.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -author: Althoff, Tim and Nilforoshan, Hamed and Hua, Jenna and Leskovec, Jure -description: null -highlight: 0 -journal: Nature Communications -number: '1' -optpublisher: Nature Publishing Group UK London -pages: '267' -pdf: althoff2022diet.pdf -thumbnail: althoff2022diet.png -title: Large-scale diet tracking data reveal disparate associations between food environment - and diet -volume: '13' -year: '2022' ---- \ No newline at end of file diff --git a/_publications/althoffModeration.md b/_publications/althoffModeration.md deleted file mode 100644 index fcd1c18..0000000 --- a/_publications/althoffModeration.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -author: David Wadden and Tal August and Qisheng Li and Tim Althoff -description: '' -highlight: 0 -journal: ICWSM -award: Best Paper (Outstanding Study Design) -note: Under submission. -pdf: althoffModeration.pdf -thumbnail: althoffModeration.png -title: The Effect of Moderation on Online Mental Health Conversations -year: '2021' ---- \ No newline at end of file diff --git a/_publications/althoffPocketskills.md b/_publications/althoffPocketskills.md deleted file mode 100644 index 63c761b..0000000 --- a/_publications/althoffPocketskills.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -author: Jessica Schroeder and Jina Suh and Chelsey Wilks and Mary Czerwinski and Sean - Munson and James Fogarty and Tim Althoff -description: '' -highlight: 0 -journal: EAI Pervasive Health -note: Under submission. -pdf: althoffPocketskills.pdf -thumbnail: althoffPocketskills.png -title: Data-Driven Implications for Translating Evidence-Based Psychotherapies into - Technology-Delivered Interventions -year: '2020' ---- \ No newline at end of file diff --git a/_publications/althoffTalklifeEngagement.md b/_publications/althoffTalklifeEngagement.md deleted file mode 100644 index 1081250..0000000 --- a/_publications/althoffTalklifeEngagement.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -author: Ashish Sharma and Monojit Choudhury and Tim Althoff and Amit Sharma -description: '' -highlight: 0 -journal: ICWSM -note: Under submission. -pdf: althoffTalklifeEngagement.pdf -thumbnail: althoffTalklifeEngagement.png -title: 'Engagement Patterns of Peer-to-Peer Interactions on Mental Health Platforms' -year: '2020' ---- diff --git a/_publications/gordonactivity2019.md b/_publications/gordonactivity2019.md deleted file mode 100644 index b2df911..0000000 --- a/_publications/gordonactivity2019.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -abstract: 'Activity tracking apps often make use of goals as one of their core motivational - tools. There are two critical components to this tool: setting a goal, and subsequently - achieving that goal. Despite its crucial role in how a number of prominent self-tracking - apps function, there has been relatively little investigation of the goal-setting - and achievement aspects of self-tracking apps. Here we explore this issue, investigating - a particular goal setting and achievement process that is extensive, recorded, and - crucial for both the app and its users'' success: weight loss goals in MyFitnessPal. - We present a large-scale study of 1.4 million users and weight loss goals, allowing - for an unprecedented detailed view of how people set and achieve their goals. We - find that, even for difficult long-term goals, behavior within the first 7 days - predicts those who ultimately achieve their goals, that is, those who lose at least - as much weight as they set out to, and those who do not. For instance, high amounts - of early weight loss, which some researchers have classified as unsustainable, leads - to higher goal achievement rates. We also show that early food intake, self-monitoring - motivation, and attitude towards the goal are important factors. We then show that - we can use our findings to predict goal achievement with an accuracy of 79% ROC - AUC just 7 days after a goal is set. Finally, we discuss how our findings could - inform steps to improve goal achievement in self-tracking apps.' -address: New York, NY, USA -author: Gordon, Mitchell and Althoff, Tim and Leskovec, Jure -booktitle: '' -description: '' -doi: 10.1145/3308558.3313432 -highlight: 0 -isbn: '9781450366748' -location: San Francisco, CA, USA -numpages: '12' -pages: 571–582 -pdf: gordonactivity2019.pdf -publisher: Association for Computing Machinery -series: WWW '19 -thumbnail: gordonactivity2019.png -title: 'Goal-Setting And Achievement In Activity Tracking Apps: A Case Study Of MyFitnessPal' -url: https://doi.org/10.1145/3308558.3313432 -year: '2019' ---- \ No newline at end of file diff --git a/_publications/gu2024blade.md b/_publications/gu2024blade.md deleted file mode 100644 index 9db80df..0000000 --- a/_publications/gu2024blade.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -author: Gu, Ken and Shang, Ruoxi and Jiang, Ruien and Kuang, Keying and Lin, Richard-John and Althoff, Tim -booktitle: Findings of the 2024 Conference on Empirical Methods in Natural Language Processing -title: BLADE - Benchmarking Language Model Agents for Data-Driven Science -year: '2024' -pdf: guBLADEBenchmarkingLanguage2024a.pdf -thumbnail: guBLADE.png ---- \ No newline at end of file diff --git a/_publications/gu2024how_analysts.md b/_publications/gu2024how_analysts.md deleted file mode 100644 index 23ceda0..0000000 --- a/_publications/gu2024how_analysts.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -author: Gu, Ken and Grunde-McLaughlin, Madeleine and McNutt, Andrew M. and Heer, Jeffrey and Althoff, Tim -booktitle: Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems -title: How Do Data Analysts Respond to AI Assistance? A Wizard-of-Oz Study -year: '2024' -pdf: guHowDoDataAnalysts2024.pdf -thumbnail: guHowDoDataAnalysts.png ---- \ No newline at end of file diff --git a/_publications/gu2024how_understand.md b/_publications/gu2024how_understand.md deleted file mode 100644 index b331514..0000000 --- a/_publications/gu2024how_understand.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -author: Gu, Ken and Shang, Ruoxi and Althoff, Tim and Wang, Chenglong and Drucker, Steven M. -booktitle: Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems -title: How Do Analysts Understand and Verify AI-Assisted Data Analyses? -year: '2024' -pdf: guHowDoAnalystsUnderstand2024.pdf -thumbnail: guHowDoDataAnalystsUnderstand.png ---- \ No newline at end of file diff --git a/_publications/hicks2022leveraging.md b/_publications/hicks2022leveraging.md deleted file mode 100644 index f8e20b5..0000000 --- a/_publications/hicks2022leveraging.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -author: Hicks, Jennifer L and Boswell, Melissa A and Althoff, Tim and Crum, Alia J - and Ku, Joy P and Landay, James A and Moya, Paula ML and Murnane, Elizabeth L and - Snyder, Michael P and King, Abby C and others -description: null -highlight: 0 -journal: Annual Review of Public Health -pdf: hicks2022leveraging.pdf -publisher: Annual Reviews -thumbnail: hicks2022leveraging.png -title: 'Leveraging Mobile Technology for Public Health Promotion: A Multidisciplinary - Perspective' -volume: '44' -year: '2022' ---- \ No newline at end of file diff --git a/_publications/kurashima2018tipas.md b/_publications/kurashima2018tipas.md deleted file mode 100644 index 83cd762..0000000 --- a/_publications/kurashima2018tipas.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -author: Kurashima, Takeshi and Althoff, Tim and Leskovec, Jure -booktitle: WWW -description: '' -highlight: 0 -note: Online Appendix. \url{http://bit.ly/2stjpB4} -optjournal: foo -optnote: \url{http://bit.ly/2gGUnWb} -opttitle: '{Online appendix of this paper}' -pdf: kurashima2018tipas.pdf -thumbnail: kurashima2018tipas.png -title: 'Modeling Interdependent and Periodic Real-World Action Sequences' -year: '2018' ---- \ No newline at end of file diff --git a/_publications/lin-etal-2022-gendered.md b/_publications/lin-etal-2022-gendered.md deleted file mode 100644 index daaba19..0000000 --- a/_publications/lin-etal-2022-gendered.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -abstract: 'Mental health stigma prevents many individuals from receiving the appropriate - care, and social psychology studies have shown that mental health tends to be overlooked - in men. In this work, we investigate gendered mental health stigma in masked language - models. In doing so, we operationalize mental health stigma by developing a framework - grounded in psychology research: we use clinical psychology literature to curate - prompts, then evaluate the models{''} propensity to generate gendered words. We - find that masked language models capture societal stigma about gender in mental - health: models are consistently more likely to predict female subjects than male - in sentences about having a mental health condition (32{\%} vs. 19{\%}), and this - disparity is exacerbated for sentences that indicate treatment-seeking behavior. - Furthermore, we find that different models capture dimensions of stigma differently - for men and women, associating stereotypes like anger, blame, and pity more with - women with mental health conditions than with men. In showing the complex nuances - of models{''} gendered mental health stigma, we demonstrate that context and overlapping - dimensions of identity are important considerations when assessing computational - models{''} social biases.' -address: Abu Dhabi, United Arab Emirates -author: Lin, Inna and Njoo, Lucille and Field, Anjalie and Sharma, Ashish and Reinecke, - Katharina and Althoff, Tim and Tsvetkov, Yulia -booktitle: EMNLP -description: If you have ever considered using NLP for Mental Health applications, - it’s vital to know what the models have inadvertently learned about people with - mental health issues. In our EMNLP 2022 paper, we find that masked LMs capture societal - stigma about gender in mental health. -highlight: 1 -month: December -pages: 2152--2170 -pdf: lin-etal-2022-gendered.pdf -publisher: Association for Computational Linguistics -thumbnail: lin-etal-2022-gendered.png -title: Gendered Mental Health Stigma in Masked Language Models -url: https://aclanthology.org/2022.emnlp-main.139 -year: '2022' ---- diff --git a/_publications/lin2024imbue.md b/_publications/lin2024imbue.md deleted file mode 100644 index 8cc5d95..0000000 --- a/_publications/lin2024imbue.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -author: Lin, Inna and Sharma, Ashish and Rytting, Christopher and Miner, Adam and Suh, Jina and Althoff, Tim -booktitle: Proceedings of the 62nd Annual Meeting of the Association for Computational Linguistics -title: IMBUE - Improving Interpersonal Effectiveness through Simulation and Just-in-time Feedback with Human-Language Model Interaction -year: '2024' -pdf: linIMBUE2024.pdf -thumbnail: linIMBUE.png ---- \ No newline at end of file diff --git a/_publications/liupaths2020.md b/_publications/liupaths2020.md deleted file mode 100644 index 88c5c58..0000000 --- a/_publications/liupaths2020.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -abstract: Drawing reliable inferences from data involves many, sometimes arbitrary, - decisions across phases of data collection, wrangling, and modeling. As different - choices can lead to diverging conclusions, understanding how researchers make analytic - decisions is important for supporting robust and replicable analysis. In this study, - we pore over nine published research studies and conduct semi-structured interviews - with their authors. We observe that researchers often base their decisions on methodological - or theoretical concerns, but subject to constraints arising from the data, expertise, - or perceived interpretability. We confirm that researchers may experiment with choices - in search of desirable results, but also identify other reasons why researchers - explore alternatives yet omit findings. In concert with our interviews, we also - contribute visualizations for communicating decision processes throughout an analysis. - Based on our results, we identify design opportunities for strengthening end-to-end - analysis, for instance via tracking and meta-analysis of multiple decision paths. -address: New York, NY, USA -author: Liu, Yang and Althoff, Tim and Heer, Jeffrey -booktitle: 'CHI' -description: '' -doi: 10.1145/3313831.3376533 -highlight: 0 -isbn: '9781450367080' -keywords: reproducibility, analytic decision making, garden of forking paths, data - analysis, multiverse analysis, interview study -location: Honolulu, HI, USA -numpages: '14' -pages: 1–14 -pdf: liupaths2020.pdf -publisher: Association for Computing Machinery -series: CHI '20 -thumbnail: liupaths2020.png -title: 'Paths Explored, Paths Omitted, Paths Obscured: Decision Points & Selective - Reporting in End-to-End Data Analysis' -url: https://doi.org/10.1145/3313831.3376533 -year: '2020' ---- \ No newline at end of file diff --git a/_publications/merrill2024language.md b/_publications/merrill2024language.md deleted file mode 100644 index 2946c98..0000000 --- a/_publications/merrill2024language.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -author: Merrill, Mike A. and Tan, Mingtian and Gupta, Vinayak and Hartvigsen, Tom and Althoff, Tim -booktitle: Proceedings of the 2024 Conference on Empirical Methods in Natural Language Processing -title: Language Models Still Struggle to Zero-shot Reason about Time Series -year: '2024' -pdf: merrillLanguageModelsStill2024.pdf -thumbnail: merrillLanguageModels.png ---- \ No newline at end of file diff --git a/_publications/merrillHomekit2020BenchmarkTime2023.md b/_publications/merrillHomekit2020BenchmarkTime2023.md deleted file mode 100644 index 1fb10e0..0000000 --- a/_publications/merrillHomekit2020BenchmarkTime2023.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -abstract: 'Despite increased interest in wearables as tools for detecting various - health conditions, there are not as of yet any large public benchmarks for such - mobile sensing data. The few datasets that are available do not contain data from - more than dozens of individuals, do not contain high-resolution raw data or do not - include dataloaders for easy integration into machine learning pipelines. Here, - we present Homekit2020: the first large-scale public benchmark for time series classification - of wearable sensor data. Our dataset contains over 14 million hours of minute-level - multimodal FitBit data, symptom reports, and ground-truth laboratory PCR influenza - test results, along with an evaluation framework that mimics realistic model deployments - and efficiently characterizes statistical uncertainty in model selection in the - presence of extreme class imbalance. Furthermore, we implement and evaluate nine - neural and non-neural time series classification models on our benchmark across - 450 total training runs in order to establish state of the art performance.' -author: Merrill, Mike A and Safranchik, Esteban and Kolbeinsson, Arinbjorn and Gade, - Piyusha and Ramirez, Ernesto and Schmidt, Ludwig and Foshchini, Luca and Althoff, - Tim -description: 'Despite increased interest in wearables as tools for detecting various - health conditions, there are not as of yet any large public benchmarks for such - mobile sensing data. Our dataset contains over 14 million hours of minute-level - multimodal FitBit data, symptom reports, and ground-truth laboratory PCR influenza - test results, along with an evaluation framework that mimics realistic model deployments - and efficiently characterizes statistical uncertainty in model selection in the - presence of extreme class imbalance.' -highlight: 1 -code: https://github.com/behavioral-data/Homekit2020 -file: /Users/michaelmerrill/Zotero/storage/S72M77YC/Merrill et al. - Homekit2020 A - Benchmark for Time Series Classific.pdf -journal: Conference on Health, Inference, and Learning -langid: english -month: March -pdf: merrillHomekit2020BenchmarkTime2023.pdf -thumbnail: merrillHomekit2020BenchmarkTime2023.png -title: 'Homekit2020: A Benchmark for Time Series Classification on a Large - Mobile Sensing Dataset with Laboratory Tested Ground Truth of Influenza - Infections' -year: '2023' ---- \ No newline at end of file diff --git a/_publications/merrillSelfsupervisedPretrainingTransfer2023.md b/_publications/merrillSelfsupervisedPretrainingTransfer2023.md deleted file mode 100644 index 43f2d87..0000000 --- a/_publications/merrillSelfsupervisedPretrainingTransfer2023.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -abstract: Detailed mobile sensing data from phones, watches, and fitness trackers - offer an unparalleled opportunity to quantify and act upon previously unmeasurable - behavioral changes in order to improve individual health and accelerate responses - to emerging diseases. Unlike in natural language processing and computer vision, - deep representation learning has yet to broadly impact this domain, in which the - vast majority of research and clinical applications still rely on manually defined - features and boosted tree models or even forgo predictive modeling altogether due - to insufficient accuracy. This is due to unique challenges in the behavioral health - domain, including very small datasets (\textasciitilde 10\^1 participants), which - frequently contain missing data, consist of long time series with critical long-range - dependencies (length{$>$}10\^4), and extreme class imbalances ({$>$}10\^3:1). -archiveprefix: arxiv -author: Merrill, Mike A. and Althoff, Tim -description: null -eprint: '2205.13607' -file: /Users/michaelmerrill/Zotero/storage/QRXUFB52/Merrill and Althoff - 2022 - Self-supervised - Pretraining and Transfer Learning .pdf;/Users/michaelmerrill/Zotero/storage/TNEAQ9SK/2205.html -highlight: 0 -journal: Conference on Health, Inference, and Learning -keywords: Computer Science - Human-Computer Interaction,Computer Science - Machine - Learning -month: March -pdf: merrillSelfsupervisedPretrainingTransfer2023.pdf -primaryclass: cs -thumbnail: merrillSelfsupervisedPretrainingTransfer2023.png -title: Self-Supervised Pretraining and Transfer Learning Enable Flu and COVID-19 - Predictions in Small Mobile Sensing Datasets -urldate: '2022-06-02' -year: '2023' ---- \ No newline at end of file diff --git a/_publications/merrill_multiverse_2021.md b/_publications/merrill_multiverse_2021.md deleted file mode 100644 index 7e1e529..0000000 --- a/_publications/merrill_multiverse_2021.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -abstract: Data analyses are based on a series of “decision points” including data - filtering, feature operationalization and selection, model specification, and parametric - assumptions. “Multiverse Analysis” research has shown that a lack of exploration - of these decisions can lead to non-robust conclusions based on highly sensitive - decision points. Importantly, even if myopic analyses are technically correct, analysts’ - focus on one set of decision points precludes them from exploring alternate formulations - that may produce very different results. Prior work has also shown that analysts’ - exploration is often limited based on their training, domain, and personal experience. - However, supporting analysts in exploring alternative approaches is challenging - and typically requires expert feedback that is costly and hard to scale. -address: Virtual Event Singapore -author: Merrill, Mike A. and Zhang, Ge and Althoff, Tim -booktitle: KDD -description: Data analyses are based on a series of “decision points” including data - filtering, feature operationalization and selection, model specification, and parametric - assumptions. In this work we mine Kaggle for hundreds of thousands of decision points - and train a novel language model to suggest alternative analyses. -doi: 10.1145/3447548.3467455 -file: Merrill et al. - 2021 - MULTIVERSE Mining Collective Data Science Knowled.pdf:/Users/michaelmerrill/Zotero/storage/5SIZTGV6/Merrill - et al. - 2021 - MULTIVERSE Mining Collective Data Science Knowled.pdf:application/pdf -highlight: 0 -isbn: 978-1-4503-8332-5 -language: en -month: August -pages: 1212--1222 -pdf: merrill_multiverse_2021.pdf -publisher: ACM -shorttitle: '{MULTIVERSE}' -thumbnail: merrill_multiverse_2021.png -title: 'MULTIVERSE: Mining Collective Data Science Knowledge from Code on the Web - to Suggest Alternative Analysis Approaches' -url: https://dl.acm.org/doi/10.1145/3447548.3467455 -urldate: '2021-08-30' -year: '2021' ---- \ No newline at end of file diff --git a/_publications/mezlini2021estimating.md b/_publications/mezlini2021estimating.md deleted file mode 100644 index bd4d363..0000000 --- a/_publications/mezlini2021estimating.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -author: Mezlini, Aziz and Shapiro, Allison and Daza, Eric J and Caddigan, Eamon and - Ramirez, Ernesto and Althoff, Tim and Foschini, Luca -description: null -highlight: 0 -journal: JAMA Network Open -optpublisher: '' -pdf: mezlini2021estimating.pdf -thumbnail: mezlini2021estimating.png -title: Estimating the Burden of Influenza on Daily Activity at Population Scale Using - Commercial Wearable Sensors -year: '2022' ---- \ No newline at end of file diff --git a/_publications/miner2022computational.md b/_publications/miner2022computational.md deleted file mode 100644 index 3ded42d..0000000 --- a/_publications/miner2022computational.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -author: Miner, Adam S and Fleming, Scott L and Haque, Albert and Fries, Jason A and - Althoff, Tim and Wilfley, Denise E and Agras, W Stewart and Milstein, Arnold and - Hancock, Jeff and Asch, Steven M and others -description: null -highlight: 0 -journal: npj Mental Health Research -number: '1' -optpublisher: Nature Publishing Group UK London -pages: '19' -pdf: miner2022computational.pdf -thumbnail: miner2022computational.png -title: A computational approach to measure the linguistic characteristics of psychotherapy - timing, responsiveness, and consistency -volume: '1' -year: '2022' ---- \ No newline at end of file diff --git a/_publications/sefidgarpassively2020.md b/_publications/sefidgarpassively2020.md deleted file mode 100644 index 5c59f98..0000000 --- a/_publications/sefidgarpassively2020.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -abstract: 'A deep understanding of how discrimination impacts psychological health - and well-being of students could allow us to better protect individuals at risk - and support those who encounter discrimination. While the link between discrimination - and diminished psychological and physical well-being is well established, existing - research largely focuses on chronic discrimination and long-term outcomes. A better - understanding of the short-term behavioral correlates of discrimination events could - help us to concretely quantify such experiences, which in turn could support policy - and intervention design. In this paper we specifically examine, for the first time, - what behaviors change and in what ways in relation to discrimination. We use actively-reported - and passively-measured markers of health and well-being in a sample of 209 first-year - college students over the course of two academic quarters. We examine changes in - indicators of psychological state in relation to reports of unfair treatment in - terms of five categories of behaviors: physical activity, phone usage, social interaction, - mobility, and sleep. We find that students who encounter unfair treatment become - more physically active, interact more with their phone in the morning, make more - calls in the evening, and spend more time in bed on the day of the event. Some of - these patterns continue the next day. Our results further our understanding of the - impact of discrimination and can inform intervention work.' -address: New York, NY, USA -articleno: '114' -author: Sefidgar, Yasaman S. and Seo, Woosuk and Kuehn, Kevin S. and Althoff, Tim - and Browning, Anne and Riskin, Eve and Nurius, Paula S. and Dey, Anind K. and Mankoff, - Jennifer -description: '' -doi: 10.1145/3359216 -highlight: 0 -issue_date: November 2019 -journal: 'CSCW' -keywords: discrimination, mobile health, microaggression, mobile sensing -month: November -number: CSCW -numpages: '29' -pdf: sefidgarpassively2020.pdf -publisher: Association for Computing Machinery -thumbnail: sefidgarpassively2020.png -title: Passively-Sensed Behavioral Correlates of Discrimination Events in College - Students -url: https://doi.org/10.1145/3359216 -volume: '3' -year: '2019' ---- \ No newline at end of file diff --git a/_publications/shameli2017gamification.md b/_publications/shameli2017gamification.md deleted file mode 100644 index f01110a..0000000 --- a/_publications/shameli2017gamification.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -author: Shameli, Ali and Althoff, Tim and Saberi, Amin and Leskovec, Jure -booktitle: WWW -description: '' -highlight: 0 -optbooktitle: Proceedings of the 26th International Conference on World Wide Web Companion -optorganization: International World Wide Web Conferences Steering Committee -optpages: 455--463 -pdf: shameli2017gamification.pdf -thumbnail: shameli2017gamification.png -title: 'How gamification affects physical activity: Large-scale analysis of walking - challenges in a mobile application' -year: '2017' ---- \ No newline at end of file diff --git a/_publications/sharma2020computational.md b/_publications/sharma2020computational.md deleted file mode 100644 index e83bf98..0000000 --- a/_publications/sharma2020computational.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -archiveprefix: arXiv -author: Ashish Sharma and Adam S. Miner and David C. Atkins and Tim Althoff -journal: EMNLP -description: '' -eprint: '2009.08441' -highlight: 0 -pdf: sharma2020computational.pdf -primaryclass: cs.CL -thumbnail: sharma2020computational.png -title: A Computational Approach to Understanding Empathy Expressed in Text-Based Mental - Health Support -year: '2020' ---- \ No newline at end of file diff --git a/_publications/sharma2021facilitating.md b/_publications/sharma2021facilitating.md deleted file mode 100644 index a4fb670..0000000 --- a/_publications/sharma2021facilitating.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -author: Sharma, Ashish and Lin, Inna W and Miner, Adam S and Atkins, David C and Althoff, - Tim -booktitle: WWW -award: Best Paper (single award across all 1736 submissions) -description: Access to mental health care is a global challenge that online peer support - platforms like TalkLife can help mitigate. Millions of people seek and provide support - online but they struggle to have effective conversations. In this paper, we work - towards improving empathy in online mental health support conversations. We introduce - empathic rewriting, a new task for transforming low-empathy conversations to higher - empathy. We propose PARTNER, a deep reinforcement learning agent that learns to - make sentence-level edits to conversations in order to increase the expressed level - of empathy while maintaining conversation quality through specificity, fluency, - and diversity. -highlight: 0 -pdf: sharma2021facilitating.pdf -thumbnail: sharma2021facilitating.png -title: 'Towards Facilitating Empathic Conversations in Online Mental Health Support: - A Reinforcement Learning Approach' -year: '2021' ---- diff --git a/_publications/sharma2023human.md b/_publications/sharma2023human.md deleted file mode 100644 index fcbd869..0000000 --- a/_publications/sharma2023human.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -author: Sharma, Ashish and Lin, Inna W and Miner, Adam S and Atkins, David C and Althoff, - Tim -description: How can AI help improve access to mental health care? Our Nature Machine - Intelligence paper shows that human-AI collaboration can empower people to respond - more empathically in online peer-to-peer mental health support. -highlight: 1 -journal: Nature Machine Intelligence -pages: 1--12 -pdf: sharma2023human.pdf -publisher: Nature Publishing Group UK London -thumbnail: sharma2023human.png -title: Human-AI Collaboration Enables More Empathic Conversations in Text-based Peer-to-Peer - Mental Health Support -year: '2023' ---- \ No newline at end of file diff --git a/_publications/sharma2024computational.md b/_publications/sharma2024computational.md deleted file mode 100644 index 3b253a7..0000000 --- a/_publications/sharma2024computational.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -author: Chiu, Yu Ying* and Sharma, Ashish* and Lin, Inna and Althoff, Tim -booktitle: Preprint -title: A Computational Framework for Behavioral Assessment of LLM Therapists -year: '2024' -pdf: sharma2024computational.pdf -thumbnail: sharmaComputational.png ---- \ No newline at end of file diff --git a/_publications/sharma2024facilitating.md b/_publications/sharma2024facilitating.md deleted file mode 100644 index 33d1043..0000000 --- a/_publications/sharma2024facilitating.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -author: Sharma, Ashish and Rushton, Kevin and Lin, Inna and Nguyen, Theresa and Althoff, Tim -booktitle: Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems -title: Facilitating Self-Guided Mental Health Interventions Through Human-Language Model Interaction - A Case Study of Cognitive Restructuring -year: '2024' -pdf: sharmaFacilitatingSelf-Guided2024.pdf -thumbnail: sharmafacilitating.png ---- \ No newline at end of file diff --git a/_publications/suh2020populationscale.md b/_publications/suh2020populationscale.md deleted file mode 100644 index 7be8617..0000000 --- a/_publications/suh2020populationscale.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -archiveprefix: arXiv -author: Jina Suh and Eric Horvitz and Ryen W. White and Tim Althoff -description: The COVID-19 pandemic has fundamentally changed our lives beyond just our physical health. To understand the impact of the pandemic and associated policy decisions on a multitude of human needs, we propose a computational methodology, building on Maslow's hierarchy of needs, that can capture a holistic view of relative changes in needs following the pandemic through a difference-in-differences approach that corrects for seasonality and volume variations. When applied to over 35 billion search interactions spanning over 36000 ZIP codes in the US, we found that the expression of basic human needs has increased exponentially while higher-level aspirations declined, that the durations of shelter-in-place mandates significantly impacted social-emotional needs, and that there are potential barriers to meeting critical needs online. -eprint: "2008.07045" -highlight: 0 -pdf: suh2020populationscale.pdf -primaryclass: cs.CY -journal: WSDM -thumbnail: suh2020populationscale.png -title: - "Population-Scale Study of Human Needs During the COVID-19 Pandemic: Analysis - and Implications" -year: "2021" ---- diff --git a/_publications/suhDisparateImpactsOnline2022.md b/_publications/suhDisparateImpactsOnline2022.md deleted file mode 100644 index 06fe78c..0000000 --- a/_publications/suhDisparateImpactsOnline2022.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -abstract: Abstract The COVID-19 pandemic has stimulated important changes in online - information access as digital engagement became necessary to meet the demand for - health, economic, and educational resources. Our analysis of 55 billion everyday - web search interactions during the pandemic across 25,150 US ZIP codes reveals that - the extent to which different communities of internet users enlist digital resources - varies based on socioeconomic and environmental factors. For example, we find that - ZIP codes with lower income intensified their access to health information to a - smaller extent than ZIP codes with higher income. We show that ZIP codes with higher - proportions of Black or Hispanic residents intensified their access to unemployment - resources to a greater extent, while revealing patterns of unemployment site visits - unseen by the claims data. Such differences frame important questions on the relationship - between differential information search behaviors and the downstream real-world - implications on more and less advantaged populations. -author: Suh, Jina and Horvitz, Eric and White, Ryen W. and Althoff, Tim -description: The pandemic prompted increased digital engagement for health, economic, and educational resources. Analyzing 55 billion web searches across 25,150 US ZIP codes, we found differing use of digital resources based on socioeconomic and environmental factors. Lower-income areas accessed health information less than higher-income ones. ZIP codes with more Black or Hispanic residents used unemployment resources more, with unique patterns. These disparities raise important questions about the impact of information search behaviors on disadvantaged populations. -doi: 10.1038/s41467-022-34592-z -file: Suh et al. - 2022 - Disparate impacts on online information access dur.pdf:/Users/michaelmerrill/Zotero/storage/L83KGF2X/Suh - et al. - 2022 - Disparate impacts on online information access dur.pdf:application/pdf -highlight: 1 -issn: 2041-1723 -journal: Nature Communications -language: en -month: November -number: '1' -pages: '7094' -pdf: suhDisparateImpactsOnline2022.pdf -thumbnail: suhDisparateImpactsOnline2022.png -title: Disparate impacts on online information access during the Covid-19 pandemic -url: https://www.nature.com/articles/s41467-022-34592-z -urldate: '2023-05-08' -volume: '13' -year: '2022' ---- \ No newline at end of file diff --git a/_publications/weld2022adjusting_confounders.md b/_publications/weld2022adjusting_confounders.md deleted file mode 100644 index 896c2dc..0000000 --- a/_publications/weld2022adjusting_confounders.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -author: Galen Weld, Peter West, Maria Glenski, David Arbour, Ryan Rossi, and Tim Althoff -booktitle: ICWSM -description: null -highlight: 0 -pdf: weld2022adjusting_confounders.pdf -thumbnail: weld2022adjusting_confounders.JPG -title: 'Adjusting for Confounders with Text: Challenges and an Empirical Evaluation - Framework for Causal Inference' -year: '2022' ---- \ No newline at end of file diff --git a/_publications/weld2022community_values.md b/_publications/weld2022community_values.md deleted file mode 100644 index de3d061..0000000 --- a/_publications/weld2022community_values.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -author: Weld, Galen and Zhang, Amy X. and Althoff, Tim -booktitle: ICWSM -description: null -highlight: 0 -pdf: weld2022community_values.pdf -thumbnail: weld2022community_values.jpg -title: What Makes Online Communities 'Better'? Measuring Values, Consensus, and Conflict - across Thousands of Subreddits -year: '2022' ---- \ No newline at end of file diff --git a/_publications/weld2024making.md b/_publications/weld2024making.md deleted file mode 100644 index ddd2221..0000000 --- a/_publications/weld2024making.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -author: Weld, Galen and Zhang, Amy X. and Althoff, Tim -booktitle: Proceedings of the Eighteenth International AAAI Conference on Web and Social Media -title: Making Online Communities 'Better': A Taxonomy of Community Values on Reddit -year: '2024' -pdf: weldMakingOnlineCommunities2024.pdf -thumbnail: weldmaking.png ---- \ No newline at end of file diff --git a/_publications/xu2022GLOBEM.md b/_publications/xu2022GLOBEM.md deleted file mode 100644 index 99210c3..0000000 --- a/_publications/xu2022GLOBEM.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -author: Xuhai Xu, Han Zhang, Yasaman Sefidgar, Yiyi Ren, Xin Liu, Woosuk Seo, Jennifer - Brown, Kevin Kuehn, Mike A. Merrill, Paula Nurius, Shwetak Patel, Tim Althoff, Margaret - E. Morris, Eve Riskin, Jennifer Mankoff, and Anind K. Dey -copyright: Creative Commons Attribution 4.0 International -doi: 10.48550/ARXIV.2211.02733 -journal: NeurIPS -key: xu2022GLOBEM -keywords: 'Machine Learning (cs.LG), Artificial Intelligence (cs.AI), Human-Computer - Interaction (cs.HC), FOS: Computer and information sciences, FOS: Computer and information - sciences, I.2.1; E.m, 68T09' -pdf: resources/pubpdfs/xu2022GLOBEM.pdf -publisher: arXiv -thumbnail: xu2022GLOBEM.png -title: ' Globem dataset: Multi-year datasets for longitudinal human behavior modeling - generalization' -url: https://arxiv.org/abs/2211.02733 -year: '2022' ---- \ No newline at end of file diff --git a/_publications/xu2023globemimwut.md b/_publications/xu2023globemimwut.md deleted file mode 100644 index 187344c..0000000 --- a/_publications/xu2023globemimwut.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -author: Xu, Xuhai and Liu, Xin and Zhang, Han and Wang, Weichen and Nepal, Subigya - and Sefidgar, Yasaman and Seo, Woosuk and Kuehn, Kevin S and Huckins, Jeremy F and - Morris, Margaret E and Nurius, Paula S. and Riskin, Eve A. and Patel, Shwetak and - Althoff, Tim and Campell, Andrew and Dey, Anind K. and Mankoff, Jennifer C. -description: null -highlight: 0 -journal: ACM IMWUT -optjournal: Proceedings of the ACM on Interactive, Mobile, Wearable and Ubiquitous - Technologies -optnumber: '4' -optpages: 1--34 -optpublisher: ACM New York, NY, USA -optvolume: '6' -pdf: xu2023globemimwut.pdf -thumbnail: xu2023globemimwut.png -title: 'GLOBEM: Cross-Dataset Generalization of Longitudinal Human Behavior Modeling' -year: '2023' ---- \ No newline at end of file diff --git a/_publications/xuleveraging2019.md b/_publications/xuleveraging2019.md deleted file mode 100644 index a03abc6..0000000 --- a/_publications/xuleveraging2019.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -abstract: The rate of depression in college students is rising, which is known to - increase suicide risk, lower academic performance and double the likelihood of dropping - out of school. Existing work on finding relationships between passively sensed behavior - and depression, as well as detecting depression, mainly derives relevant unimodal - features from a single sensor. However, co-occurrence of values in multiple sensors - may provide better features, because such features can describe behavior in context. - We present a new method to extract contextually filtered features from passively - collected, time-series mobile data via association rule mining. After calculating - traditional unimodal features from the data, we extract rules that relate unimodal - features to each other using association rule mining. We extract rules from each - class separately (e.g., depression vs. non-depression). We introduce a new metric - to select a subset of rules that distinguish between the two classes. From these - rules, which capture the relationship between multiple unimodal features, we automatically - extract contextually filtered features. These features are then fed into a traditional - machine learning pipeline to detect the class of interest (in our case, depression), - defined by whether a student has a high BDI-II score at the end of the semester. - The behavior rules generated by our methods are highly interpretable representations - of differences between classes. Our best model uses contextually-filtered features - to significantly outperform a standard model that uses only unimodal features, by - an average of 9.7% across a variety of metrics. We further verified the generalizability - of our approach on a second dataset, and achieved very similar results. -address: New York, NY, USA -articleno: '116' -author: Xu, Xuhai and Chikersal, Prerna and Doryab, Afsaneh and Villalba, Daniella - K. and Dutcher, Janine M. and Tumminia, Michael J. and Althoff, Tim and Cohen, Sheldon - and Creswell, Kasey G. and Creswell, J. David and Mankoff, Jennifer and Dey, Anind - K. -description: '' -doi: 10.1145/3351274 -highlight: 0 -issue_date: September 2019 -journal: IMWUT -keywords: Passive sensing, Depression detection, Behavior mining, Association rule - mining -month: September -number: '3' -numpages: '33' -pdf: xuleveraging2019.pdf -publisher: Association for Computing Machinery -thumbnail: xuleveraging2019.png -title: Leveraging Routine Behavior and Contextually-Filtered Features for Depression - Detection among College Students -url: https://doi.org/10.1145/3351274 -volume: '3' -year: '2019' ---- \ No newline at end of file diff --git a/_publications/zech2023mhatsengagement.md b/_publications/zech2023mhatsengagement.md deleted file mode 100644 index 8ca8346..0000000 --- a/_publications/zech2023mhatsengagement.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -author: Zech, James M and Johnson, Morgan and Pullman, Michael D and Hull, Thomas - D and Althoff, Tim and Munson, Sean A and Fridling, Nicole and Litvin, Boris and - Wu, Jerilyn and Areán, Patricia A -description: null -highlight: 0 -journal: JMIR Formative Research -pdf: zech2023mhatsengagement.pdf -thumbnail: zech2023mhatsengagement.png -title: 'Mapping User Engagement in Digital Psychotherapy: An Integrative Engagement - Model' -year: '2023' ---- \ No newline at end of file diff --git a/_publications/zhou2024correcting.md b/_publications/zhou2024correcting.md deleted file mode 100644 index 95fcce2..0000000 --- a/_publications/zhou2024correcting.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -author: Zhou, Xinyi and Sharma, Ashish and Zhang, Amy and Althoff, Tim -booktitle: Preprint -title: Correcting misinformation on social media with a large language model -year: '2024' -pdf: zhouCorrectingMisinformation2024.pdf -thumbnail: zhouCorrectingMis.png ---- \ No newline at end of file diff --git a/_sass/_bootstrap.scss b/_sass/_bootstrap.scss deleted file mode 100644 index 9babefd..0000000 --- a/_sass/_bootstrap.scss +++ /dev/null @@ -1,58 +0,0 @@ -/*! - * Bootstrap v3.3.7 (http://getbootstrap.com) - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -// Core variables and mixins -@import "bootstrap/variables"; -@import "bootstrap/mixins"; - -// Reset and dependencies -@import "bootstrap/normalize"; -@import "bootstrap/print"; -@import "bootstrap/glyphicons"; - -// Core CSS -@import "bootstrap/scaffolding"; -@import "bootstrap/type"; -@import "bootstrap/code"; -@import "bootstrap/grid"; -@import "bootstrap/tables"; -@import "bootstrap/forms"; -@import "bootstrap/buttons"; - -// Components -@import "bootstrap/component-animations"; -@import "bootstrap/dropdowns"; -@import "bootstrap/button-groups"; -@import "bootstrap/input-groups"; -@import "bootstrap/navs"; -@import "bootstrap/navbar"; -@import "bootstrap/breadcrumbs"; -@import "bootstrap/pagination"; -@import "bootstrap/pager"; -@import "bootstrap/labels"; -@import "bootstrap/badges"; -@import "bootstrap/jumbotron"; -@import "bootstrap/thumbnails"; -@import "bootstrap/alerts"; -@import "bootstrap/progress-bars"; -@import "bootstrap/media"; -@import "bootstrap/list-group"; -@import "bootstrap/panels"; -@import "bootstrap/responsive-embed"; -@import "bootstrap/wells"; -@import "bootstrap/close"; - -// Components w/ JavaScript -@import "bootstrap/modals"; -@import "bootstrap/tooltip"; -@import "bootstrap/popovers"; -@import "bootstrap/carousel"; - -// Utility classes -@import "bootstrap/utilities"; -@import "bootstrap/responsive-utilities"; -@import "bootstrap/bootswatch"; - diff --git a/_sass/bootstrap/_alerts.scss b/_sass/bootstrap/_alerts.scss deleted file mode 100644 index 7d1e1fd..0000000 --- a/_sass/bootstrap/_alerts.scss +++ /dev/null @@ -1,73 +0,0 @@ -// -// Alerts -// -------------------------------------------------- - - -// Base styles -// ------------------------- - -.alert { - padding: $alert-padding; - margin-bottom: $line-height-computed; - border: 1px solid transparent; - border-radius: $alert-border-radius; - - // Headings for larger alerts - h4 { - margin-top: 0; - // Specified for the h4 to prevent conflicts of changing $headings-color - color: inherit; - } - - // Provide class for links that match alerts - .alert-link { - font-weight: $alert-link-font-weight; - } - - // Improve alignment and spacing of inner content - > p, - > ul { - margin-bottom: 0; - } - - > p + p { - margin-top: 5px; - } -} - -// Dismissible alerts -// -// Expand the right padding and account for the close button's positioning. - -.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. -.alert-dismissible { - padding-right: ($alert-padding + 20); - - // Adjust close link position - .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; - } -} - -// Alternate styles -// -// Generate contextual modifier classes for colorizing the alert. - -.alert-success { - @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text); -} - -.alert-info { - @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text); -} - -.alert-warning { - @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text); -} - -.alert-danger { - @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text); -} diff --git a/_sass/bootstrap/_badges.scss b/_sass/bootstrap/_badges.scss deleted file mode 100644 index 70002e0..0000000 --- a/_sass/bootstrap/_badges.scss +++ /dev/null @@ -1,68 +0,0 @@ -// -// Badges -// -------------------------------------------------- - - -// Base class -.badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: $font-size-small; - font-weight: $badge-font-weight; - color: $badge-color; - line-height: $badge-line-height; - vertical-align: middle; - white-space: nowrap; - text-align: center; - background-color: $badge-bg; - border-radius: $badge-border-radius; - - // Empty badges collapse automatically (not available in IE8) - &:empty { - display: none; - } - - // Quick fix for badges in buttons - .btn & { - position: relative; - top: -1px; - } - - .btn-xs &, - .btn-group-xs > .btn & { - top: 0; - padding: 1px 5px; - } - - // [converter] extracted a& to a.badge - - // Account for badges in navs - .list-group-item.active > &, - .nav-pills > .active > a > & { - color: $badge-active-color; - background-color: $badge-active-bg; - } - - .list-group-item > & { - float: right; - } - - .list-group-item > & + & { - margin-right: 5px; - } - - .nav-pills > li > a > & { - margin-left: 3px; - } -} - -// Hover state, but only for links -a.badge { - &:hover, - &:focus { - color: $badge-link-hover-color; - text-decoration: none; - cursor: pointer; - } -} diff --git a/_sass/bootstrap/_bootswatch.scss b/_sass/bootstrap/_bootswatch.scss deleted file mode 100644 index 2d35f52..0000000 --- a/_sass/bootstrap/_bootswatch.scss +++ /dev/null @@ -1,523 +0,0 @@ -// Lumen 3.3.7 -// Bootswatch -// ----------------------------------------------------- - -$web-font-path: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700,400italic" !default; -@import url($web-font-path); - -@mixin shadow($width: 4px){ - border-width: 0 1px $width 1px; -} - -// Navbar ===================================================================== - -.navbar { - @include shadow(); -} - -// Buttons ==================================================================== - -.btn { - padding: ($padding-base-vertical + 2) $padding-base-horizontal $padding-base-vertical; - @include shadow(); - font-size: 12px; - font-weight: bold; - text-transform: uppercase; - - &:hover { - margin-top: 1px; - border-bottom-width: 3px; - } - - &:active { - margin-top: 2px; - border-bottom-width: 2px; - @include box-shadow(none); - } - - &-lg, - &-group-lg > .btn { - padding: ($padding-large-vertical + 2) $padding-large-horizontal $padding-large-vertical; - line-height: 15px; - } - - &-sm, - &-group-sm > .btn { - padding: ($padding-small-vertical + 2) $padding-small-horizontal $padding-small-vertical; - } - - &-xs, - &-group-xs > .btn { - padding: ($padding-xs-vertical + 2) $padding-xs-horizontal $padding-xs-vertical; - } - - &-default:hover, - &-default:focus, - &-group.open .dropdown-toggle.btn-default { - background-color: $btn-default-bg; - border-color: $btn-default-border; - } - - &-primary:hover, - &-primary:focus, - &-group.open .dropdown-toggle.btn-primary { - background-color: $btn-primary-bg; - border-color: $btn-primary-border; - } - - &-success:hover, - &-success:focus, - &-group.open .dropdown-toggle.btn-success { - background-color: $btn-success-bg; - border-color: $btn-success-border; - } - - &-info:hover, - &-info:focus, - &-group.open .dropdown-toggle.btn-info { - background-color: $btn-info-bg; - border-color: $btn-info-border; - } - - &-warning:hover, - &-warning:focus, - &-group.open .dropdown-toggle.btn-warning { - background-color: $btn-warning-bg; - border-color: $btn-warning-border; - } - - &-danger:hover, - &-danger:focus, - &-group.open .dropdown-toggle.btn-danger { - background-color: $btn-danger-bg; - border-color: $btn-danger-border; - } - - &-group.open .dropdown-toggle { - @include box-shadow(none); - } -} - -.navbar-btn { - &:hover { - margin-top: 8px - } - - &:active { - margin-top: 9px - } - - &.btn-sm { - &:hover { - margin-top: 11px - } - - &:active { - margin-top: 12px - } - } - - &.btn-xs { - &:hover { - margin-top: 15px - } - - &:active { - margin-top: 16px - } - } -} - -.btn-group-vertical { - .btn + .btn { - &:hover { - border-top-width: 1px; - } - - &:active { - border-top-width: 2px; - } - } -} - -// Typography ================================================================= - -.text-primary, -.text-primary:hover { - color: $brand-primary; -} - -.text-success, -.text-success:hover { - color: $brand-success; -} - -.text-danger, -.text-danger:hover { - color: $brand-danger; -} - -.text-warning, -.text-warning:hover { - color: $brand-warning; -} - -.text-info, -.text-info:hover { - color: $brand-info; -} - -// Tables ===================================================================== - -table, -.table { - - a:not(.btn) { - text-decoration: underline; - } - - .dropdown-menu a { - text-decoration: none; - } - - .success, - .warning, - .danger, - .info { - color: #fff; - - a:not(.btn) { - color: #fff; - } - } - - &:not(.table-bordered) { - > thead > tr > th, - > tbody > tr > th, - > tfoot > tr > th, - > thead > tr > td, - > tbody > tr > td, - > tfoot > tr > td { - border-color: transparent; - } - } -} - -// Forms ====================================================================== - -.form-control { - @include box-shadow(inset 0 2px 0 rgba(0, 0, 0, 0.075)); -} - -label { - font-weight: normal; -} - -.has-warning { - .help-block, - .control-label, - .radio, - .checkbox, - .radio-inline, - .checkbox-inline, - &.radio label, - &.checkbox label, - &.radio-inline label, - &.checkbox-inline label, - .form-control-feedback { - color: $brand-warning; - } - - .form-control, - .form-control:focus { - border: 1px solid $brand-warning; - @include box-shadow(inset 0 2px 0 rgba(0, 0, 0, 0.075)); - } - - .input-group-addon { - border: 1px solid $brand-warning; - } -} - -.has-error { - .help-block, - .control-label, - .radio, - .checkbox, - .radio-inline, - .checkbox-inline, - &.radio label, - &.checkbox label, - &.radio-inline label, - &.checkbox-inline label, - .form-control-feedback { - color: $brand-danger; - } - - .form-control, - .form-control:focus { - border: 1px solid $brand-danger; - @include box-shadow(inset 0 2px 0 rgba(0, 0, 0, 0.075)); - } - - .input-group-addon { - border: 1px solid $brand-danger; - } -} - -.has-success { - .help-block, - .control-label, - .radio, - .checkbox, - .radio-inline, - .checkbox-inline, - &.radio label, - &.checkbox label, - &.radio-inline label, - &.checkbox-inline label, - .form-control-feedback { - color: $brand-success; - } - - .form-control, - .form-control:focus { - border: 1px solid $brand-success; - @include box-shadow(inset 0 2px 0 rgba(0, 0, 0, 0.075)); - } - - .input-group-addon { - border: 1px solid $brand-success; - } -} - -// Navs ======================================================================= - -.nav { - .open > a, - .open > a:hover, - .open > a:focus { - border-color: transparent; - } -} - -.nav-tabs { - - > li > a { - margin-top: 6px; - border-color: $navbar-default-border; - color: $gray-dark; - @include transition(all 0.2s ease-in-out); - } - - > li > a:hover, - > li > a:focus, - > li.active > a, - > li.active > a:hover, - > li.active > a:focus, - .open > a, - .open > a:hover, - .open > a:focus { - padding-bottom: ($padding-large-vertical + 3); - margin-top: 0; - } - - .open > a, - .open > a:hover, - .open > a:focus { - border-color: $navbar-default-border; - } - - > li.disabled > a:hover, - > li.disabled > a:focus { - padding-top: 10px; - padding-bottom: 10px; - margin-top: 6px; - } - - &.nav-justified > li { - vertical-align: bottom; - } -} - -.dropdown-menu { - margin-top: 0; - @include shadow(); - border-top-width: 1px; - @include box-shadow(none); -} - -.breadcrumb { - border-color: darken($breadcrumb-bg, 5%); - border-style: solid; - @include shadow(); -} - -.pagination, -.pager { - - > li > a, - > li > span { - position: relative; - top: 0; - @include shadow(); - color: $pagination-color; - font-size: 12px; - font-weight: bold; - text-transform: uppercase; - - &:hover { - top: 1px; - border-bottom-width: 3px; - } - - &:active { - top: 2px; - border-bottom-width: 2px; - } - } - - > .disabled > a, - > .disabled > span { - - &:hover { - top: 0; - @include shadow(); - } - - &:active { - top: 0; - @include shadow(); - } - } -} - -.pager { - - > li > a, - > li > span, - > .disabled > a, - > .disabled > span { - - &, - &:hover, - &:active { - border-left-width: 2px; - border-right-width: 2px; - } - } -} - -// Indicators ================================================================= - -.close { - color: #fff; - text-decoration: none; - opacity: 0.4; - - &:hover, - &:focus { - color: #fff; - opacity: 1; - } -} - -.alert { - @include shadow(); - - .alert-link { - font-weight: normal; - color: #fff; - text-decoration: underline; - } -} - -.label { - font-weight: normal; -} - -// Progress bars ============================================================== - -.progress { - border: 1px solid $navbar-default-border; - @include box-shadow(inset 0 2px 0 rgba(0, 0, 0, 0.1)); - - &-bar { - @include box-shadow(inset 0 -4px 0 rgba(0, 0, 0, 0.15)); - } -} - -// Containers ================================================================= - -.well { - border: 1px solid $navbar-default-border; - @include box-shadow(inset 0 2px 0 rgba(0, 0, 0, 0.05)); -} - -a.list-group-item { - - &.active, - &.active:hover, - &.active:focus { - border-color: $list-group-border; - } - - &-success { - &.active { - background-color: $state-success-bg; - } - - &.active:hover, - &.active:focus { - background-color: darken($state-success-bg, 5%); - } - } - - &-warning { - &.active { - background-color: $state-warning-bg; - } - - &.active:hover, - &.active:focus { - background-color: darken($state-warning-bg, 5%); - } - } - - &-danger { - &.active { - background-color: $state-danger-bg; - } - - &.active:hover, - &.active:focus { - background-color: darken($state-danger-bg, 5%); - } - } -} - -.jumbotron { - border: 1px solid $navbar-default-border; - @include box-shadow(inset 0 2px 0 rgba(0, 0, 0, 0.05)); -} - -.panel { - border: 1px solid $navbar-default-border; - @include shadow(); - - &-default { - .close { - color: $text-color; - } - } -} - -.modal { - .close { - color: $text-color; - } -} - -.popover { - color: $text-color; -} diff --git a/_sass/bootstrap/_breadcrumbs.scss b/_sass/bootstrap/_breadcrumbs.scss deleted file mode 100644 index b61f0c7..0000000 --- a/_sass/bootstrap/_breadcrumbs.scss +++ /dev/null @@ -1,28 +0,0 @@ -// -// Breadcrumbs -// -------------------------------------------------- - - -.breadcrumb { - padding: $breadcrumb-padding-vertical $breadcrumb-padding-horizontal; - margin-bottom: $line-height-computed; - list-style: none; - background-color: $breadcrumb-bg; - border-radius: $border-radius-base; - - > li { - display: inline-block; - - + li:before { - // [converter] Workaround for https://github.com/sass/libsass/issues/1115 - $nbsp: "\00a0"; - content: "#{$breadcrumb-separator}#{$nbsp}"; // Unicode space added since inline-block means non-collapsing white-space - padding: 0 5px; - color: $breadcrumb-color; - } - } - - > .active { - color: $breadcrumb-active-color; - } -} diff --git a/_sass/bootstrap/_button-groups.scss b/_sass/bootstrap/_button-groups.scss deleted file mode 100644 index 4b385f5..0000000 --- a/_sass/bootstrap/_button-groups.scss +++ /dev/null @@ -1,244 +0,0 @@ -// -// Button groups -// -------------------------------------------------- - -// Make the div behave like a button -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; // match .btn alignment given font-size hack above - > .btn { - position: relative; - float: left; - // Bring the "active" button to the front - &:hover, - &:focus, - &:active, - &.active { - z-index: 2; - } - } -} - -// Prevent double borders when buttons are next to each other -.btn-group { - .btn + .btn, - .btn + .btn-group, - .btn-group + .btn, - .btn-group + .btn-group { - margin-left: -1px; - } -} - -// Optional: Group multiple button groups together for a toolbar -.btn-toolbar { - margin-left: -5px; // Offset the first child's margin - @include clearfix; - - .btn, - .btn-group, - .input-group { - float: left; - } - > .btn, - > .btn-group, - > .input-group { - margin-left: 5px; - } -} - -.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; -} - -// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match -.btn-group > .btn:first-child { - margin-left: 0; - &:not(:last-child):not(.dropdown-toggle) { - @include border-right-radius(0); - } -} -// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it -.btn-group > .btn:last-child:not(:first-child), -.btn-group > .dropdown-toggle:not(:first-child) { - @include border-left-radius(0); -} - -// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) -.btn-group > .btn-group { - float: left; -} -.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group > .btn-group:first-child:not(:last-child) { - > .btn:last-child, - > .dropdown-toggle { - @include border-right-radius(0); - } -} -.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { - @include border-left-radius(0); -} - -// On active and open, don't show outline -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - - -// Sizing -// -// Remix the default button sizing classes into new ones for easier manipulation. - -.btn-group-xs > .btn { @extend .btn-xs; } -.btn-group-sm > .btn { @extend .btn-sm; } -.btn-group-lg > .btn { @extend .btn-lg; } - - -// Split button dropdowns -// ---------------------- - -// Give the line between buttons some depth -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; -} -.btn-group > .btn-lg + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; -} - -// The clickable button for toggling the menu -// Remove the gradient and set the same inset shadow as the :active state -.btn-group.open .dropdown-toggle { - @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); - - // Show no shadow for `.btn-link` since it has no other button styles. - &.btn-link { - @include box-shadow(none); - } -} - - -// Reposition the caret -.btn .caret { - margin-left: 0; -} -// Carets in other button sizes -.btn-lg .caret { - border-width: $caret-width-large $caret-width-large 0; - border-bottom-width: 0; -} -// Upside down carets for .dropup -.dropup .btn-lg .caret { - border-width: 0 $caret-width-large $caret-width-large; -} - - -// Vertical button groups -// ---------------------- - -.btn-group-vertical { - > .btn, - > .btn-group, - > .btn-group > .btn { - display: block; - float: none; - width: 100%; - max-width: 100%; - } - - // Clear floats so dropdown menus can be properly placed - > .btn-group { - @include clearfix; - > .btn { - float: none; - } - } - - > .btn + .btn, - > .btn + .btn-group, - > .btn-group + .btn, - > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; - } -} - -.btn-group-vertical > .btn { - &:not(:first-child):not(:last-child) { - border-radius: 0; - } - &:first-child:not(:last-child) { - @include border-top-radius($btn-border-radius-base); - @include border-bottom-radius(0); - } - &:last-child:not(:first-child) { - @include border-top-radius(0); - @include border-bottom-radius($btn-border-radius-base); - } -} -.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; -} -.btn-group-vertical > .btn-group:first-child:not(:last-child) { - > .btn:last-child, - > .dropdown-toggle { - @include border-bottom-radius(0); - } -} -.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { - @include border-top-radius(0); -} - - -// Justified button groups -// ---------------------- - -.btn-group-justified { - display: table; - width: 100%; - table-layout: fixed; - border-collapse: separate; - > .btn, - > .btn-group { - float: none; - display: table-cell; - width: 1%; - } - > .btn-group .btn { - width: 100%; - } - - > .btn-group .dropdown-menu { - left: auto; - } -} - - -// Checkbox and radio options -// -// In order to support the browser's form validation feedback, powered by the -// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use -// `display: none;` or `visibility: hidden;` as that also hides the popover. -// Simply visually hiding the inputs via `opacity` would leave them clickable in -// certain cases which is prevented by using `clip` and `pointer-events`. -// This way, we ensure a DOM element is visible to position the popover from. -// -// See https://github.com/twbs/bootstrap/pull/12794 and -// https://github.com/twbs/bootstrap/pull/14559 for more information. - -[data-toggle="buttons"] { - > .btn, - > .btn-group > .btn { - input[type="radio"], - input[type="checkbox"] { - position: absolute; - clip: rect(0,0,0,0); - pointer-events: none; - } - } -} diff --git a/_sass/bootstrap/_buttons.scss b/_sass/bootstrap/_buttons.scss deleted file mode 100644 index 6452b70..0000000 --- a/_sass/bootstrap/_buttons.scss +++ /dev/null @@ -1,168 +0,0 @@ -// -// Buttons -// -------------------------------------------------- - - -// Base styles -// -------------------------------------------------- - -.btn { - display: inline-block; - margin-bottom: 0; // For input.btn - font-weight: $btn-font-weight; - text-align: center; - vertical-align: middle; - touch-action: manipulation; - cursor: pointer; - background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 - border: 1px solid transparent; - white-space: nowrap; - @include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $btn-border-radius-base); - @include user-select(none); - - &, - &:active, - &.active { - &:focus, - &.focus { - @include tab-focus; - } - } - - &:hover, - &:focus, - &.focus { - color: $btn-default-color; - text-decoration: none; - } - - &:active, - &.active { - outline: 0; - background-image: none; - @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); - } - - &.disabled, - &[disabled], - fieldset[disabled] & { - cursor: $cursor-disabled; - @include opacity(.65); - @include box-shadow(none); - } - - // [converter] extracted a& to a.btn -} - -a.btn { - &.disabled, - fieldset[disabled] & { - pointer-events: none; // Future-proof disabling of clicks on `` elements - } -} - - -// Alternate buttons -// -------------------------------------------------- - -.btn-default { - @include button-variant($btn-default-color, $btn-default-bg, $btn-default-border); -} -.btn-primary { - @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border); -} -// Success appears as green -.btn-success { - @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border); -} -// Info appears as blue-green -.btn-info { - @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border); -} -// Warning appears as orange -.btn-warning { - @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border); -} -// Danger and error appear as red -.btn-danger { - @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border); -} - - -// Link buttons -// ------------------------- - -// Make a button look and behave like a link -.btn-link { - color: $link-color; - font-weight: normal; - border-radius: 0; - - &, - &:active, - &.active, - &[disabled], - fieldset[disabled] & { - background-color: transparent; - @include box-shadow(none); - } - &, - &:hover, - &:focus, - &:active { - border-color: transparent; - } - &:hover, - &:focus { - color: $link-hover-color; - text-decoration: $link-hover-decoration; - background-color: transparent; - } - &[disabled], - fieldset[disabled] & { - &:hover, - &:focus { - color: $btn-link-disabled-color; - text-decoration: none; - } - } -} - - -// Button Sizes -// -------------------------------------------------- - -.btn-lg { - // line-height: ensure even-numbered height of button next to large input - @include button-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $btn-border-radius-large); -} -.btn-sm { - // line-height: ensure proper height of button next to small input - @include button-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small); -} -.btn-xs { - @include button-size($padding-xs-vertical, $padding-xs-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small); -} - - -// Block button -// -------------------------------------------------- - -.btn-block { - display: block; - width: 100%; -} - -// Vertically space out multiple block buttons -.btn-block + .btn-block { - margin-top: 5px; -} - -// Specificity overrides -input[type="submit"], -input[type="reset"], -input[type="button"] { - &.btn-block { - width: 100%; - } -} diff --git a/_sass/bootstrap/_carousel.scss b/_sass/bootstrap/_carousel.scss deleted file mode 100644 index 823476a..0000000 --- a/_sass/bootstrap/_carousel.scss +++ /dev/null @@ -1,270 +0,0 @@ -// -// Carousel -// -------------------------------------------------- - - -// Wrapper for the slide container and indicators -.carousel { - position: relative; -} - -.carousel-inner { - position: relative; - overflow: hidden; - width: 100%; - - > .item { - display: none; - position: relative; - @include transition(.6s ease-in-out left); - - // Account for jankitude on images - > img, - > a > img { - @include img-responsive; - line-height: 1; - } - - // WebKit CSS3 transforms for supported devices - @media all and (transform-3d), (-webkit-transform-3d) { - @include transition-transform(0.6s ease-in-out); - @include backface-visibility(hidden); - @include perspective(1000px); - - &.next, - &.active.right { - @include translate3d(100%, 0, 0); - left: 0; - } - &.prev, - &.active.left { - @include translate3d(-100%, 0, 0); - left: 0; - } - &.next.left, - &.prev.right, - &.active { - @include translate3d(0, 0, 0); - left: 0; - } - } - } - - > .active, - > .next, - > .prev { - display: block; - } - - > .active { - left: 0; - } - - > .next, - > .prev { - position: absolute; - top: 0; - width: 100%; - } - - > .next { - left: 100%; - } - > .prev { - left: -100%; - } - > .next.left, - > .prev.right { - left: 0; - } - - > .active.left { - left: -100%; - } - > .active.right { - left: 100%; - } - -} - -// Left/right controls for nav -// --------------------------- - -.carousel-control { - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: $carousel-control-width; - @include opacity($carousel-control-opacity); - font-size: $carousel-control-font-size; - color: $carousel-control-color; - text-align: center; - text-shadow: $carousel-text-shadow; - background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug - // We can't have this transition here because WebKit cancels the carousel - // animation if you trip this while in the middle of another animation. - - // Set gradients for backgrounds - &.left { - @include gradient-horizontal($start-color: rgba(0,0,0,.0001), $end-color: rgba(0,0,0,.0001)); - } - &.right { - left: auto; - right: 0; - @include gradient-horizontal($start-color: rgba(0,0,0,.0001), $end-color: rgba(0,0,0,.0001)); - } - - // Hover/focus state - &:hover, - &:focus { - outline: 0; - color: $carousel-control-color; - text-decoration: none; - @include opacity(.9); - } - - // Toggles - .icon-prev, - .icon-next, - .glyphicon-chevron-left, - .glyphicon-chevron-right { - position: absolute; - top: 50%; - margin-top: -10px; - z-index: 5; - display: inline-block; - } - .icon-prev, - .glyphicon-chevron-left { - left: 50%; - margin-left: -10px; - } - .icon-next, - .glyphicon-chevron-right { - right: 50%; - margin-right: -10px; - } - .icon-prev, - .icon-next { - width: 20px; - height: 20px; - line-height: 1; - font-family: serif; - } - - - .icon-prev { - &:before { - content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) - } - } - .icon-next { - &:before { - content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) - } - } -} - -// Optional indicator pips -// -// Add an unordered list with the following class and add a list item for each -// slide your carousel holds. - -.carousel-indicators { - position: absolute; - bottom: 10px; - left: 50%; - z-index: 15; - width: 60%; - margin-left: -30%; - padding-left: 0; - list-style: none; - text-align: center; - - li { - display: inline-block; - width: 10px; - height: 10px; - margin: 1px; - text-indent: -999px; - border: 1px solid $carousel-indicator-border-color; - border-radius: 10px; - cursor: pointer; - - // IE8-9 hack for event handling - // - // Internet Explorer 8-9 does not support clicks on elements without a set - // `background-color`. We cannot use `filter` since that's not viewed as a - // background color by the browser. Thus, a hack is needed. - // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer - // - // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we - // set alpha transparency for the best results possible. - background-color: #000 \9; // IE8 - background-color: rgba(0,0,0,0); // IE9 - } - .active { - margin: 0; - width: 12px; - height: 12px; - background-color: $carousel-indicator-active-bg; - } -} - -// Optional captions -// ----------------------------- -// Hidden by default for smaller viewports -.carousel-caption { - position: absolute; - left: 15%; - right: 15%; - bottom: 20px; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: $carousel-caption-color; - text-align: center; - text-shadow: $carousel-text-shadow; - & .btn { - text-shadow: none; // No shadow for button elements in carousel-caption - } -} - - -// Scale up controls for tablets and up -@media screen and (min-width: $screen-sm-min) { - - // Scale up the controls a smidge - .carousel-control { - .glyphicon-chevron-left, - .glyphicon-chevron-right, - .icon-prev, - .icon-next { - width: ($carousel-control-font-size * 1.5); - height: ($carousel-control-font-size * 1.5); - margin-top: ($carousel-control-font-size / -2); - font-size: ($carousel-control-font-size * 1.5); - } - .glyphicon-chevron-left, - .icon-prev { - margin-left: ($carousel-control-font-size / -2); - } - .glyphicon-chevron-right, - .icon-next { - margin-right: ($carousel-control-font-size / -2); - } - } - - // Show and left align the captions - .carousel-caption { - left: 20%; - right: 20%; - padding-bottom: 30px; - } - - // Move up the indicators - .carousel-indicators { - bottom: 20px; - } -} diff --git a/_sass/bootstrap/_close.scss b/_sass/bootstrap/_close.scss deleted file mode 100644 index 3b74d8a..0000000 --- a/_sass/bootstrap/_close.scss +++ /dev/null @@ -1,36 +0,0 @@ -// -// Close icons -// -------------------------------------------------- - - -.close { - float: right; - font-size: ($font-size-base * 1.5); - font-weight: $close-font-weight; - line-height: 1; - color: $close-color; - text-shadow: $close-text-shadow; - @include opacity(.2); - - &:hover, - &:focus { - color: $close-color; - text-decoration: none; - cursor: pointer; - @include opacity(.5); - } - - // [converter] extracted button& to button.close -} - -// Additional properties for button version -// iOS requires the button element instead of an anchor tag. -// If you want the anchor version, it requires `href="#"`. -// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} diff --git a/_sass/bootstrap/_code.scss b/_sass/bootstrap/_code.scss deleted file mode 100644 index caa5f06..0000000 --- a/_sass/bootstrap/_code.scss +++ /dev/null @@ -1,69 +0,0 @@ -// -// Code (inline and block) -// -------------------------------------------------- - - -// Inline and block code styles -code, -kbd, -pre, -samp { - font-family: $font-family-monospace; -} - -// Inline code -code { - padding: 2px 4px; - font-size: 90%; - color: $code-color; - background-color: $code-bg; - border-radius: $border-radius-base; -} - -// User input typically entered via keyboard -kbd { - padding: 2px 4px; - font-size: 90%; - color: $kbd-color; - background-color: $kbd-bg; - border-radius: $border-radius-small; - box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); - - kbd { - padding: 0; - font-size: 100%; - font-weight: bold; - box-shadow: none; - } -} - -// Blocks of code -pre { - display: block; - padding: (($line-height-computed - 1) / 2); - margin: 0 0 ($line-height-computed / 2); - font-size: ($font-size-base - 1); // 14px to 13px - line-height: $line-height-base; - word-break: break-all; - word-wrap: break-word; - color: $pre-color; - background-color: $pre-bg; - border: 1px solid $pre-border-color; - border-radius: $border-radius-base; - - // Account for some code outputs that place code tags in pre tags - code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border-radius: 0; - } -} - -// Enable scrollable blocks of code -.pre-scrollable { - max-height: $pre-scrollable-max-height; - overflow-y: scroll; -} diff --git a/_sass/bootstrap/_component-animations.scss b/_sass/bootstrap/_component-animations.scss deleted file mode 100644 index ca3b43c..0000000 --- a/_sass/bootstrap/_component-animations.scss +++ /dev/null @@ -1,37 +0,0 @@ -// -// Component animations -// -------------------------------------------------- - -// Heads up! -// -// We don't use the `.opacity()` mixin here since it causes a bug with text -// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. - -.fade { - opacity: 0; - @include transition(opacity .15s linear); - &.in { - opacity: 1; - } -} - -.collapse { - display: none; - - &.in { display: block; } - // [converter] extracted tr&.in to tr.collapse.in - // [converter] extracted tbody&.in to tbody.collapse.in -} - -tr.collapse.in { display: table-row; } - -tbody.collapse.in { display: table-row-group; } - -.collapsing { - position: relative; - height: 0; - overflow: hidden; - @include transition-property(height, visibility); - @include transition-duration(.35s); - @include transition-timing-function(ease); -} diff --git a/_sass/bootstrap/_dropdowns.scss b/_sass/bootstrap/_dropdowns.scss deleted file mode 100644 index aac8459..0000000 --- a/_sass/bootstrap/_dropdowns.scss +++ /dev/null @@ -1,216 +0,0 @@ -// -// Dropdown menus -// -------------------------------------------------- - - -// Dropdown arrow/caret -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: $caret-width-base dashed; - border-top: $caret-width-base solid \9; // IE8 - border-right: $caret-width-base solid transparent; - border-left: $caret-width-base solid transparent; -} - -// The dropdown wrapper (div) -.dropup, -.dropdown { - position: relative; -} - -// Prevent the focus on the dropdown toggle when closing dropdowns -.dropdown-toggle:focus { - outline: 0; -} - -// The dropdown menu (ul) -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: $zindex-dropdown; - display: none; // none by default, but block on "open" of the menu - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; // override default ul - list-style: none; - font-size: $font-size-base; - text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) - background-color: $dropdown-bg; - border: 1px solid $dropdown-fallback-border; // IE8 fallback - border: 1px solid $dropdown-border; - border-radius: $border-radius-base; - @include box-shadow(0 6px 12px rgba(0,0,0,.175)); - background-clip: padding-box; - - // Aligns the dropdown menu to right - // - // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]` - &.pull-right { - right: 0; - left: auto; - } - - // Dividers (basically an hr) within the dropdown - .divider { - @include nav-divider($dropdown-divider-bg); - } - - // Links within the dropdown menu - > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: $line-height-base; - color: $dropdown-link-color; - white-space: nowrap; // prevent links from randomly breaking onto new lines - } -} - -// Hover/Focus state -.dropdown-menu > li > a { - &:hover, - &:focus { - text-decoration: none; - color: $dropdown-link-hover-color; - background-color: $dropdown-link-hover-bg; - } -} - -// Active state -.dropdown-menu > .active > a { - &, - &:hover, - &:focus { - color: $dropdown-link-active-color; - text-decoration: none; - outline: 0; - background-color: $dropdown-link-active-bg; - } -} - -// Disabled state -// -// Gray out text and ensure the hover/focus state remains gray - -.dropdown-menu > .disabled > a { - &, - &:hover, - &:focus { - color: $dropdown-link-disabled-color; - } - - // Nuke hover/focus effects - &:hover, - &:focus { - text-decoration: none; - background-color: transparent; - background-image: none; // Remove CSS gradient - @include reset-filter; - cursor: $cursor-disabled; - } -} - -// Open state for the dropdown -.open { - // Show the menu - > .dropdown-menu { - display: block; - } - - // Remove the outline when :focus is triggered - > a { - outline: 0; - } -} - -// Menu positioning -// -// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown -// menu with the parent. -.dropdown-menu-right { - left: auto; // Reset the default from `.dropdown-menu` - right: 0; -} -// With v3, we enabled auto-flipping if you have a dropdown within a right -// aligned nav component. To enable the undoing of that, we provide an override -// to restore the default dropdown menu alignment. -// -// This is only for left-aligning a dropdown menu within a `.navbar-right` or -// `.pull-right` nav component. -.dropdown-menu-left { - left: 0; - right: auto; -} - -// Dropdown section headers -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: $font-size-small; - line-height: $line-height-base; - color: $dropdown-header-color; - white-space: nowrap; // as with > li > a -} - -// Backdrop to catch body clicks on mobile, etc. -.dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: ($zindex-dropdown - 10); -} - -// Right aligned dropdowns -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} - -// Allow for dropdowns to go bottom up (aka, dropup-menu) -// -// Just add .dropup after the standard .dropdown class and you're set, bro. -// TODO: abstract this so that the navbar fixed styles are not placed here? - -.dropup, -.navbar-fixed-bottom .dropdown { - // Reverse the caret - .caret { - border-top: 0; - border-bottom: $caret-width-base dashed; - border-bottom: $caret-width-base solid \9; // IE8 - content: ""; - } - // Different positioning for bottom up menu - .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 2px; - } -} - - -// Component alignment -// -// Reiterate per navbar.less and the modified component alignment there. - -@media (min-width: $grid-float-breakpoint) { - .navbar-right { - .dropdown-menu { - right: 0; left: auto; - } - // Necessary for overrides of the default right aligned menu. - // Will remove come v4 in all likelihood. - .dropdown-menu-left { - left: 0; right: auto; - } - } -} diff --git a/_sass/bootstrap/_forms.scss b/_sass/bootstrap/_forms.scss deleted file mode 100644 index ac26a6a..0000000 --- a/_sass/bootstrap/_forms.scss +++ /dev/null @@ -1,617 +0,0 @@ -// -// Forms -// -------------------------------------------------- - - -// Normalize non-controls -// -// Restyle and baseline non-control form elements. - -fieldset { - padding: 0; - margin: 0; - border: 0; - // Chrome and Firefox set a `min-width: min-content;` on fieldsets, - // so we reset that to ensure it behaves more like a standard block element. - // See https://github.com/twbs/bootstrap/issues/12359. - min-width: 0; -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: $line-height-computed; - font-size: ($font-size-base * 1.5); - line-height: inherit; - color: $legend-color; - border: 0; - border-bottom: 1px solid $legend-border-color; -} - -label { - display: inline-block; - max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141) - margin-bottom: 5px; - font-weight: bold; -} - - -// Normalize form controls -// -// While most of our form styles require extra classes, some basic normalization -// is required to ensure optimum display with or without those classes to better -// address browser inconsistencies. - -// Override content-box in Normalize (* isn't specific enough) -input[type="search"] { - @include box-sizing(border-box); -} - -// Position radios and checkboxes better -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; // IE8-9 - line-height: normal; -} - -input[type="file"] { - display: block; -} - -// Make range inputs behave like textual form controls -input[type="range"] { - display: block; - width: 100%; -} - -// Make multiple select elements height not fixed -select[multiple], -select[size] { - height: auto; -} - -// Focus for file, radio, and checkbox -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - @include tab-focus; -} - -// Adjust output element -output { - display: block; - padding-top: ($padding-base-vertical + 1); - font-size: $font-size-base; - line-height: $line-height-base; - color: $input-color; -} - - -// Common form controls -// -// Shared size and type resets for form controls. Apply `.form-control` to any -// of the following form controls: -// -// select -// textarea -// input[type="text"] -// input[type="password"] -// input[type="datetime"] -// input[type="datetime-local"] -// input[type="date"] -// input[type="month"] -// input[type="time"] -// input[type="week"] -// input[type="number"] -// input[type="email"] -// input[type="url"] -// input[type="search"] -// input[type="tel"] -// input[type="color"] - -.form-control { - display: block; - width: 100%; - height: $input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border) - padding: $padding-base-vertical $padding-base-horizontal; - font-size: $font-size-base; - line-height: $line-height-base; - color: $input-color; - background-color: $input-bg; - background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 - border: 1px solid $input-border; - border-radius: $input-border-radius; // Note: This has no effect on s in CSS. - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); - @include transition(border-color ease-in-out .15s, box-shadow ease-in-out .15s); - - // Customize the `:focus` state to imitate native WebKit styles. - @include form-control-focus; - - // Placeholder - @include placeholder; - - // Unstyle the caret on `` background color -$input-bg: #fff !default; -//** `` background color -$input-bg-disabled: $gray-lighter !default; - -//** Text color for ``s -$input-color: $gray !default; -//** `` border color -$input-border: #ccc !default; - -// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4 -//** Default `.form-control` border radius -// This has no effect on ``s in CSS. -$input-border-radius: $border-radius-base !default; -//** Large `.form-control` border radius -$input-border-radius-large: $border-radius-large !default; -//** Small `.form-control` border radius -$input-border-radius-small: $border-radius-small !default; - -//** Border color for inputs on focus -$input-border-focus: #66afe9 !default; - -//** Placeholder text color -$input-color-placeholder: #999 !default; - -//** Default `.form-control` height -$input-height-base: ($line-height-computed + ($padding-base-vertical * 2) + 2) !default; -//** Large `.form-control` height -$input-height-large: (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default; -//** Small `.form-control` height -$input-height-small: (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default; - -//** `.form-group` margin -$form-group-margin-bottom: 15px !default; - -$legend-color: $gray-dark !default; -$legend-border-color: #e5e5e5 !default; - -//** Background color for textual input addons -$input-group-addon-bg: $gray-lighter !default; -//** Border color for textual input addons -$input-group-addon-border-color: $input-border !default; - -//** Disabled cursor for form controls and buttons. -$cursor-disabled: not-allowed !default; - - -//== Dropdowns -// -//## Dropdown menu container and contents. - -//** Background for the dropdown menu. -$dropdown-bg: #fff !default; -//** Dropdown menu `border-color`. -$dropdown-border: rgba(0,0,0,.15) !default; -//** Dropdown menu `border-color` **for IE8**. -$dropdown-fallback-border: #ccc !default; -//** Divider color for between dropdown items. -$dropdown-divider-bg: #e5e5e5 !default; - -//** Dropdown link text color. -$dropdown-link-color: $gray-dark !default; -//** Hover color for dropdown links. -$dropdown-link-hover-color: darken($gray-dark, 5%) !default; -//** Hover background for dropdown links. -$dropdown-link-hover-bg: #f5f5f5 !default; - -//** Active dropdown menu item text color. -$dropdown-link-active-color: $component-active-color !default; -//** Active dropdown menu item background color. -$dropdown-link-active-bg: $component-active-bg !default; - -//** Disabled dropdown menu item background color. -$dropdown-link-disabled-color: $gray-light !default; - -//** Text color for headers within dropdown menus. -$dropdown-header-color: $gray-light !default; - -//** Deprecated `$dropdown-caret-color` as of v3.1.0 -$dropdown-caret-color: #000 !default; - - -//-- Z-index master list -// -// Warning: Avoid customizing these values. They're used for a bird's eye view -// of components dependent on the z-axis and are designed to all work together. -// -// Note: These variables are not generated into the Customizer. - -$zindex-navbar: 1000 !default; -$zindex-dropdown: 1000 !default; -$zindex-popover: 1060 !default; -$zindex-tooltip: 1070 !default; -$zindex-navbar-fixed: 1030 !default; -$zindex-modal-background: 1040 !default; -$zindex-modal: 1050 !default; - - -//== Media queries breakpoints -// -//## Define the breakpoints at which your layout will change, adapting to different screen sizes. - -// Extra small screen / phone -//** Deprecated `$screen-xs` as of v3.0.1 -$screen-xs: 480px !default; -//** Deprecated `$screen-xs-min` as of v3.2.0 -$screen-xs-min: $screen-xs !default; -//** Deprecated `$screen-phone` as of v3.0.1 -$screen-phone: $screen-xs-min !default; - -// Small screen / tablet -//** Deprecated `$screen-sm` as of v3.0.1 -$screen-sm: 768px !default; -$screen-sm-min: $screen-sm !default; -//** Deprecated `$screen-tablet` as of v3.0.1 -$screen-tablet: $screen-sm-min !default; - -// Medium screen / desktop -//** Deprecated `$screen-md` as of v3.0.1 -$screen-md: 992px !default; -$screen-md-min: $screen-md !default; -//** Deprecated `$screen-desktop` as of v3.0.1 -$screen-desktop: $screen-md-min !default; - -// Large screen / wide desktop -//** Deprecated `$screen-lg` as of v3.0.1 -$screen-lg: 1200px !default; -$screen-lg-min: $screen-lg !default; -//** Deprecated `$screen-lg-desktop` as of v3.0.1 -$screen-lg-desktop: $screen-lg-min !default; - -// So media queries don't overlap when required, provide a maximum -$screen-xs-max: ($screen-sm-min - 1) !default; -$screen-sm-max: ($screen-md-min - 1) !default; -$screen-md-max: ($screen-lg-min - 1) !default; - - -//== Grid system -// -//## Define your custom responsive grid. - -//** Number of columns in the grid. -$grid-columns: 12 !default; -//** Padding between columns. Gets divided in half for the left and right. -$grid-gutter-width: 30px !default; -// Navbar collapse -//** Point at which the navbar becomes uncollapsed. -$grid-float-breakpoint: $screen-sm-min !default; -//** Point at which the navbar begins collapsing. -$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default; - - -//== Container sizes -// -//## Define the maximum width of `.container` for different screen sizes. - -// Small screen / tablet -$container-tablet: (720px + $grid-gutter-width) !default; -//** For `$screen-sm-min` and up. -$container-sm: $container-tablet !default; - -// Medium screen / desktop -$container-desktop: (940px + $grid-gutter-width) !default; -//** For `$screen-md-min` and up. -$container-md: $container-desktop !default; - -// Large screen / wide desktop -$container-large-desktop: (1140px + $grid-gutter-width) !default; -//** For `$screen-lg-min` and up. -$container-lg: $container-large-desktop !default; - - -//== Navbar -// -//## - -// Basics of a navbar -$navbar-height: 50px !default; -$navbar-margin-bottom: $line-height-computed !default; -$navbar-border-radius: $border-radius-base !default; -$navbar-padding-horizontal: floor(($grid-gutter-width / 2)) !default; -$navbar-padding-vertical: (($navbar-height - $line-height-computed) / 2) !default; -$navbar-collapse-max-height: 340px !default; - -$navbar-default-color: #777 !default; -$navbar-default-bg: #f8f8f8 !default; -$navbar-default-border: darken($navbar-default-bg, 6.5%) !default; - -// Navbar links -$navbar-default-link-color: #777 !default; -$navbar-default-link-hover-color: #333 !default; -$navbar-default-link-hover-bg: transparent !default; -$navbar-default-link-active-color: #555 !default; -$navbar-default-link-active-bg: darken($navbar-default-bg, 6.5%) !default; -$navbar-default-link-disabled-color: #ccc !default; -$navbar-default-link-disabled-bg: transparent !default; - -// Navbar brand label -$navbar-default-brand-color: $navbar-default-link-color !default; -$navbar-default-brand-hover-color: darken($navbar-default-brand-color, 10%) !default; -$navbar-default-brand-hover-bg: transparent !default; - -// Navbar toggle -$navbar-default-toggle-hover-bg: #ddd !default; -$navbar-default-toggle-icon-bar-bg: #888 !default; -$navbar-default-toggle-border-color: #ddd !default; - - -//=== Inverted navbar -// Reset inverted navbar basics -$navbar-inverse-color: lighten($gray-light, 15%) !default; -$navbar-inverse-bg: #222 !default; -$navbar-inverse-border: darken($navbar-inverse-bg, 10%) !default; - -// Inverted navbar links -$navbar-inverse-link-color: lighten($gray-light, 15%) !default; -$navbar-inverse-link-hover-color: #fff !default; -$navbar-inverse-link-hover-bg: transparent !default; -$navbar-inverse-link-active-color: $navbar-inverse-link-hover-color !default; -$navbar-inverse-link-active-bg: darken($navbar-inverse-bg, 10%) !default; -$navbar-inverse-link-disabled-color: #444 !default; -$navbar-inverse-link-disabled-bg: transparent !default; - -// Inverted navbar brand label -$navbar-inverse-brand-color: $navbar-inverse-link-color !default; -$navbar-inverse-brand-hover-color: #fff !default; -$navbar-inverse-brand-hover-bg: transparent !default; - -// Inverted navbar toggle -$navbar-inverse-toggle-hover-bg: #333 !default; -$navbar-inverse-toggle-icon-bar-bg: #fff !default; -$navbar-inverse-toggle-border-color: #333 !default; - - -//== Navs -// -//## - -//=== Shared nav styles -$nav-link-padding: 10px 15px !default; -$nav-link-hover-bg: $gray-lighter !default; - -$nav-disabled-link-color: $gray-light !default; -$nav-disabled-link-hover-color: $gray-light !default; - -//== Tabs -$nav-tabs-border-color: #ddd !default; - -$nav-tabs-link-hover-border-color: $gray-lighter !default; - -$nav-tabs-active-link-hover-bg: $body-bg !default; -$nav-tabs-active-link-hover-color: $gray !default; -$nav-tabs-active-link-hover-border-color: #ddd !default; - -$nav-tabs-justified-link-border-color: #ddd !default; -$nav-tabs-justified-active-link-border-color: $body-bg !default; - -//== Pills -$nav-pills-border-radius: $border-radius-base !default; -$nav-pills-active-link-hover-bg: $component-active-bg !default; -$nav-pills-active-link-hover-color: $component-active-color !default; - - -//== Pagination -// -//## - -$pagination-color: $link-color !default; -$pagination-bg: #fff !default; -$pagination-border: #ddd !default; - -$pagination-hover-color: $link-hover-color !default; -$pagination-hover-bg: $gray-lighter !default; -$pagination-hover-border: #ddd !default; - -$pagination-active-color: #fff !default; -$pagination-active-bg: $brand-primary !default; -$pagination-active-border: $brand-primary !default; - -$pagination-disabled-color: $gray-light !default; -$pagination-disabled-bg: #fff !default; -$pagination-disabled-border: #ddd !default; - - -//== Pager -// -//## - -$pager-bg: $pagination-bg !default; -$pager-border: $pagination-border !default; -$pager-border-radius: 15px !default; - -$pager-hover-bg: $pagination-hover-bg !default; - -$pager-active-bg: $pagination-active-bg !default; -$pager-active-color: $pagination-active-color !default; - -$pager-disabled-color: $pagination-disabled-color !default; - - -//== Jumbotron -// -//## - -$jumbotron-padding: 30px !default; -$jumbotron-color: inherit !default; -$jumbotron-bg: $gray-lighter !default; -$jumbotron-heading-color: inherit !default; -$jumbotron-font-size: ceil(($font-size-base * 1.5)) !default; -$jumbotron-heading-font-size: ceil(($font-size-base * 4.5)) !default; - - -//== Form states and alerts -// -//## Define colors for form feedback states and, by default, alerts. - -$state-success-text: #3c763d !default; -$state-success-bg: #dff0d8 !default; -$state-success-border: darken(adjust-hue($state-success-bg, -10), 5%) !default; - -$state-info-text: #31708f !default; -$state-info-bg: #d9edf7 !default; -$state-info-border: darken(adjust-hue($state-info-bg, -10), 7%) !default; - -$state-warning-text: #8a6d3b !default; -$state-warning-bg: #fcf8e3 !default; -$state-warning-border: darken(adjust-hue($state-warning-bg, -10), 5%) !default; - -$state-danger-text: #a94442 !default; -$state-danger-bg: #f2dede !default; -$state-danger-border: darken(adjust-hue($state-danger-bg, -10), 5%) !default; - - -//== Tooltips -// -//## - -//** Tooltip max width -$tooltip-max-width: 200px !default; -//** Tooltip text color -$tooltip-color: #fff !default; -//** Tooltip background color -$tooltip-bg: #000 !default; -$tooltip-opacity: .9 !default; - -//** Tooltip arrow width -$tooltip-arrow-width: 5px !default; -//** Tooltip arrow color -$tooltip-arrow-color: $tooltip-bg !default; - - -//== Popovers -// -//## - -//** Popover body background color -$popover-bg: #fff !default; -//** Popover maximum width -$popover-max-width: 276px !default; -//** Popover border color -$popover-border-color: rgba(0,0,0,.2) !default; -//** Popover fallback border color -$popover-fallback-border-color: #ccc !default; - -//** Popover title background color -$popover-title-bg: darken($popover-bg, 3%) !default; - -//** Popover arrow width -$popover-arrow-width: 10px !default; -//** Popover arrow color -$popover-arrow-color: $popover-bg !default; - -//** Popover outer arrow width -$popover-arrow-outer-width: ($popover-arrow-width + 1) !default; -//** Popover outer arrow color -$popover-arrow-outer-color: fade_in($popover-border-color, 0.05) !default; -//** Popover outer arrow fallback color -$popover-arrow-outer-fallback-color: darken($popover-fallback-border-color, 20%) !default; - - -//== Labels -// -//## - -//** Default label background color -$label-default-bg: $gray-light !default; -//** Primary label background color -$label-primary-bg: $brand-primary !default; -//** Success label background color -$label-success-bg: $brand-success !default; -//** Info label background color -$label-info-bg: $brand-info !default; -//** Warning label background color -$label-warning-bg: $brand-warning !default; -//** Danger label background color -$label-danger-bg: $brand-danger !default; - -//** Default label text color -$label-color: #fff !default; -//** Default text color of a linked label -$label-link-hover-color: #fff !default; - - -//== Modals -// -//## - -//** Padding applied to the modal body -$modal-inner-padding: 15px !default; - -//** Padding applied to the modal title -$modal-title-padding: 15px !default; -//** Modal title line-height -$modal-title-line-height: $line-height-base !default; - -//** Background color of modal content area -$modal-content-bg: #fff !default; -//** Modal content border color -$modal-content-border-color: rgba(0,0,0,.2) !default; -//** Modal content border color **for IE8** -$modal-content-fallback-border-color: #999 !default; - -//** Modal backdrop background color -$modal-backdrop-bg: #000 !default; -//** Modal backdrop opacity -$modal-backdrop-opacity: .5 !default; -//** Modal header border color -$modal-header-border-color: #e5e5e5 !default; -//** Modal footer border color -$modal-footer-border-color: $modal-header-border-color !default; - -$modal-lg: 900px !default; -$modal-md: 600px !default; -$modal-sm: 300px !default; - - -//== Alerts -// -//## Define alert colors, border radius, and padding. - -$alert-padding: 15px !default; -$alert-border-radius: $border-radius-base !default; -$alert-link-font-weight: bold !default; - -$alert-success-bg: $state-success-bg !default; -$alert-success-text: $state-success-text !default; -$alert-success-border: $state-success-border !default; - -$alert-info-bg: $state-info-bg !default; -$alert-info-text: $state-info-text !default; -$alert-info-border: $state-info-border !default; - -$alert-warning-bg: $state-warning-bg !default; -$alert-warning-text: $state-warning-text !default; -$alert-warning-border: $state-warning-border !default; - -$alert-danger-bg: $state-danger-bg !default; -$alert-danger-text: $state-danger-text !default; -$alert-danger-border: $state-danger-border !default; - - -//== Progress bars -// -//## - -//** Background color of the whole progress component -$progress-bg: #f5f5f5 !default; -//** Progress bar text color -$progress-bar-color: #fff !default; -//** Variable for setting rounded corners on progress bar. -$progress-border-radius: $border-radius-base !default; - -//** Default progress bar color -$progress-bar-bg: $brand-primary !default; -//** Success progress bar color -$progress-bar-success-bg: $brand-success !default; -//** Warning progress bar color -$progress-bar-warning-bg: $brand-warning !default; -//** Danger progress bar color -$progress-bar-danger-bg: $brand-danger !default; -//** Info progress bar color -$progress-bar-info-bg: $brand-info !default; - - -//== List group -// -//## - -//** Background color on `.list-group-item` -$list-group-bg: #fff !default; -//** `.list-group-item` border color -$list-group-border: #ddd !default; -//** List group border radius -$list-group-border-radius: $border-radius-base !default; - -//** Background color of single list items on hover -$list-group-hover-bg: #f5f5f5 !default; -//** Text color of active list items -$list-group-active-color: $component-active-color !default; -//** Background color of active list items -$list-group-active-bg: $component-active-bg !default; -//** Border color of active list elements -$list-group-active-border: $list-group-active-bg !default; -//** Text color for content within active list items -$list-group-active-text-color: lighten($list-group-active-bg, 40%) !default; - -//** Text color of disabled list items -$list-group-disabled-color: $gray-light !default; -//** Background color of disabled list items -$list-group-disabled-bg: $gray-lighter !default; -//** Text color for content within disabled list items -$list-group-disabled-text-color: $list-group-disabled-color !default; - -$list-group-link-color: #555 !default; -$list-group-link-hover-color: $list-group-link-color !default; -$list-group-link-heading-color: #333 !default; - - -//== Panels -// -//## - -$panel-bg: #fff !default; -$panel-body-padding: 15px !default; -$panel-heading-padding: 10px 15px !default; -$panel-footer-padding: $panel-heading-padding !default; -$panel-border-radius: $border-radius-base !default; - -//** Border color for elements within panels -$panel-inner-border: #ddd !default; -$panel-footer-bg: #f5f5f5 !default; - -$panel-default-text: $gray-dark !default; -$panel-default-border: #ddd !default; -$panel-default-heading-bg: #f5f5f5 !default; - -$panel-primary-text: #fff !default; -$panel-primary-border: $brand-primary !default; -$panel-primary-heading-bg: $brand-primary !default; - -$panel-success-text: $state-success-text !default; -$panel-success-border: $state-success-border !default; -$panel-success-heading-bg: $state-success-bg !default; - -$panel-info-text: $state-info-text !default; -$panel-info-border: $state-info-border !default; -$panel-info-heading-bg: $state-info-bg !default; - -$panel-warning-text: $state-warning-text !default; -$panel-warning-border: $state-warning-border !default; -$panel-warning-heading-bg: $state-warning-bg !default; - -$panel-danger-text: $state-danger-text !default; -$panel-danger-border: $state-danger-border !default; -$panel-danger-heading-bg: $state-danger-bg !default; - - -//== Thumbnails -// -//## - -//** Padding around the thumbnail image -$thumbnail-padding: 4px !default; -//** Thumbnail background color -$thumbnail-bg: $body-bg !default; -//** Thumbnail border color -$thumbnail-border: #ddd !default; -//** Thumbnail border radius -$thumbnail-border-radius: $border-radius-base !default; - -//** Custom text color for thumbnail captions -$thumbnail-caption-color: $text-color !default; -//** Padding around the thumbnail caption -$thumbnail-caption-padding: 9px !default; - - -//== Wells -// -//## - -$well-bg: #f5f5f5 !default; -$well-border: darken($well-bg, 7%) !default; - - -//== Badges -// -//## - -$badge-color: #fff !default; -//** Linked badge text color on hover -$badge-link-hover-color: #fff !default; -$badge-bg: $gray-light !default; - -//** Badge text color in active nav link -$badge-active-color: $link-color !default; -//** Badge background color in active nav link -$badge-active-bg: #fff !default; - -$badge-font-weight: bold !default; -$badge-line-height: 1 !default; -$badge-border-radius: 10px !default; - - -//== Breadcrumbs -// -//## - -$breadcrumb-padding-vertical: 8px !default; -$breadcrumb-padding-horizontal: 15px !default; -//** Breadcrumb background color -$breadcrumb-bg: #f5f5f5 !default; -//** Breadcrumb text color -$breadcrumb-color: #ccc !default; -//** Text color of current page in the breadcrumb -$breadcrumb-active-color: $gray-light !default; -//** Textual separator for between breadcrumb elements -$breadcrumb-separator: "/" !default; - - -//== Carousel -// -//## - -$carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6) !default; - -$carousel-control-color: #fff !default; -$carousel-control-width: 15% !default; -$carousel-control-opacity: .5 !default; -$carousel-control-font-size: 20px !default; - -$carousel-indicator-active-bg: #fff !default; -$carousel-indicator-border-color: #fff !default; - -$carousel-caption-color: #fff !default; - - -//== Close -// -//## - -$close-font-weight: bold !default; -$close-color: #000 !default; -$close-text-shadow: 0 1px 0 #fff !default; - - -//== Code -// -//## - -$code-color: #c7254e !default; -$code-bg: #f9f2f4 !default; - -$kbd-color: #fff !default; -$kbd-bg: #333 !default; - -$pre-bg: #f5f5f5 !default; -$pre-color: $gray-dark !default; -$pre-border-color: #ccc !default; -$pre-scrollable-max-height: 340px !default; - - -//== Type -// -//## - -//** Horizontal offset for forms and lists. -$component-offset-horizontal: 180px !default; -//** Text muted color -$text-muted: $gray-light !default; -//** Abbreviations and acronyms border color -$abbr-border-color: $gray-light !default; -//** Headings small color -$headings-small-color: $gray-light !default; -//** Blockquote small color -$blockquote-small-color: $gray-light !default; -//** Blockquote font size -$blockquote-font-size: ($font-size-base * 1.25) !default; -//** Blockquote border color -$blockquote-border-color: $gray-lighter !default; -//** Page header border color -$page-header-border-color: $gray-lighter !default; -//** Width of horizontal description list titles -$dl-horizontal-offset: $component-offset-horizontal !default; -//** Point at which .dl-horizontal becomes horizontal -$dl-horizontal-breakpoint: $grid-float-breakpoint !default; -//** Horizontal line color. -$hr-border: $gray-lighter !default; diff --git a/_sass/bootstrap/_variables.scss b/_sass/bootstrap/_variables.scss deleted file mode 100644 index 26e7e3b..0000000 --- a/_sass/bootstrap/_variables.scss +++ /dev/null @@ -1,870 +0,0 @@ -$bootstrap-sass-asset-helper: false !default; -// Lumen 3.3.7 -// Variables -// -------------------------------------------------- - - -//== Colors -// -//## Gray and brand colors for use across Bootstrap. - -$gray-base: #000 !default; -$gray-darker: lighten($gray-base, 13.5%) !default; // #222 -$gray-dark: lighten($gray-base, 20%) !default; // #333 -$gray: lighten($gray-base, 33.5%) !default; // #555 -$gray-light: lighten($gray-base, 60%) !default; // #999 -$gray-lighter: lighten($gray-base, 93.5%) !default; // #eee - -$brand-primary: #158CBA !default; -$brand-success: #28B62C !default; -$brand-info: #75CAEB !default; -$brand-warning: #FF851B !default; -$brand-danger: #FF4136 !default; - - -//== Scaffolding -// -//## Settings for some of the most global styles. - -//** Background color for ``. -$body-bg: #fff !default; -//** Global text color on ``. -$text-color: $gray !default; - -//** Global textual link color. -$link-color: $brand-primary !default; -//** Link hover color set via `darken()` function. -$link-hover-color: $link-color !default; -//** Link hover decoration. -$link-hover-decoration: underline !default; - - -//== Typography -// -//## Font, line-height, and color for body text, headings, and more. - -$font-family-sans-serif: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif !default; -$font-family-serif: Georgia, "Times New Roman", Times, serif !default; -//** Default monospace fonts for ``, ``, and `
`.
-$font-family-monospace:   Menlo, Monaco, Consolas, "Courier New", monospace !default;
-$font-family-base:        $font-family-sans-serif !default;
-
-$font-size-base:          16px !default;
-$font-size-large:         ceil(($font-size-base * 1.25)) !default; // ~18px
-$font-size-small:         ceil(($font-size-base * 0.85)) !default; // ~12px
-
-$font-size-h1:            floor(($font-size-base * 2.6)) !default; // ~36px
-$font-size-h2:            floor(($font-size-base * 2.15)) !default; // ~30px
-$font-size-h3:            ceil(($font-size-base * 1.7)) !default; // ~24px
-$font-size-h4:            ceil(($font-size-base * 1.25)) !default; // ~18px
-$font-size-h5:            $font-size-base !default;
-$font-size-h6:            ceil(($font-size-base * 0.85)) !default; // ~12px
-
-//** Unit-less `line-height` for use in components like buttons.
-$line-height-base:        1.428571429 !default; // 20/14
-//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
-$line-height-computed:    floor(($font-size-base * $line-height-base)) !default; // ~20px
-
-//** By default, this inherits from the ``.
-$headings-font-family:    inherit !default;
-$headings-font-weight:    400 !default;
-$headings-line-height:    1.1 !default;
-$headings-color:          $gray-dark !default;
-
-
-//== Iconography
-//
-//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
-
-//** Load fonts from this directory.
-$icon-font-path: if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/") !default;
-//** File name for all font files.
-$icon-font-name:          "glyphicons-halflings-regular" !default;
-//** Element ID within SVG icon file.
-$icon-font-svg-id:        "glyphicons_halflingsregular" !default;
-
-
-//== Components
-//
-//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
-
-$padding-base-vertical:     7px !default;
-$padding-base-horizontal:   12px !default;
-
-$padding-large-vertical:    13px !default;
-$padding-large-horizontal:  16px !default;
-
-$padding-small-vertical:    4px !default;
-$padding-small-horizontal:  10px !default;
-
-$padding-xs-vertical:       1px !default;
-$padding-xs-horizontal:     5px !default;
-
-$line-height-large:         1.3333333 !default; // extra decimals for Win 8.1 Chrome
-$line-height-small:         1.5 !default;
-
-$border-radius-base:        4px !default;
-$border-radius-large:       5px !default;
-$border-radius-small:       2px !default;
-
-//** Global color for active items (e.g., navs or dropdowns).
-$component-active-color:    #fff !default;
-//** Global background color for active items (e.g., navs or dropdowns).
-$component-active-bg:       $brand-primary !default;
-
-//** Width of the `border` for generating carets that indicate dropdowns.
-$caret-width-base:          4px !default;
-//** Carets increase slightly in size for larger components.
-$caret-width-large:         5px !default;
-
-
-//== Tables
-//
-//## Customizes the `.table` component with basic values, each used across all table variations.
-
-//** Padding for ``s and ``s.
-$table-cell-padding:            8px !default;
-//** Padding for cells in `.table-condensed`.
-$table-condensed-cell-padding:  5px !default;
-
-//** Default background color used for all tables.
-$table-bg:                      transparent !default;
-//** Background color used for `.table-striped`.
-$table-bg-accent:               #f9f9f9 !default;
-//** Background color used for `.table-hover`.
-$table-bg-hover:                #f5f5f5 !default;
-$table-bg-active:               $table-bg-hover !default;
-
-//** Border color for table and cell borders.
-$table-border-color:            $gray-lighter !default;
-
-
-//== Buttons
-//
-//## For each of Bootstrap's buttons, define text, background and border color.
-
-$btn-font-weight:                normal !default;
-
-$btn-default-color:              $gray !default;
-$btn-default-bg:                 $gray-lighter !default;
-$btn-default-border:             darken($btn-default-bg, 5%) !default;
-
-$btn-primary-color:              #fff !default;
-$btn-primary-bg:                 $brand-primary !default;
-$btn-primary-border:             darken($btn-primary-bg, 5%) !default;
-
-$btn-success-color:              #fff !default;
-$btn-success-bg:                 $brand-success !default;
-$btn-success-border:             darken($btn-success-bg, 5%) !default;
-
-$btn-info-color:                 #fff !default;
-$btn-info-bg:                    $brand-info !default;
-$btn-info-border:                darken($btn-info-bg, 5%) !default;
-
-$btn-warning-color:              #fff !default;
-$btn-warning-bg:                 $brand-warning !default;
-$btn-warning-border:             darken($btn-warning-bg, 5%) !default;
-
-$btn-danger-color:               #fff !default;
-$btn-danger-bg:                  $brand-danger !default;
-$btn-danger-border:              darken($btn-danger-bg, 5%) !default;
-
-$btn-link-disabled-color:        $gray-light !default;
-
-// Allows for customizing button radius independently from global border radius
-$btn-border-radius-base:         $border-radius-base !default;
-$btn-border-radius-large:        $border-radius-large !default;
-$btn-border-radius-small:        $border-radius-small !default;
-
-
-//== Forms
-//
-//##
-
-//** `` background color
-$input-bg:                       #fff !default;
-//** `` background color
-$input-bg-disabled:              $gray-lighter !default;
-
-//** Text color for ``s
-$input-color:                    $gray !default;
-//** `` border color
-$input-border:                   darken(#f8f8f8, 6.5%) !default;
-
-// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
-//** Default `.form-control` border radius
-// This has no effect on ``s in CSS.
-$input-border-radius:            $border-radius-base !default;
-//** Large `.form-control` border radius
-$input-border-radius-large:      $border-radius-large !default;
-//** Small `.form-control` border radius
-$input-border-radius-small:      $border-radius-small !default;
-
-//** Border color for inputs on focus
-$input-border-focus:             #66afe9 !default;
-
-//** Placeholder text color
-$input-color-placeholder:        $gray-light !default;
-
-//** Default `.form-control` height
-$input-height-base:              ($line-height-computed + ($padding-base-vertical * 2) + 4) !default;
-//** Large `.form-control` height
-$input-height-large:             (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default;
-//** Small `.form-control` height
-$input-height-small:             (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default;
-
-//** `.form-group` margin
-$form-group-margin-bottom:       15px !default;
-
-$legend-color:                   $gray-dark !default;
-$legend-border-color:            #e5e5e5 !default;
-
-//** Background color for textual input addons
-$input-group-addon-bg:           $gray-lighter !default;
-//** Border color for textual input addons
-$input-group-addon-border-color: $input-border !default;
-
-//** Disabled cursor for form controls and buttons.
-$cursor-disabled:                not-allowed !default;
-
-
-//== Dropdowns
-//
-//## Dropdown menu container and contents.
-
-//** Background for the dropdown menu.
-$dropdown-bg:                    #fff !default;
-//** Dropdown menu `border-color`.
-$dropdown-border:                $input-border !default;
-//** Dropdown menu `border-color` **for IE8**.
-$dropdown-fallback-border:       #ccc !default;
-//** Divider color for between dropdown items.
-$dropdown-divider-bg:            $gray-lighter !default;
-
-//** Dropdown link text color.
-$dropdown-link-color:            $gray-light !default;
-//** Hover color for dropdown links.
-$dropdown-link-hover-color:      $gray-dark !default;
-//** Hover background for dropdown links.
-$dropdown-link-hover-bg:         transparent !default;
-
-//** Active dropdown menu item text color.
-$dropdown-link-active-color:     $component-active-color !default;
-//** Active dropdown menu item background color.
-$dropdown-link-active-bg:        $component-active-bg !default;
-
-//** Disabled dropdown menu item background color.
-$dropdown-link-disabled-color:   $gray-lighter !default;
-
-//** Text color for headers within dropdown menus.
-$dropdown-header-color:          $gray-light !default;
-
-//** Deprecated `$dropdown-caret-color` as of v3.1.0
-$dropdown-caret-color:           #000 !default;
-
-
-//-- Z-index master list
-//
-// Warning: Avoid customizing these values. They're used for a bird's eye view
-// of components dependent on the z-axis and are designed to all work together.
-//
-// Note: These variables are not generated into the Customizer.
-
-$zindex-navbar:            1000 !default;
-$zindex-dropdown:          1000 !default;
-$zindex-popover:           1060 !default;
-$zindex-tooltip:           1070 !default;
-$zindex-navbar-fixed:      1030 !default;
-$zindex-modal-background:  1040 !default;
-$zindex-modal:             1050 !default;
-
-
-//== Media queries breakpoints
-//
-//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
-
-// Extra small screen / phone
-//** Deprecated `$screen-xs` as of v3.0.1
-$screen-xs:                  480px !default;
-//** Deprecated `$screen-xs-min` as of v3.2.0
-$screen-xs-min:              $screen-xs !default;
-//** Deprecated `$screen-phone` as of v3.0.1
-$screen-phone:               $screen-xs-min !default;
-
-// Small screen / tablet
-//** Deprecated `$screen-sm` as of v3.0.1
-$screen-sm:                  768px !default;
-$screen-sm-min:              $screen-sm !default;
-//** Deprecated `$screen-tablet` as of v3.0.1
-$screen-tablet:              $screen-sm-min !default;
-
-// Medium screen / desktop
-//** Deprecated `$screen-md` as of v3.0.1
-$screen-md:                  992px !default;
-$screen-md-min:              $screen-md !default;
-//** Deprecated `$screen-desktop` as of v3.0.1
-$screen-desktop:             $screen-md-min !default;
-
-// Large screen / wide desktop
-//** Deprecated `$screen-lg` as of v3.0.1
-$screen-lg:                  200px !default;
-$screen-lg-min:              $screen-lg !default;
-//** Deprecated `$screen-lg-desktop` as of v3.0.1
-$screen-lg-desktop:          $screen-lg-min !default;
-
-// So media queries don't overlap when required, provide a maximum
-$screen-xs-max:              ($screen-sm-min - 1) !default;
-$screen-sm-max:              ($screen-md-min - 1) !default;
-$screen-md-max:              ($screen-lg-min - 1) !default;
-
-
-//== Grid system
-//
-//## Define your custom responsive grid.
-
-//** Number of columns in the grid.
-$grid-columns:              12 !default;
-//** Padding between columns. Gets divided in half for the left and right.
-$grid-gutter-width:         30px !default;
-// Navbar collapse
-//** Point at which the navbar becomes uncollapsed.
-$grid-float-breakpoint:     $screen-sm-min !default;
-//** Point at which the navbar begins collapsing.
-$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default;
-
-
-//== Container sizes
-//
-//## Define the maximum width of `.container` for different screen sizes.
-
-// Small screen / tablet
-$container-tablet:             (720px + $grid-gutter-width) !default;
-//** For `$screen-sm-min` and up.
-$container-sm:                 $container-tablet !default;
-
-// Medium screen / desktop
-$container-desktop:            (940px + $grid-gutter-width) !default;
-//** For `$screen-md-min` and up.
-$container-md:                 $container-desktop !default;
-
-// Large screen / wide desktop
-$container-large-desktop:      (1140px + $grid-gutter-width) !default;
-//** For `$screen-lg-min` and up.
-$container-lg:                 $container-large-desktop !default;
-
-
-//== Navbar
-//
-//##
-
-// Basics of a navbar
-$navbar-height:                    50px !default;
-$navbar-margin-bottom:             $line-height-computed !default;
-$navbar-border-radius:             $border-radius-base !default;
-$navbar-padding-horizontal:        floor(($grid-gutter-width / 2)) !default;
-$navbar-padding-vertical:          (($navbar-height - $line-height-computed) / 2) !default;
-$navbar-collapse-max-height:       340px !default;
-
-$navbar-default-color:             $text-color !default;
-$navbar-default-bg:                #f8f8f8 !default;
-$navbar-default-border:            $input-border !default;
-
-// Navbar links
-$navbar-default-link-color:                $gray-light !default;
-$navbar-default-link-hover-color:          $gray-dark !default;
-$navbar-default-link-hover-bg:             transparent !default;
-$navbar-default-link-active-color:         $navbar-default-link-hover-color !default;
-$navbar-default-link-active-bg:            transparent !default;
-$navbar-default-link-disabled-color:       $gray-lighter !default;
-$navbar-default-link-disabled-bg:          transparent !default;
-
-// Navbar brand label
-$navbar-default-brand-color:               $navbar-default-link-hover-color !default;
-$navbar-default-brand-hover-color:         $navbar-default-link-hover-color !default;
-$navbar-default-brand-hover-bg:            transparent !default;
-
-// Navbar toggle
-$navbar-default-toggle-hover-bg:           #fff !default;
-$navbar-default-toggle-icon-bar-bg:        $gray-light !default;
-$navbar-default-toggle-border-color:       $gray-lighter !default;
-
-
-//=== Inverted navbar
-// Reset inverted navbar basics
-$navbar-inverse-color:                      $gray-light !default;
-$navbar-inverse-bg:                         #fff !default;
-$navbar-inverse-border:                     darken($navbar-inverse-bg, 10%) !default;
-
-// Inverted navbar links
-$navbar-inverse-link-color:                 $gray-light !default;
-$navbar-inverse-link-hover-color:           $gray-dark !default;
-$navbar-inverse-link-hover-bg:              transparent !default;
-$navbar-inverse-link-active-color:          $navbar-inverse-link-hover-color !default;
-$navbar-inverse-link-active-bg:             transparent !default;
-$navbar-inverse-link-disabled-color:        $gray-lighter !default;
-$navbar-inverse-link-disabled-bg:           transparent !default;
-
-// Inverted navbar brand label
-$navbar-inverse-brand-color:                $navbar-inverse-link-color !default;
-$navbar-inverse-brand-hover-color:          $navbar-inverse-link-hover-color !default;
-$navbar-inverse-brand-hover-bg:             transparent !default;
-
-// Inverted navbar toggle
-$navbar-inverse-toggle-hover-bg:            $gray-lighter !default;
-$navbar-inverse-toggle-icon-bar-bg:         $gray-light !default;
-$navbar-inverse-toggle-border-color:        $gray-lighter !default;
-
-
-//== Navs
-//
-//##
-
-//=== Shared nav styles
-$nav-link-padding:                          10px 15px !default;
-$nav-link-hover-bg:                         #fff !default;
-
-$nav-disabled-link-color:                   $gray-light !default;
-$nav-disabled-link-hover-color:             $gray-light !default;
-
-//== Tabs
-$nav-tabs-border-color:                     $navbar-default-border !default;
-
-$nav-tabs-link-hover-border-color:          $gray-lighter !default;
-
-$nav-tabs-active-link-hover-bg:             #fff !default;
-$nav-tabs-active-link-hover-color:          $gray !default;
-$nav-tabs-active-link-hover-border-color:   $nav-tabs-border-color !default;
-
-$nav-tabs-justified-link-border-color:            $nav-tabs-border-color !default;
-$nav-tabs-justified-active-link-border-color:     $body-bg !default;
-
-//== Pills
-$nav-pills-border-radius:                   $border-radius-base !default;
-$nav-pills-active-link-hover-bg:            $component-active-bg !default;
-$nav-pills-active-link-hover-color:         $component-active-color !default;
-
-
-//== Pagination
-//
-//##
-
-$pagination-color:                     $btn-default-color !default;
-$pagination-bg:                        $btn-default-bg !default;
-$pagination-border:                    $btn-default-border !default;
-
-$pagination-hover-color:               $pagination-color !default;
-$pagination-hover-bg:                  $pagination-bg !default;
-$pagination-hover-border:              $pagination-border !default;
-
-$pagination-active-color:              #fff !default;
-$pagination-active-bg:                 $brand-primary !default;
-$pagination-active-border:             $btn-primary-border !default;
-
-$pagination-disabled-color:            $gray-light !default;
-$pagination-disabled-bg:               $pagination-bg !default;
-$pagination-disabled-border:           $pagination-border !default;
-
-
-//== Pager
-//
-//##
-
-$pager-bg:                             $pagination-bg !default;
-$pager-border:                         $pagination-border !default;
-$pager-border-radius:                  15px !default;
-
-$pager-hover-bg:                       $pagination-hover-bg !default;
-
-$pager-active-bg:                      $pagination-active-bg !default;
-$pager-active-color:                   $pagination-active-color !default;
-
-$pager-disabled-color:                 $pagination-disabled-color !default;
-
-
-//== Jumbotron
-//
-//##
-
-$jumbotron-padding:              30px !default;
-$jumbotron-color:                inherit !default;
-$jumbotron-bg:                   #fafafa !default;
-$jumbotron-heading-color:        inherit !default;
-$jumbotron-font-size:            ceil(($font-size-base * 1.5)) !default;
-$jumbotron-heading-font-size:    ceil(($font-size-base * 4.5)) !default;
-
-
-//== Form states and alerts
-//
-//## Define colors for form feedback states and, by default, alerts.
-
-$state-success-text:             #fff !default;
-$state-success-bg:               $brand-success !default;
-$state-success-border:           darken($state-success-bg, 4%) !default;
-
-$state-info-text:                #fff !default;
-$state-info-bg:                  $brand-info !default;
-$state-info-border:              darken($state-info-bg, 12%) !default;
-
-$state-warning-text:             #fff !default;
-$state-warning-bg:               $brand-warning !default;
-$state-warning-border:           darken($state-warning-bg, 5%) !default;
-
-$state-danger-text:              #fff !default;
-$state-danger-bg:                $brand-danger !default;
-$state-danger-border:            darken($state-danger-bg, 10%) !default;
-
-
-//== Tooltips
-//
-//##
-
-//** Tooltip max width
-$tooltip-max-width:           200px !default;
-//** Tooltip text color
-$tooltip-color:               #fff !default;
-//** Tooltip background color
-$tooltip-bg:                  #000 !default;
-$tooltip-opacity:             .9 !default;
-
-//** Tooltip arrow width
-$tooltip-arrow-width:         5px !default;
-//** Tooltip arrow color
-$tooltip-arrow-color:         $tooltip-bg !default;
-
-
-//== Popovers
-//
-//##
-
-//** Popover body background color
-$popover-bg:                          #fff !default;
-//** Popover maximum width
-$popover-max-width:                   276px !default;
-//** Popover border color
-$popover-border-color:                rgba(0,0,0,.2) !default;
-//** Popover fallback border color
-$popover-fallback-border-color:       #ccc !default;
-
-//** Popover title background color
-$popover-title-bg:                    darken($popover-bg, 3%) !default;
-
-//** Popover arrow width
-$popover-arrow-width:                 10px !default;
-//** Popover arrow color
-$popover-arrow-color:                 $popover-bg !default;
-
-//** Popover outer arrow width
-$popover-arrow-outer-width:           ($popover-arrow-width + 1) !default;
-//** Popover outer arrow color
-$popover-arrow-outer-color:           fadein($popover-border-color, 5%) !default;
-//** Popover outer arrow fallback color
-$popover-arrow-outer-fallback-color:  darken($popover-fallback-border-color, 20%) !default;
-
-
-//== Labels
-//
-//##
-
-//** Default label background color
-$label-default-bg:            $gray-light !default;
-//** Primary label background color
-$label-primary-bg:            $brand-primary !default;
-//** Success label background color
-$label-success-bg:            $brand-success !default;
-//** Info label background color
-$label-info-bg:               $brand-info !default;
-//** Warning label background color
-$label-warning-bg:            $brand-warning !default;
-//** Danger label background color
-$label-danger-bg:             $brand-danger !default;
-
-//** Default label text color
-$label-color:                 #fff !default;
-//** Default text color of a linked label
-$label-link-hover-color:      #fff !default;
-
-
-//== Modals
-//
-//##
-
-//** Padding applied to the modal body
-$modal-inner-padding:         20px !default;
-
-//** Padding applied to the modal title
-$modal-title-padding:         15px !default;
-//** Modal title line-height
-$modal-title-line-height:     $line-height-base !default;
-
-//** Background color of modal content area
-$modal-content-bg:                             #fff !default;
-//** Modal content border color
-$modal-content-border-color:                   rgba(0,0,0,.05) !default;
-//** Modal content border color **for IE8**
-$modal-content-fallback-border-color:          $gray-lighter !default;
-
-//** Modal backdrop background color
-$modal-backdrop-bg:           #000 !default;
-//** Modal backdrop opacity
-$modal-backdrop-opacity:      .5 !default;
-//** Modal header border color
-$modal-header-border-color:   #e5e5e5 !default;
-//** Modal footer border color
-$modal-footer-border-color:   $modal-header-border-color !default;
-
-$modal-lg:                    900px !default;
-$modal-md:                    600px !default;
-$modal-sm:                    300px !default;
-
-
-//== Alerts
-//
-//## Define alert colors, border radius, and padding.
-
-$alert-padding:               15px !default;
-$alert-border-radius:         $border-radius-base !default;
-$alert-link-font-weight:      bold !default;
-
-$alert-success-bg:            $state-success-bg !default;
-$alert-success-text:          $state-success-text !default;
-$alert-success-border:        $state-success-border !default;
-
-$alert-info-bg:               $state-info-bg !default;
-$alert-info-text:             $state-info-text !default;
-$alert-info-border:           $state-info-border !default;
-
-$alert-warning-bg:            $state-warning-bg !default;
-$alert-warning-text:          $state-warning-text !default;
-$alert-warning-border:        $state-warning-border !default;
-
-$alert-danger-bg:             $state-danger-bg !default;
-$alert-danger-text:           $state-danger-text !default;
-$alert-danger-border:         $state-danger-border !default;
-
-
-//== Progress bars
-//
-//##
-
-//** Background color of the whole progress component
-$progress-bg:                 $jumbotron-bg !default;
-//** Progress bar text color
-$progress-bar-color:          #fff !default;
-//** Variable for setting rounded corners on progress bar.
-$progress-border-radius:      $border-radius-base !default;
-
-//** Default progress bar color
-$progress-bar-bg:             $brand-primary !default;
-//** Success progress bar color
-$progress-bar-success-bg:     $brand-success !default;
-//** Warning progress bar color
-$progress-bar-warning-bg:     $brand-warning !default;
-//** Danger progress bar color
-$progress-bar-danger-bg:      $brand-danger !default;
-//** Info progress bar color
-$progress-bar-info-bg:        $brand-info !default;
-
-
-//== List group
-//
-//##
-
-//** Background color on `.list-group-item`
-$list-group-bg:                 #fff !default;
-//** `.list-group-item` border color
-$list-group-border:             $gray-lighter !default;
-//** List group border radius
-$list-group-border-radius:      $border-radius-base !default;
-
-//** Background color of single list items on hover
-$list-group-hover-bg:           #f5f5f5 !default;
-//** Text color of active list items
-$list-group-active-color:       $component-active-color !default;
-//** Background color of active list elements
-$list-group-active-bg:          $component-active-bg !default;
-//** Background color of active list items
-$list-group-active-border:      $list-group-active-bg !default;
-//** Text color for content within active list items
-$list-group-active-text-color:  lighten($list-group-active-bg, 40%) !default;
-
-//** Text color of disabled list items
-$list-group-disabled-color:      $gray-light !default;
-//** Background color of disabled list items
-$list-group-disabled-bg:         $gray-lighter !default;
-//** Text color for content within disabled list items
-$list-group-disabled-text-color: $list-group-disabled-color !default;
-
-$list-group-link-color:         #555 !default;
-$list-group-link-hover-color:   $list-group-link-color !default;
-$list-group-link-heading-color: #333 !default;
-
-
-//== Panels
-//
-//##
-
-$panel-bg:                    #fff !default;
-$panel-body-padding:          15px !default;
-$panel-heading-padding:       10px 15px !default;
-$panel-footer-padding:        $panel-heading-padding !default;
-$panel-border-radius:         $border-radius-base !default;
-
-//** Border color for elements within panels
-$panel-inner-border:          transparent !default;
-$panel-footer-bg:             #f5f5f5 !default;
-
-$panel-default-text:          $gray-dark !default;
-$panel-default-border:        transparent !default;
-$panel-default-heading-bg:    #f5f5f5 !default;
-
-$panel-primary-text:          #fff !default;
-$panel-primary-border:        transparent !default;
-$panel-primary-heading-bg:    $brand-primary !default;
-
-$panel-success-text:          $state-success-text !default;
-$panel-success-border:        transparent !default;
-$panel-success-heading-bg:    $state-success-bg !default;
-
-$panel-info-text:             $state-info-text !default;
-$panel-info-border:           transparent !default;
-$panel-info-heading-bg:       $state-info-bg !default;
-
-$panel-warning-text:          $state-warning-text !default;
-$panel-warning-border:        transparent !default;
-$panel-warning-heading-bg:    $state-warning-bg !default;
-
-$panel-danger-text:           $state-danger-text !default;
-$panel-danger-border:         transparent !default;
-$panel-danger-heading-bg:     $state-danger-bg !default;
-
-
-//== Thumbnails
-//
-//##
-
-//** Padding around the thumbnail image
-$thumbnail-padding:           4px !default;
-//** Thumbnail background color
-$thumbnail-bg:                $body-bg !default;
-//** Thumbnail border color
-$thumbnail-border:            $gray-lighter !default;
-//** Thumbnail border radius
-$thumbnail-border-radius:     $border-radius-base !default;
-
-//** Custom text color for thumbnail captions
-$thumbnail-caption-color:     $text-color !default;
-//** Padding around the thumbnail caption
-$thumbnail-caption-padding:   9px !default;
-
-
-//== Wells
-//
-//##
-
-$well-bg:                     $jumbotron-bg !default;
-$well-border:                 darken($well-bg, 7%) !default;
-
-
-//== Badges
-//
-//##
-
-$badge-color:                 #fff !default;
-//** Linked badge text color on hover
-$badge-link-hover-color:      #fff !default;
-$badge-bg:                    $brand-primary !default;
-
-//** Badge text color in active nav link
-$badge-active-color:          $link-color !default;
-//** Badge background color in active nav link
-$badge-active-bg:             #fff !default;
-
-$badge-font-weight:           normal !default;
-$badge-line-height:           1 !default;
-$badge-border-radius:         10px !default;
-
-
-//== Breadcrumbs
-//
-//##
-
-$breadcrumb-padding-vertical:   8px !default;
-$breadcrumb-padding-horizontal: 15px !default;
-//** Breadcrumb background color
-$breadcrumb-bg:                 $well-bg !default;
-//** Breadcrumb text color
-$breadcrumb-color:              $gray-light !default;
-//** Text color of current page in the breadcrumb
-$breadcrumb-active-color:       $gray-light !default;
-//** Textual separator for between breadcrumb elements
-$breadcrumb-separator:          ">" !default;
-
-
-//== Carousel
-//
-//##
-
-$carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6) !default;
-
-$carousel-control-color:                      #fff !default;
-$carousel-control-width:                      15% !default;
-$carousel-control-opacity:                    .7 !default;
-$carousel-control-font-size:                  20px !default;
-
-$carousel-indicator-active-bg:                #fff !default;
-$carousel-indicator-border-color:             #fff !default;
-
-$carousel-caption-color:                      #fff !default;
-
-
-//== Close
-//
-//##
-
-$close-font-weight:           bold !default;
-$close-color:                 #fff !default;
-$close-text-shadow:           0 1px 0 #fff !default;
-
-
-//== Code
-//
-//##
-
-$code-color:                  #c7254e !default;
-$code-bg:                     #f9f2f4 !default;
-
-$kbd-color:                   #fff !default;
-$kbd-bg:                      #333 !default;
-
-$pre-bg:                      #f5f5f5 !default;
-$pre-color:                   $gray-dark !default;
-$pre-border-color:            #ccc !default;
-$pre-scrollable-max-height:   340px !default;
-
-
-//== Type
-//
-//##
-
-//** Horizontal offset for forms and lists.
-$component-offset-horizontal: 180px !default;
-//** Text muted color
-$text-muted:                  $gray-light !default;
-//** Abbreviations and acronyms border color
-$abbr-border-color:           $gray-light !default;
-//** Headings small color
-$headings-small-color:        $gray-light !default;
-//** Blockquote small color
-$blockquote-small-color:      $gray-light !default;
-//** Blockquote font size
-$blockquote-font-size:        ($font-size-base * 1.25) !default;
-//** Blockquote border color
-$blockquote-border-color:     $gray-lighter !default;
-//** Page header border color
-$page-header-border-color:    $gray-lighter !default;
-//** Width of horizontal description list titles
-$dl-horizontal-offset:        $component-offset-horizontal !default;
-//** Point at which .dl-horizontal becomes horizontal
-$dl-horizontal-breakpoint:    $grid-float-breakpoint !default;
-//** Horizontal line color.
-$hr-border:                   $gray-lighter !default;
diff --git a/_sass/bootstrap/_wells.scss b/_sass/bootstrap/_wells.scss
deleted file mode 100644
index b865711..0000000
--- a/_sass/bootstrap/_wells.scss
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Wells
-// --------------------------------------------------
-
-
-// Base class
-.well {
-  min-height: 20px;
-  padding: 19px;
-  margin-bottom: 20px;
-  background-color: $well-bg;
-  border: 1px solid $well-border;
-  border-radius: $border-radius-base;
-  @include box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
-  blockquote {
-    border-color: #ddd;
-    border-color: rgba(0,0,0,.15);
-  }
-}
-
-// Sizes
-.well-lg {
-  padding: 24px;
-  border-radius: $border-radius-large;
-}
-.well-sm {
-  padding: 9px;
-  border-radius: $border-radius-small;
-}
diff --git a/_sass/bootstrap/mixins/_alerts.scss b/_sass/bootstrap/mixins/_alerts.scss
deleted file mode 100644
index 3faf0b5..0000000
--- a/_sass/bootstrap/mixins/_alerts.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-// Alerts
-
-@mixin alert-variant($background, $border, $text-color) {
-  background-color: $background;
-  border-color: $border;
-  color: $text-color;
-
-  hr {
-    border-top-color: darken($border, 5%);
-  }
-  .alert-link {
-    color: darken($text-color, 10%);
-  }
-}
diff --git a/_sass/bootstrap/mixins/_background-variant.scss b/_sass/bootstrap/mixins/_background-variant.scss
deleted file mode 100644
index 4c7769e..0000000
--- a/_sass/bootstrap/mixins/_background-variant.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-// Contextual backgrounds
-
-// [converter] $parent hack
-@mixin bg-variant($parent, $color) {
-  #{$parent} {
-    background-color: $color;
-  }
-  a#{$parent}:hover,
-  a#{$parent}:focus {
-    background-color: darken($color, 10%);
-  }
-}
diff --git a/_sass/bootstrap/mixins/_border-radius.scss b/_sass/bootstrap/mixins/_border-radius.scss
deleted file mode 100644
index ce19499..0000000
--- a/_sass/bootstrap/mixins/_border-radius.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-// Single side border-radius
-
-@mixin border-top-radius($radius) {
-  border-top-right-radius: $radius;
-   border-top-left-radius: $radius;
-}
-@mixin border-right-radius($radius) {
-  border-bottom-right-radius: $radius;
-     border-top-right-radius: $radius;
-}
-@mixin border-bottom-radius($radius) {
-  border-bottom-right-radius: $radius;
-   border-bottom-left-radius: $radius;
-}
-@mixin border-left-radius($radius) {
-  border-bottom-left-radius: $radius;
-     border-top-left-radius: $radius;
-}
diff --git a/_sass/bootstrap/mixins/_buttons.scss b/_sass/bootstrap/mixins/_buttons.scss
deleted file mode 100644
index b93f84b..0000000
--- a/_sass/bootstrap/mixins/_buttons.scss
+++ /dev/null
@@ -1,65 +0,0 @@
-// Button variants
-//
-// Easily pump out default styles, as well as :hover, :focus, :active,
-// and disabled options for all buttons
-
-@mixin button-variant($color, $background, $border) {
-  color: $color;
-  background-color: $background;
-  border-color: $border;
-
-  &:focus,
-  &.focus {
-    color: $color;
-    background-color: darken($background, 10%);
-        border-color: darken($border, 25%);
-  }
-  &:hover {
-    color: $color;
-    background-color: darken($background, 10%);
-        border-color: darken($border, 12%);
-  }
-  &:active,
-  &.active,
-  .open > &.dropdown-toggle {
-    color: $color;
-    background-color: darken($background, 10%);
-        border-color: darken($border, 12%);
-
-    &:hover,
-    &:focus,
-    &.focus {
-      color: $color;
-      background-color: darken($background, 17%);
-          border-color: darken($border, 25%);
-    }
-  }
-  &:active,
-  &.active,
-  .open > &.dropdown-toggle {
-    background-image: none;
-  }
-  &.disabled,
-  &[disabled],
-  fieldset[disabled] & {
-    &:hover,
-    &:focus,
-    &.focus {
-      background-color: $background;
-          border-color: $border;
-    }
-  }
-
-  .badge {
-    color: $background;
-    background-color: $color;
-  }
-}
-
-// Button sizes
-@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
-  padding: $padding-vertical $padding-horizontal;
-  font-size: $font-size;
-  line-height: $line-height;
-  border-radius: $border-radius;
-}
diff --git a/_sass/bootstrap/mixins/_center-block.scss b/_sass/bootstrap/mixins/_center-block.scss
deleted file mode 100644
index e06fb5e..0000000
--- a/_sass/bootstrap/mixins/_center-block.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-// Center-align a block level element
-
-@mixin center-block() {
-  display: block;
-  margin-left: auto;
-  margin-right: auto;
-}
diff --git a/_sass/bootstrap/mixins/_clearfix.scss b/_sass/bootstrap/mixins/_clearfix.scss
deleted file mode 100644
index dc3e2ab..0000000
--- a/_sass/bootstrap/mixins/_clearfix.scss
+++ /dev/null
@@ -1,22 +0,0 @@
-// Clearfix
-//
-// For modern browsers
-// 1. The space content is one way to avoid an Opera bug when the
-//    contenteditable attribute is included anywhere else in the document.
-//    Otherwise it causes space to appear at the top and bottom of elements
-//    that are clearfixed.
-// 2. The use of `table` rather than `block` is only necessary if using
-//    `:before` to contain the top-margins of child elements.
-//
-// Source: http://nicolasgallagher.com/micro-clearfix-hack/
-
-@mixin clearfix() {
-  &:before,
-  &:after {
-    content: " "; // 1
-    display: table; // 2
-  }
-  &:after {
-    clear: both;
-  }
-}
diff --git a/_sass/bootstrap/mixins/_forms.scss b/_sass/bootstrap/mixins/_forms.scss
deleted file mode 100644
index 277aa5f..0000000
--- a/_sass/bootstrap/mixins/_forms.scss
+++ /dev/null
@@ -1,88 +0,0 @@
-// Form validation states
-//
-// Used in forms.less to generate the form validation CSS for warnings, errors,
-// and successes.
-
-@mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) {
-  // Color the label and help text
-  .help-block,
-  .control-label,
-  .radio,
-  .checkbox,
-  .radio-inline,
-  .checkbox-inline,
-  &.radio label,
-  &.checkbox label,
-  &.radio-inline label,
-  &.checkbox-inline label  {
-    color: $text-color;
-  }
-  // Set the border and box shadow on specific inputs to match
-  .form-control {
-    border-color: $border-color;
-    @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
-    &:focus {
-      border-color: darken($border-color, 10%);
-      $shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%);
-      @include box-shadow($shadow);
-    }
-  }
-  // Set validation states also for addons
-  .input-group-addon {
-    color: $text-color;
-    border-color: $border-color;
-    background-color: $background-color;
-  }
-  // Optional feedback icon
-  .form-control-feedback {
-    color: $text-color;
-  }
-}
-
-
-// Form control focus state
-//
-// Generate a customized focus state and for any input with the specified color,
-// which defaults to the `$input-border-focus` variable.
-//
-// We highly encourage you to not customize the default value, but instead use
-// this to tweak colors on an as-needed basis. This aesthetic change is based on
-// WebKit's default styles, but applicable to a wider range of browsers. Its
-// usability and accessibility should be taken into account with any change.
-//
-// Example usage: change the default blue border and shadow to white for better
-// contrast against a dark gray background.
-@mixin form-control-focus($color: $input-border-focus) {
-  $color-rgba: rgba(red($color), green($color), blue($color), .6);
-  &:focus {
-    border-color: $color;
-    outline: 0;
-    @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px $color-rgba);
-  }
-}
-
-// Form control sizing
-//
-// Relative text size, padding, and border-radii changes for form controls. For
-// horizontal sizing, wrap controls in the predefined grid classes. `

We’ll only email about this benchmark.

; } diff --git a/app/join/page.jsx b/app/join/page.jsx new file mode 100644 index 0000000..05a7516 --- /dev/null +++ b/app/join/page.jsx @@ -0,0 +1,8 @@ +import PageHeading from '@/components/page-heading'; +export const metadata = { title: 'Open positions', alternates: { canonical: '/join/' } }; +export default function Join() { + return <>
+

We have a postdoc position available.

+

We are also looking for PhD students, especially in but not limited to deep learning, causal inference, data science and mobile health. If you're interested please apply to the UW Allen School. Go Dawgs!

+
; +} diff --git a/app/layout.jsx b/app/layout.jsx new file mode 100644 index 0000000..b261981 --- /dev/null +++ b/app/layout.jsx @@ -0,0 +1,22 @@ +import Link from 'next/link'; +import Navigation from '@/components/navigation'; +import './globals.css'; +export const metadata = { + metadataBase: new URL('https://behavioral-data.github.io'), + title: { default: 'Behavioral Data Science · University of Washington', template: '%s · Behavioral Data Science' }, + description: 'Our aim is to explore and understand behavior through the lens of data science.', +}; +export default function RootLayout({ children }) { + return Skip to content + +
{children}
+ ; +} diff --git a/app/news/page.jsx b/app/news/page.jsx new file mode 100644 index 0000000..f93d1bf --- /dev/null +++ b/app/news/page.jsx @@ -0,0 +1,6 @@ +import Link from 'next/link'; +import ReactMarkdown from 'react-markdown'; +import { papers, news, formatDate } from '@/lib/content'; +import PageHeading from '@/components/page-heading'; +export const metadata = { title: 'News', alternates: { canonical: '/news/' } }; +export default function News() { return <>
{news.map(n =>
{n.headline}
)}

Awards

{papers.filter(p => p.award).map(p =>
{p.year}

{p.award}

{p.title}

{p.authors}

)}
; } diff --git a/app/not-found.jsx b/app/not-found.jsx new file mode 100644 index 0000000..76e1c9a --- /dev/null +++ b/app/not-found.jsx @@ -0,0 +1,3 @@ +import Link from 'next/link'; +import PageHeading from '@/components/page-heading'; +export default function NotFound() { return <>Sorry, but the page you were trying to view does not exist.Home; } diff --git a/app/page.jsx b/app/page.jsx new file mode 100644 index 0000000..09c4a93 --- /dev/null +++ b/app/page.jsx @@ -0,0 +1,19 @@ +import Link from 'next/link'; +import { papers, people, sponsors } from '@/lib/content'; +import PaperCard from '@/components/paper-card'; +export default function Home() { + const selected = papers.filter(p => p.highlight).slice(0, 2); + return <> +
+

Welcome to the Behavioral Data Science Lab

+
+

We are a research group at the Paul G. Allen School of Computer Science of Engineering. Our aim is to explore and understand behavior through the lens of data science.

+

The Behavioral Data Science Group develops computational methods that leverage large-scale behavioral data to extract actionable insights about our lives, health and happiness through combining techniques from data science, social network analysis, and natural language processing. We currently work on research related to mental health, misinformation online, scientific reproducibility, and informing the COVID-19 response.

+
+
+

Group highlights

Publications
{selected.map(p => )}
+

Publications

{papers.length} papers
{papers.slice(0, 3).map(p => )}
Full List
+

Our Group

Team
{people.filter(p => p.status === 'member' && p.image).slice(0, 4).map(p => {p.name}{p.name})}
+

Support From

{sponsors.map(s => {s.name})}
+ ; +} diff --git a/app/people/[id]/page.jsx b/app/people/[id]/page.jsx new file mode 100644 index 0000000..5b0f323 --- /dev/null +++ b/app/people/[id]/page.jsx @@ -0,0 +1,14 @@ +import Link from 'next/link'; +import { notFound } from 'next/navigation'; +import { people, papers, safeUrl } from '@/lib/content'; +import { matchesPerson } from '@/lib/publications.mjs'; +import PaperCard from '@/components/paper-card'; +import PageHeading from '@/components/page-heading'; +export const dynamicParams = false; +export function generateStaticParams() { return people.map(p => ({ id: p.id })); } +export async function generateMetadata({ params }) { const { id } = await params; return { title: people.find(p => p.id === id)?.name || 'Person', alternates: { canonical: `/people/${id}/` } }; } +export default async function Person({ params }) { + const { id } = await params; const p = people.find(p => p.id === id); if (!p) notFound(); + const related = papers.filter(paper => matchesPerson(paper, p.name)); + return <>
{p.image && {p.name}}

{p.role}

{safeUrl(p.website) && Personal website}{p.topics.length > 0 && <>

Research interests

{p.topics.map(t => {t})}
}
{related.length > 0 &&

Publications

{related.map(paper => )}
}Team; +} diff --git a/app/pictures/page.jsx b/app/pictures/page.jsx new file mode 100644 index 0000000..0c0c367 --- /dev/null +++ b/app/pictures/page.jsx @@ -0,0 +1,3 @@ +import PageHeading from '@/components/page-heading'; +export const metadata = { title: 'Pictures' }; +export default function Page() { return ; } diff --git a/app/publications/[id]/page.jsx b/app/publications/[id]/page.jsx new file mode 100644 index 0000000..21b8bc2 --- /dev/null +++ b/app/publications/[id]/page.jsx @@ -0,0 +1,19 @@ +import Link from 'next/link'; +import { notFound } from 'next/navigation'; +import ReactMarkdown from 'react-markdown'; +import { papers, safeUrl } from '@/lib/content'; +import { bibtex } from '@/lib/publications.mjs'; +export const dynamicParams = false; +export function generateStaticParams() { return papers.map(p => ({ id: p.id })); } +export async function generateMetadata({ params }) { + const { id } = await params; const p = papers.find(p => p.id === id); + return { title: p?.title || 'Publication', alternates: { canonical: `/publications/${id}/` }, other: p ? { citation_title: p.title, citation_publication_date: String(p.year) } : {} }; +} +export default async function Publication({ params }) { + const { id } = await params; const p = papers.find(p => p.id === id); if (!p) notFound(); + const doi = p.doi ? (/^https?:\/\//.test(p.doi) ? p.doi : `https://doi.org/${p.doi}`) : ''; + return <>
Publications
{p.year} · {p.venue}

{p.title}

{p.authorNames?.join(', ') || p.authors}

{p.award &&
{p.award}
}
{p.pdf && PDF}{safeUrl(doi) && DOI}{safeUrl(p.code) && Code}{safeUrl(p.url) && Website}
+ {p.image && {`Research} + {p.description &&
{p.description}
} +

BibTeX

{bibtex(p)}
; +} diff --git a/app/publications/page.jsx b/app/publications/page.jsx new file mode 100644 index 0000000..79189bb --- /dev/null +++ b/app/publications/page.jsx @@ -0,0 +1,7 @@ +import { papers, people } from '@/lib/content'; +import PageHeading from '@/components/page-heading'; +import PublicationExplorer from '@/components/publication-explorer'; +export const metadata = { title: 'Publications', alternates: { canonical: '/publications/' } }; +export default function Publications() { + return <>; +} diff --git a/app/research/page.jsx b/app/research/page.jsx new file mode 100644 index 0000000..58f484d --- /dev/null +++ b/app/research/page.jsx @@ -0,0 +1,3 @@ +import PageHeading from '@/components/page-heading'; +export const metadata = { title: 'Research' }; +export default function Page() { return ; } diff --git a/app/robots.js b/app/robots.js new file mode 100644 index 0000000..75f665b --- /dev/null +++ b/app/robots.js @@ -0,0 +1,2 @@ +export const dynamic = 'force-static'; +export default function robots() { return { rules: { userAgent: '*', allow: '/' }, sitemap: 'https://behavioral-data.github.io/sitemap.xml' }; } diff --git a/app/sitemap.js b/app/sitemap.js new file mode 100644 index 0000000..d8448ab --- /dev/null +++ b/app/sitemap.js @@ -0,0 +1,3 @@ +import { papers, people } from '@/lib/content'; +export const dynamic = 'force-static'; +export default function sitemap() { return ['/', '/team/', '/publications/', '/news/', '/join/', '/research/', '/idiofid/', ...papers.map(p=>`/publications/${p.id}/`), ...people.map(p=>`/people/${p.id}/`)].map(path => ({ url: `https://behavioral-data.github.io${path}` })); } diff --git a/app/team/page.jsx b/app/team/page.jsx new file mode 100644 index 0000000..44b543c --- /dev/null +++ b/app/team/page.jsx @@ -0,0 +1,13 @@ +import Link from 'next/link'; +import { people, alumni, safeUrl } from '@/lib/content'; +import PageHeading from '@/components/page-heading'; +export const metadata = { title: 'People', alternates: { canonical: '/team/' } }; +function PersonGrid({ members }) { return
{members.map(p =>
{p.image ? {p.name} :
}

{p.name}

{p.role}

)}
; } +export default function Team() { + const members = people.filter(p => p.status === 'member'); const visitors = people.filter(p => p.status === 'visitor'); + const mergedAlumni = [...alumni]; + for (const p of people.filter(p => p.status === 'alumni')) { + if (!mergedAlumni.some(a => a.name.toLowerCase().startsWith(p.name.toLowerCase()))) mergedAlumni.push({ name: `${p.name}, ${p.role}`, site: p.website }); + } + return <>{visitors.length > 0 &&

Current Visitors

}

Alumni

    {mergedAlumni.map(a =>
  • {safeUrl(a.site) ? {a.name} : a.name}
  • )}
; +} diff --git a/app/vacancies/page.jsx b/app/vacancies/page.jsx new file mode 100644 index 0000000..e8b8ca2 --- /dev/null +++ b/app/vacancies/page.jsx @@ -0,0 +1 @@ +export { default, metadata } from '../join/page'; diff --git a/bdata.bib b/bdata.bib deleted file mode 100644 index c4e325c..0000000 --- a/bdata.bib +++ /dev/null @@ -1,90 +0,0 @@ -@poster{frank2017sensing, - title={Sensing depression: Using smartphone sensors to predict changes in depression severity}, - author={Frank, Ellen and Merrill, Michael and Aung, Hane and Soares, Claudio and Kennedy, Sidney and Matthews, Mark and Kupfer, David and Lalovic, Aleksandra and Choudhury, Tanzeem}, - booktitle={Neuropsychopharmacology}, - volume={43}, - pages={S346--S346}, - year={2017}, - organization={NATURE PUBLISHING GROUP MACMILLAN BUILDING, 4 CRINAN ST, LONDON N1 9XW, ENGLAND}, - venue= {The 56th Annual Meeting of the American College of Neuropsychopharmacology} -} - - -@poster{frank2016sensing, - title={Continuous Behavioral Data as a Potential Depression Biomarker}, - author={Frank, Ellen and Merrill, Michael and Aung, Hane and Soares, Claudio and Kennedy, Sidney and Matthews, Mark and Kupfer, David and Lalovic, Aleksandra and Choudhury, Tanzeem}, - booktitle={Neuropsychopharmacology}, - year = {2016}, - organization={NATURE PUBLISHING GROUP MACMILLAN BUILDING, 4 CRINAN ST, LONDON N1 9XW, ENGLAND}, - venue= {The 56th Annual Meeting of the American College of Neuropsychopharmacology} -} - -@inproceedings{tseng2016ubicomp, - author = {Tseng, Vincent W. S. and Merrill, Michael and Wittleder, Franziska and Abdullah, Saeed and Aung, Min Hane and Choudhury, Tanzeem}, - title = {Assessing Mental Health Issues on College Campuses: Preliminary Findings from a Pilot Study}, - year = {2016}, - isbn = {9781450344623}, - publisher = {Association for Computing Machinery}, - address = {New York, NY, USA}, - url = {https://doi.org/10.1145/2968219.2968308}, - doi = {10.1145/2968219.2968308}, - booktitle = {Proceedings of the 2016 ACM International Joint Conference on Pervasive and Ubiquitous Computing: Adjunct}, - pages = {1200–1208}, - numpages = {9}, - keywords = {predictive modeling, mobile sensing, mental health, behavioral intervention, mHealth}, - location = {Heidelberg, Germany}, - series = {UbiComp ’16}, - venue = {Ubicomp} -} - -@article{ben-zeev_crosscheck_2017, - title = {{CrossCheck}: {Integrating} self-report, behavioral sensing, and smartphone use to identify digital indicators of psychotic relapse}, - volume = {40}, - issn = {1095-158X}, - shorttitle = {{CrossCheck}}, - url = {https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5593755/}, - doi = {10.1037/prj0000243}, - abstract = {Objective - This purpose of this study was to describe and demonstrate CrossCheck, a multimodal data collection system designed to aid in continuous remote monitoring and identification of subjective and objective indicators of psychotic relapse - Methods - Individuals with schizophrenia-spectrum disorders received a smartphone with the monitoring system installed along with unlimited data plan for 12 months. Participants were instructed to carry the device with them and to complete brief self-reports multiple times a week. Multi-modal behavioral sensing (i.e., physical activity, geospatial activity, speech frequency and duration) and device use data (i.e., call and text activity, app use) were captured automatically. Five individuals who experienced psychiatric hospitalization were selected and described for instructive purposes. - - Results - Participants had unique digital indicators of their psychotic relapse. For some, self-reports provided clear and potentially actionable description of symptom exacerbation prior to hospitalization. Others had behavioral sensing data trends (e.g., shifts in geolocation patterns, declines in physical activity) or device use patterns (e.g., increased nighttime app use, discontinuation of all smartphone use) that reflected the changes they experienced more effectively. - - Conclusion - Advancements in mobile technology are enabling collection of an abundance of information that until recently was largely inaccessible to clinical research and practice. However, remote monitoring and relapse detection is in its nascency. Development and evaluation of innovative data management, modeling, and signal-detection techniques that can identify changes within an individual over time (i.e. unique relapse signatures) will be essential if we are to capitalize on these data to improve treatment and prevention.}, - number = {3}, - urldate = {2020-06-25}, - journal = {Psychiatric Rehabilitation Journal}, - venue = {Psychiatric Rehabilitation Journal}, - author = {Ben-Zeev, Dror and Brian, Rachel and Wang, Rui and Wang, Weichen and Campbell, Andrew T. and Aung, Min S. H. and Merrill, Michael and Tseng, Vincent W. S. and Choudhury, Tanzeem and Hauser, Marta and Kane, John M. and Scherer, Emily A.}, - month = sep, - year = {2017}, - pmid = {28368138}, - pmcid = {PMC5593755}, - pages = {266--275}, - file = {PubMed Central Full Text PDF:/Users/michaelmerrill/Zotero/storage/BM5A6Q6N/Ben-Zeev et al. - 2017 - CrossCheck Integrating self-report, behavioral se.pdf:application/pdf} -} - - -@inproceedings{wang_crosscheck_2016, - address = {Heidelberg Germany}, - title = {{CrossCheck}: toward passive sensing and detection of mental health changes in people with schizophrenia}, - isbn = {978-1-4503-4461-6}, - shorttitle = {{CrossCheck}}, - url = {https://dl.acm.org/doi/10.1145/2971648.2971740}, - doi = {10.1145/2971648.2971740}, - abstract = {Early detection of mental health changes in individuals with serious mental illness is critical for effective intervention. CrossCheck is the first step towards the passive monitoring of mental health indicators in patients with schizophrenia and paves the way towards relapse prediction and early intervention. In this paper, we present initial results from an ongoing randomized control trial, where passive smartphone sensor data is collected from 21 outpatients with schizophrenia recently discharged from hospital over a period ranging from 2-8.5 months. Our results indicate that there are statistically significant associations between automatically tracked behavioral features related to sleep, mobility, conversations, smartphone usage and self-reported indicators of mental health in schizophrenia. Using these features we build inference models capable of accurately predicting aggregated scores of mental health indicators in schizophrenia with a mean error of 7.6\% of the score range. Finally, we discuss results on the level of personalization that is needed to account for the known variations within people. We show that by leveraging knowledge from a population with schizophrenia, it is possible to train accurate personalized models that require fewer individual-specific data to quickly adapt to new users.}, - language = {en}, - urldate = {2020-06-25}, - booktitle = {Proceedings of the 2016 {ACM} {International} {Joint} {Conference} on {Pervasive} and {Ubiquitous} {Computing}}, - publisher = {ACM}, - author = {Wang, Rui and Aung, Min S. H. and Abdullah, Saeed and Brian, Rachel and Campbell, Andrew T. and Choudhury, Tanzeem and Hauser, Marta and Kane, John and Merrill, Michael and Scherer, Emily A. and Tseng, Vincent W. S. and Ben-Zeev, Dror}, - month = sep, - year = {2016}, - pages = {886--897}, - file = {Wang et al. - 2016 - CrossCheck toward passive sensing and detection o.pdf:/Users/michaelmerrill/Zotero/storage/88HEZH9G/Wang et al. - 2016 - CrossCheck toward passive sensing and detection o.pdf:application/pdf}, - venue = {Ubicomp} -} - diff --git a/biblib/__init__.py b/biblib/__init__.py deleted file mode 100644 index 6a4bb8f..0000000 --- a/biblib/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = 'bib algo messages'.split() diff --git a/biblib/algo.py b/biblib/algo.py deleted file mode 100644 index 8485447..0000000 --- a/biblib/algo.py +++ /dev/null @@ -1,485 +0,0 @@ -"""Algorithms for manipulating BibTeX data. - -This module implements various algorithms supplied by BibTeX to style -files, as well as some algorithms to make BibTeX data more accessible -to Python. -""" - -__all__ = ('Name parse_names ' + - 'parse_month ' + - 'title_case ' + - 'TeXProcessor TeXToUnicode tex_to_unicode').split() - -import re -import collections -import unicodedata -import string - -from . import messages - -# Control sequences (defined as "control_seq_ilk" in bibtex) and their -# Unicode translations. This is similar to, but slightly different -# from the TeX definitions (of course). -_CONTROL_SEQS = { - '\\i': 'ı', '\\j': 'ȷ', '\\oe': 'œ', '\\OE': 'Œ', - '\\ae': 'æ', '\\AE': 'Æ', '\\aa': 'å', '\\AA': 'Å', - '\\o': 'ø', '\\O': 'Ø', '\\l': 'ł', '\\L': 'Ł', '\\ss': 'ß' -} - -class NameParser: - def __init__(self): - pass - - def __depth(self, data): - depth, depths = 0, [0] * len(data) - for pos, ch in enumerate(data): - depths[pos] = depth - if ch == '{': - depth += 1 - depths[pos] = depth - elif ch == '}': - depth -= 1 - return depths - - def __split_depth0(self, regexp, data, flags=0): - regexp = re.compile(regexp, flags=flags) - depths = self.__depth(data) - parts, last = [], 0 - for m in regexp.finditer(data): - if depths[m.start()] == 0: - parts.append(data[last:m.start()]) - last = m.end() - if regexp.groups: - parts.extend(m.groups()) - parts.append(data[last:]) - return parts - - def _first_char(self, data): - """Return the first character of data (in bibtex's sense).""" - # XXX Should this be pulled out as some generic algorithm? - pos = 0 - depths = self.__depth(data) - while True: - if pos == len(data): - return '' - elif data[pos].isalpha(): - return data[pos] - elif data.startswith('{\\', pos): - # Special character - pos += 1 - m = re.compile(r'\\[a-zA-Z]+').match(data, pos) - if m and m.group() in _CONTROL_SEQS: - # Known bibtex control sequence - return _CONTROL_SEQS[m.group()] - # Scan for the first alphabetic character - while pos < len(data) and depths[pos]: - if data[pos].isalpha(): - return data[pos] - pos += 1 - elif data[pos] == '{': - # Skip brace group - while pos < len(data) and depths[pos]: - pos += 1 - else: - pos += 1 - - def __split_von_last(self, toks): - # See von_name_ends_and_last_name_starts_stuff - for von_end in range(len(toks) - 1, 1, -2): - if self._first_char(toks[von_end - 2]).islower(): - return (toks[:von_end-1], toks[von_end:]) - return ([], toks) - - def parse(self, string, pos): - """Parse a BibTeX name list. - - Returns a list of Name objects. Raises InputError if there is - a syntax error. - """ - - # See x_format_name - - # Split names (see name_scan_for_and) - name_strings = [n.strip() for n in self.__split_depth0( - '[ \t]and(?=[ \t])', string, flags=re.IGNORECASE)] - - # Process each name - names = [] - for name_string in name_strings: - # Remove leading and trailing white space, ~, and -, and - # trailing commas. - name_string = name_trailing = name_string.lstrip('-~ \t') - name_string = name_string.rstrip('-~ \t,') - if ',' in name_trailing[len(name_string):]: - # BibTeX warns about this because it often indicates a - # bigger syntax problem - pos.warn('trailing comma after name `{}\''.format(name_string)) - - # Split on depth-0 commas and further split tokens in each - # part, keeping only the first connector between each - # token. - parts = [self.__split_depth0('([-~ \t])[-~ \t]*', part.strip()) - for part in self.__split_depth0(',', name_string)] - - # Process name depending on how many commas there were - first = von = last = jr = [] - if len(parts) == 1: - # "First von Last" - toks = parts[0] - # The von tokens start with the first lower-case token - # (but cannot start at the last token) - for von_start in range(0, len(toks) - 2, 2): - if self._first_char(toks[von_start]).islower(): - # Found beginning; now find the end - first = toks[:max(0, von_start-1)] - von, last = self.__split_von_last(toks[von_start:]) - break - else: - # No von tokens. Find hyphen-connected last name - # tokens. - for last_start in range(len(toks) - 1, -1, -2): - if last_start and toks[last_start-1] != '-': - break - first = toks[:max(0, last_start-1)] - last = toks[last_start:] - elif 2 <= len(parts) <= 3: - # "von Last, First[, Jr]" - von, last = self.__split_von_last(parts[0]) - first = parts[1] - if len(parts) == 3: - jr = parts[2] - else: - pos.raise_error( - 'too many commas in name `{}\''.format(name_string)) - - names.append(Name(''.join(first), ''.join(von), - ''.join(last), ''.join(jr))) - return names - -class Name(collections.namedtuple('Name', 'first von last jr')): - """A parsed name. - - The name is parsed in to first name, "von", last name, and the - complement (or "jr"). Each component is in uninterpreted form - (e.g., TeX syntax). Missing components are set to the empty - string. - """ - - def is_others(self): - return self.first == '' and self.von == '' and \ - self.last == 'others' and self.jr == '' - - def pretty(self, template='{first} {von} {last} {jr}'): - """Pretty-print author according to template. - - The template is a 'format' template with the added feature - that literal text surrounding fields that expand to empty - strings is prioritized, rather than concatenated. - Specifically, of the literal text snippets between two - non-null fields, only the first of the highest priority is - kept, where non-white space outranks white space outranks the - empty string. Literal text before and after the first and - last fields is always kept. - - Hence, if the template is '{von} {last}, {first}, {jr}' and - the name has a last and a jr not no von or first, then the - first comma will be kept and the space and second dropped. If - the name has only a von and a last, then both commas will be - dropped. If the name has only a last, then all separators - will be dropped. - """ - - # XXX BibTeX's own format.name$ templates are more - # sophisticated than this, and it's not clear these are easier - # to use. These do have the (dubious) benefit of having - # access to the usual format machinery. - - def priority(string): - if not string: - return 0 - elif string.isspace(): - return 1 - return 2 - fields = {'first': self.first, 'von': self.von, - 'last': self.last, 'jr': self.jr} - f = string.Formatter() - pieces = [''] - first_field, last_field = 0, -1 - leading = trailing = '' - for i, (literal_text, field_name, format_spec, conv) in \ - enumerate(f.parse(template)): - if i == 0: - # Always keep leading text - leading = literal_text - elif field_name is None: - # Always keep trailing test - trailing = literal_text - elif priority(literal_text) > priority(pieces[-1]): - # Overrides previous piece - pieces[-1] = literal_text - - if field_name is not None: - obj, _ = f.get_field(field_name, (), fields) - if not obj: - continue - obj = f.convert_field(obj, conv) - if first_field == 0: - first_field = len(pieces) - last_field = len(pieces) - pieces.extend([f.format_field(obj, format_spec), '']) - # Only keep the pieces between non-null fields - pieces = pieces[first_field:last_field + 1] - return leading + ''.join(pieces) + trailing - -def parse_names(string, pos=messages.Pos.unknown): - """Parse a BibTeX name list (e.g., an author or editor field). - - Returns a list of Name objects. The parsing is equivalent to - BibTeX's built-in "format.name$" function. Raises InputError if - there is a syntax error. - """ - return NameParser().parse(string, pos) - -_MONTHS = 'January February March April May June July August September October November December'.lower().split() - -def parse_month(string, pos=messages.Pos.unknown): - """Parse a BibTeX month field. - - This performs fairly fuzzy parsing that supports all standard - month macro styles (and then some). - - Raises InputError if the field cannot be parsed. - """ - val = string.strip().rstrip('.').lower() - for i, name in enumerate(_MONTHS): - if name.startswith(val) and len(val) >= 3: - return i + 1 - pos.raise_error('invalid month `{}\''.format(string)) - -CS_RE = re.compile(r'\\[a-zA-Z]+') - -def title_case(string, pos=messages.Pos.unknown): - """Convert to title case (like BibTeX's built-in "change.case$"). - - Raises InputError if the title string contains syntax errors. - """ - - # See "@" - out = [] - level, prev_colon, pos = 0, False, 0 - while pos < len(string): - keep = (pos == 0 or (prev_colon and string[pos-1] in ' \t\n')) - - if level == 0 and string.startswith('{\\', pos) and not keep: - # Special character - out.append(string[pos]) - pos += 1 - level += 1 - - while level and pos < len(string): - if string[pos] == '\\': - m = CS_RE.match(string, pos) - if m: - if m.group() in _CONTROL_SEQS: - # Lower case control sequence - out.append(m.group().lower()) - else: - # Unknown control sequence, keep case - out.append(m.group()) - pos = m.end() - continue - elif string[pos] == '{': - level += 1 - elif string[pos] == '}': - level -= 1 - - # Lower-case non-control sequence - out.append(string[pos].lower()) - pos += 1 - - prev_colon = False - continue - - # Handle braces - char = string[pos] - if char == '{': - level += 1 - elif char == '}': - if level == 0: - pos.raise_error('unexpected }') - level -= 1 - - # Handle colon state - if char == ':': - prev_colon = True - elif char not in ' \t\n': - prev_colon = False - - # Change case of a regular character - if level > 0 or keep: - out.append(string[pos]) - else: - out.append(string[pos].lower()) - pos += 1 - - return ''.join(out) - -# A TeX control sequence is -# -# 1) an active character (subsequent white space is NOT ignored) or, -# 2) a \ followed by either -# 2.1) a sequence of letter-category characters (subsequent white -# space is ignored), or -# 2.2) a single space-category character (subsequent white space is -# ignored), or -# 2.3) a single other character (subsequent white space is NOT -# ignored). -# -# This regexp assumes plain TeX's initial category codes. Technically -# only ~ and \f are active characters, but we include several other -# special characters that we want to abort on. -tex_cs_re = re.compile( - r'([~\f$&#^_]|(\\[a-zA-Z]+|\\[ \t\r\n])|\\.)(?(2)[ \t\r\n]*)') - -class TeXProcessor: - """Base class for simple TeX macro processors. - - This assumes the initial category codes set up by plain.tex (and, - likewise, LaTeX). - """ - - def process(self, string, pos): - """Expand active characters and macros in string. - - Raises InputError if it encounters an active character or - macro it doesn't recognize. - """ - - self.__data = string - self.__off = 0 - self.__pos = pos - - # Process macros - while True: - m = tex_cs_re.search(self.__data, self.__off) - if not m: - break - self.__off = m.end() - macro = m.group(1) - nval = self._expand(macro) - if nval is None: - if macro.startswith('\\'): - pos.raise_error('unknown macro `{}\''.format(macro)) - pos.raise_error( - 'unknown special character `{}\''.format(macro)) - self.__data = self.__data[:m.start()] + nval + \ - self.__data[self.__off:] - self.__off = m.start() + len(nval) - - return self.__data - - def _scan_argument(self): - """Scan an return a macro argument.""" - if self.__off >= len(self.__data): - self.__pos.raise_error('macro argument expected') - if self.__data[self.__off] == '{': - start = self.__off - depth = 0 - while depth or self.__off == start: - if self.__data[self.__off] == '{': - depth += 1 - elif self.__data[self.__off] == '}': - depth -= 1 - self.__off += 1 - return self.__data[start + 1:self.__off - 1] - elif self.__data[self.__off] == '\\': - m = tex_cs_re.match(self.__data, self.__off) - self.__off = m.end() - return m.group(1) - else: - arg = self.__data[self.__off] - self.__off += 1 - return arg - - def _expand(self, cs): - """Return the expansion of an active character or control sequence. - - Returns None if the sequence is unknown. This should be - overridden by sub-classes. - """ - return None - -class TeXToUnicode(TeXProcessor): - """A simple TeX-to-unicode converter. - - This interprets accents and other special tokens like '--' and - eliminates braces. - """ - - # Simple TeX-to-Unicode replacements - _SIMPLE = { - # Active characters - '~': '\u00A0', - # chardefs from plain.tex - '\\%': '%', '\\&': '&', '\\#': '#', '\\$': '$', '\\ss': 'ß', - '\\ae': 'æ', '\\oe': 'œ', '\\o': 'ø', - '\\AE': 'Æ', '\\OE': 'Œ', '\\O': 'Ø', - '\\i': 'ı', '\\j': 'ȷ', - '\\aa': 'å', '\\AA': 'Å', '\\l': 'ł', '\\L': 'Ł', - # Other defs from plain.tex - '\\_': '_', '\\dag': '†', '\\ddag': '‡', '\\S': '§', '\\P': '¶', - } - - # TeX accent control sequences to Unicode combining characters - _ACCENTS = { - # Accents defined in plain.tex - '\\`': '\u0300', "\\'": '\u0301', '\\v': '\u030C', '\\u': '\u0306', - '\\=': '\u0304', '\\^': '\u0302', '\\.': '\u0307', '\\H': '\u030B', - '\\~': '\u0303', '\\"': '\u0308', - '\\d': '\u0323', '\\b': '\u0331', '\\c': '\u0327', - # Other accents that seem to be standard, but I can't find - # their definitions - '\\r': '\u030A', '\\k': '\u0328' - } - - def process(self, string, pos): - string = super().process(string, pos) - - # Handle ligatures that are unique to TeX. This must be done - # after macro expansion, but before brace removal because - # braces inhibit ligatures. - string = string.replace('---', '\u2014').replace('--', '\u2013') - - # Remove braces - return string.replace('{', '').replace('}', '') - - def _expand(self, cs): - if cs in self._SIMPLE: - return self._SIMPLE[cs] - if cs in self._ACCENTS: - arg = self._scan_argument() - if len(arg) == 0: - seq, rest = ' ' + self._ACCENTS[cs], '' - elif arg.startswith('\\i') or arg.startswith('\\j'): - # Unicode combining marks should be applied to the - # regular i, not the dotless i. - seq, rest = arg[1] + self._ACCENTS[cs], arg[2:] - else: - seq, rest = arg[0] + self._ACCENTS[cs], arg[1:] - return unicodedata.normalize('NFC', seq) + rest - return None - -def tex_to_unicode(string, pos=messages.Pos.unknown): - """Convert a BibTeX field value written in TeX to Unicode. - - This interprets accents and other special tokens like '--' and - eliminates braces. Raises InputError if it encounters a macro it - doesn't understand. - - Note that BibTeX's internal understanding of accented characters - (e.g., purify$ and change.case$) is much more limited than TeX's. - This implements something closer to TeX on the assumption that the - goal is to display the string. - """ - - return TeXToUnicode().process(string, pos) diff --git a/biblib/bib.py b/biblib/bib.py deleted file mode 100644 index 117b8fd..0000000 --- a/biblib/bib.py +++ /dev/null @@ -1,496 +0,0 @@ -"""Parser and representation for BibTeX .bib databases. - -This parser is derived directly from the WEB source code for BibTeX -- -especially section "Reading the database file(s)" -- and hence -(barring bugs in translation) should be fully compatible with BibTeX's -own parser. -""" - -__all__ = 'Parser Entry FieldError resolve_crossrefs'.split() - -import sys -import re -import collections -from collections.abc import Iterable - -from . import messages - -# Match sequences of legal identifier characters, except that the -# first is not allowed to be a digit (see id_class) -ID_RE = re.compile('(?![0-9])(?:(?![ \t"#%\'(),={}])[\x20-\x7f])+') -# BibTeX only considers space, tab, and newline to be white space (see -# lex_class) -SPACE_RE = re.compile('[ \t\n]*') - -class ParseError(Exception): - pass - -class Parser: - """A parser for .bib BibTeX database files.""" - - def __init__(self, *, month_style='full'): - """Initialize an empty database. - - This also initializes standard month macros (which are usually - provided by the style file). month_style may be 'full' to get - full names, 'abbrv' to get abbrv.bst-style abbreviated names, - or None to not initialize month macros. - - The database should be populated by calling parse one or more - times. The final contents of the database can be retrieved by - calling finalize. - """ - - self.__log, self.__errors = [], False - self.__entries = collections.OrderedDict() - - if month_style == 'full': - self.__macros = {'jan': 'January', 'feb': 'February', - 'mar': 'March', 'apr': 'April', - 'may': 'May', 'jun': 'June', - 'jul': 'July', 'aug': 'August', - 'sep': 'September', 'oct': 'October', - 'nov': 'November', 'dec': 'December'} - elif month_style == 'abbrv': - self.__macros = {'jan': 'Jan.', 'feb': 'Feb.', - 'mar': 'Mar.', 'apr': 'Apr.', - 'may': 'May', 'jun': 'June', - 'jul': 'July', 'aug': 'Aug.', - 'sep': 'Sept.', 'oct': 'Oct.', - 'nov': 'Nov.', 'dec': 'Dec.'} - elif month_style == None: - self.__macros = {} - else: - raise ValueError('Unknown month style {}'.format(month_style)) - - def string(self, name, value): - """Declare a macro, just like an @string command.""" - self.__macros[name] = value - - def parse(self, str_or_fp_or_iter, name=None, *, log_fp=None): - """Parse the contents of str_or_fp_or_iter and return self. - - str_or_fp_or_iter must be a string, a file-like object, or an - iterable of string or file-like objects to parse in - succession. If name is not None, it is used as the file name. - Otherwise, a name is constructed in a type-appropriate way. - - If log_fp is not None, it must be a file-local object to which - warnings and InputErrors will be logged. This logger will be - attached to all Pos instances created from the file being - parsed, so any warnings or InputErrors raised from later - operations on derived objects (like entries or field values) - will also be logged to log_fp. - - If there are any errors in the input, raises a (potentially - bundled) InputError. - - Parse can be called multiple times to parse subsequent .bib - files. Later files will have access to, for example, strings - defined in earlier files. - """ - - recoverer = messages.InputErrorRecoverer() - if isinstance(str_or_fp_or_iter, str): - self.__data = str_or_fp_or_iter - fname = name or '' - elif isinstance(str_or_fp_or_iter, Iterable) and \ - not hasattr(str_or_fp_or_iter, 'read'): - for obj in str_or_fp_or_iter: - with recoverer: - self.parse(obj, name=name, log_fp=log_fp) - recoverer.reraise() - return self - else: - self.__data = str_or_fp_or_iter.read() - try: - fname = name or str_or_fp_or_iter.name - except AttributeError: - fname = '' - self.__off = 0 - - # Remove trailing whitespace from lines in data (see input_ln - # in bibtex.web) - self.__data = re.sub('[ \t]+$', '', self.__data, flags=re.MULTILINE) - self.__pos_factory = messages.PosFactory(fname, self.__data, log_fp) - - # Parse entries - while self.__off < len(self.__data): - # Just continue to the next entry if there's an error - with recoverer: - self._scan_command_or_entry() - recoverer.reraise() - return self - - def get_entries(self): - """Return the entry database. - - The database is an ordered dictionary mapping from lower-cased - keys to Entry objects. - """ - return self.__entries - - def _fail(self, msg, off=None): - if off is None: - off = self.__off - self.__pos_factory.offset_to_pos(off).raise_error(msg) - - def _warn(self, msg, off=None): - if off is None: - off = self.__off - self.__pos_factory.offset_to_pos(off).warn(msg) - - # Base parsers. These are the only methods that directly - # manipulate self.__data. - - def _try_tok(self, regexp, skip_space=True): - """Scan regexp followed by white space. - - Returns the matched text, or None if the match failed.""" - if isinstance(regexp, str): - regexp = re.compile(regexp) - m = regexp.match(self.__data, self.__off) - if m is None: - return None - self.__off = m.end() - if skip_space: - self._skip_space() - return m.group(0) - - def _scan_balanced_text(self, term): - """Scan brace-balanced text terminated with character term.""" - start, level = self.__off, 0 - while self.__off < len(self.__data): - char = self.__data[self.__off] - if level == 0 and char == term: - text = self.__data[start:self.__off] - self.__off += 1 - self._skip_space() - return text - elif char == '{': - level += 1 - elif char == '}': - level -= 1 - if level < 0: - self._fail('unexpected }') - self.__off += 1 - self._fail('unterminated string') - - def _skip_space(self): - # This is equivalent to eat_bib_white_space, except that we do - # it automatically after every token, whereas bibtex carefully - # and explicitly does it between every token. - self.__off = SPACE_RE.match(self.__data, self.__off).end() - - # Helpers - - def _tok(self, regexp, fail=None): - """Scan token regexp or fail with the given message.""" - res = self._try_tok(regexp) - if res is None: - assert fail - self._fail(fail) - return res - - # Productions - - def _scan_identifier(self): - return self._tok(ID_RE, 'expected identifier') - - def _scan_command_or_entry(self): - # See get_bib_command_or_entry_and_process - - # Skip to the next database entry or command - self._tok('[^@]*') - pos = self.__pos_factory.offset_to_pos(self.__off) - if not self._try_tok('@'): - return None - - # Scan command or entry type - typ = self._scan_identifier().lower() - - if typ == 'comment': - # Believe it or not, BibTeX doesn't do anything with what - # comes after an @comment, treating it like any other - # inter-entry noise. - return None - - left = self._tok('[{(]', 'expected { or ( after entry type') - right, right_re = (')', '\\)') if left == '(' else ('}', '}') - - if typ == 'preamble': - # Parse the preamble, but ignore it - self._scan_field_value() - self._tok(right_re, 'expected '+right) - return None - - if typ == 'string': - name = self._scan_identifier().lower() - if name in self.__macros: - self._warn('macro `{}\' redefined'.format(name)) - self._tok('=', 'expected = after string name') - value = self._scan_field_value() - self._tok(right_re, 'expected '+right) - self.__macros[name] = value - return None - - # Not a command, must be a database entry - - # Scan the entry's database key - if left == '(': - # The database key is anything up to a comma, white - # space, or end-of-line (yes, the key can be empty, - # and it can include a close paren) - key = self._tok('[^, \t\n]*') - else: - # The database key is anything up to comma, white - # space, right brace, or end-of-line - key = self._tok('[^, \t}\n]*') - - # Scan entries (starting with comma or close after key) - fields = [] - field_pos = {} - while True: - if self._try_tok(right_re): - break - self._tok(',', 'expected {} or ,'.format(right)) - if self._try_tok(right_re): - break - - # Scan field name and value - field_off = self.__off - field = self._scan_identifier().lower() - self._tok('=', 'expected = after field name') - value = self._scan_field_value() - - if field in field_pos: - pos.warn('repeated field `{}\''.format(field)) - continue - - fields.append((field, value)) - field_pos[field] = self.__pos_factory.offset_to_pos(field_off) - - #if key.lower() in self.__entries: - # self._fail('repeated entry') - self.__entries[key.lower()] = Entry(fields, typ, key, pos, field_pos) - - def _scan_field_value(self): - # See scan_and_store_the_field_value_and_eat_white - value = self._scan_field_piece() - while self._try_tok('#'): - value += self._scan_field_piece() - # Compress spaces in the text. Bibtex does this - # (painstakingly) as it goes, but the final effect is the same - # (see check_for_and_compress_bib_white_space). - value = re.sub('[ \t\n]+', ' ', value) - # Strip leading and trailing space (literally just space, see - # @) - return value.strip(' ') - - def _scan_field_piece(self): - # See scan_a_field_token_and_eat_white - piece = self._try_tok('[0-9]+') - if piece is not None: - return piece - if self._try_tok('{', skip_space=False): - return self._scan_balanced_text('}') - if self._try_tok('"', skip_space=False): - return self._scan_balanced_text('"') - opos = self.__off - piece = self._try_tok(ID_RE) - if piece is not None: - if piece.lower() not in self.__macros: - self._warn('unknown macro `{}\''.format(piece), opos) - return '' - return self.__macros[piece.lower()] - self._fail('expected string, number, or macro name') - -class FieldError(KeyError): - def __init__(self, field, entry=None): - super().__init__(field) - self.__entry = entry - - def __str__(self): - return '{}: missing field `{}\''.format(self.__entry, self.args[0]) - -MONTH_MACROS = 'jan feb mar apr may jun jul aug sep oct nov dec'.split() - -class Entry(collections.OrderedDict): - """An entry in a BibTeX database. - - This is an ordered dictionary of fields, plus some additional - properties: typ gives the type of the entry, such as "journal", - canonicalized to lower case. key gives the database entry key - (case is preserved, but should be ignored for comparisons). pos - is a messages.Pos instance giving the position of this entry in - the database file. field_pos is a simple dictionary from field - names to message.Pos instances. - - Field values are as they would be seen by a .bst file: white space - is cleaned up, but they retain macros, BibTeX-style accents, etc. - Use algo.tex_to_unicode to interpret field values to user-friendly - Unicode strings. - """ - - def __init__(self, fields, typ=None, key=None, pos=None, field_pos=None): - super().__init__(fields) - self.typ, self.key, self.pos, self.field_pos = typ, key, pos, field_pos - - def copy(self): - return self.__class__(self, self.typ, self.key, self.pos, self.field_pos) - - def __str__(self): - return '`{}\' at {}'.format(self.key, self.pos) - - def __getitem__(self, field): - try: - return super().__getitem__(field) - except KeyError: - raise FieldError(field, self) from None - - def __eq__(self, o): - """Two Entries are equal if they have the same fields, type, and key.""" - return super().__eq__(o) and self.typ == o.typ and self.key == o.key - - def to_bib(self, *, month_to_macro=True, wrap_width=70): - """Return this entry formatted as a BibTeX .bib entry. - - If month_to_macro is True, attempt to parse month names and - replace them with their standard macro. - - If wrap_width is not None, word wrap the entry at this many - columns (long words and hyphens are not split). - """ - - lines = ['@%s{%s,' % (self.typ, self.key)] - for k, v in self.items(): - start = ' {:12} = '.format(k) - - if month_to_macro and k == 'month': - try: - macro = MONTH_MACROS[self.month_num() - 1] - except messages.InputError: - pass - else: - lines.append(start + macro + ',') - continue - - if v.isdigit(): - lines.append(start + v + ',') - elif wrap_width is None: - lines.append(start + '{' + v + '},') - else: - lines.append(textwrap.fill( - v, width=wrap_width, - # Keep whitespace formatting as it is - expand_tabs=False, replace_whitespace=False, - # Don't break long things like URLs - break_long_words=False, break_on_hyphens=False, - initial_indent=start + '{', subsequent_indent=' ') + '},') - lines.append('}') - return '\n'.join(lines) - - def resolve_crossref(self, entries): - """Return a new entry with crossref-ed fields incorporated. - - entries must be the database in which to find any crossref-ed - database entries. - """ - if 'crossref' not in self: - return self - nentry = self.copy() - source = entries[self['crossref'].lower()] - if 'crossref' in source: - self.field_pos['crossref'].warn('nested crossref') - for k, v in source.items(): - if k not in nentry: - nentry[k] = v - nentry.field_pos[k] = source.field_pos[k] - del nentry['crossref'] - return nentry - - def date_key(self): - """Return a sort key appropriate for sorting by date. - - Returns a tuple ([year, [month]]) where year and month are - numeric. Raises InputError if the entry has year and/or month - fields, but they are malformed. - """ - - key = () - year, month = self.get('year'), self.get('month') - if year is not None: - if not year.isdigit(): - self.field_pos['year'].raise_error( - 'invalid year `{}\''.format(year)) - key += (int(year),) - if month is not None: - if year is None: - self.field_pos['month'].raise_error('month without year') - key += (self.month_num(),) - return key - - def authors(self, field='author'): - """Return a list of parsed author names. - - This is a wrapper for biblib.algo.parse_names. - """ - from .algo import parse_names - return parse_names(self[field], self.field_pos[field]) - - def month_num(self, field='month'): - """Convert the month of this entry into a number in [1,12]. - - This is a wrapper for biblib.algo.parse_month (which see). - - Raises KeyError if this entry does not have the specified - field and InputError if the field cannot be parsed. - """ - from .algo import parse_month - return parse_month(self[field], pos=self.field_pos[field]) - -def resolve_crossrefs(db, min_crossrefs=None): - """Resolve cross-referenced entries in db. - - This returns a new database containing the same entries in the - same order as db, but any entries that crossref another entry are - expanded with the fields for the cross-referenced entry. - - If min_crossrefs is not None, then any entry that is - cross-referenced by min_crossrefs or more other entries will *not* - be expanded and entries that cross-reference it will retain their - crossref field. If min_crossrefs is None, entries are always - expanded. (This mimics BibTeX "-min-crossrefs" option.) - - If there are unknown crossrefs, raises a (potentially bundled) - InputError. - """ - if min_crossrefs is not None: - counts = collections.Counter(entry['crossref'].lower() - for entry in db.values() - if 'crossref' in entry) - else: - counts = None - - key_idx = {k: i for i, k in enumerate(db)} - recoverer = messages.InputErrorRecoverer() - ndb = collections.OrderedDict() - for entry_idx, (key, entry) in enumerate(db.items()): - crossref = entry.get('crossref') - if crossref is None: - ndb[key] = entry - else: - with recoverer: - crossref_idx = key_idx.get(crossref.lower()) - if crossref_idx is None: - entry.field_pos['crossref'].raise_error( - 'unknown crossref `{}\''.format(crossref)) - elif crossref_idx < entry_idx: - entry.field_pos['crossref'].raise_error( - 'crossref `{}\' must come after entry'.format(crossref)) - elif counts and counts[crossref.lower()] >= min_crossrefs: - ndb[key] = entry - else: - ndb[key] = entry.resolve_crossref(db) - recoverer.reraise() - return ndb diff --git a/biblib/messages.py b/biblib/messages.py deleted file mode 100644 index 2cae7cb..0000000 --- a/biblib/messages.py +++ /dev/null @@ -1,126 +0,0 @@ -import collections -import threading -import warnings - -class Pos(collections.namedtuple('Pos', 'fname line col log_fp')): - """A position in a file. - - This also optionally tracks a file-like object for logging - warnings and errors associated with this file. - """ - - def __str__(self): - return '{}:{}:{}'.format(self.fname, self.line, self.col) - - def warn(self, msg): - """Log msg to this Pos's logger. - - If log_fp is None, the warning is silently discarded. - """ - if self.log_fp is not None: - self.log_fp.write('{}: warning: {}\n'.format(self, msg)) - - def raise_error(self, msg): - """Log and raise InputError([(self, msg)]).""" - if self.log_fp is not None: - self.log_fp.write('{}: error: {}\n'.format(self, msg)) - raise InputError([(self, msg)]) - -Pos.unknown = Pos('', 1, 0, None) - -class PosFactory: - """A factory that translates character offsets to Pos instances.""" - - def __init__(self, fname, string, log_fp=None): - self.__fname = fname - self.__string = string - self.__log_fp = log_fp - self.__cache = (0, 1, 0) - - def offset_to_pos(self, offset): - last_off, last_line, last_col = self.__cache - if last_off < offset: - last_off, last_line, last_col = 0, 1, 0 - - line = self.__string.count('\n', last_off, offset) + last_line - lastnl = self.__string.rfind('\n', last_off, offset) - if lastnl == -1: - col = last_col + (offset - last_off) - else: - col = offset - lastnl - 1 - self.__cache = (offset, line, col) - - return Pos(self.__fname, line, col, self.__log_fp) - -class InputError(ValueError): - """One or more errors with associated Pos instances. - - An InputError representing multiple errors is a "bundled" error. - These can be created when recovering from errors with an - InputErrorRecoverer. - """ - - def __init__(self, list_of_pos_msg): - super().__init__(list_of_pos_msg) - - def __str__(self): - list_of_msg_pos = self.args[0] - if len(list_of_msg_pos) == 1: - return '1 error' - return '{} errors'.format(len(list_of_msg_pos)) - -class InputErrorRecoverer: - """A context manager for recovering from and bundling InputErrors. - - This context manager catches and collects InputErrors, effectively - recovering from InputErrors at the end of the with block. An - InputErrorRecoverer can be used several times, after which - collected errors can be re-raised as a bundled InputError. For - example, a caller that wishes to parse several files without - stopping because of an error in one file can do something like - this: - - recoverer = InputErrorRecoverer() - for filename in filenames: - with recoverer: - parse(filename) - recoverer.reraise() - - An InputErrorRecoverer *must* be either reraised or disposed (even - if no errors occurred). Otherwise a UserWarning will be issued. - """ - - def __init__(self): - self.__errors = [] - - def __enter__(self): - return None - - def __exit__(self, exc_type, exc_value, traceback): - if self.__errors is None: - raise ValueError('InputErrorRecoverer already disposed') - if isinstance(exc_value, InputError): - self.__errors.extend(exc_value.args) - return True - - def __del__(self): - if self.__errors is not None: - try: - warnings.warn('InputErrorRecoverer must be reraised or disposed', - stacklevel=2) - except TypeError as e: - # If Python is exiting, warnings.warn has a habit of - # raising TypeError("'NoneType' object is not - # iterable",). Ignore it. - pass - - def reraise(self): - """If any errors have been collected, raise a bundled InputError.""" - errors = self.__errors - self.dispose() - if errors: - raise InputError(errors) - - def dispose(self): - """Discard all collected errors.""" - self.__errors = None diff --git a/biblib/test.py b/biblib/test.py deleted file mode 100644 index 714d89a..0000000 --- a/biblib/test.py +++ /dev/null @@ -1,327 +0,0 @@ -import unittest -import collections -import io -from .bib import * -from .algo import * -from .messages import * -from . import algo - -def od(*args): - return collections.OrderedDict(zip(args[::2], args[1::2])) - -def ent(typ, key, fields): - return Entry(fields, typ, key) - -class BibParserTest(unittest.TestCase): - def __test_parse(self, string, ents): - # Parse string and get entries - got = list(Parser().parse(string).get_entries().values()) - self.assertEqual(got, ents) - - def test_basic(self): - self.__test_parse( - '@misc{x, title="title", author={author}}\n@misc{y, title=123,}', - [ent('misc', 'x', od('title', 'title', - 'author', 'author')), - ent('misc', 'y', od('title', '123'))]) - - def test_balanced(self): - self.__test_parse( - '@misc{x, title={a{b}c}, author="x{y}z"}', - [ent('misc', 'x', od('title', 'a{b}c', - 'author', 'x{y}z'))]) - - def test_whitespace(self): - self.__test_parse( - ' @ misc { x , title = {a} , }', - [ent('misc', 'x', od('title', 'a'))]) - - def test_compress(self): - self.__test_parse( - '@misc{x, title={ a\t b\n c }}', - [ent('misc', 'x', od('title', 'a b c'))]) - - def test_funny_keys(self): - self.__test_parse( - '@misc{@"#%\'()=, title="a"}', - [ent('misc', '@"#%\'()=', od('title', 'a'))]) - for string in ['@misc{}', '@misc{,}', '@misc{\n}']: - self.__test_parse(string, [ent('misc', '', od())]) - self.__test_parse( - '@misc{,title="a"}', - [ent('misc', '', od('title', 'a'))]) - self.__test_parse( - '@misc(k)ey, title="a")\n@misc{k{ey, title="a"}', - [ent('misc', 'k)ey', od('title', 'a')), - ent('misc', 'k{ey', od('title', 'a'))]) - - def test_string(self): - self.__test_parse( - '@string{foo = {a}}\n@misc{x, title = foo # "b" # foo # 2}', - [ent('misc', 'x', od('title', 'aba2'))]) - - def test_comment(self): - self.__test_parse( - # Braces intentionally unbalanced, everything on one line - '@comment{abc@misc{x}', - [ent('misc', 'x', od())]) - -class EntryTest(unittest.TestCase): - def test_to_bib(self): - entry = Entry([('author', 'An Author'), - ('title', 'This is a ' + 'really '*10 + 'long title'), - ('month', 'November'), ('year', '2013')], - typ='misc', key='key', field_pos={'month': Pos.unknown}) - self.assertEqual( - entry.to_bib(), - '''\ -@misc{key, - author = {An Author}, - title = {This is a really really really really really really - really really really really long title}, - month = nov, - year = 2013, -}''') - self.assertEqual( - entry.to_bib(month_to_macro=False, wrap_width=None), - '''\ -@misc{key, - author = {An Author}, - title = {This is a really really really really really really really really really really long title}, - month = {November}, - year = 2013, -}''') - - def test_month_num(self): - def test(string, expect): - entry = Entry([('month', string)], field_pos={'month': Pos.unknown}) - self.assertEqual(entry.month_num(), expect) - for i, name in enumerate(['Jan.','Feb.','Mar.','Apr.','May','June', - 'July','Aug.','Sept.','Oct.','Nov.','Dec.']): - test(name, i+1) - for i, name in enumerate(['January','February','March','April', - 'May','June','July','August', - 'September','October','November','December']): - test(name, i+1) - self.assertRaises(InputError, test, 'Foo', None) - self.assertRaises(InputError, test, 'Janruary', None) - - def test_date_key(self): - def test(year, month, expect): - fields = [] - if year: fields.append(('year', year)) - if month: fields.append(('month', month)) - entry = Entry(fields, field_pos={'year' : Pos.unknown, - 'month' : Pos.unknown}) - got = entry.date_key() - if expect is not None: - self.assertEqual(got, expect) - test(None, None, ()) - test('2013', None, (2013,)) - test('2013', 'jan', (2013, 1)) - self.assertRaises(InputError, test, 'x', None, None) - self.assertRaises(InputError, test, None, 'jan', None) - self.assertRaises(InputError, test, '2013', 'foo', None) - -class CrossRefTest(unittest.TestCase): - def setUp(self): - self.parser = Parser().parse("""\ - @misc{ent1, title={Title 1}, crossref={ent2}} - @misc{ent2, title={Title 2}, booktitle={Book title 2}}""") - - def test_basic(self): - db = resolve_crossrefs(self.parser.get_entries()) - self.assertEqual( - [('ent1', ent('misc', 'ent1', [('title', 'Title 1'), - ('booktitle', 'Book title 2')])), - ('ent2', ent('misc', 'ent2', [('title', 'Title 2'), - ('booktitle', 'Book title 2')]))], - list(db.items())) - - def test_min_crossrefs(self): - db = resolve_crossrefs(self.parser.get_entries(), min_crossrefs=1) - self.assertEqual( - [('ent1', ent('misc', 'ent1', [('title', 'Title 1'), - ('crossref', 'ent2')])), - ('ent2', ent('misc', 'ent2', [('title', 'Title 2'), - ('booktitle', 'Book title 2')]))], - list(db.items())) - - db = resolve_crossrefs(self.parser.get_entries(), min_crossrefs=2) - self.assertEqual( - [('ent1', ent('misc', 'ent1', [('title', 'Title 1'), - ('booktitle', 'Book title 2')])), - ('ent2', ent('misc', 'ent2', [('title', 'Title 2'), - ('booktitle', 'Book title 2')]))], - list(db.items())) - - def test_self_crossref(self): - # This is accepted, believe it or not (though BibTeX warns) - log = io.StringIO() - self.parser.parse("@misc{ent3, title={Title 3}, crossref={ent3}}", - name='', log_fp=log) - resolve_crossrefs(self.parser.get_entries()) - self.assertIn(':1:', log.getvalue()) - - def test_bad_order(self): - self.parser.parse("""\ - @misc{ent3, title={Title 3}, crossref={ent2}}""") - with self.assertRaises(InputError) as ar: - resolve_crossrefs(self.parser.get_entries()) - self.assertEqual(1, len(ar.exception.args[0])) - -class NameParserTest(unittest.TestCase): - def test_first_char(self): - p = algo.NameParser() - for check, expect in [('abc', 'a'), ('ABC', 'A'), (' abc', 'a'), - ('\\abc', 'a'), ('{a} bc', 'b'), - ('{\\`a}bc', 'a'), ('{\\aa}bc', 'å'), - ('{\\a}bc', 'a')]: - self.assertEqual(p._first_char(check), expect) - - def test_and(self): - p = parse_names - self.assertEqual(p('A B and C D'), - [Name('A', '', 'B', ''), Name('C', '', 'D', '')]) - self.assertEqual(p('A B AND C D'), - [Name('A', '', 'B', ''), Name('C', '', 'D', '')]) - self.assertEqual(p('A B and and C D'), - [Name('A', '', 'B', ''), Name('', '', '', ''), - Name('C', '', 'D', '')]) - self.assertEqual(p('A B and and'), - [Name('A', '', 'B', ''), Name('', '', 'and', '')]) - self.assertEqual(p('A B { and } C D'), - [Name('A B { and } C', '', 'D', '')]) - self.assertEqual(p('A B {\\ and } C D'), - [Name('A B', '{\\ and }', 'C D', '')]) - - def __test_names(self, *tests): - for test in tests: - if len(test) == 4: - test = test + ('',) - names = parse_names(test[0]) - self.assertEqual(names, [Name(*test[1:])], - 'parsing {!r}'.format(test[0])) - - def test_first_von_last(self): - # Examples mostly from Nicolas Markey's Tame the BeaST - self.__test_names( - ('jean de la fontaine', '', 'jean de la', 'fontaine'), - ('Jean de la fontaine', 'Jean', 'de la', 'fontaine'), - ('Jean De La fontaine', 'Jean De La', '', 'fontaine'), - ('Jean {de} la fontaine', 'Jean {de}', 'la', 'fontaine'), - ('jean {de} {la} fontaine', '', 'jean', '{de} {la} fontaine'), - ('Jean {de} {la} fontaine', 'Jean {de} {la}', '', 'fontaine'), - ('Jean De La Fontaine', 'Jean De La', '', 'Fontaine'), - ('jean De la Fontaine', '', 'jean De la', 'Fontaine'), - ('Jean de La Fontaine', 'Jean', 'de', 'La Fontaine'), - ('Jean-Baptiste Poquelin', 'Jean-Baptiste', '', 'Poquelin'), - ('Jean-Baptiste-Poquelin', '', '', 'Jean-Baptiste-Poquelin'), - ('Jean- Baptiste-Poquelin', '', '', 'Jean-Baptiste-Poquelin'), - ('Jean Baptiste Poquelin', 'Jean Baptiste', '', 'Poquelin'), - ('Jean Baptiste-Poquelin', 'Jean', '', 'Baptiste-Poquelin'), - ('Jean Baptiste~Poquelin', 'Jean Baptiste', '', 'Poquelin'), - ('Jean-baptiste Poquelin', 'Jean', 'baptiste', 'Poquelin')) - - def test_von_last_first(self): - self.__test_names( - ('de la fontaine, Jean', 'Jean', 'de la', 'fontaine'), - ('De La Fontaine, Jean', 'Jean', '', 'De La Fontaine'), - ('De la Fontaine, Jean', 'Jean', 'De la', 'Fontaine'), - ('de La Fontaine, Jean', 'Jean', 'de', 'La Fontaine'), - ('{D}e {L}a Cruz, Maria', 'Maria', '{D}e {L}a', 'Cruz')) - - def test_von_last_jr_first(self): - self.__test_names( - ('de la fontaine, Jean, Jr', 'Jean', 'de la', 'fontaine', 'Jr'), - ('De La Fontaine, Jean, Jr', 'Jean', '', 'De La Fontaine', 'Jr'), - ('De la Fontaine, Jean, Jr', 'Jean', 'De la', 'Fontaine', 'Jr'), - ('de La Fontaine, Jean, Jr', 'Jean', 'de', 'La Fontaine', 'Jr')) - -class NamePrettyTest(unittest.TestCase): - def __test(self, template, gen): - for i in range(0x10): - name = Name('f' if i & 1 else '', - 'v' if i & 2 else '', - 'l' if i & 4 else '', - 'j' if i & 8 else '') - got = name.pretty(template) - self.assertEqual(gen(name), got) - - def __clean(self, string): - import re - string = re.sub(' +', ' ', string) - string = re.sub(' *(, )+', ', ', string) - return string.strip(' ,') - - def test_basic(self): - self.__test( - '{first}{von}{jr}{last}', - lambda n: n.first+n.von+n.jr+n.last) - self.__test( - '{first} {von} {last} {jr}', - lambda n: self.__clean(' '.join([n.first, n.von, n.last, n.jr]))) - self.__test( - '{von} {last}, {first}', - lambda n: self.__clean('{0.von} {0.last}, {0.first}'.format(n))) - self.__test( - '{von} {last}, {first}, {jr}', - lambda n: self.__clean('{0.von} {0.last}, {0.first}, {0.jr}'.format(n))) - - def test_before_and_after(self): - self.__test( - 'a{first}{von}{jr}{last}b', - lambda n: 'a'+n.first+n.von+n.jr+n.last+'b') - self.__test( - 'a{first} {von} {last} {jr}b', - lambda n: 'a'+self.__clean(' '.join([n.first, n.von, n.last, n.jr]))+'b') - -class CaseTest(unittest.TestCase): - def __test(self, *tests): - for string, want in tests: - self.assertEqual(title_case(string), want, - 'title-casing {!r}'.format(string)) - - def test_basic(self): - self.__test( - ('ABC DEF', 'Abc def'), - ('abc def', 'abc def'), - ('ABC {DEF} GHI', 'Abc {DEF} ghi'), - ('ABC D{E}F GHI', 'Abc d{E}f ghi')) - - def test_colons(self): - self.__test( - ('ABC DEF: GHI JKL', 'Abc def: Ghi jkl'), - ('ABC DEF: GHI JKL', 'Abc def: Ghi jkl'), - ('ABC DEF:GHI JKL', 'Abc def:ghi jkl')) - - def test_special(self): - self.__test( - # Brace groups beginning with special characters are - # lower-cased throughout, even under deeper braces - (r'x {\AE X {X \AE}}', r'x {\ae x {x \ae}}'), - # Unknown control sequences also trigger brace group - # lower-casing, but are themselves left alone - (r'x {\LaTeX X {X} \AE \LaTeX}', r'x {\LaTeX x {x} \ae \LaTeX}'), - # Special characters are only interpreted at level 1 - (r'x {{\AE}}', r'x {{\AE}}'), - # If a brace group does not start with a slash, it doesn't - # get touched. - (r'x {AE X \AE}', r'x {AE X \AE}'), - # Special characters that start at position 0 or after a - # colon are untouched - (r'{\AE X {X} \AE} X', r'{\AE X {X} \AE} x'), - (r'X: {\AE X {X} \AE}', r'X: {\AE X {X} \AE}'), - (r'X:{\ae x {x} \ae}', r'X:{\ae x {x} \ae}')) - -class TeXToUnicodeTest(unittest.TestCase): - def test_simple(self): - self.assertEqual(tex_to_unicode(r'~\%\&\#\$'), '\u00A0%&#$') - self.assertEqual(tex_to_unicode(r'x\ss y\i'), 'xßyı') - - def test_accents(self): - self.assertEqual(tex_to_unicode(r'{\`a}\^{e}'), 'àê') - self.assertEqual(tex_to_unicode(r'\`i\`\i'), 'ìì') - - def test_ligatures(self): - self.assertEqual(tex_to_unicode(r'a--b---c-{-}d'), 'a\u2013b\u2014c--d') diff --git a/components/navigation.jsx b/components/navigation.jsx new file mode 100644 index 0000000..81979a7 --- /dev/null +++ b/components/navigation.jsx @@ -0,0 +1,8 @@ +'use client'; +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +const links = [['/', 'Home'], ['/team/', 'Team'], ['/publications/', 'Publications'], ['/news/', 'News'], ['/join/', 'Open positions']]; +export default function Navigation() { + const pathname = usePathname(); + return ; +} diff --git a/components/page-heading.jsx b/components/page-heading.jsx new file mode 100644 index 0000000..39002b4 --- /dev/null +++ b/components/page-heading.jsx @@ -0,0 +1,3 @@ +export default function PageHeading({ eyebrow, title, children }) { + return
{eyebrow &&
{eyebrow}
}

{title}

{children &&

{children}

}
; +} diff --git a/components/paper-card.jsx b/components/paper-card.jsx new file mode 100644 index 0000000..77778b8 --- /dev/null +++ b/components/paper-card.jsx @@ -0,0 +1,13 @@ +import Link from 'next/link'; +export default function PaperCard({ paper, featured = false }) { + return
+ {featured && {paper.image ? : {paper.year}}} +
{paper.year} · {paper.venue || 'Publication'}
+

{paper.title}

+

{paper.authorNames?.join(', ') || paper.authors}

+ {paper.award &&

{paper.award}

} + {featured && paper.description &&

{paper.description}

} +
Read more{paper.pdf && PDF}
+
+
; +} diff --git a/components/publication-explorer.jsx b/components/publication-explorer.jsx new file mode 100644 index 0000000..908028a --- /dev/null +++ b/components/publication-explorer.jsx @@ -0,0 +1,17 @@ +'use client'; +import { useMemo, useState } from 'react'; +import { filterPapers } from '@/lib/publications.mjs'; +import PaperCard from './paper-card'; +export default function PublicationExplorer({ papers, people }) { + const [query, setQuery] = useState(''); + const [year, setYear] = useState(''); + const [author, setAuthor] = useState(''); + const [awardsOnly, setAwardsOnly] = useState(false); + const years = [...new Set(papers.map(p => p.year))].sort((a,b) => b-a); + const results = useMemo(() => filterPapers(papers, { query, year, author, awardsOnly }), [papers, query, year, author, awardsOnly]); + const reset = () => { setQuery(''); setYear(''); setAuthor(''); setAwardsOnly(false); }; + return <>
+

{results.length} {results.length === 1 ? 'publication' : 'publications'}

+ {results.length ?
{results.map(p => )}
:

No matching publications

} + ; +} diff --git a/content/alumni.json b/content/alumni.json new file mode 100644 index 0000000..b89958c --- /dev/null +++ b/content/alumni.json @@ -0,0 +1,49 @@ +[ + { + "name": "Mike Merrill, PhD Student", + "site": "https://mikemerrill.io" + }, + { + "name": "Chris Rytting, Postdoc", + "site": "https://chrisrytting.github.io/" + }, + { + "name": "Ashish Sharma, PhD Student", + "site": "https://ash-shar.github.io/" + }, + { + "name": "Vinayak Gupta, Postdoc", + "site": "https://gvinayak.github.io/" + }, + { + "name": "Antonia Saravanou, Visiting Researcher", + "site": "https://antonia42.github.io/" + }, + { + "name": "Bret Nestor, Postdoc", + "site": "http://www.cs.toronto.edu/~bretnestor/" + }, + { + "name": "Jina Suh, PhD Student, Fall 2018 - Winter 2023", + "site": "https://www.microsoft.com/en-us/research/people/jinsuh/" + }, + { + "name": "Jacopo Mocellin, Visiting Master's Student, Spring 2022" + }, + { + "name": "Ethan Hsu, Visiting Master's Student, Summer 2021 - Winter 2022", + "site": "https://ethan5437.github.io/" + }, + { + "name": "Joy He-Yueya, Bachelor's Student Research Assistant, Fall 2019 - Spring 2021", + "site": "https://joyheyueya.github.io/" + }, + { + "name": "Remy Deshayes, Visiting Master's Student, Summer 2020 - Fall 2020", + "site": "https://remydeshayes.github.io/" + }, + { + "name": "Ge Zhang, Visiting Bachelor's Student, Fall 2019 - Fall 2020", + "site": "https://gezhangrp.com/" + } +] diff --git a/content/news.json b/content/news.json new file mode 100644 index 0000000..982279a --- /dev/null +++ b/content/news.json @@ -0,0 +1,17 @@ +[ + { + "date": "2021-06-10", + "headline": "Tim, Inna, Ashish, and Galen win 4 Best Paper awards at WWW, ICWSM, and NLP4IF!", + "id": "news-2" + }, + { + "date": "2020-11-02", + "headline": "Our fancy site is live!", + "id": "news-3" + }, + { + "date": "2020-09-02", + "headline": "Welcome to our new PhD Students Inna and Ken!", + "id": "news-1" + } +] diff --git a/content/people.json b/content/people.json new file mode 100644 index 0000000..f4ebf94 --- /dev/null +++ b/content/people.json @@ -0,0 +1,472 @@ +[ + { + "id": "advaitbhat", + "name": "Advait Bhat", + "role": "PhD Student", + "website": "https://advaitmb.com/", + "image": "/resources/headshots/advait.jpeg", + "status": "member", + "priority": 5, + "topics": [ + "Human-AI Interaction", + "Human-Computer Interaction", + "Natural Language Processing", + "Computational Social Science" + ], + "legacy": { + "headshot": "advait.jpeg", + "is_visiting": false, + "name": "Advait Bhat", + "priority": 5, + "research_areas": [ + "Human-AI Interaction", + "Human-Computer Interaction", + "Natural Language Processing", + "Computational Social Science" + ], + "site": "https://advaitmb.com/", + "title": "PhD Student" + } + }, + { + "id": "antoniasaravanou", + "name": "Antonia Saravanou", + "role": "Visiting Researcher", + "website": "https://antonia42.github.io/", + "image": "/resources/headshots/antoniasaravanou.jpg", + "status": "alumni", + "priority": 5, + "topics": [], + "legacy": { + "headshot": "antoniasaravanou.jpg", + "is_visiting": false, + "name": "Antonia Saravanou", + "priority": 5, + "research_areas": null, + "site": "https://antonia42.github.io/", + "title": "Visiting Researcher", + "inactive": true + } + }, + { + "id": "ashishsharma", + "name": "Ashish Sharma", + "role": "PhD Student", + "website": "https://ash-shar.github.io/", + "image": "/resources/headshots/ashishsharma.png", + "status": "alumni", + "priority": 5, + "topics": [ + "NLP", + "Computational Social Science" + ], + "legacy": { + "headshot": "ashishsharma.png", + "is_visiting": false, + "name": "Ashish Sharma", + "priority": 5, + "research_areas": [ + "NLP", + "Computational Social Science" + ], + "site": "https://ash-shar.github.io/", + "title": "PhD Student", + "inactive": true + } + }, + { + "id": "bretnestor", + "name": "Bret Nestor", + "role": "Postdoc", + "website": "http://www.cs.toronto.edu/~bretnestor/", + "image": "/resources/headshots/bretnestor.jpg", + "status": "alumni", + "priority": 5, + "topics": [], + "legacy": { + "headshot": "bretnestor.jpg", + "is_visiting": false, + "name": "Bret Nestor", + "priority": 5, + "research_areas": null, + "site": "http://www.cs.toronto.edu/~bretnestor/", + "title": "Postdoc", + "inactive": true + } + }, + { + "id": "chengli", + "name": "Cheng Li", + "role": "PhD Student", + "website": "https://chengli0228.github.io/", + "image": "/resources/headshots/cl.png", + "status": "member", + "priority": 6, + "topics": [], + "legacy": { + "name": "Cheng Li", + "title": "PhD Student", + "site": "https://chengli0228.github.io/", + "headshot": "cl.png", + "research_areas": null, + "priority": 6, + "is_visiting": false + } + }, + { + "id": "deniznazarova", + "name": "Deniz Nazarova", + "role": "PhD Student", + "website": "https://gonzoden.github.io/", + "image": "/resources/headshots/deniz.jpeg", + "status": "member", + "priority": 5, + "topics": [ + "AI in Therapy", + "NLP", + "Multilingual NLP", + "AI Bias", + "HCI" + ], + "legacy": { + "headshot": "deniz.jpeg", + "is_visiting": false, + "name": "Deniz Nazarova", + "priority": 5, + "research_areas": [ + "AI in Therapy", + "NLP", + "Multilingual NLP", + "AI Bias", + "HCI" + ], + "site": "https://gonzoden.github.io/", + "title": "PhD Student" + } + }, + { + "id": "galenweld", + "name": "Galen Weld", + "role": "Postdoc", + "website": "https://galenweld.com/", + "image": "/resources/headshots/galenweld.png", + "status": "member", + "priority": 2, + "topics": [ + "causal inference", + " online communities" + ], + "legacy": { + "headshot": "galenweld.png", + "is_visiting": false, + "name": "Galen Weld", + "priority": 2, + "research_areas": [ + "causal inference", + " online communities" + ], + "site": "https://galenweld.com/", + "title": "Postdoc" + } + }, + { + "id": "innalin", + "name": "Inna Lin", + "role": "PhD Student", + "website": "https://innawy.github.io", + "image": "/resources/headshots/innalin.jpg", + "status": "member", + "priority": 4, + "topics": [], + "legacy": { + "headshot": "innalin.jpg", + "is_visiting": false, + "name": "Inna Lin", + "priority": 4, + "research_areas": null, + "site": "https://innawy.github.io", + "title": "PhD Student" + } + }, + { + "id": "jinasuh", + "name": "Jina Suh", + "role": "PhD", + "website": "https://www.microsoft.com/en-us/research/people/jinsuh/", + "image": "/resources/headshots/jinasuh.jpg", + "status": "alumni", + "priority": 4, + "topics": [ + "Human-Centered Data Science", + "Human-Centered Design", + "Human-Centered AI" + ], + "legacy": { + "headshot": "jinasuh.jpg", + "is_visiting": false, + "name": "Jina Suh", + "priority": 4, + "research_areas": [ + "Human-Centered Data Science", + "Human-Centered Design", + "Human-Centered AI" + ], + "site": "https://www.microsoft.com/en-us/research/people/jinsuh/", + "title": "PhD", + "inactive": true + } + }, + { + "id": "joyhe-yueya", + "name": "Joy He-Yueya", + "role": "Bachelor's Student", + "website": "https://joyheyueya.github.io", + "image": "/resources/headshots/joyhe-yueya.jpg", + "status": "alumni", + "priority": 8, + "topics": [], + "legacy": { + "headshot": "joyhe-yueya.jpg", + "is_visiting": false, + "name": "Joy He-Yueya", + "priority": 8, + "research_areas": null, + "site": "https://joyheyueya.github.io", + "title": "Bachelor's Student", + "inactive": true + } + }, + { + "id": "kengu", + "name": "Ken Gu", + "role": "PhD Student", + "website": "https://kenqgu.com/", + "image": "/resources/headshots/kengu.jpg", + "status": "member", + "priority": 4, + "topics": [], + "legacy": { + "headshot": "kengu.jpg", + "is_visiting": false, + "name": "Ken Gu", + "priority": 4, + "research_areas": null, + "site": "https://kenqgu.com/", + "title": "PhD Student" + } + }, + { + "id": "margaretli", + "name": "Margaret Li", + "role": "PhD Student", + "website": "https://margs.li", + "image": "/resources/headshots/margaretli.png", + "status": "member", + "priority": 3, + "topics": [ + "NLP", + "Dialogue", + "ML" + ], + "legacy": { + "headshot": "margaretli.png", + "is_visiting": false, + "name": "Margaret Li", + "priority": 3, + "research_areas": [ + "NLP", + "Dialogue", + "ML" + ], + "site": "https://margs.li", + "title": "PhD Student" + } + }, + { + "id": "melihyilmaz", + "name": "Melih Yilmaz", + "role": "PhD Student", + "website": "", + "image": "/resources/headshots/melihyilmaz.png", + "status": "alumni", + "priority": 5, + "topics": [], + "legacy": { + "headshot": "melihyilmaz.png", + "is_visiting": false, + "name": "Melih Yilmaz", + "priority": 5, + "research_areas": null, + "site": null, + "title": "PhD Student", + "inactive": true + } + }, + { + "id": "mickelliu", + "name": "Mickel Liu", + "role": "PhD Student", + "website": "https://mickel-liu.github.io/", + "image": "/resources/headshots/mickelliu.png", + "status": "alumni", + "priority": 4, + "topics": [ + "Agent Alignment", + "Multi-Agent Systems", + "Large Language Models", + "Reinforcement Learning" + ], + "legacy": { + "headshot": "mickelliu.png", + "is_visiting": false, + "name": "Mickel Liu", + "priority": 4, + "research_areas": [ + "Agent Alignment", + "Multi-Agent Systems", + "Large Language Models", + "Reinforcement Learning" + ], + "site": "https://mickel-liu.github.io/", + "title": "PhD Student", + "inactive": true + } + }, + { + "id": "mikemerrill", + "name": "Mike Merrill", + "role": "PhD Student", + "website": "https://mikemerrill.io", + "image": "/resources/headshots/mikemerrill.jpeg", + "status": "alumni", + "priority": 5, + "topics": [], + "legacy": { + "headshot": "mikemerrill.jpeg", + "is_visiting": false, + "name": "Mike Merrill", + "priority": 5, + "research_areas": null, + "site": "https://mikemerrill.io", + "title": "PhD Student", + "inactive": true + } + }, + { + "id": "remydeshayes", + "name": "Remy Deshayes", + "role": "Master's Student", + "website": "https://remydeshayes.github.io/", + "image": "/resources/headshots/remydeshayes.png", + "status": "alumni", + "priority": 7, + "topics": [], + "legacy": { + "headshot": "remydeshayes.png", + "is_visiting": true, + "name": "Remy Deshayes", + "priority": 7, + "research_areas": null, + "site": "https://remydeshayes.github.io/", + "title": "Master's Student", + "inactive": true + } + }, + { + "id": "rongwudannyxu", + "name": "Rongwu Danny Xu", + "role": "PhD Student", + "website": "https://rongwuxu.com/", + "image": "/resources/headshots/rongwu.png", + "status": "member", + "priority": 6, + "topics": [], + "legacy": { + "name": "Rongwu Danny Xu", + "title": "PhD Student", + "site": "https://rongwuxu.com/", + "headshot": "rongwu.png", + "research_areas": null, + "priority": 6, + "is_visiting": false + } + }, + { + "id": "timalthoff", + "name": "Tim Althoff", + "role": "Assistant Professor", + "website": "http://www.timalthoff.com/", + "image": "/resources/headshots/timalthoff.jpg", + "status": "member", + "priority": 1, + "topics": [], + "legacy": { + "headshot": "timalthoff.jpg", + "is_visiting": false, + "name": "Tim Althoff", + "priority": 1, + "research_areas": null, + "site": "http://www.timalthoff.com/", + "title": "Assistant Professor" + } + }, + { + "id": "vinayakgupta", + "name": "Vinayak Gupta", + "role": "Postdoc", + "website": "https://gvinayak.github.io/", + "image": "/resources/headshots/vinayakgupta.png", + "status": "alumni", + "priority": 5, + "topics": [], + "legacy": { + "headshot": "vinayakgupta.png", + "is_visiting": false, + "name": "Vinayak Gupta", + "priority": 5, + "research_areas": null, + "site": "https://gvinayak.github.io/", + "title": "Postdoc", + "inactive": true + } + }, + { + "id": "xinyizhou", + "name": "Xinyi Zhou", + "role": "Postdoc", + "website": "https://xinyizhou.xyz/", + "image": "/resources/headshots/xinyizhou.jpg", + "status": "alumni", + "priority": 3, + "topics": [], + "legacy": { + "headshot": "xinyizhou.jpg", + "is_visiting": false, + "name": "Xinyi Zhou", + "priority": 3, + "research_areas": null, + "site": "https://xinyizhou.xyz/", + "title": "Postdoc", + "inactive": true + } + }, + { + "id": "yasamansefidgar", + "name": "Yasaman Sefidgar", + "role": "Postdoc", + "website": "https://sefyas.github.io/", + "image": "/resources/headshots/yasamansefidgar.png", + "status": "member", + "priority": 2, + "topics": [], + "legacy": { + "name": "Yasaman Sefidgar", + "title": "Postdoc", + "site": "https://sefyas.github.io/", + "headshot": "yasamansefidgar.png", + "research_areas": null, + "priority": 2, + "is_visiting": false + } + } +] diff --git a/content/publications.json b/content/publications.json new file mode 100644 index 0000000..92a8393 --- /dev/null +++ b/content/publications.json @@ -0,0 +1,1664 @@ +[ + { + "id": "sharma2024computational", + "title": "A Computational Framework for Behavioral Assessment of LLM Therapists", + "authors": "Chiu, Yu Ying* and Sharma, Ashish* and Lin, Inna and Althoff, Tim", + "year": 2024, + "venue": "Preprint", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/sharma2024computational.pdf", + "image": "/resources/thumbnails/sharmaComputational.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Chiu, Yu Ying* and Sharma, Ashish* and Lin, Inna and Althoff, Tim", + "booktitle": "Preprint", + "title": "A Computational Framework for Behavioral Assessment of LLM Therapists", + "year": "2024", + "pdf": "sharma2024computational.pdf", + "thumbnail": "sharmaComputational.png" + }, + "authorNames": [ + "Yu Ying* Chiu", + "Ashish* Sharma", + "Inna Lin", + "Tim Althoff" + ] + }, + { + "id": "gu2024blade", + "title": "BLADE - Benchmarking Language Model Agents for Data-Driven Science", + "authors": "Gu, Ken and Shang, Ruoxi and Jiang, Ruien and Kuang, Keying and Lin, Richard-John and Althoff, Tim", + "year": 2024, + "venue": "Findings of the 2024 Conference on Empirical Methods in Natural Language Processing", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/guBLADEBenchmarkingLanguage2024a.pdf", + "image": "/resources/thumbnails/guBLADE.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Gu, Ken and Shang, Ruoxi and Jiang, Ruien and Kuang, Keying and Lin, Richard-John and Althoff, Tim", + "booktitle": "Findings of the 2024 Conference on Empirical Methods in Natural Language Processing", + "title": "BLADE - Benchmarking Language Model Agents for Data-Driven Science", + "year": "2024", + "pdf": "guBLADEBenchmarkingLanguage2024a.pdf", + "thumbnail": "guBLADE.png" + }, + "authorNames": [ + "Ken Gu", + "Ruoxi Shang", + "Ruien Jiang", + "Keying Kuang", + "Richard-John Lin", + "Tim Althoff" + ] + }, + { + "id": "zhou2024correcting", + "title": "Correcting misinformation on social media with a large language model", + "authors": "Zhou, Xinyi and Sharma, Ashish and Zhang, Amy and Althoff, Tim", + "year": 2024, + "venue": "Preprint", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/zhouCorrectingMisinformation2024.pdf", + "image": "/resources/thumbnails/zhouCorrectingMis.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Zhou, Xinyi and Sharma, Ashish and Zhang, Amy and Althoff, Tim", + "booktitle": "Preprint", + "title": "Correcting misinformation on social media with a large language model", + "year": "2024", + "pdf": "zhouCorrectingMisinformation2024.pdf", + "thumbnail": "zhouCorrectingMis.png" + }, + "authorNames": [ + "Xinyi Zhou", + "Ashish Sharma", + "Amy Zhang", + "Tim Althoff" + ] + }, + { + "id": "sharma2024facilitating", + "title": "Facilitating Self-Guided Mental Health Interventions Through Human-Language Model Interaction - A Case Study of Cognitive Restructuring", + "authors": "Sharma, Ashish and Rushton, Kevin and Lin, Inna and Nguyen, Theresa and Althoff, Tim", + "year": 2024, + "venue": "Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/sharmaFacilitatingSelf-Guided2024.pdf", + "image": "/resources/thumbnails/sharmafacilitating.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Sharma, Ashish and Rushton, Kevin and Lin, Inna and Nguyen, Theresa and Althoff, Tim", + "booktitle": "Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems", + "title": "Facilitating Self-Guided Mental Health Interventions Through Human-Language Model Interaction - A Case Study of Cognitive Restructuring", + "year": "2024", + "pdf": "sharmaFacilitatingSelf-Guided2024.pdf", + "thumbnail": "sharmafacilitating.png" + }, + "authorNames": [ + "Ashish Sharma", + "Kevin Rushton", + "Inna Lin", + "Theresa Nguyen", + "Tim Althoff" + ] + }, + { + "id": "gu2024how_understand", + "title": "How Do Analysts Understand and Verify AI-Assisted Data Analyses?", + "authors": "Gu, Ken and Shang, Ruoxi and Althoff, Tim and Wang, Chenglong and Drucker, Steven M.", + "year": 2024, + "venue": "Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/guHowDoAnalystsUnderstand2024.pdf", + "image": "/resources/thumbnails/guHowDoDataAnalystsUnderstand.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Gu, Ken and Shang, Ruoxi and Althoff, Tim and Wang, Chenglong and Drucker, Steven M.", + "booktitle": "Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems", + "title": "How Do Analysts Understand and Verify AI-Assisted Data Analyses?", + "year": "2024", + "pdf": "guHowDoAnalystsUnderstand2024.pdf", + "thumbnail": "guHowDoDataAnalystsUnderstand.png" + }, + "authorNames": [ + "Ken Gu", + "Ruoxi Shang", + "Tim Althoff", + "Chenglong Wang", + "Steven M. Drucker" + ] + }, + { + "id": "gu2024how_analysts", + "title": "How Do Data Analysts Respond to AI Assistance? A Wizard-of-Oz Study", + "authors": "Gu, Ken and Grunde-McLaughlin, Madeleine and McNutt, Andrew M. and Heer, Jeffrey and Althoff, Tim", + "year": 2024, + "venue": "Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/guHowDoDataAnalysts2024.pdf", + "image": "/resources/thumbnails/guHowDoDataAnalysts.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Gu, Ken and Grunde-McLaughlin, Madeleine and McNutt, Andrew M. and Heer, Jeffrey and Althoff, Tim", + "booktitle": "Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems", + "title": "How Do Data Analysts Respond to AI Assistance? A Wizard-of-Oz Study", + "year": "2024", + "pdf": "guHowDoDataAnalysts2024.pdf", + "thumbnail": "guHowDoDataAnalysts.png" + }, + "authorNames": [ + "Ken Gu", + "Madeleine Grunde-McLaughlin", + "Andrew M. McNutt", + "Jeffrey Heer", + "Tim Althoff" + ] + }, + { + "id": "lin2024imbue", + "title": "IMBUE - Improving Interpersonal Effectiveness through Simulation and Just-in-time Feedback with Human-Language Model Interaction", + "authors": "Lin, Inna and Sharma, Ashish and Rytting, Christopher and Miner, Adam and Suh, Jina and Althoff, Tim", + "year": 2024, + "venue": "Proceedings of the 62nd Annual Meeting of the Association for Computational Linguistics", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/linIMBUE2024.pdf", + "image": "/resources/thumbnails/linIMBUE.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Lin, Inna and Sharma, Ashish and Rytting, Christopher and Miner, Adam and Suh, Jina and Althoff, Tim", + "booktitle": "Proceedings of the 62nd Annual Meeting of the Association for Computational Linguistics", + "title": "IMBUE - Improving Interpersonal Effectiveness through Simulation and Just-in-time Feedback with Human-Language Model Interaction", + "year": "2024", + "pdf": "linIMBUE2024.pdf", + "thumbnail": "linIMBUE.png" + }, + "authorNames": [ + "Inna Lin", + "Ashish Sharma", + "Christopher Rytting", + "Adam Miner", + "Jina Suh", + "Tim Althoff" + ] + }, + { + "id": "merrill2024language", + "title": "Language Models Still Struggle to Zero-shot Reason about Time Series", + "authors": "Merrill, Mike A. and Tan, Mingtian and Gupta, Vinayak and Hartvigsen, Tom and Althoff, Tim", + "year": 2024, + "venue": "Proceedings of the 2024 Conference on Empirical Methods in Natural Language Processing", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/merrillLanguageModelsStill2024.pdf", + "image": "/resources/thumbnails/merrillLanguageModels.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Merrill, Mike A. and Tan, Mingtian and Gupta, Vinayak and Hartvigsen, Tom and Althoff, Tim", + "booktitle": "Proceedings of the 2024 Conference on Empirical Methods in Natural Language Processing", + "title": "Language Models Still Struggle to Zero-shot Reason about Time Series", + "year": "2024", + "pdf": "merrillLanguageModelsStill2024.pdf", + "thumbnail": "merrillLanguageModels.png" + }, + "authorNames": [ + "Mike A. Merrill", + "Mingtian Tan", + "Vinayak Gupta", + "Tom Hartvigsen", + "Tim Althoff" + ] + }, + { + "id": "weld2024making", + "title": "Making Online Communities 'Better': A Taxonomy of Community Values on Reddit", + "authors": "Weld, Galen and Zhang, Amy X. and Althoff, Tim", + "year": 2024, + "venue": "Proceedings of the Eighteenth International AAAI Conference on Web and Social Media", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/weldMakingOnlineCommunities2024.pdf", + "image": "/resources/thumbnails/weldmaking.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Weld, Galen and Zhang, Amy X. and Althoff, Tim", + "booktitle": "Proceedings of the Eighteenth International AAAI Conference on Web and Social Media", + "title": "Making Online Communities 'Better': A Taxonomy of Community Values on Reddit", + "year": "2024", + "pdf": "weldMakingOnlineCommunities2024.pdf", + "thumbnail": "weldmaking.png" + }, + "authorNames": [ + "Galen Weld", + "Amy X. Zhang", + "Tim Althoff" + ] + }, + { + "id": "xu2023globemimwut", + "title": "GLOBEM: Cross-Dataset Generalization of Longitudinal Human Behavior Modeling", + "authors": "Xu, Xuhai and Liu, Xin and Zhang, Han and Wang, Weichen and Nepal, Subigya and Sefidgar, Yasaman and Seo, Woosuk and Kuehn, Kevin S and Huckins, Jeremy F and Morris, Margaret E and Nurius, Paula S. and Riskin, Eve A. and Patel, Shwetak and Althoff, Tim and Campell, Andrew and Dey, Anind K. and Mankoff, Jennifer C.", + "year": 2023, + "venue": "ACM IMWUT", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/xu2023globemimwut.pdf", + "image": "/resources/thumbnails/xu2023globemimwut.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Xu, Xuhai and Liu, Xin and Zhang, Han and Wang, Weichen and Nepal, Subigya and Sefidgar, Yasaman and Seo, Woosuk and Kuehn, Kevin S and Huckins, Jeremy F and Morris, Margaret E and Nurius, Paula S. and Riskin, Eve A. and Patel, Shwetak and Althoff, Tim and Campell, Andrew and Dey, Anind K. and Mankoff, Jennifer C.", + "description": null, + "highlight": 0, + "journal": "ACM IMWUT", + "optjournal": "Proceedings of the ACM on Interactive, Mobile, Wearable and Ubiquitous Technologies", + "optnumber": "4", + "optpages": "1--34", + "optpublisher": "ACM New York, NY, USA", + "optvolume": "6", + "pdf": "xu2023globemimwut.pdf", + "thumbnail": "xu2023globemimwut.png", + "title": "GLOBEM: Cross-Dataset Generalization of Longitudinal Human Behavior Modeling", + "year": "2023" + }, + "authorNames": [ + "Xuhai Xu", + "Xin Liu", + "Han Zhang", + "Weichen Wang", + "Subigya Nepal", + "Yasaman Sefidgar", + "Woosuk Seo", + "Kevin S Kuehn", + "Jeremy F Huckins", + "Margaret E Morris", + "Paula S. Nurius", + "Eve A. Riskin", + "Shwetak Patel", + "Tim Althoff", + "Andrew Campell", + "Anind K. Dey", + "Jennifer C. Mankoff" + ] + }, + { + "id": "merrillHomekit2020BenchmarkTime2023", + "title": "Homekit2020: A Benchmark for Time Series Classification on a Large Mobile Sensing Dataset with Laboratory Tested Ground Truth of Influenza Infections", + "authors": "Merrill, Mike A and Safranchik, Esteban and Kolbeinsson, Arinbjorn and Gade, Piyusha and Ramirez, Ernesto and Schmidt, Ludwig and Foshchini, Luca and Althoff, Tim", + "year": 2023, + "venue": "Conference on Health, Inference, and Learning", + "description": "Despite increased interest in wearables as tools for detecting various health conditions, there are not as of yet any large public benchmarks for such mobile sensing data. Our dataset contains over 14 million hours of minute-level multimodal FitBit data, symptom reports, and ground-truth laboratory PCR influenza test results, along with an evaluation framework that mimics realistic model deployments and efficiently characterizes statistical uncertainty in model selection in the presence of extreme class imbalance.", + "highlight": true, + "award": "", + "pdf": "/resources/pubpdfs/merrillHomekit2020BenchmarkTime2023.pdf", + "image": "/resources/thumbnails/merrillHomekit2020BenchmarkTime2023.png", + "code": "https://github.com/behavioral-data/Homekit2020", + "doi": "", + "url": "", + "legacy": { + "abstract": "Despite increased interest in wearables as tools for detecting various health conditions, there are not as of yet any large public benchmarks for such mobile sensing data. The few datasets that are available do not contain data from more than dozens of individuals, do not contain high-resolution raw data or do not include dataloaders for easy integration into machine learning pipelines. Here, we present Homekit2020: the first large-scale public benchmark for time series classification of wearable sensor data. Our dataset contains over 14 million hours of minute-level multimodal FitBit data, symptom reports, and ground-truth laboratory PCR influenza test results, along with an evaluation framework that mimics realistic model deployments and efficiently characterizes statistical uncertainty in model selection in the presence of extreme class imbalance. Furthermore, we implement and evaluate nine neural and non-neural time series classification models on our benchmark across 450 total training runs in order to establish state of the art performance.", + "author": "Merrill, Mike A and Safranchik, Esteban and Kolbeinsson, Arinbjorn and Gade, Piyusha and Ramirez, Ernesto and Schmidt, Ludwig and Foshchini, Luca and Althoff, Tim", + "description": "Despite increased interest in wearables as tools for detecting various health conditions, there are not as of yet any large public benchmarks for such mobile sensing data. Our dataset contains over 14 million hours of minute-level multimodal FitBit data, symptom reports, and ground-truth laboratory PCR influenza test results, along with an evaluation framework that mimics realistic model deployments and efficiently characterizes statistical uncertainty in model selection in the presence of extreme class imbalance.", + "highlight": 1, + "code": "https://github.com/behavioral-data/Homekit2020", + "file": "/Users/michaelmerrill/Zotero/storage/S72M77YC/Merrill et al. - Homekit2020 A Benchmark for Time Series Classific.pdf", + "journal": "Conference on Health, Inference, and Learning", + "langid": "english", + "month": "March", + "pdf": "merrillHomekit2020BenchmarkTime2023.pdf", + "thumbnail": "merrillHomekit2020BenchmarkTime2023.png", + "title": "Homekit2020: A Benchmark for Time Series Classification on a Large Mobile Sensing Dataset with Laboratory Tested Ground Truth of Influenza Infections", + "year": "2023" + }, + "authorNames": [ + "Mike A Merrill", + "Esteban Safranchik", + "Arinbjorn Kolbeinsson", + "Piyusha Gade", + "Ernesto Ramirez", + "Ludwig Schmidt", + "Luca Foshchini", + "Tim Althoff" + ] + }, + { + "id": "sharma2023human", + "title": "Human-AI Collaboration Enables More Empathic Conversations in Text-based Peer-to-Peer Mental Health Support", + "authors": "Sharma, Ashish and Lin, Inna W and Miner, Adam S and Atkins, David C and Althoff, Tim", + "year": 2023, + "venue": "Nature Machine Intelligence", + "description": "How can AI help improve access to mental health care? Our Nature Machine Intelligence paper shows that human-AI collaboration can empower people to respond more empathically in online peer-to-peer mental health support.", + "highlight": true, + "award": "", + "pdf": "/resources/pubpdfs/sharma2023human.pdf", + "image": "/resources/thumbnails/sharma2023human.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Sharma, Ashish and Lin, Inna W and Miner, Adam S and Atkins, David C and Althoff, Tim", + "description": "How can AI help improve access to mental health care? Our Nature Machine Intelligence paper shows that human-AI collaboration can empower people to respond more empathically in online peer-to-peer mental health support.", + "highlight": 1, + "journal": "Nature Machine Intelligence", + "pages": "1--12", + "pdf": "sharma2023human.pdf", + "publisher": "Nature Publishing Group UK London", + "thumbnail": "sharma2023human.png", + "title": "Human-AI Collaboration Enables More Empathic Conversations in Text-based Peer-to-Peer Mental Health Support", + "year": "2023" + }, + "authorNames": [ + "Ashish Sharma", + "Inna W Lin", + "Adam S Miner", + "David C Atkins", + "Tim Althoff" + ] + }, + { + "id": "zech2023mhatsengagement", + "title": "Mapping User Engagement in Digital Psychotherapy: An Integrative Engagement Model", + "authors": "Zech, James M and Johnson, Morgan and Pullman, Michael D and Hull, Thomas D and Althoff, Tim and Munson, Sean A and Fridling, Nicole and Litvin, Boris and Wu, Jerilyn and Areán, Patricia A", + "year": 2023, + "venue": "JMIR Formative Research", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/zech2023mhatsengagement.pdf", + "image": "/resources/thumbnails/zech2023mhatsengagement.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Zech, James M and Johnson, Morgan and Pullman, Michael D and Hull, Thomas D and Althoff, Tim and Munson, Sean A and Fridling, Nicole and Litvin, Boris and Wu, Jerilyn and Areán, Patricia A", + "description": null, + "highlight": 0, + "journal": "JMIR Formative Research", + "pdf": "zech2023mhatsengagement.pdf", + "thumbnail": "zech2023mhatsengagement.png", + "title": "Mapping User Engagement in Digital Psychotherapy: An Integrative Engagement Model", + "year": "2023" + }, + "authorNames": [ + "James M Zech", + "Morgan Johnson", + "Michael D Pullman", + "Thomas D Hull", + "Tim Althoff", + "Sean A Munson", + "Nicole Fridling", + "Boris Litvin", + "Jerilyn Wu", + "Patricia A Areán" + ] + }, + { + "id": "merrillSelfsupervisedPretrainingTransfer2023", + "title": "Self-Supervised Pretraining and Transfer Learning Enable Flu and COVID-19 Predictions in Small Mobile Sensing Datasets", + "authors": "Merrill, Mike A. and Althoff, Tim", + "year": 2023, + "venue": "Conference on Health, Inference, and Learning", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/merrillSelfsupervisedPretrainingTransfer2023.pdf", + "image": "/resources/thumbnails/merrillSelfsupervisedPretrainingTransfer2023.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "abstract": "Detailed mobile sensing data from phones, watches, and fitness trackers offer an unparalleled opportunity to quantify and act upon previously unmeasurable behavioral changes in order to improve individual health and accelerate responses to emerging diseases. Unlike in natural language processing and computer vision, deep representation learning has yet to broadly impact this domain, in which the vast majority of research and clinical applications still rely on manually defined features and boosted tree models or even forgo predictive modeling altogether due to insufficient accuracy. This is due to unique challenges in the behavioral health domain, including very small datasets (\\textasciitilde 10\\^1 participants), which frequently contain missing data, consist of long time series with critical long-range dependencies (length{$>$}10\\^4), and extreme class imbalances ({$>$}10\\^3:1).", + "archiveprefix": "arxiv", + "author": "Merrill, Mike A. and Althoff, Tim", + "description": null, + "eprint": "2205.13607", + "file": "/Users/michaelmerrill/Zotero/storage/QRXUFB52/Merrill and Althoff - 2022 - Self-supervised Pretraining and Transfer Learning .pdf;/Users/michaelmerrill/Zotero/storage/TNEAQ9SK/2205.html", + "highlight": 0, + "journal": "Conference on Health, Inference, and Learning", + "keywords": "Computer Science - Human-Computer Interaction,Computer Science - Machine Learning", + "month": "March", + "pdf": "merrillSelfsupervisedPretrainingTransfer2023.pdf", + "primaryclass": "cs", + "thumbnail": "merrillSelfsupervisedPretrainingTransfer2023.png", + "title": "Self-Supervised Pretraining and Transfer Learning Enable Flu and COVID-19 Predictions in Small Mobile Sensing Datasets", + "urldate": "2022-06-02", + "year": "2023" + }, + "authorNames": [ + "Mike A. Merrill", + "Tim Althoff" + ] + }, + { + "id": "Gu2022UnderstandingAS", + "title": "Understanding and Supporting Debugging Workflows in Multiverse Analysis", + "authors": "Ken Gu, Eunice Jun and Tim Althoff", + "year": 2023, + "venue": "CHI", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/Gu2022UnderstandingAS.pdf", + "image": "/resources/thumbnails/Gu2022UnderstandingAS.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Ken Gu, Eunice Jun and Tim Althoff", + "description": null, + "highlight": 0, + "journal": "CHI", + "pdf": "Gu2022UnderstandingAS.pdf", + "thumbnail": "Gu2022UnderstandingAS.png", + "title": "Understanding and Supporting Debugging Workflows in Multiverse Analysis", + "year": "2023" + }, + "authorNames": [ + "Ken Gu", + "Eunice Jun", + "Tim Althoff" + ] + }, + { + "id": "xu2022GLOBEM", + "title": " Globem dataset: Multi-year datasets for longitudinal human behavior modeling generalization", + "authors": "Xuhai Xu, Han Zhang, Yasaman Sefidgar, Yiyi Ren, Xin Liu, Woosuk Seo, Jennifer Brown, Kevin Kuehn, Mike A. Merrill, Paula Nurius, Shwetak Patel, Tim Althoff, Margaret E. Morris, Eve Riskin, Jennifer Mankoff, and Anind K. Dey", + "year": 2022, + "venue": "NeurIPS", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/xu2022GLOBEM.pdf", + "image": "/resources/thumbnails/xu2022GLOBEM.png", + "code": "", + "doi": "10.48550/ARXIV.2211.02733", + "url": "https://arxiv.org/abs/2211.02733", + "legacy": { + "author": "Xuhai Xu, Han Zhang, Yasaman Sefidgar, Yiyi Ren, Xin Liu, Woosuk Seo, Jennifer Brown, Kevin Kuehn, Mike A. Merrill, Paula Nurius, Shwetak Patel, Tim Althoff, Margaret E. Morris, Eve Riskin, Jennifer Mankoff, and Anind K. Dey", + "copyright": "Creative Commons Attribution 4.0 International", + "doi": "10.48550/ARXIV.2211.02733", + "journal": "NeurIPS", + "key": "xu2022GLOBEM", + "keywords": "Machine Learning (cs.LG), Artificial Intelligence (cs.AI), Human-Computer Interaction (cs.HC), FOS: Computer and information sciences, FOS: Computer and information sciences, I.2.1; E.m, 68T09", + "pdf": "resources/pubpdfs/xu2022GLOBEM.pdf", + "publisher": "arXiv", + "thumbnail": "xu2022GLOBEM.png", + "title": " Globem dataset: Multi-year datasets for longitudinal human behavior modeling generalization", + "url": "https://arxiv.org/abs/2211.02733", + "year": "2022" + }, + "authorNames": [ + "Xuhai Xu", + "Han Zhang", + "Yasaman Sefidgar", + "Yiyi Ren", + "Xin Liu", + "Woosuk Seo", + "Jennifer Brown", + "Kevin Kuehn", + "Mike A. Merrill", + "Paula Nurius", + "Shwetak Patel", + "Tim Althoff", + "Margaret E. Morris", + "Eve Riskin", + "Jennifer Mankoff", + "Anind K. Dey" + ] + }, + { + "id": "miner2022computational", + "title": "A computational approach to measure the linguistic characteristics of psychotherapy timing, responsiveness, and consistency", + "authors": "Miner, Adam S and Fleming, Scott L and Haque, Albert and Fries, Jason A and Althoff, Tim and Wilfley, Denise E and Agras, W Stewart and Milstein, Arnold and Hancock, Jeff and Asch, Steven M and others", + "year": 2022, + "venue": "npj Mental Health Research", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/miner2022computational.pdf", + "image": "/resources/thumbnails/miner2022computational.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Miner, Adam S and Fleming, Scott L and Haque, Albert and Fries, Jason A and Althoff, Tim and Wilfley, Denise E and Agras, W Stewart and Milstein, Arnold and Hancock, Jeff and Asch, Steven M and others", + "description": null, + "highlight": 0, + "journal": "npj Mental Health Research", + "number": "1", + "optpublisher": "Nature Publishing Group UK London", + "pages": "19", + "pdf": "miner2022computational.pdf", + "thumbnail": "miner2022computational.png", + "title": "A computational approach to measure the linguistic characteristics of psychotherapy timing, responsiveness, and consistency", + "volume": "1", + "year": "2022" + }, + "authorNames": [ + "Adam S Miner", + "Scott L Fleming", + "Albert Haque", + "Jason A Fries", + "Tim Althoff", + "Denise E Wilfley", + "W Stewart Agras", + "Arnold Milstein", + "Jeff Hancock", + "Steven M Asch", + "others" + ] + }, + { + "id": "weld2022adjusting_confounders", + "title": "Adjusting for Confounders with Text: Challenges and an Empirical Evaluation Framework for Causal Inference", + "authors": "Galen Weld, Peter West, Maria Glenski, David Arbour, Ryan Rossi, and Tim Althoff", + "year": 2022, + "venue": "ICWSM", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/weld2022adjusting_confounders.pdf", + "image": "/resources/thumbnails/weld2022adjusting_confounders.JPG", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Galen Weld, Peter West, Maria Glenski, David Arbour, Ryan Rossi, and Tim Althoff", + "booktitle": "ICWSM", + "description": null, + "highlight": 0, + "pdf": "weld2022adjusting_confounders.pdf", + "thumbnail": "weld2022adjusting_confounders.JPG", + "title": "Adjusting for Confounders with Text: Challenges and an Empirical Evaluation Framework for Causal Inference", + "year": "2022" + }, + "authorNames": [ + "Galen Weld", + "Peter West", + "Maria Glenski", + "David Arbour", + "Ryan Rossi", + "Tim Althoff" + ] + }, + { + "id": "suhDisparateImpactsOnline2022", + "title": "Disparate impacts on online information access during the Covid-19 pandemic", + "authors": "Suh, Jina and Horvitz, Eric and White, Ryen W. and Althoff, Tim", + "year": 2022, + "venue": "Nature Communications", + "description": "The pandemic prompted increased digital engagement for health, economic, and educational resources. Analyzing 55 billion web searches across 25,150 US ZIP codes, we found differing use of digital resources based on socioeconomic and environmental factors. Lower-income areas accessed health information less than higher-income ones. ZIP codes with more Black or Hispanic residents used unemployment resources more, with unique patterns. These disparities raise important questions about the impact of information search behaviors on disadvantaged populations.", + "highlight": true, + "award": "", + "pdf": "/resources/pubpdfs/suhDisparateImpactsOnline2022.pdf", + "image": "/resources/thumbnails/suhDisparateImpactsOnline2022.png", + "code": "", + "doi": "10.1038/s41467-022-34592-z", + "url": "https://www.nature.com/articles/s41467-022-34592-z", + "legacy": { + "abstract": "Abstract The COVID-19 pandemic has stimulated important changes in online information access as digital engagement became necessary to meet the demand for health, economic, and educational resources. Our analysis of 55 billion everyday web search interactions during the pandemic across 25,150 US ZIP codes reveals that the extent to which different communities of internet users enlist digital resources varies based on socioeconomic and environmental factors. For example, we find that ZIP codes with lower income intensified their access to health information to a smaller extent than ZIP codes with higher income. We show that ZIP codes with higher proportions of Black or Hispanic residents intensified their access to unemployment resources to a greater extent, while revealing patterns of unemployment site visits unseen by the claims data. Such differences frame important questions on the relationship between differential information search behaviors and the downstream real-world implications on more and less advantaged populations.", + "author": "Suh, Jina and Horvitz, Eric and White, Ryen W. and Althoff, Tim", + "description": "The pandemic prompted increased digital engagement for health, economic, and educational resources. Analyzing 55 billion web searches across 25,150 US ZIP codes, we found differing use of digital resources based on socioeconomic and environmental factors. Lower-income areas accessed health information less than higher-income ones. ZIP codes with more Black or Hispanic residents used unemployment resources more, with unique patterns. These disparities raise important questions about the impact of information search behaviors on disadvantaged populations.", + "doi": "10.1038/s41467-022-34592-z", + "file": "Suh et al. - 2022 - Disparate impacts on online information access dur.pdf:/Users/michaelmerrill/Zotero/storage/L83KGF2X/Suh et al. - 2022 - Disparate impacts on online information access dur.pdf:application/pdf", + "highlight": 1, + "issn": "2041-1723", + "journal": "Nature Communications", + "language": "en", + "month": "November", + "number": "1", + "pages": "7094", + "pdf": "suhDisparateImpactsOnline2022.pdf", + "thumbnail": "suhDisparateImpactsOnline2022.png", + "title": "Disparate impacts on online information access during the Covid-19 pandemic", + "url": "https://www.nature.com/articles/s41467-022-34592-z", + "urldate": "2023-05-08", + "volume": "13", + "year": "2022" + }, + "authorNames": [ + "Jina Suh", + "Eric Horvitz", + "Ryen W. White", + "Tim Althoff" + ] + }, + { + "id": "mezlini2021estimating", + "title": "Estimating the Burden of Influenza on Daily Activity at Population Scale Using Commercial Wearable Sensors", + "authors": "Mezlini, Aziz and Shapiro, Allison and Daza, Eric J and Caddigan, Eamon and Ramirez, Ernesto and Althoff, Tim and Foschini, Luca", + "year": 2022, + "venue": "JAMA Network Open", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/mezlini2021estimating.pdf", + "image": "/resources/thumbnails/mezlini2021estimating.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Mezlini, Aziz and Shapiro, Allison and Daza, Eric J and Caddigan, Eamon and Ramirez, Ernesto and Althoff, Tim and Foschini, Luca", + "description": null, + "highlight": 0, + "journal": "JAMA Network Open", + "optpublisher": "", + "pdf": "mezlini2021estimating.pdf", + "thumbnail": "mezlini2021estimating.png", + "title": "Estimating the Burden of Influenza on Daily Activity at Population Scale Using Commercial Wearable Sensors", + "year": "2022" + }, + "authorNames": [ + "Aziz Mezlini", + "Allison Shapiro", + "Eric J Daza", + "Eamon Caddigan", + "Ernesto Ramirez", + "Tim Althoff", + "Luca Foschini" + ] + }, + { + "id": "lin-etal-2022-gendered", + "title": "Gendered Mental Health Stigma in Masked Language Models", + "authors": "Lin, Inna and Njoo, Lucille and Field, Anjalie and Sharma, Ashish and Reinecke, Katharina and Althoff, Tim and Tsvetkov, Yulia", + "year": 2022, + "venue": "EMNLP", + "description": "If you have ever considered using NLP for Mental Health applications, it’s vital to know what the models have inadvertently learned about people with mental health issues. In our EMNLP 2022 paper, we find that masked LMs capture societal stigma about gender in mental health.", + "highlight": true, + "award": "", + "pdf": "/resources/pubpdfs/lin-etal-2022-gendered.pdf", + "image": "/resources/thumbnails/lin-etal-2022-gendered.png", + "code": "", + "doi": "", + "url": "https://aclanthology.org/2022.emnlp-main.139", + "legacy": { + "abstract": "Mental health stigma prevents many individuals from receiving the appropriate care, and social psychology studies have shown that mental health tends to be overlooked in men. In this work, we investigate gendered mental health stigma in masked language models. In doing so, we operationalize mental health stigma by developing a framework grounded in psychology research: we use clinical psychology literature to curate prompts, then evaluate the models{'} propensity to generate gendered words. We find that masked language models capture societal stigma about gender in mental health: models are consistently more likely to predict female subjects than male in sentences about having a mental health condition (32{\\%} vs. 19{\\%}), and this disparity is exacerbated for sentences that indicate treatment-seeking behavior. Furthermore, we find that different models capture dimensions of stigma differently for men and women, associating stereotypes like anger, blame, and pity more with women with mental health conditions than with men. In showing the complex nuances of models{'} gendered mental health stigma, we demonstrate that context and overlapping dimensions of identity are important considerations when assessing computational models{'} social biases.", + "address": "Abu Dhabi, United Arab Emirates", + "author": "Lin, Inna and Njoo, Lucille and Field, Anjalie and Sharma, Ashish and Reinecke, Katharina and Althoff, Tim and Tsvetkov, Yulia", + "booktitle": "EMNLP", + "description": "If you have ever considered using NLP for Mental Health applications, it’s vital to know what the models have inadvertently learned about people with mental health issues. In our EMNLP 2022 paper, we find that masked LMs capture societal stigma about gender in mental health.", + "highlight": 1, + "month": "December", + "pages": "2152--2170", + "pdf": "lin-etal-2022-gendered.pdf", + "publisher": "Association for Computational Linguistics", + "thumbnail": "lin-etal-2022-gendered.png", + "title": "Gendered Mental Health Stigma in Masked Language Models", + "url": "https://aclanthology.org/2022.emnlp-main.139", + "year": "2022" + }, + "authorNames": [ + "Inna Lin", + "Lucille Njoo", + "Anjalie Field", + "Ashish Sharma", + "Katharina Reinecke", + "Tim Althoff", + "Yulia Tsvetkov" + ] + }, + { + "id": "althoff2022diet", + "title": "Large-scale diet tracking data reveal disparate associations between food environment and diet", + "authors": "Althoff, Tim and Nilforoshan, Hamed and Hua, Jenna and Leskovec, Jure", + "year": 2022, + "venue": "Nature Communications", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2022diet.pdf", + "image": "/resources/thumbnails/althoff2022diet.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim and Nilforoshan, Hamed and Hua, Jenna and Leskovec, Jure", + "description": null, + "highlight": 0, + "journal": "Nature Communications", + "number": "1", + "optpublisher": "Nature Publishing Group UK London", + "pages": "267", + "pdf": "althoff2022diet.pdf", + "thumbnail": "althoff2022diet.png", + "title": "Large-scale diet tracking data reveal disparate associations between food environment and diet", + "volume": "13", + "year": "2022" + }, + "authorNames": [ + "Tim Althoff", + "Hamed Nilforoshan", + "Jenna Hua", + "Jure Leskovec" + ] + }, + { + "id": "hicks2022leveraging", + "title": "Leveraging Mobile Technology for Public Health Promotion: A Multidisciplinary Perspective", + "authors": "Hicks, Jennifer L and Boswell, Melissa A and Althoff, Tim and Crum, Alia J and Ku, Joy P and Landay, James A and Moya, Paula ML and Murnane, Elizabeth L and Snyder, Michael P and King, Abby C and others", + "year": 2022, + "venue": "Annual Review of Public Health", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/hicks2022leveraging.pdf", + "image": "/resources/thumbnails/hicks2022leveraging.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Hicks, Jennifer L and Boswell, Melissa A and Althoff, Tim and Crum, Alia J and Ku, Joy P and Landay, James A and Moya, Paula ML and Murnane, Elizabeth L and Snyder, Michael P and King, Abby C and others", + "description": null, + "highlight": 0, + "journal": "Annual Review of Public Health", + "pdf": "hicks2022leveraging.pdf", + "publisher": "Annual Reviews", + "thumbnail": "hicks2022leveraging.png", + "title": "Leveraging Mobile Technology for Public Health Promotion: A Multidisciplinary Perspective", + "volume": "44", + "year": "2022" + }, + "authorNames": [ + "Jennifer L Hicks", + "Melissa A Boswell", + "Tim Althoff", + "Alia J Crum", + "Joy P Ku", + "James A Landay", + "Paula ML Moya", + "Elizabeth L Murnane", + "Michael P Snyder", + "Abby C King", + "others" + ] + }, + { + "id": "weld2022community_values", + "title": "What Makes Online Communities 'Better'? Measuring Values, Consensus, and Conflict across Thousands of Subreddits", + "authors": "Weld, Galen and Zhang, Amy X. and Althoff, Tim", + "year": 2022, + "venue": "ICWSM", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/weld2022community_values.pdf", + "image": "/resources/thumbnails/weld2022community_values.jpg", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Weld, Galen and Zhang, Amy X. and Althoff, Tim", + "booktitle": "ICWSM", + "description": null, + "highlight": 0, + "pdf": "weld2022community_values.pdf", + "thumbnail": "weld2022community_values.jpg", + "title": "What Makes Online Communities 'Better'? Measuring Values, Consensus, and Conflict across Thousands of Subreddits", + "year": "2022" + }, + "authorNames": [ + "Galen Weld", + "Amy X. Zhang", + "Tim Althoff" + ] + }, + { + "id": "merrill_multiverse_2021", + "title": "MULTIVERSE: Mining Collective Data Science Knowledge from Code on the Web to Suggest Alternative Analysis Approaches", + "authors": "Merrill, Mike A. and Zhang, Ge and Althoff, Tim", + "year": 2021, + "venue": "KDD", + "description": "Data analyses are based on a series of “decision points” including data filtering, feature operationalization and selection, model specification, and parametric assumptions. In this work we mine Kaggle for hundreds of thousands of decision points and train a novel language model to suggest alternative analyses.", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/merrill_multiverse_2021.pdf", + "image": "/resources/thumbnails/merrill_multiverse_2021.png", + "code": "", + "doi": "10.1145/3447548.3467455", + "url": "https://dl.acm.org/doi/10.1145/3447548.3467455", + "legacy": { + "abstract": "Data analyses are based on a series of “decision points” including data filtering, feature operationalization and selection, model specification, and parametric assumptions. “Multiverse Analysis” research has shown that a lack of exploration of these decisions can lead to non-robust conclusions based on highly sensitive decision points. Importantly, even if myopic analyses are technically correct, analysts’ focus on one set of decision points precludes them from exploring alternate formulations that may produce very different results. Prior work has also shown that analysts’ exploration is often limited based on their training, domain, and personal experience. However, supporting analysts in exploring alternative approaches is challenging and typically requires expert feedback that is costly and hard to scale.", + "address": "Virtual Event Singapore", + "author": "Merrill, Mike A. and Zhang, Ge and Althoff, Tim", + "booktitle": "KDD", + "description": "Data analyses are based on a series of “decision points” including data filtering, feature operationalization and selection, model specification, and parametric assumptions. In this work we mine Kaggle for hundreds of thousands of decision points and train a novel language model to suggest alternative analyses.", + "doi": "10.1145/3447548.3467455", + "file": "Merrill et al. - 2021 - MULTIVERSE Mining Collective Data Science Knowled.pdf:/Users/michaelmerrill/Zotero/storage/5SIZTGV6/Merrill et al. - 2021 - MULTIVERSE Mining Collective Data Science Knowled.pdf:application/pdf", + "highlight": 0, + "isbn": "978-1-4503-8332-5", + "language": "en", + "month": "August", + "pages": "1212--1222", + "pdf": "merrill_multiverse_2021.pdf", + "publisher": "ACM", + "shorttitle": "{MULTIVERSE}", + "thumbnail": "merrill_multiverse_2021.png", + "title": "MULTIVERSE: Mining Collective Data Science Knowledge from Code on the Web to Suggest Alternative Analysis Approaches", + "url": "https://dl.acm.org/doi/10.1145/3447548.3467455", + "urldate": "2021-08-30", + "year": "2021" + }, + "authorNames": [ + "Mike A. Merrill", + "Ge Zhang", + "Tim Althoff" + ] + }, + { + "id": "Weld_Glenski_Althoff_2021", + "title": "Political Bias and Factualness in News Sharing across more than 100,000 Online Communities", + "authors": "Weld, Galen and Glenski, Maria and Althoff, Tim", + "year": 2021, + "venue": "ICWSM", + "description": "Studying news shared online is challenging due to the massive volume of content which is shared. In this work, we conduct the largest study of news sharing to date, analyzing more than 550 million links to news articles posted on reddit over four years. Using non-partisan news source ratings of sources' political bias and factualness, we find that up- and down-voting mechanisms generally decrease the visibility of biased and low factual content, and that such content is very concentrated, being mostly shared in only a small fraction of all communities.", + "highlight": true, + "award": "Best Paper (Outstanding Analysis)", + "pdf": "/resources/pubpdfs/Weld_Glenski_Althoff_2021.pdf", + "image": "/resources/thumbnails/Weld_Glenski_Althoff_2021.jpg", + "code": "", + "doi": "", + "url": "https://ojs.aaai.org/index.php/ICWSM/article/view/18104", + "legacy": { + "abstractnote": "As civil discourse increasingly takes place online, misinformation and the polarization of news shared in online communities have become ever more relevant concerns with real world harms across our society. Studying online news sharing at scale is challenging due to the massive volume of content which is shared by millions of users across thousands of communities. Therefore, existing research has largely focused on specific communities or specific interventions, such as bans. However, understanding the prevalence and spread of misinformation and polarization more broadly, across thousands of online communities, is critical for the development of governance strategies, interventions, and community design. Here, we conduct the largest study of news sharing on reddit to date, analyzing more than 550 million links spanning 4 years. We use non-partisan news source ratings from Media Bias/Fact Check to annotate links to news sources with their political bias and factualness. We find that, compared to left-leaning communities, right-leaning communities have 105% more variance in the political bias of their news sources, and more links to relatively-more biased sources, on average. We observe that reddit users’ voting and re-sharing behaviors generally decrease the visibility of extremely biased and low factual content, which receives 20% fewer upvotes and 30% fewer exposures from crossposts than more neutral or more factual content. This suggests that reddit is more resilient to low factual content than Twitter. We show that extremely biased and low factual content is very concentrated, with 99% of such content being shared in only 0.5% of communities, giving credence to the recent strategy of community-wide bans and quarantines.", + "author": "Weld, Galen and Glenski, Maria and Althoff, Tim", + "description": "Studying news shared online is challenging due to the massive volume of content which is shared. In this work, we conduct the largest study of news sharing to date, analyzing more than 550 million links to news articles posted on reddit over four years. Using non-partisan news source ratings of sources' political bias and factualness, we find that up- and down-voting mechanisms generally decrease the visibility of biased and low factual content, and that such content is very concentrated, being mostly shared in only a small fraction of all communities.", + "highlight": 1, + "journal": "ICWSM", + "month": "May", + "number": "1", + "pages": "796-807", + "pdf": "Weld_Glenski_Althoff_2021.pdf", + "award": "Best Paper (Outstanding Analysis)", + "thumbnail": "Weld_Glenski_Althoff_2021.jpg", + "title": "Political Bias and Factualness in News Sharing across more than 100,000 Online Communities", + "url": "https://ojs.aaai.org/index.php/ICWSM/article/view/18104", + "volume": "15", + "year": "2021" + }, + "authorNames": [ + "Galen Weld", + "Maria Glenski", + "Tim Althoff" + ] + }, + { + "id": "suh2020populationscale", + "title": "Population-Scale Study of Human Needs During the COVID-19 Pandemic: Analysis and Implications", + "authors": "Jina Suh and Eric Horvitz and Ryen W. White and Tim Althoff", + "year": 2021, + "venue": "WSDM", + "description": "The COVID-19 pandemic has fundamentally changed our lives beyond just our physical health. To understand the impact of the pandemic and associated policy decisions on a multitude of human needs, we propose a computational methodology, building on Maslow's hierarchy of needs, that can capture a holistic view of relative changes in needs following the pandemic through a difference-in-differences approach that corrects for seasonality and volume variations. When applied to over 35 billion search interactions spanning over 36000 ZIP codes in the US, we found that the expression of basic human needs has increased exponentially while higher-level aspirations declined, that the durations of shelter-in-place mandates significantly impacted social-emotional needs, and that there are potential barriers to meeting critical needs online.", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/suh2020populationscale.pdf", + "image": "/resources/thumbnails/suh2020populationscale.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "archiveprefix": "arXiv", + "author": "Jina Suh and Eric Horvitz and Ryen W. White and Tim Althoff", + "description": "The COVID-19 pandemic has fundamentally changed our lives beyond just our physical health. To understand the impact of the pandemic and associated policy decisions on a multitude of human needs, we propose a computational methodology, building on Maslow's hierarchy of needs, that can capture a holistic view of relative changes in needs following the pandemic through a difference-in-differences approach that corrects for seasonality and volume variations. When applied to over 35 billion search interactions spanning over 36000 ZIP codes in the US, we found that the expression of basic human needs has increased exponentially while higher-level aspirations declined, that the durations of shelter-in-place mandates significantly impacted social-emotional needs, and that there are potential barriers to meeting critical needs online.", + "eprint": "2008.07045", + "highlight": 0, + "pdf": "suh2020populationscale.pdf", + "primaryclass": "cs.CY", + "journal": "WSDM", + "thumbnail": "suh2020populationscale.png", + "title": "Population-Scale Study of Human Needs During the COVID-19 Pandemic: Analysis and Implications", + "year": "2021" + }, + "authorNames": [ + "Jina Suh", + "Eric Horvitz", + "Ryen W. White", + "Tim Althoff" + ] + }, + { + "id": "althoffModeration", + "title": "The Effect of Moderation on Online Mental Health Conversations", + "authors": "David Wadden and Tal August and Qisheng Li and Tim Althoff", + "year": 2021, + "venue": "ICWSM", + "description": "", + "highlight": false, + "award": "Best Paper (Outstanding Study Design)", + "pdf": "/resources/pubpdfs/althoffModeration.pdf", + "image": "/resources/thumbnails/althoffModeration.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "David Wadden and Tal August and Qisheng Li and Tim Althoff", + "description": "", + "highlight": 0, + "journal": "ICWSM", + "award": "Best Paper (Outstanding Study Design)", + "note": "Under submission.", + "pdf": "althoffModeration.pdf", + "thumbnail": "althoffModeration.png", + "title": "The Effect of Moderation on Online Mental Health Conversations", + "year": "2021" + }, + "authorNames": [ + "David Wadden", + "Tal August", + "Qisheng Li", + "Tim Althoff" + ] + }, + { + "id": "sharma2021facilitating", + "title": "Towards Facilitating Empathic Conversations in Online Mental Health Support: A Reinforcement Learning Approach", + "authors": "Sharma, Ashish and Lin, Inna W and Miner, Adam S and Atkins, David C and Althoff, Tim", + "year": 2021, + "venue": "WWW", + "description": "Access to mental health care is a global challenge that online peer support platforms like TalkLife can help mitigate. Millions of people seek and provide support online but they struggle to have effective conversations. In this paper, we work towards improving empathy in online mental health support conversations. We introduce empathic rewriting, a new task for transforming low-empathy conversations to higher empathy. We propose PARTNER, a deep reinforcement learning agent that learns to make sentence-level edits to conversations in order to increase the expressed level of empathy while maintaining conversation quality through specificity, fluency, and diversity.", + "highlight": false, + "award": "Best Paper (single award across all 1736 submissions)", + "pdf": "/resources/pubpdfs/sharma2021facilitating.pdf", + "image": "/resources/thumbnails/sharma2021facilitating.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Sharma, Ashish and Lin, Inna W and Miner, Adam S and Atkins, David C and Althoff, Tim", + "booktitle": "WWW", + "award": "Best Paper (single award across all 1736 submissions)", + "description": "Access to mental health care is a global challenge that online peer support platforms like TalkLife can help mitigate. Millions of people seek and provide support online but they struggle to have effective conversations. In this paper, we work towards improving empathy in online mental health support conversations. We introduce empathic rewriting, a new task for transforming low-empathy conversations to higher empathy. We propose PARTNER, a deep reinforcement learning agent that learns to make sentence-level edits to conversations in order to increase the expressed level of empathy while maintaining conversation quality through specificity, fluency, and diversity.", + "highlight": 0, + "pdf": "sharma2021facilitating.pdf", + "thumbnail": "sharma2021facilitating.png", + "title": "Towards Facilitating Empathic Conversations in Online Mental Health Support: A Reinforcement Learning Approach", + "year": "2021" + }, + "authorNames": [ + "Ashish Sharma", + "Inna W Lin", + "Adam S Miner", + "David C Atkins", + "Tim Althoff" + ] + }, + { + "id": "sharma2020computational", + "title": "A Computational Approach to Understanding Empathy Expressed in Text-Based Mental Health Support", + "authors": "Ashish Sharma and Adam S. Miner and David C. Atkins and Tim Althoff", + "year": 2020, + "venue": "EMNLP", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/sharma2020computational.pdf", + "image": "/resources/thumbnails/sharma2020computational.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "archiveprefix": "arXiv", + "author": "Ashish Sharma and Adam S. Miner and David C. Atkins and Tim Althoff", + "journal": "EMNLP", + "description": "", + "eprint": "2009.08441", + "highlight": 0, + "pdf": "sharma2020computational.pdf", + "primaryclass": "cs.CL", + "thumbnail": "sharma2020computational.png", + "title": "A Computational Approach to Understanding Empathy Expressed in Text-Based Mental Health Support", + "year": "2020" + }, + "authorNames": [ + "Ashish Sharma", + "Adam S. Miner", + "David C. Atkins", + "Tim Althoff" + ] + }, + { + "id": "althoffPocketskills", + "title": "Data-Driven Implications for Translating Evidence-Based Psychotherapies into Technology-Delivered Interventions", + "authors": "Jessica Schroeder and Jina Suh and Chelsey Wilks and Mary Czerwinski and Sean Munson and James Fogarty and Tim Althoff", + "year": 2020, + "venue": "EAI Pervasive Health", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoffPocketskills.pdf", + "image": "/resources/thumbnails/althoffPocketskills.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Jessica Schroeder and Jina Suh and Chelsey Wilks and Mary Czerwinski and Sean Munson and James Fogarty and Tim Althoff", + "description": "", + "highlight": 0, + "journal": "EAI Pervasive Health", + "note": "Under submission.", + "pdf": "althoffPocketskills.pdf", + "thumbnail": "althoffPocketskills.png", + "title": "Data-Driven Implications for Translating Evidence-Based Psychotherapies into Technology-Delivered Interventions", + "year": "2020" + }, + "authorNames": [ + "Jessica Schroeder", + "Jina Suh", + "Chelsey Wilks", + "Mary Czerwinski", + "Sean Munson", + "James Fogarty", + "Tim Althoff" + ] + }, + { + "id": "althoffTalklifeEngagement", + "title": "Engagement Patterns of Peer-to-Peer Interactions on Mental Health Platforms", + "authors": "Ashish Sharma and Monojit Choudhury and Tim Althoff and Amit Sharma", + "year": 2020, + "venue": "ICWSM", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoffTalklifeEngagement.pdf", + "image": "/resources/thumbnails/althoffTalklifeEngagement.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Ashish Sharma and Monojit Choudhury and Tim Althoff and Amit Sharma", + "description": "", + "highlight": 0, + "journal": "ICWSM", + "note": "Under submission.", + "pdf": "althoffTalklifeEngagement.pdf", + "thumbnail": "althoffTalklifeEngagement.png", + "title": "Engagement Patterns of Peer-to-Peer Interactions on Mental Health Platforms", + "year": "2020" + }, + "authorNames": [ + "Ashish Sharma", + "Monojit Choudhury", + "Tim Althoff", + "Amit Sharma" + ] + }, + { + "id": "liupaths2020", + "title": "Paths Explored, Paths Omitted, Paths Obscured: Decision Points & Selective Reporting in End-to-End Data Analysis", + "authors": "Liu, Yang and Althoff, Tim and Heer, Jeffrey", + "year": 2020, + "venue": "CHI", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/liupaths2020.pdf", + "image": "/resources/thumbnails/liupaths2020.png", + "code": "", + "doi": "10.1145/3313831.3376533", + "url": "https://doi.org/10.1145/3313831.3376533", + "legacy": { + "abstract": "Drawing reliable inferences from data involves many, sometimes arbitrary, decisions across phases of data collection, wrangling, and modeling. As different choices can lead to diverging conclusions, understanding how researchers make analytic decisions is important for supporting robust and replicable analysis. In this study, we pore over nine published research studies and conduct semi-structured interviews with their authors. We observe that researchers often base their decisions on methodological or theoretical concerns, but subject to constraints arising from the data, expertise, or perceived interpretability. We confirm that researchers may experiment with choices in search of desirable results, but also identify other reasons why researchers explore alternatives yet omit findings. In concert with our interviews, we also contribute visualizations for communicating decision processes throughout an analysis. Based on our results, we identify design opportunities for strengthening end-to-end analysis, for instance via tracking and meta-analysis of multiple decision paths.", + "address": "New York, NY, USA", + "author": "Liu, Yang and Althoff, Tim and Heer, Jeffrey", + "booktitle": "CHI", + "description": "", + "doi": "10.1145/3313831.3376533", + "highlight": 0, + "isbn": "9781450367080", + "keywords": "reproducibility, analytic decision making, garden of forking paths, data analysis, multiverse analysis, interview study", + "location": "Honolulu, HI, USA", + "numpages": "14", + "pages": "1–14", + "pdf": "liupaths2020.pdf", + "publisher": "Association for Computing Machinery", + "series": "CHI '20", + "thumbnail": "liupaths2020.png", + "title": "Paths Explored, Paths Omitted, Paths Obscured: Decision Points & Selective Reporting in End-to-End Data Analysis", + "url": "https://doi.org/10.1145/3313831.3376533", + "year": "2020" + }, + "authorNames": [ + "Yang Liu", + "Tim Althoff", + "Jeffrey Heer" + ] + }, + { + "id": "gordonactivity2019", + "title": "Goal-Setting And Achievement In Activity Tracking Apps: A Case Study Of MyFitnessPal", + "authors": "Gordon, Mitchell and Althoff, Tim and Leskovec, Jure", + "year": 2019, + "venue": "", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/gordonactivity2019.pdf", + "image": "/resources/thumbnails/gordonactivity2019.png", + "code": "", + "doi": "10.1145/3308558.3313432", + "url": "https://doi.org/10.1145/3308558.3313432", + "legacy": { + "abstract": "Activity tracking apps often make use of goals as one of their core motivational tools. There are two critical components to this tool: setting a goal, and subsequently achieving that goal. Despite its crucial role in how a number of prominent self-tracking apps function, there has been relatively little investigation of the goal-setting and achievement aspects of self-tracking apps. Here we explore this issue, investigating a particular goal setting and achievement process that is extensive, recorded, and crucial for both the app and its users' success: weight loss goals in MyFitnessPal. We present a large-scale study of 1.4 million users and weight loss goals, allowing for an unprecedented detailed view of how people set and achieve their goals. We find that, even for difficult long-term goals, behavior within the first 7 days predicts those who ultimately achieve their goals, that is, those who lose at least as much weight as they set out to, and those who do not. For instance, high amounts of early weight loss, which some researchers have classified as unsustainable, leads to higher goal achievement rates. We also show that early food intake, self-monitoring motivation, and attitude towards the goal are important factors. We then show that we can use our findings to predict goal achievement with an accuracy of 79% ROC AUC just 7 days after a goal is set. Finally, we discuss how our findings could inform steps to improve goal achievement in self-tracking apps.", + "address": "New York, NY, USA", + "author": "Gordon, Mitchell and Althoff, Tim and Leskovec, Jure", + "booktitle": "", + "description": "", + "doi": "10.1145/3308558.3313432", + "highlight": 0, + "isbn": "9781450366748", + "location": "San Francisco, CA, USA", + "numpages": "12", + "pages": "571–582", + "pdf": "gordonactivity2019.pdf", + "publisher": "Association for Computing Machinery", + "series": "WWW '19", + "thumbnail": "gordonactivity2019.png", + "title": "Goal-Setting And Achievement In Activity Tracking Apps: A Case Study Of MyFitnessPal", + "url": "https://doi.org/10.1145/3308558.3313432", + "year": "2019" + }, + "authorNames": [ + "Mitchell Gordon", + "Tim Althoff", + "Jure Leskovec" + ] + }, + { + "id": "xuleveraging2019", + "title": "Leveraging Routine Behavior and Contextually-Filtered Features for Depression Detection among College Students", + "authors": "Xu, Xuhai and Chikersal, Prerna and Doryab, Afsaneh and Villalba, Daniella K. and Dutcher, Janine M. and Tumminia, Michael J. and Althoff, Tim and Cohen, Sheldon and Creswell, Kasey G. and Creswell, J. David and Mankoff, Jennifer and Dey, Anind K.", + "year": 2019, + "venue": "IMWUT", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/xuleveraging2019.pdf", + "image": "/resources/thumbnails/xuleveraging2019.png", + "code": "", + "doi": "10.1145/3351274", + "url": "https://doi.org/10.1145/3351274", + "legacy": { + "abstract": "The rate of depression in college students is rising, which is known to increase suicide risk, lower academic performance and double the likelihood of dropping out of school. Existing work on finding relationships between passively sensed behavior and depression, as well as detecting depression, mainly derives relevant unimodal features from a single sensor. However, co-occurrence of values in multiple sensors may provide better features, because such features can describe behavior in context. We present a new method to extract contextually filtered features from passively collected, time-series mobile data via association rule mining. After calculating traditional unimodal features from the data, we extract rules that relate unimodal features to each other using association rule mining. We extract rules from each class separately (e.g., depression vs. non-depression). We introduce a new metric to select a subset of rules that distinguish between the two classes. From these rules, which capture the relationship between multiple unimodal features, we automatically extract contextually filtered features. These features are then fed into a traditional machine learning pipeline to detect the class of interest (in our case, depression), defined by whether a student has a high BDI-II score at the end of the semester. The behavior rules generated by our methods are highly interpretable representations of differences between classes. Our best model uses contextually-filtered features to significantly outperform a standard model that uses only unimodal features, by an average of 9.7% across a variety of metrics. We further verified the generalizability of our approach on a second dataset, and achieved very similar results.", + "address": "New York, NY, USA", + "articleno": "116", + "author": "Xu, Xuhai and Chikersal, Prerna and Doryab, Afsaneh and Villalba, Daniella K. and Dutcher, Janine M. and Tumminia, Michael J. and Althoff, Tim and Cohen, Sheldon and Creswell, Kasey G. and Creswell, J. David and Mankoff, Jennifer and Dey, Anind K.", + "description": "", + "doi": "10.1145/3351274", + "highlight": 0, + "issue_date": "September 2019", + "journal": "IMWUT", + "keywords": "Passive sensing, Depression detection, Behavior mining, Association rule mining", + "month": "September", + "number": "3", + "numpages": "33", + "pdf": "xuleveraging2019.pdf", + "publisher": "Association for Computing Machinery", + "thumbnail": "xuleveraging2019.png", + "title": "Leveraging Routine Behavior and Contextually-Filtered Features for Depression Detection among College Students", + "url": "https://doi.org/10.1145/3351274", + "volume": "3", + "year": "2019" + }, + "authorNames": [ + "Xuhai Xu", + "Prerna Chikersal", + "Afsaneh Doryab", + "Daniella K. Villalba", + "Janine M. Dutcher", + "Michael J. Tumminia", + "Tim Althoff", + "Sheldon Cohen", + "Kasey G. Creswell", + "J. David Creswell", + "Jennifer Mankoff", + "Anind K. Dey" + ] + }, + { + "id": "sefidgarpassively2020", + "title": "Passively-Sensed Behavioral Correlates of Discrimination Events in College Students", + "authors": "Sefidgar, Yasaman S. and Seo, Woosuk and Kuehn, Kevin S. and Althoff, Tim and Browning, Anne and Riskin, Eve and Nurius, Paula S. and Dey, Anind K. and Mankoff, Jennifer", + "year": 2019, + "venue": "CSCW", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/sefidgarpassively2020.pdf", + "image": "/resources/thumbnails/sefidgarpassively2020.png", + "code": "", + "doi": "10.1145/3359216", + "url": "https://doi.org/10.1145/3359216", + "legacy": { + "abstract": "A deep understanding of how discrimination impacts psychological health and well-being of students could allow us to better protect individuals at risk and support those who encounter discrimination. While the link between discrimination and diminished psychological and physical well-being is well established, existing research largely focuses on chronic discrimination and long-term outcomes. A better understanding of the short-term behavioral correlates of discrimination events could help us to concretely quantify such experiences, which in turn could support policy and intervention design. In this paper we specifically examine, for the first time, what behaviors change and in what ways in relation to discrimination. We use actively-reported and passively-measured markers of health and well-being in a sample of 209 first-year college students over the course of two academic quarters. We examine changes in indicators of psychological state in relation to reports of unfair treatment in terms of five categories of behaviors: physical activity, phone usage, social interaction, mobility, and sleep. We find that students who encounter unfair treatment become more physically active, interact more with their phone in the morning, make more calls in the evening, and spend more time in bed on the day of the event. Some of these patterns continue the next day. Our results further our understanding of the impact of discrimination and can inform intervention work.", + "address": "New York, NY, USA", + "articleno": "114", + "author": "Sefidgar, Yasaman S. and Seo, Woosuk and Kuehn, Kevin S. and Althoff, Tim and Browning, Anne and Riskin, Eve and Nurius, Paula S. and Dey, Anind K. and Mankoff, Jennifer", + "description": "", + "doi": "10.1145/3359216", + "highlight": 0, + "issue_date": "November 2019", + "journal": "CSCW", + "keywords": "discrimination, mobile health, microaggression, mobile sensing", + "month": "November", + "number": "CSCW", + "numpages": "29", + "pdf": "sefidgarpassively2020.pdf", + "publisher": "Association for Computing Machinery", + "thumbnail": "sefidgarpassively2020.png", + "title": "Passively-Sensed Behavioral Correlates of Discrimination Events in College Students", + "url": "https://doi.org/10.1145/3359216", + "volume": "3", + "year": "2019" + }, + "authorNames": [ + "Yasaman S. Sefidgar", + "Woosuk Seo", + "Kevin S. Kuehn", + "Tim Althoff", + "Anne Browning", + "Eve Riskin", + "Paula S. Nurius", + "Anind K. Dey", + "Jennifer Mankoff" + ] + }, + { + "id": "kurashima2018tipas", + "title": "Modeling Interdependent and Periodic Real-World Action Sequences", + "authors": "Kurashima, Takeshi and Althoff, Tim and Leskovec, Jure", + "year": 2018, + "venue": "WWW", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/kurashima2018tipas.pdf", + "image": "/resources/thumbnails/kurashima2018tipas.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Kurashima, Takeshi and Althoff, Tim and Leskovec, Jure", + "booktitle": "WWW", + "description": "", + "highlight": 0, + "note": "Online Appendix. \\url{http://bit.ly/2stjpB4}", + "optjournal": "foo", + "optnote": "\\url{http://bit.ly/2gGUnWb}", + "opttitle": "{Online appendix of this paper}", + "pdf": "kurashima2018tipas.pdf", + "thumbnail": "kurashima2018tipas.png", + "title": "Modeling Interdependent and Periodic Real-World Action Sequences", + "year": "2018" + }, + "authorNames": [ + "Takeshi Kurashima", + "Tim Althoff", + "Jure Leskovec" + ] + }, + { + "id": "althoff2018psychomotor", + "title": "Psychomotor function measured via online activity predicts motor vehicle fatality risk", + "authors": "Althoff, Tim and Horvitz, Eric and White, Ryen W", + "year": 2018, + "venue": "NPJ Digital Medicine", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2018psychomotor.pdf", + "image": "/resources/thumbnails/althoff2018psychomotor.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim and Horvitz, Eric and White, Ryen W", + "description": "", + "highlight": 0, + "journal": "NPJ Digital Medicine", + "optnumber": "1", + "optpages": "3", + "optpublisher": "Nature Publishing Group", + "optvolume": "1", + "pdf": "althoff2018psychomotor.pdf", + "thumbnail": "althoff2018psychomotor.png", + "title": "Psychomotor function measured via online activity predicts motor vehicle fatality risk", + "year": "2018" + }, + "authorNames": [ + "Tim Althoff", + "Eric Horvitz", + "Ryen W White" + ] + }, + { + "id": "althoff2016onlineappendix", + "title": "Harnessing the Web for Population-Scale Physiological Sensing: A Case Study of Sleep and Performance. ", + "authors": "Althoff, Tim and Horvitz, Eric and White, Ryen W and Zeitzer, Jamie", + "year": 2017, + "venue": "WWW", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2016onlineappendix.pdf", + "image": "/resources/thumbnails/althoff2016onlineappendix.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim and Horvitz, Eric and White, Ryen W and Zeitzer, Jamie", + "booktitle": "WWW", + "description": "", + "highlight": 0, + "note": "\\url{http://stanford.io/2ejFPhD}", + "optauthor": "Althoff, Tim and others", + "pdf": "althoff2016onlineappendix.pdf", + "thumbnail": "althoff2016onlineappendix.png", + "title": "Harnessing the Web for Population-Scale Physiological Sensing: A Case Study of Sleep and Performance. ", + "year": "2017" + }, + "authorNames": [ + "Tim Althoff", + "Eric Horvitz", + "Ryen W White", + "Jamie Zeitzer" + ] + }, + { + "id": "shameli2017gamification", + "title": "How gamification affects physical activity: Large-scale analysis of walking challenges in a mobile application", + "authors": "Shameli, Ali and Althoff, Tim and Saberi, Amin and Leskovec, Jure", + "year": 2017, + "venue": "WWW", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/shameli2017gamification.pdf", + "image": "/resources/thumbnails/shameli2017gamification.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Shameli, Ali and Althoff, Tim and Saberi, Amin and Leskovec, Jure", + "booktitle": "WWW", + "description": "", + "highlight": 0, + "optbooktitle": "Proceedings of the 26th International Conference on World Wide Web Companion", + "optorganization": "International World Wide Web Conferences Steering Committee", + "optpages": "455--463", + "pdf": "shameli2017gamification.pdf", + "thumbnail": "shameli2017gamification.png", + "title": "How gamification affects physical activity: Large-scale analysis of walking challenges in a mobile application", + "year": "2017" + }, + "authorNames": [ + "Ali Shameli", + "Tim Althoff", + "Amin Saberi", + "Jure Leskovec" + ] + }, + { + "id": "althoff2017large", + "title": "Large-scale physical activity data reveal worldwide activity inequality", + "authors": "Althoff, Tim and Sosic, Rok and Hicks, Jennifer L and King, Abby C and Delp, Scott L and Leskovec, Jure", + "year": 2017, + "venue": "Nature", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2017large.pdf", + "image": "/resources/thumbnails/althoff2017large.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim and Sosic, Rok and Hicks, Jennifer L and King, Abby C and Delp, Scott L and Leskovec, Jure", + "description": "", + "highlight": 0, + "journal": "Nature", + "optpublisher": "Nature Research", + "pdf": "althoff2017large.pdf", + "thumbnail": "althoff2017large.png", + "title": "Large-scale physical activity data reveal worldwide activity inequality", + "year": "2017" + }, + "authorNames": [ + "Tim Althoff", + "Rok Sosic", + "Jennifer L Hicks", + "Abby C King", + "Scott L Delp", + "Jure Leskovec" + ] + }, + { + "id": "althoff2017onlineactions", + "title": "Online Actions with Offline Impact: How Online Social Networks Influence Online and Offline User Behavior", + "authors": "Althoff, Tim and Jindal, Pranav and Leskovec, Jure", + "year": 2017, + "venue": "WSDM", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2017onlineactions.pdf", + "image": "/resources/thumbnails/althoff2017onlineactions.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim and Jindal, Pranav and Leskovec, Jure", + "booktitle": "WSDM", + "description": "", + "highlight": 0, + "pdf": "althoff2017onlineactions.pdf", + "thumbnail": "althoff2017onlineactions.png", + "title": "Online Actions with Offline Impact: How Online Social Networks Influence Online and Offline User Behavior", + "year": "2017" + }, + "authorNames": [ + "Tim Althoff", + "Pranav Jindal", + "Jure Leskovec" + ] + }, + { + "id": "althoff2017population", + "title": "Population-Scale Pervasive Health", + "authors": "Althoff, Tim", + "year": 2017, + "venue": "IEEE Pervasive Computing", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2017population.pdf", + "image": "/resources/thumbnails/althoff2017population.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim", + "description": "", + "highlight": 0, + "journal": "IEEE Pervasive Computing", + "number": "4", + "pages": "75--79", + "pdf": "althoff2017population.pdf", + "publisher": "IEEE", + "thumbnail": "althoff2017population.png", + "title": "Population-Scale Pervasive Health", + "volume": "16", + "year": "2017" + }, + "authorNames": [ + "Tim Althoff" + ] + }, + { + "id": "althoff2016pokemon", + "title": "Influence of Pokémon Go on Physical Activity", + "authors": "Althoff, Tim and White, Ryen W and Horvitz, Eric", + "year": 2016, + "venue": "JMIR", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2016pokemon.pdf", + "image": "/resources/thumbnails/althoff2016pokemon.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim and White, Ryen W and Horvitz, Eric", + "description": "", + "highlight": 0, + "journal": "JMIR", + "optday": "06", + "optdoi": "10.2196/jmir.6759", + "optmonth": "Dec", + "optnote": "doi:10.2196/jmir.6759", + "optnumber": "12", + "optpages": "e315", + "opttitle": "Influence of Pokémon Go on Physical Activity: Study and Implications", + "opturl": "http://www.jmir.org/2016/12/e315/", + "optvolume": "18", + "pdf": "althoff2016pokemon.pdf", + "thumbnail": "althoff2016pokemon.png", + "title": "Influence of Pokémon Go on Physical Activity", + "year": "2016" + }, + "authorNames": [ + "Tim Althoff", + "Ryen W White", + "Eric Horvitz" + ] + }, + { + "id": "althoff2016counseling", + "title": "Large-scale Analysis of Counseling Conversations: {An} Application of Natural Language Processing to Mental Health", + "authors": "Althoff, Tim and Clark, Kevin and Leskovec, Jure", + "year": 2016, + "venue": "TACL", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2016counseling.pdf", + "image": "/resources/thumbnails/althoff2016counseling.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim and Clark, Kevin and Leskovec, Jure", + "description": "", + "highlight": 0, + "journal": "TACL", + "optjournal": "Transactions of the Association for Computational Linguistics", + "pdf": "althoff2016counseling.pdf", + "thumbnail": "althoff2016counseling.png", + "title": "Large-scale Analysis of Counseling Conversations: {An} Application of Natural Language Processing to Mental Health", + "year": "2016" + }, + "authorNames": [ + "Tim Althoff", + "Kevin Clark", + "Jure Leskovec" + ] + }, + { + "id": "althoff2015donor", + "title": "Donor retention in online crowdfunding communities: A case study of DonorsChoose.org", + "authors": "Althoff, Tim and Leskovec, Jure", + "year": 2015, + "venue": "WWW", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2015donor.pdf", + "image": "/resources/thumbnails/althoff2015donor.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim and Leskovec, Jure", + "booktitle": "WWW", + "description": "", + "highlight": 0, + "optbooktitle": "Proceedings of the 24th International Conference on World Wide Web", + "optorganization": "International World Wide Web Conferences Steering Committee", + "optpages": "34--44", + "pdf": "althoff2015donor.pdf", + "thumbnail": "althoff2015donor.png", + "title": "Donor retention in online crowdfunding communities: A case study of DonorsChoose.org", + "year": "2015" + }, + "authorNames": [ + "Tim Althoff", + "Jure Leskovec" + ] + }, + { + "id": "althoff2014ask", + "title": "How to Ask for a Favor: A Case Study on the Success of Altruistic Requests.", + "authors": "Althoff, Tim and Danescu-Niculescu-Mizil, Cristian and Jurafsky, Dan", + "year": 2014, + "venue": "ICWSM", + "description": "", + "highlight": false, + "award": "", + "pdf": "/resources/pubpdfs/althoff2014ask.pdf", + "image": "/resources/thumbnails/althoff2014ask.png", + "code": "", + "doi": "", + "url": "", + "legacy": { + "author": "Althoff, Tim and Danescu-Niculescu-Mizil, Cristian and Jurafsky, Dan", + "booktitle": "ICWSM", + "description": "", + "highlight": 0, + "pdf": "althoff2014ask.pdf", + "thumbnail": "althoff2014ask.png", + "title": "How to Ask for a Favor: A Case Study on the Success of Altruistic Requests.", + "year": "2014" + }, + "authorNames": [ + "Tim Althoff", + "Cristian Danescu-Niculescu-Mizil", + "Dan Jurafsky" + ] + } +] diff --git a/content/sponsors.json b/content/sponsors.json new file mode 100644 index 0000000..ad5b79d --- /dev/null +++ b/content/sponsors.json @@ -0,0 +1,30 @@ +[ + { + "path": "/spons/adobe.jpg", + "name": "Adobe" + }, + { + "path": "/spons/ai2.png", + "name": "AI2" + }, + { + "path": "/spons/gates.png", + "name": "The Bill and Melinda Gates Foundation" + }, + { + "path": "/spons/msr.gif", + "name": "Microsoft Research" + }, + { + "path": "/spons/nih.png", + "name": "The National Institutes of Health" + }, + { + "path": "/spons/nsf.png", + "name": "The National Science Foundation" + }, + { + "path": "/spons/onr.png", + "name": "The Office of Naval Research" + } +] diff --git a/css/main.scss b/css/main.scss deleted file mode 100644 index 0d9c9f2..0000000 --- a/css/main.scss +++ /dev/null @@ -1,254 +0,0 @@ ---- ---- - -@import "bootstrap"; - -html { - height: 100%; -} - -body { - padding-top: 70px; - height: 100%; - display: flex; - flex-direction: column; -} - -figcaption { - text-align: right; - margin-top: -20px; - margin-bottom: 20px; -} - -/* Top navigation bar */ - -.navbar-brand { - padding: 0; - padding-left: ($grid-gutter-width / 2); - padding-right: ($grid-gutter-width / 2); - img { - margin: 0; - height: $navbar-height; - } -} - -p.byline { - text-align: center; - font-size: 18px; - line-height: 36px; - margin-top: -24px; - margin-bottom: 48px; -} - -.container-fluid { - margin-right: auto; - margin-left: auto; - max-width: 1000px; /* or 950px */ -} - -/* Home, News */ -.home { - flex: 1; - width: 100%; -} - -#newsid p { - text-align: left; -} - -#homeidtmp h1 { - text-align: center; -} - -#newsid img { - margin-top: 6px; - margin-bottom: 6px; -} - -#newslogo { - width: 40%; - display: block; - margin-left: auto; - margin-right: auto; - padding-bottom: 20px; -} - -/* Team & Publications */ -.bdata-img-headshot { - border-radius: 50%; - box-shadow: 2px 2px 5px #888888; - width: 150px; - height: 150px; - margin-left: auto; - margin-right: auto; - display: block; - max-width: none; -} - -@media (max-width: $screen-sm-min) { - .bdata-img-headshot { - width: 100%; - height: 100%; - } -} - -.spons { - height: 100px; - margin-left: 5px; - margin-right: 5px; - // display: block; - // max-width: 100%; -} - -.bdata-member { - display: flex; - flex-direction: column; - margin-left: auto; - margin-right: auto; - display: block; - text-align: center; -} - -.hider { - max-height: 100px; - height: auto; - transition: ease-in-out all 0.2s; - overflow:hidden; - } - -.bdata-pub-highlight { - position: relative; - display: flex; - flex-direction: row; - min-width: 0; - word-wrap: break-word; - // background-color: #eee; - background-clip: border-box; - border: 1px solid #eee; - border-radius: $border-radius-base; - margin-bottom: $grid-gutter-width; - align-items: center; - - > hr { - margin-right: 0; - margin-left: 0; - } - - > .list-group:first-child { - .list-group-item:first-child { - border-radius: $border-radius-base; - } - } - - > .list-group:last-child { - .list-group-item:last-child { - border-radius: $border-radius-base; - } - } -} - -.bdata-pub-img-highlight { - width: 200px; - border-top-left-radius: $border-radius-base; - border-top-right-radius: $border-radius-base; - padding: 10px; -} - -.bdata-pub-body { - // Enable `flex-grow: 1` for decks and groups so that card blocks take up - // as much space as possible, ensuring footers are aligned to the bottom. - flex: 1 1 auto; - padding: 0 $grid-gutter-width / 2; - display: flex; - flex-direction: column; -} - -.bdata-pub-title-highlight { - // overflow: hidden; - display: -webkit-box; - // -webkit-line-clamp: 1; - -webkit-box-orient: vertical; - // height: $line-height-computed; - font-weight: bold; -} - -.bdata-pub-subtitle-highlight { - // overflow: hidden; - // display: -webkit-box; - -webkit-line-clamp: 1; - -webkit-box-orient: vertical; - // height: 5 * $line-height-computed; -} - -.bdata-pub { - position: relative; - display: flex; - flex-direction: row; - min-width: 0; - word-wrap: break-word; - background-clip: border-box; - border-radius: $border-radius-base; - margin-bottom: $grid-gutter-width / 2; - align-items: flex-start; -} - -.bdata-pub-img { - width: 100px; - border-top-left-radius: $border-radius-base; - border-top-right-radius: $border-radius-base; - padding: 10px; -} - -.bdata-pub-title { - overflow: hidden; - font-weight: bold; - > p { - margin: 0; - } -} - -#picid img { - margin: 6px 3px 60px 6px; - border-radius: 1%; - box-shadow: 2px 2px 5px #888888; -} -#gridid .row { - margin-bottom: 24px; -} - -/* Grid overrides */ -.col-sm-1, -.col-sm-2, -.col-sm-3, -.col-sm-5, -.col-sm-6, -.col-sm-7, -.col-sm-8, -.col-sm-9, -.col-sm-10, -.col-sm-11, -.col-sm-12 { - padding-left: 16px; - padding-right: 16px; -} - -/* Grid overrides */ -.col-sm-4 { - padding-left: 26px; - padding-right: 26px; -} - -/* Carusel */ - -.carousel { - border-radius: 3px 3px 3px 3px; - margin-bottom: 20px; - margin-top: 20px; - margin-left: 30px; - margin-right: 30px; -} - -.award { - color: #a83262; - font-weight: bold; -} \ No newline at end of file diff --git a/js/bootstrap.js b/js/bootstrap.js deleted file mode 100644 index 01fbbcb..0000000 --- a/js/bootstrap.js +++ /dev/null @@ -1,2363 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under the MIT license - */ - -if (typeof jQuery === 'undefined') { - throw new Error('Bootstrap\'s JavaScript requires jQuery') -} - -+function ($) { - 'use strict'; - var version = $.fn.jquery.split(' ')[0].split('.') - if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) { - throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3') - } -}(jQuery); - -/* ======================================================================== - * Bootstrap: transition.js v3.3.6 - * http://getbootstrap.com/javascript/#transitions - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) - // ============================================================ - - function transitionEnd() { - var el = document.createElement('bootstrap') - - var transEndEventNames = { - WebkitTransition : 'webkitTransitionEnd', - MozTransition : 'transitionend', - OTransition : 'oTransitionEnd otransitionend', - transition : 'transitionend' - } - - for (var name in transEndEventNames) { - if (el.style[name] !== undefined) { - return { end: transEndEventNames[name] } - } - } - - return false // explicit for ie8 ( ._.) - } - - // http://blog.alexmaccaw.com/css-transitions - $.fn.emulateTransitionEnd = function (duration) { - var called = false - var $el = this - $(this).one('bsTransitionEnd', function () { called = true }) - var callback = function () { if (!called) $($el).trigger($.support.transition.end) } - setTimeout(callback, duration) - return this - } - - $(function () { - $.support.transition = transitionEnd() - - if (!$.support.transition) return - - $.event.special.bsTransitionEnd = { - bindType: $.support.transition.end, - delegateType: $.support.transition.end, - handle: function (e) { - if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) - } - } - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: alert.js v3.3.6 - * http://getbootstrap.com/javascript/#alerts - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // ALERT CLASS DEFINITION - // ====================== - - var dismiss = '[data-dismiss="alert"]' - var Alert = function (el) { - $(el).on('click', dismiss, this.close) - } - - Alert.VERSION = '3.3.6' - - Alert.TRANSITION_DURATION = 150 - - Alert.prototype.close = function (e) { - var $this = $(this) - var selector = $this.attr('data-target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - var $parent = $(selector) - - if (e) e.preventDefault() - - if (!$parent.length) { - $parent = $this.closest('.alert') - } - - $parent.trigger(e = $.Event('close.bs.alert')) - - if (e.isDefaultPrevented()) return - - $parent.removeClass('in') - - function removeElement() { - // detach from parent, fire event then clean up data - $parent.detach().trigger('closed.bs.alert').remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent - .one('bsTransitionEnd', removeElement) - .emulateTransitionEnd(Alert.TRANSITION_DURATION) : - removeElement() - } - - - // ALERT PLUGIN DEFINITION - // ======================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.alert') - - if (!data) $this.data('bs.alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - var old = $.fn.alert - - $.fn.alert = Plugin - $.fn.alert.Constructor = Alert - - - // ALERT NO CONFLICT - // ================= - - $.fn.alert.noConflict = function () { - $.fn.alert = old - return this - } - - - // ALERT DATA-API - // ============== - - $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: button.js v3.3.6 - * http://getbootstrap.com/javascript/#buttons - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // BUTTON PUBLIC CLASS DEFINITION - // ============================== - - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Button.DEFAULTS, options) - this.isLoading = false - } - - Button.VERSION = '3.3.6' - - Button.DEFAULTS = { - loadingText: 'loading...' - } - - Button.prototype.setState = function (state) { - var d = 'disabled' - var $el = this.$element - var val = $el.is('input') ? 'val' : 'html' - var data = $el.data() - - state += 'Text' - - if (data.resetText == null) $el.data('resetText', $el[val]()) - - // push to event loop to allow forms to submit - setTimeout($.proxy(function () { - $el[val](data[state] == null ? this.options[state] : data[state]) - - if (state == 'loadingText') { - this.isLoading = true - $el.addClass(d).attr(d, d) - } else if (this.isLoading) { - this.isLoading = false - $el.removeClass(d).removeAttr(d) - } - }, this), 0) - } - - Button.prototype.toggle = function () { - var changed = true - var $parent = this.$element.closest('[data-toggle="buttons"]') - - if ($parent.length) { - var $input = this.$element.find('input') - if ($input.prop('type') == 'radio') { - if ($input.prop('checked')) changed = false - $parent.find('.active').removeClass('active') - this.$element.addClass('active') - } else if ($input.prop('type') == 'checkbox') { - if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false - this.$element.toggleClass('active') - } - $input.prop('checked', this.$element.hasClass('active')) - if (changed) $input.trigger('change') - } else { - this.$element.attr('aria-pressed', !this.$element.hasClass('active')) - this.$element.toggleClass('active') - } - } - - - // BUTTON PLUGIN DEFINITION - // ======================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.button') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.button', (data = new Button(this, options))) - - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - var old = $.fn.button - - $.fn.button = Plugin - $.fn.button.Constructor = Button - - - // BUTTON NO CONFLICT - // ================== - - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } - - - // BUTTON DATA-API - // =============== - - $(document) - .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - Plugin.call($btn, 'toggle') - if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault() - }) - .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { - $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: carousel.js v3.3.6 - * http://getbootstrap.com/javascript/#carousel - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // CAROUSEL CLASS DEFINITION - // ========================= - - var Carousel = function (element, options) { - this.$element = $(element) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.paused = null - this.sliding = null - this.interval = null - this.$active = null - this.$items = null - - this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) - - this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element - .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) - .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) - } - - Carousel.VERSION = '3.3.6' - - Carousel.TRANSITION_DURATION = 600 - - Carousel.DEFAULTS = { - interval: 5000, - pause: 'hover', - wrap: true, - keyboard: true - } - - Carousel.prototype.keydown = function (e) { - if (/input|textarea/i.test(e.target.tagName)) return - switch (e.which) { - case 37: this.prev(); break - case 39: this.next(); break - default: return - } - - e.preventDefault() - } - - Carousel.prototype.cycle = function (e) { - e || (this.paused = false) - - this.interval && clearInterval(this.interval) - - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - - return this - } - - Carousel.prototype.getItemIndex = function (item) { - this.$items = item.parent().children('.item') - return this.$items.index(item || this.$active) - } - - Carousel.prototype.getItemForDirection = function (direction, active) { - var activeIndex = this.getItemIndex(active) - var willWrap = (direction == 'prev' && activeIndex === 0) - || (direction == 'next' && activeIndex == (this.$items.length - 1)) - if (willWrap && !this.options.wrap) return active - var delta = direction == 'prev' ? -1 : 1 - var itemIndex = (activeIndex + delta) % this.$items.length - return this.$items.eq(itemIndex) - } - - Carousel.prototype.to = function (pos) { - var that = this - var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" - if (activeIndex == pos) return this.pause().cycle() - - return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) - } - - Carousel.prototype.pause = function (e) { - e || (this.paused = true) - - if (this.$element.find('.next, .prev').length && $.support.transition) { - this.$element.trigger($.support.transition.end) - this.cycle(true) - } - - this.interval = clearInterval(this.interval) - - return this - } - - Carousel.prototype.next = function () { - if (this.sliding) return - return this.slide('next') - } - - Carousel.prototype.prev = function () { - if (this.sliding) return - return this.slide('prev') - } - - Carousel.prototype.slide = function (type, next) { - var $active = this.$element.find('.item.active') - var $next = next || this.getItemForDirection(type, $active) - var isCycling = this.interval - var direction = type == 'next' ? 'left' : 'right' - var that = this - - if ($next.hasClass('active')) return (this.sliding = false) - - var relatedTarget = $next[0] - var slideEvent = $.Event('slide.bs.carousel', { - relatedTarget: relatedTarget, - direction: direction - }) - this.$element.trigger(slideEvent) - if (slideEvent.isDefaultPrevented()) return - - this.sliding = true - - isCycling && this.pause() - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) - $nextIndicator && $nextIndicator.addClass('active') - } - - var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" - if ($.support.transition && this.$element.hasClass('slide')) { - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - $active - .one('bsTransitionEnd', function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { - that.$element.trigger(slidEvent) - }, 0) - }) - .emulateTransitionEnd(Carousel.TRANSITION_DURATION) - } else { - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger(slidEvent) - } - - isCycling && this.cycle() - - return this - } - - - // CAROUSEL PLUGIN DEFINITION - // ========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.carousel') - var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) - var action = typeof option == 'string' ? option : options.slide - - if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (action) data[action]() - else if (options.interval) data.pause().cycle() - }) - } - - var old = $.fn.carousel - - $.fn.carousel = Plugin - $.fn.carousel.Constructor = Carousel - - - // CAROUSEL NO CONFLICT - // ==================== - - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this - } - - - // CAROUSEL DATA-API - // ================= - - var clickHandler = function (e) { - var href - var $this = $(this) - var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 - if (!$target.hasClass('carousel')) return - var options = $.extend({}, $target.data(), $this.data()) - var slideIndex = $this.attr('data-slide-to') - if (slideIndex) options.interval = false - - Plugin.call($target, options) - - if (slideIndex) { - $target.data('bs.carousel').to(slideIndex) - } - - e.preventDefault() - } - - $(document) - .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) - .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) - - $(window).on('load', function () { - $('[data-ride="carousel"]').each(function () { - var $carousel = $(this) - Plugin.call($carousel, $carousel.data()) - }) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: collapse.js v3.3.6 - * http://getbootstrap.com/javascript/#collapse - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // COLLAPSE PUBLIC CLASS DEFINITION - // ================================ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Collapse.DEFAULTS, options) - this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + - '[data-toggle="collapse"][data-target="#' + element.id + '"]') - this.transitioning = null - - if (this.options.parent) { - this.$parent = this.getParent() - } else { - this.addAriaAndCollapsedClass(this.$element, this.$trigger) - } - - if (this.options.toggle) this.toggle() - } - - Collapse.VERSION = '3.3.6' - - Collapse.TRANSITION_DURATION = 350 - - Collapse.DEFAULTS = { - toggle: true - } - - Collapse.prototype.dimension = function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - Collapse.prototype.show = function () { - if (this.transitioning || this.$element.hasClass('in')) return - - var activesData - var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') - - if (actives && actives.length) { - activesData = actives.data('bs.collapse') - if (activesData && activesData.transitioning) return - } - - var startEvent = $.Event('show.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - if (actives && actives.length) { - Plugin.call(actives, 'hide') - activesData || actives.data('bs.collapse', null) - } - - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - .addClass('collapsing')[dimension](0) - .attr('aria-expanded', true) - - this.$trigger - .removeClass('collapsed') - .attr('aria-expanded', true) - - this.transitioning = 1 - - var complete = function () { - this.$element - .removeClass('collapsing') - .addClass('collapse in')[dimension]('') - this.transitioning = 0 - this.$element - .trigger('shown.bs.collapse') - } - - if (!$.support.transition) return complete.call(this) - - var scrollSize = $.camelCase(['scroll', dimension].join('-')) - - this.$element - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) - } - - Collapse.prototype.hide = function () { - if (this.transitioning || !this.$element.hasClass('in')) return - - var startEvent = $.Event('hide.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var dimension = this.dimension() - - this.$element[dimension](this.$element[dimension]())[0].offsetHeight - - this.$element - .addClass('collapsing') - .removeClass('collapse in') - .attr('aria-expanded', false) - - this.$trigger - .addClass('collapsed') - .attr('aria-expanded', false) - - this.transitioning = 1 - - var complete = function () { - this.transitioning = 0 - this.$element - .removeClass('collapsing') - .addClass('collapse') - .trigger('hidden.bs.collapse') - } - - if (!$.support.transition) return complete.call(this) - - this.$element - [dimension](0) - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(Collapse.TRANSITION_DURATION) - } - - Collapse.prototype.toggle = function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - Collapse.prototype.getParent = function () { - return $(this.options.parent) - .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') - .each($.proxy(function (i, element) { - var $element = $(element) - this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) - }, this)) - .end() - } - - Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { - var isOpen = $element.hasClass('in') - - $element.attr('aria-expanded', isOpen) - $trigger - .toggleClass('collapsed', !isOpen) - .attr('aria-expanded', isOpen) - } - - function getTargetFromTrigger($trigger) { - var href - var target = $trigger.attr('data-target') - || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 - - return $(target) - } - - - // COLLAPSE PLUGIN DEFINITION - // ========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.collapse') - var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) - - if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false - if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.collapse - - $.fn.collapse = Plugin - $.fn.collapse.Constructor = Collapse - - - // COLLAPSE NO CONFLICT - // ==================== - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - // COLLAPSE DATA-API - // ================= - - $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { - var $this = $(this) - - if (!$this.attr('data-target')) e.preventDefault() - - var $target = getTargetFromTrigger($this) - var data = $target.data('bs.collapse') - var option = data ? 'toggle' : $this.data() - - Plugin.call($target, option) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: dropdown.js v3.3.6 - * http://getbootstrap.com/javascript/#dropdowns - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // DROPDOWN CLASS DEFINITION - // ========================= - - var backdrop = '.dropdown-backdrop' - var toggle = '[data-toggle="dropdown"]' - var Dropdown = function (element) { - $(element).on('click.bs.dropdown', this.toggle) - } - - Dropdown.VERSION = '3.3.6' - - function getParent($this) { - var selector = $this.attr('data-target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - var $parent = selector && $(selector) - - return $parent && $parent.length ? $parent : $this.parent() - } - - function clearMenus(e) { - if (e && e.which === 3) return - $(backdrop).remove() - $(toggle).each(function () { - var $this = $(this) - var $parent = getParent($this) - var relatedTarget = { relatedTarget: this } - - if (!$parent.hasClass('open')) return - - if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return - - $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) - - if (e.isDefaultPrevented()) return - - $this.attr('aria-expanded', 'false') - $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) - }) - } - - Dropdown.prototype.toggle = function (e) { - var $this = $(this) - - if ($this.is('.disabled, :disabled')) return - - var $parent = getParent($this) - var isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { - // if mobile we use a backdrop because click events don't delegate - $(document.createElement('div')) - .addClass('dropdown-backdrop') - .insertAfter($(this)) - .on('click', clearMenus) - } - - var relatedTarget = { relatedTarget: this } - $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) - - if (e.isDefaultPrevented()) return - - $this - .trigger('focus') - .attr('aria-expanded', 'true') - - $parent - .toggleClass('open') - .trigger($.Event('shown.bs.dropdown', relatedTarget)) - } - - return false - } - - Dropdown.prototype.keydown = function (e) { - if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return - - var $this = $(this) - - e.preventDefault() - e.stopPropagation() - - if ($this.is('.disabled, :disabled')) return - - var $parent = getParent($this) - var isActive = $parent.hasClass('open') - - if (!isActive && e.which != 27 || isActive && e.which == 27) { - if (e.which == 27) $parent.find(toggle).trigger('focus') - return $this.trigger('click') - } - - var desc = ' li:not(.disabled):visible a' - var $items = $parent.find('.dropdown-menu' + desc) - - if (!$items.length) return - - var index = $items.index(e.target) - - if (e.which == 38 && index > 0) index-- // up - if (e.which == 40 && index < $items.length - 1) index++ // down - if (!~index) index = 0 - - $items.eq(index).trigger('focus') - } - - - // DROPDOWN PLUGIN DEFINITION - // ========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.dropdown') - - if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - var old = $.fn.dropdown - - $.fn.dropdown = Plugin - $.fn.dropdown.Constructor = Dropdown - - - // DROPDOWN NO CONFLICT - // ==================== - - $.fn.dropdown.noConflict = function () { - $.fn.dropdown = old - return this - } - - - // APPLY TO STANDARD DROPDOWN ELEMENTS - // =================================== - - $(document) - .on('click.bs.dropdown.data-api', clearMenus) - .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) - .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) - .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) - .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: modal.js v3.3.6 - * http://getbootstrap.com/javascript/#modals - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // MODAL CLASS DEFINITION - // ====================== - - var Modal = function (element, options) { - this.options = options - this.$body = $(document.body) - this.$element = $(element) - this.$dialog = this.$element.find('.modal-dialog') - this.$backdrop = null - this.isShown = null - this.originalBodyPad = null - this.scrollbarWidth = 0 - this.ignoreBackdropClick = false - - if (this.options.remote) { - this.$element - .find('.modal-content') - .load(this.options.remote, $.proxy(function () { - this.$element.trigger('loaded.bs.modal') - }, this)) - } - } - - Modal.VERSION = '3.3.6' - - Modal.TRANSITION_DURATION = 300 - Modal.BACKDROP_TRANSITION_DURATION = 150 - - Modal.DEFAULTS = { - backdrop: true, - keyboard: true, - show: true - } - - Modal.prototype.toggle = function (_relatedTarget) { - return this.isShown ? this.hide() : this.show(_relatedTarget) - } - - Modal.prototype.show = function (_relatedTarget) { - var that = this - var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) - - this.$element.trigger(e) - - if (this.isShown || e.isDefaultPrevented()) return - - this.isShown = true - - this.checkScrollbar() - this.setScrollbar() - this.$body.addClass('modal-open') - - this.escape() - this.resize() - - this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) - - this.$dialog.on('mousedown.dismiss.bs.modal', function () { - that.$element.one('mouseup.dismiss.bs.modal', function (e) { - if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true - }) - }) - - this.backdrop(function () { - var transition = $.support.transition && that.$element.hasClass('fade') - - if (!that.$element.parent().length) { - that.$element.appendTo(that.$body) // don't move modals dom position - } - - that.$element - .show() - .scrollTop(0) - - that.adjustDialog() - - if (transition) { - that.$element[0].offsetWidth // force reflow - } - - that.$element.addClass('in') - - that.enforceFocus() - - var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) - - transition ? - that.$dialog // wait for modal to slide in - .one('bsTransitionEnd', function () { - that.$element.trigger('focus').trigger(e) - }) - .emulateTransitionEnd(Modal.TRANSITION_DURATION) : - that.$element.trigger('focus').trigger(e) - }) - } - - Modal.prototype.hide = function (e) { - if (e) e.preventDefault() - - e = $.Event('hide.bs.modal') - - this.$element.trigger(e) - - if (!this.isShown || e.isDefaultPrevented()) return - - this.isShown = false - - this.escape() - this.resize() - - $(document).off('focusin.bs.modal') - - this.$element - .removeClass('in') - .off('click.dismiss.bs.modal') - .off('mouseup.dismiss.bs.modal') - - this.$dialog.off('mousedown.dismiss.bs.modal') - - $.support.transition && this.$element.hasClass('fade') ? - this.$element - .one('bsTransitionEnd', $.proxy(this.hideModal, this)) - .emulateTransitionEnd(Modal.TRANSITION_DURATION) : - this.hideModal() - } - - Modal.prototype.enforceFocus = function () { - $(document) - .off('focusin.bs.modal') // guard against infinite focus loop - .on('focusin.bs.modal', $.proxy(function (e) { - if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { - this.$element.trigger('focus') - } - }, this)) - } - - Modal.prototype.escape = function () { - if (this.isShown && this.options.keyboard) { - this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { - e.which == 27 && this.hide() - }, this)) - } else if (!this.isShown) { - this.$element.off('keydown.dismiss.bs.modal') - } - } - - Modal.prototype.resize = function () { - if (this.isShown) { - $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) - } else { - $(window).off('resize.bs.modal') - } - } - - Modal.prototype.hideModal = function () { - var that = this - this.$element.hide() - this.backdrop(function () { - that.$body.removeClass('modal-open') - that.resetAdjustments() - that.resetScrollbar() - that.$element.trigger('hidden.bs.modal') - }) - } - - Modal.prototype.removeBackdrop = function () { - this.$backdrop && this.$backdrop.remove() - this.$backdrop = null - } - - Modal.prototype.backdrop = function (callback) { - var that = this - var animate = this.$element.hasClass('fade') ? 'fade' : '' - - if (this.isShown && this.options.backdrop) { - var doAnimate = $.support.transition && animate - - this.$backdrop = $(document.createElement('div')) - .addClass('modal-backdrop ' + animate) - .appendTo(this.$body) - - this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { - if (this.ignoreBackdropClick) { - this.ignoreBackdropClick = false - return - } - if (e.target !== e.currentTarget) return - this.options.backdrop == 'static' - ? this.$element[0].focus() - : this.hide() - }, this)) - - if (doAnimate) this.$backdrop[0].offsetWidth // force reflow - - this.$backdrop.addClass('in') - - if (!callback) return - - doAnimate ? - this.$backdrop - .one('bsTransitionEnd', callback) - .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : - callback() - - } else if (!this.isShown && this.$backdrop) { - this.$backdrop.removeClass('in') - - var callbackRemove = function () { - that.removeBackdrop() - callback && callback() - } - $.support.transition && this.$element.hasClass('fade') ? - this.$backdrop - .one('bsTransitionEnd', callbackRemove) - .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : - callbackRemove() - - } else if (callback) { - callback() - } - } - - // these following methods are used to handle overflowing modals - - Modal.prototype.handleUpdate = function () { - this.adjustDialog() - } - - Modal.prototype.adjustDialog = function () { - var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight - - this.$element.css({ - paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', - paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' - }) - } - - Modal.prototype.resetAdjustments = function () { - this.$element.css({ - paddingLeft: '', - paddingRight: '' - }) - } - - Modal.prototype.checkScrollbar = function () { - var fullWindowWidth = window.innerWidth - if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 - var documentElementRect = document.documentElement.getBoundingClientRect() - fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) - } - this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth - this.scrollbarWidth = this.measureScrollbar() - } - - Modal.prototype.setScrollbar = function () { - var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) - this.originalBodyPad = document.body.style.paddingRight || '' - if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) - } - - Modal.prototype.resetScrollbar = function () { - this.$body.css('padding-right', this.originalBodyPad) - } - - Modal.prototype.measureScrollbar = function () { // thx walsh - var scrollDiv = document.createElement('div') - scrollDiv.className = 'modal-scrollbar-measure' - this.$body.append(scrollDiv) - var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth - this.$body[0].removeChild(scrollDiv) - return scrollbarWidth - } - - - // MODAL PLUGIN DEFINITION - // ======================= - - function Plugin(option, _relatedTarget) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.modal') - var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) - - if (!data) $this.data('bs.modal', (data = new Modal(this, options))) - if (typeof option == 'string') data[option](_relatedTarget) - else if (options.show) data.show(_relatedTarget) - }) - } - - var old = $.fn.modal - - $.fn.modal = Plugin - $.fn.modal.Constructor = Modal - - - // MODAL NO CONFLICT - // ================= - - $.fn.modal.noConflict = function () { - $.fn.modal = old - return this - } - - - // MODAL DATA-API - // ============== - - $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { - var $this = $(this) - var href = $this.attr('href') - var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 - var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) - - if ($this.is('a')) e.preventDefault() - - $target.one('show.bs.modal', function (showEvent) { - if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown - $target.one('hidden.bs.modal', function () { - $this.is(':visible') && $this.trigger('focus') - }) - }) - Plugin.call($target, option, this) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: tooltip.js v3.3.6 - * http://getbootstrap.com/javascript/#tooltip - * Inspired by the original jQuery.tipsy by Jason Frame - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // TOOLTIP PUBLIC CLASS DEFINITION - // =============================== - - var Tooltip = function (element, options) { - this.type = null - this.options = null - this.enabled = null - this.timeout = null - this.hoverState = null - this.$element = null - this.inState = null - - this.init('tooltip', element, options) - } - - Tooltip.VERSION = '3.3.6' - - Tooltip.TRANSITION_DURATION = 150 - - Tooltip.DEFAULTS = { - animation: true, - placement: 'top', - selector: false, - template: '', - trigger: 'hover focus', - title: '', - delay: 0, - html: false, - container: false, - viewport: { - selector: 'body', - padding: 0 - } - } - - Tooltip.prototype.init = function (type, element, options) { - this.enabled = true - this.type = type - this.$element = $(element) - this.options = this.getOptions(options) - this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) - this.inState = { click: false, hover: false, focus: false } - - if (this.$element[0] instanceof document.constructor && !this.options.selector) { - throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') - } - - var triggers = this.options.trigger.split(' ') - - for (var i = triggers.length; i--;) { - var trigger = triggers[i] - - if (trigger == 'click') { - this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) - } else if (trigger != 'manual') { - var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' - var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' - - this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) - this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) - } - } - - this.options.selector ? - (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : - this.fixTitle() - } - - Tooltip.prototype.getDefaults = function () { - return Tooltip.DEFAULTS - } - - Tooltip.prototype.getOptions = function (options) { - options = $.extend({}, this.getDefaults(), this.$element.data(), options) - - if (options.delay && typeof options.delay == 'number') { - options.delay = { - show: options.delay, - hide: options.delay - } - } - - return options - } - - Tooltip.prototype.getDelegateOptions = function () { - var options = {} - var defaults = this.getDefaults() - - this._options && $.each(this._options, function (key, value) { - if (defaults[key] != value) options[key] = value - }) - - return options - } - - Tooltip.prototype.enter = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) - - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } - - if (obj instanceof $.Event) { - self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true - } - - if (self.tip().hasClass('in') || self.hoverState == 'in') { - self.hoverState = 'in' - return - } - - clearTimeout(self.timeout) - - self.hoverState = 'in' - - if (!self.options.delay || !self.options.delay.show) return self.show() - - self.timeout = setTimeout(function () { - if (self.hoverState == 'in') self.show() - }, self.options.delay.show) - } - - Tooltip.prototype.isInStateTrue = function () { - for (var key in this.inState) { - if (this.inState[key]) return true - } - - return false - } - - Tooltip.prototype.leave = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) - - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } - - if (obj instanceof $.Event) { - self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false - } - - if (self.isInStateTrue()) return - - clearTimeout(self.timeout) - - self.hoverState = 'out' - - if (!self.options.delay || !self.options.delay.hide) return self.hide() - - self.timeout = setTimeout(function () { - if (self.hoverState == 'out') self.hide() - }, self.options.delay.hide) - } - - Tooltip.prototype.show = function () { - var e = $.Event('show.bs.' + this.type) - - if (this.hasContent() && this.enabled) { - this.$element.trigger(e) - - var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) - if (e.isDefaultPrevented() || !inDom) return - var that = this - - var $tip = this.tip() - - var tipId = this.getUID(this.type) - - this.setContent() - $tip.attr('id', tipId) - this.$element.attr('aria-describedby', tipId) - - if (this.options.animation) $tip.addClass('fade') - - var placement = typeof this.options.placement == 'function' ? - this.options.placement.call(this, $tip[0], this.$element[0]) : - this.options.placement - - var autoToken = /\s?auto?\s?/i - var autoPlace = autoToken.test(placement) - if (autoPlace) placement = placement.replace(autoToken, '') || 'top' - - $tip - .detach() - .css({ top: 0, left: 0, display: 'block' }) - .addClass(placement) - .data('bs.' + this.type, this) - - this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) - this.$element.trigger('inserted.bs.' + this.type) - - var pos = this.getPosition() - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight - - if (autoPlace) { - var orgPlacement = placement - var viewportDim = this.getPosition(this.$viewport) - - placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : - placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : - placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : - placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : - placement - - $tip - .removeClass(orgPlacement) - .addClass(placement) - } - - var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) - - this.applyPlacement(calculatedOffset, placement) - - var complete = function () { - var prevHoverState = that.hoverState - that.$element.trigger('shown.bs.' + that.type) - that.hoverState = null - - if (prevHoverState == 'out') that.leave(that) - } - - $.support.transition && this.$tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - } - } - - Tooltip.prototype.applyPlacement = function (offset, placement) { - var $tip = this.tip() - var width = $tip[0].offsetWidth - var height = $tip[0].offsetHeight - - // manually read margins because getBoundingClientRect includes difference - var marginTop = parseInt($tip.css('margin-top'), 10) - var marginLeft = parseInt($tip.css('margin-left'), 10) - - // we must check for NaN for ie 8/9 - if (isNaN(marginTop)) marginTop = 0 - if (isNaN(marginLeft)) marginLeft = 0 - - offset.top += marginTop - offset.left += marginLeft - - // $.fn.offset doesn't round pixel values - // so we use setOffset directly with our own function B-0 - $.offset.setOffset($tip[0], $.extend({ - using: function (props) { - $tip.css({ - top: Math.round(props.top), - left: Math.round(props.left) - }) - } - }, offset), 0) - - $tip.addClass('in') - - // check to see if placing tip in new offset caused the tip to resize itself - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight - - if (placement == 'top' && actualHeight != height) { - offset.top = offset.top + height - actualHeight - } - - var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) - - if (delta.left) offset.left += delta.left - else offset.top += delta.top - - var isVertical = /top|bottom/.test(placement) - var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight - var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' - - $tip.offset(offset) - this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) - } - - Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { - this.arrow() - .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') - .css(isVertical ? 'top' : 'left', '') - } - - Tooltip.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() - - $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) - $tip.removeClass('fade in top bottom left right') - } - - Tooltip.prototype.hide = function (callback) { - var that = this - var $tip = $(this.$tip) - var e = $.Event('hide.bs.' + this.type) - - function complete() { - if (that.hoverState != 'in') $tip.detach() - that.$element - .removeAttr('aria-describedby') - .trigger('hidden.bs.' + that.type) - callback && callback() - } - - this.$element.trigger(e) - - if (e.isDefaultPrevented()) return - - $tip.removeClass('in') - - $.support.transition && $tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - - this.hoverState = null - - return this - } - - Tooltip.prototype.fixTitle = function () { - var $e = this.$element - if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { - $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') - } - } - - Tooltip.prototype.hasContent = function () { - return this.getTitle() - } - - Tooltip.prototype.getPosition = function ($element) { - $element = $element || this.$element - - var el = $element[0] - var isBody = el.tagName == 'BODY' - - var elRect = el.getBoundingClientRect() - if (elRect.width == null) { - // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 - elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) - } - var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() - var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } - var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null - - return $.extend({}, elRect, scroll, outerDims, elOffset) - } - - Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { - return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : - /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } - - } - - Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { - var delta = { top: 0, left: 0 } - if (!this.$viewport) return delta - - var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 - var viewportDimensions = this.getPosition(this.$viewport) - - if (/right|left/.test(placement)) { - var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll - var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight - if (topEdgeOffset < viewportDimensions.top) { // top overflow - delta.top = viewportDimensions.top - topEdgeOffset - } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow - delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset - } - } else { - var leftEdgeOffset = pos.left - viewportPadding - var rightEdgeOffset = pos.left + viewportPadding + actualWidth - if (leftEdgeOffset < viewportDimensions.left) { // left overflow - delta.left = viewportDimensions.left - leftEdgeOffset - } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow - delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset - } - } - - return delta - } - - Tooltip.prototype.getTitle = function () { - var title - var $e = this.$element - var o = this.options - - title = $e.attr('data-original-title') - || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) - - return title - } - - Tooltip.prototype.getUID = function (prefix) { - do prefix += ~~(Math.random() * 1000000) - while (document.getElementById(prefix)) - return prefix - } - - Tooltip.prototype.tip = function () { - if (!this.$tip) { - this.$tip = $(this.options.template) - if (this.$tip.length != 1) { - throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') - } - } - return this.$tip - } - - Tooltip.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) - } - - Tooltip.prototype.enable = function () { - this.enabled = true - } - - Tooltip.prototype.disable = function () { - this.enabled = false - } - - Tooltip.prototype.toggleEnabled = function () { - this.enabled = !this.enabled - } - - Tooltip.prototype.toggle = function (e) { - var self = this - if (e) { - self = $(e.currentTarget).data('bs.' + this.type) - if (!self) { - self = new this.constructor(e.currentTarget, this.getDelegateOptions()) - $(e.currentTarget).data('bs.' + this.type, self) - } - } - - if (e) { - self.inState.click = !self.inState.click - if (self.isInStateTrue()) self.enter(self) - else self.leave(self) - } else { - self.tip().hasClass('in') ? self.leave(self) : self.enter(self) - } - } - - Tooltip.prototype.destroy = function () { - var that = this - clearTimeout(this.timeout) - this.hide(function () { - that.$element.off('.' + that.type).removeData('bs.' + that.type) - if (that.$tip) { - that.$tip.detach() - } - that.$tip = null - that.$arrow = null - that.$viewport = null - }) - } - - - // TOOLTIP PLUGIN DEFINITION - // ========================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.tooltip') - var options = typeof option == 'object' && option - - if (!data && /destroy|hide/.test(option)) return - if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.tooltip - - $.fn.tooltip = Plugin - $.fn.tooltip.Constructor = Tooltip - - - // TOOLTIP NO CONFLICT - // =================== - - $.fn.tooltip.noConflict = function () { - $.fn.tooltip = old - return this - } - -}(jQuery); - -/* ======================================================================== - * Bootstrap: popover.js v3.3.6 - * http://getbootstrap.com/javascript/#popovers - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // POPOVER PUBLIC CLASS DEFINITION - // =============================== - - var Popover = function (element, options) { - this.init('popover', element, options) - } - - if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') - - Popover.VERSION = '3.3.6' - - Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { - placement: 'right', - trigger: 'click', - content: '', - template: '' - }) - - - // NOTE: POPOVER EXTENDS tooltip.js - // ================================ - - Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) - - Popover.prototype.constructor = Popover - - Popover.prototype.getDefaults = function () { - return Popover.DEFAULTS - } - - Popover.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() - var content = this.getContent() - - $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) - $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events - this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' - ](content) - - $tip.removeClass('fade top bottom left right in') - - // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do - // this manually by checking the contents. - if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() - } - - Popover.prototype.hasContent = function () { - return this.getTitle() || this.getContent() - } - - Popover.prototype.getContent = function () { - var $e = this.$element - var o = this.options - - return $e.attr('data-content') - || (typeof o.content == 'function' ? - o.content.call($e[0]) : - o.content) - } - - Popover.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.arrow')) - } - - - // POPOVER PLUGIN DEFINITION - // ========================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.popover') - var options = typeof option == 'object' && option - - if (!data && /destroy|hide/.test(option)) return - if (!data) $this.data('bs.popover', (data = new Popover(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.popover - - $.fn.popover = Plugin - $.fn.popover.Constructor = Popover - - - // POPOVER NO CONFLICT - // =================== - - $.fn.popover.noConflict = function () { - $.fn.popover = old - return this - } - -}(jQuery); - -/* ======================================================================== - * Bootstrap: scrollspy.js v3.3.6 - * http://getbootstrap.com/javascript/#scrollspy - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // SCROLLSPY CLASS DEFINITION - // ========================== - - function ScrollSpy(element, options) { - this.$body = $(document.body) - this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) - this.options = $.extend({}, ScrollSpy.DEFAULTS, options) - this.selector = (this.options.target || '') + ' .nav li > a' - this.offsets = [] - this.targets = [] - this.activeTarget = null - this.scrollHeight = 0 - - this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) - this.refresh() - this.process() - } - - ScrollSpy.VERSION = '3.3.6' - - ScrollSpy.DEFAULTS = { - offset: 10 - } - - ScrollSpy.prototype.getScrollHeight = function () { - return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) - } - - ScrollSpy.prototype.refresh = function () { - var that = this - var offsetMethod = 'offset' - var offsetBase = 0 - - this.offsets = [] - this.targets = [] - this.scrollHeight = this.getScrollHeight() - - if (!$.isWindow(this.$scrollElement[0])) { - offsetMethod = 'position' - offsetBase = this.$scrollElement.scrollTop() - } - - this.$body - .find(this.selector) - .map(function () { - var $el = $(this) - var href = $el.data('target') || $el.attr('href') - var $href = /^#./.test(href) && $(href) - - return ($href - && $href.length - && $href.is(':visible') - && [[$href[offsetMethod]().top + offsetBase, href]]) || null - }) - .sort(function (a, b) { return a[0] - b[0] }) - .each(function () { - that.offsets.push(this[0]) - that.targets.push(this[1]) - }) - } - - ScrollSpy.prototype.process = function () { - var scrollTop = this.$scrollElement.scrollTop() + this.options.offset - var scrollHeight = this.getScrollHeight() - var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() - var offsets = this.offsets - var targets = this.targets - var activeTarget = this.activeTarget - var i - - if (this.scrollHeight != scrollHeight) { - this.refresh() - } - - if (scrollTop >= maxScroll) { - return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) - } - - if (activeTarget && scrollTop < offsets[0]) { - this.activeTarget = null - return this.clear() - } - - for (i = offsets.length; i--;) { - activeTarget != targets[i] - && scrollTop >= offsets[i] - && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) - && this.activate(targets[i]) - } - } - - ScrollSpy.prototype.activate = function (target) { - this.activeTarget = target - - this.clear() - - var selector = this.selector + - '[data-target="' + target + '"],' + - this.selector + '[href="' + target + '"]' - - var active = $(selector) - .parents('li') - .addClass('active') - - if (active.parent('.dropdown-menu').length) { - active = active - .closest('li.dropdown') - .addClass('active') - } - - active.trigger('activate.bs.scrollspy') - } - - ScrollSpy.prototype.clear = function () { - $(this.selector) - .parentsUntil(this.options.target, '.active') - .removeClass('active') - } - - - // SCROLLSPY PLUGIN DEFINITION - // =========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.scrollspy') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.scrollspy - - $.fn.scrollspy = Plugin - $.fn.scrollspy.Constructor = ScrollSpy - - - // SCROLLSPY NO CONFLICT - // ===================== - - $.fn.scrollspy.noConflict = function () { - $.fn.scrollspy = old - return this - } - - - // SCROLLSPY DATA-API - // ================== - - $(window).on('load.bs.scrollspy.data-api', function () { - $('[data-spy="scroll"]').each(function () { - var $spy = $(this) - Plugin.call($spy, $spy.data()) - }) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: tab.js v3.3.6 - * http://getbootstrap.com/javascript/#tabs - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // TAB CLASS DEFINITION - // ==================== - - var Tab = function (element) { - // jscs:disable requireDollarBeforejQueryAssignment - this.element = $(element) - // jscs:enable requireDollarBeforejQueryAssignment - } - - Tab.VERSION = '3.3.6' - - Tab.TRANSITION_DURATION = 150 - - Tab.prototype.show = function () { - var $this = this.element - var $ul = $this.closest('ul:not(.dropdown-menu)') - var selector = $this.data('target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - if ($this.parent('li').hasClass('active')) return - - var $previous = $ul.find('.active:last a') - var hideEvent = $.Event('hide.bs.tab', { - relatedTarget: $this[0] - }) - var showEvent = $.Event('show.bs.tab', { - relatedTarget: $previous[0] - }) - - $previous.trigger(hideEvent) - $this.trigger(showEvent) - - if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return - - var $target = $(selector) - - this.activate($this.closest('li'), $ul) - this.activate($target, $target.parent(), function () { - $previous.trigger({ - type: 'hidden.bs.tab', - relatedTarget: $this[0] - }) - $this.trigger({ - type: 'shown.bs.tab', - relatedTarget: $previous[0] - }) - }) - } - - Tab.prototype.activate = function (element, container, callback) { - var $active = container.find('> .active') - var transition = callback - && $.support.transition - && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) - - function next() { - $active - .removeClass('active') - .find('> .dropdown-menu > .active') - .removeClass('active') - .end() - .find('[data-toggle="tab"]') - .attr('aria-expanded', false) - - element - .addClass('active') - .find('[data-toggle="tab"]') - .attr('aria-expanded', true) - - if (transition) { - element[0].offsetWidth // reflow for transition - element.addClass('in') - } else { - element.removeClass('fade') - } - - if (element.parent('.dropdown-menu').length) { - element - .closest('li.dropdown') - .addClass('active') - .end() - .find('[data-toggle="tab"]') - .attr('aria-expanded', true) - } - - callback && callback() - } - - $active.length && transition ? - $active - .one('bsTransitionEnd', next) - .emulateTransitionEnd(Tab.TRANSITION_DURATION) : - next() - - $active.removeClass('in') - } - - - // TAB PLUGIN DEFINITION - // ===================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.tab') - - if (!data) $this.data('bs.tab', (data = new Tab(this))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.tab - - $.fn.tab = Plugin - $.fn.tab.Constructor = Tab - - - // TAB NO CONFLICT - // =============== - - $.fn.tab.noConflict = function () { - $.fn.tab = old - return this - } - - - // TAB DATA-API - // ============ - - var clickHandler = function (e) { - e.preventDefault() - Plugin.call($(this), 'show') - } - - $(document) - .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) - .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: affix.js v3.3.6 - * http://getbootstrap.com/javascript/#affix - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // AFFIX CLASS DEFINITION - // ====================== - - var Affix = function (element, options) { - this.options = $.extend({}, Affix.DEFAULTS, options) - - this.$target = $(this.options.target) - .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) - .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) - - this.$element = $(element) - this.affixed = null - this.unpin = null - this.pinnedOffset = null - - this.checkPosition() - } - - Affix.VERSION = '3.3.6' - - Affix.RESET = 'affix affix-top affix-bottom' - - Affix.DEFAULTS = { - offset: 0, - target: window - } - - Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { - var scrollTop = this.$target.scrollTop() - var position = this.$element.offset() - var targetHeight = this.$target.height() - - if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false - - if (this.affixed == 'bottom') { - if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' - return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' - } - - var initializing = this.affixed == null - var colliderTop = initializing ? scrollTop : position.top - var colliderHeight = initializing ? targetHeight : height - - if (offsetTop != null && scrollTop <= offsetTop) return 'top' - if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' - - return false - } - - Affix.prototype.getPinnedOffset = function () { - if (this.pinnedOffset) return this.pinnedOffset - this.$element.removeClass(Affix.RESET).addClass('affix') - var scrollTop = this.$target.scrollTop() - var position = this.$element.offset() - return (this.pinnedOffset = position.top - scrollTop) - } - - Affix.prototype.checkPositionWithEventLoop = function () { - setTimeout($.proxy(this.checkPosition, this), 1) - } - - Affix.prototype.checkPosition = function () { - if (!this.$element.is(':visible')) return - - var height = this.$element.height() - var offset = this.options.offset - var offsetTop = offset.top - var offsetBottom = offset.bottom - var scrollHeight = Math.max($(document).height(), $(document.body).height()) - - if (typeof offset != 'object') offsetBottom = offsetTop = offset - if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) - if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) - - var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) - - if (this.affixed != affix) { - if (this.unpin != null) this.$element.css('top', '') - - var affixType = 'affix' + (affix ? '-' + affix : '') - var e = $.Event(affixType + '.bs.affix') - - this.$element.trigger(e) - - if (e.isDefaultPrevented()) return - - this.affixed = affix - this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null - - this.$element - .removeClass(Affix.RESET) - .addClass(affixType) - .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') - } - - if (affix == 'bottom') { - this.$element.offset({ - top: scrollHeight - height - offsetBottom - }) - } - } - - - // AFFIX PLUGIN DEFINITION - // ======================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.affix') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.affix', (data = new Affix(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.affix - - $.fn.affix = Plugin - $.fn.affix.Constructor = Affix - - - // AFFIX NO CONFLICT - // ================= - - $.fn.affix.noConflict = function () { - $.fn.affix = old - return this - } - - - // AFFIX DATA-API - // ============== - - $(window).on('load', function () { - $('[data-spy="affix"]').each(function () { - var $spy = $(this) - var data = $spy.data() - - data.offset = data.offset || {} - - if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom - if (data.offsetTop != null) data.offset.top = data.offsetTop - - Plugin.call($spy, data) - }) - }) - -}(jQuery); diff --git a/js/bootstrap.min.js b/js/bootstrap.min.js deleted file mode 100644 index e79c065..0000000 --- a/js/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under the MIT license - */ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/js/jquery.min.js b/js/jquery.min.js deleted file mode 100644 index 4d9b3a2..0000000 --- a/js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w("