notelm-mcp 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +456 -0
  3. package/dist/auth/auth-manager.d.ts +139 -0
  4. package/dist/auth/auth-manager.d.ts.map +1 -0
  5. package/dist/auth/auth-manager.js +960 -0
  6. package/dist/auth/auth-manager.js.map +1 -0
  7. package/dist/config.d.ts +92 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +219 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/constants.d.ts +58 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/constants.js +133 -0
  14. package/dist/constants.js.map +1 -0
  15. package/dist/errors.d.ts +26 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +41 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/index.d.ts +32 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +325 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/library/notebook-library.d.ts +70 -0
  24. package/dist/library/notebook-library.d.ts.map +1 -0
  25. package/dist/library/notebook-library.js +279 -0
  26. package/dist/library/notebook-library.js.map +1 -0
  27. package/dist/library/types.d.ts +67 -0
  28. package/dist/library/types.d.ts.map +1 -0
  29. package/dist/library/types.js +8 -0
  30. package/dist/library/types.js.map +1 -0
  31. package/dist/playwright.config.d.ts +3 -0
  32. package/dist/playwright.config.d.ts.map +1 -0
  33. package/dist/playwright.config.js +38 -0
  34. package/dist/playwright.config.js.map +1 -0
  35. package/dist/resources/resource-handlers.d.ts +22 -0
  36. package/dist/resources/resource-handlers.d.ts.map +1 -0
  37. package/dist/resources/resource-handlers.js +216 -0
  38. package/dist/resources/resource-handlers.js.map +1 -0
  39. package/dist/scripts/save-auth-state.d.ts +2 -0
  40. package/dist/scripts/save-auth-state.d.ts.map +1 -0
  41. package/dist/scripts/save-auth-state.js +91 -0
  42. package/dist/scripts/save-auth-state.js.map +1 -0
  43. package/dist/session/browser-session.d.ts +108 -0
  44. package/dist/session/browser-session.d.ts.map +1 -0
  45. package/dist/session/browser-session.js +636 -0
  46. package/dist/session/browser-session.js.map +1 -0
  47. package/dist/session/session-manager.d.ts +76 -0
  48. package/dist/session/session-manager.d.ts.map +1 -0
  49. package/dist/session/session-manager.js +273 -0
  50. package/dist/session/session-manager.js.map +1 -0
  51. package/dist/session/shared-context-manager.d.ts +107 -0
  52. package/dist/session/shared-context-manager.d.ts.map +1 -0
  53. package/dist/session/shared-context-manager.js +447 -0
  54. package/dist/session/shared-context-manager.js.map +1 -0
  55. package/dist/src/auth/auth-manager.d.ts +139 -0
  56. package/dist/src/auth/auth-manager.d.ts.map +1 -0
  57. package/dist/src/auth/auth-manager.js +960 -0
  58. package/dist/src/auth/auth-manager.js.map +1 -0
  59. package/dist/src/config.d.ts +92 -0
  60. package/dist/src/config.d.ts.map +1 -0
  61. package/dist/src/config.js +219 -0
  62. package/dist/src/config.js.map +1 -0
  63. package/dist/src/constants.d.ts +58 -0
  64. package/dist/src/constants.d.ts.map +1 -0
  65. package/dist/src/constants.js +133 -0
  66. package/dist/src/constants.js.map +1 -0
  67. package/dist/src/errors.d.ts +26 -0
  68. package/dist/src/errors.d.ts.map +1 -0
  69. package/dist/src/errors.js +41 -0
  70. package/dist/src/errors.js.map +1 -0
  71. package/dist/src/index.d.ts +32 -0
  72. package/dist/src/index.d.ts.map +1 -0
  73. package/dist/src/index.js +325 -0
  74. package/dist/src/index.js.map +1 -0
  75. package/dist/src/library/notebook-library.d.ts +70 -0
  76. package/dist/src/library/notebook-library.d.ts.map +1 -0
  77. package/dist/src/library/notebook-library.js +279 -0
  78. package/dist/src/library/notebook-library.js.map +1 -0
  79. package/dist/src/library/types.d.ts +67 -0
  80. package/dist/src/library/types.d.ts.map +1 -0
  81. package/dist/src/library/types.js +8 -0
  82. package/dist/src/library/types.js.map +1 -0
  83. package/dist/src/resources/resource-handlers.d.ts +22 -0
  84. package/dist/src/resources/resource-handlers.d.ts.map +1 -0
  85. package/dist/src/resources/resource-handlers.js +216 -0
  86. package/dist/src/resources/resource-handlers.js.map +1 -0
  87. package/dist/src/scripts/health-check.d.ts +13 -0
  88. package/dist/src/scripts/health-check.d.ts.map +1 -0
  89. package/dist/src/scripts/health-check.js +100 -0
  90. package/dist/src/scripts/health-check.js.map +1 -0
  91. package/dist/src/session/browser-session.d.ts +108 -0
  92. package/dist/src/session/browser-session.d.ts.map +1 -0
  93. package/dist/src/session/browser-session.js +642 -0
  94. package/dist/src/session/browser-session.js.map +1 -0
  95. package/dist/src/session/session-manager.d.ts +76 -0
  96. package/dist/src/session/session-manager.d.ts.map +1 -0
  97. package/dist/src/session/session-manager.js +273 -0
  98. package/dist/src/session/session-manager.js.map +1 -0
  99. package/dist/src/session/shared-context-manager.d.ts +107 -0
  100. package/dist/src/session/shared-context-manager.d.ts.map +1 -0
  101. package/dist/src/session/shared-context-manager.js +447 -0
  102. package/dist/src/session/shared-context-manager.js.map +1 -0
  103. package/dist/src/tools/definitions/ask-question.d.ts +8 -0
  104. package/dist/src/tools/definitions/ask-question.d.ts.map +1 -0
  105. package/dist/src/tools/definitions/ask-question.js +211 -0
  106. package/dist/src/tools/definitions/ask-question.js.map +1 -0
  107. package/dist/src/tools/definitions/notebook-management.d.ts +3 -0
  108. package/dist/src/tools/definitions/notebook-management.d.ts.map +1 -0
  109. package/dist/src/tools/definitions/notebook-management.js +243 -0
  110. package/dist/src/tools/definitions/notebook-management.js.map +1 -0
  111. package/dist/src/tools/definitions/session-management.d.ts +3 -0
  112. package/dist/src/tools/definitions/session-management.d.ts.map +1 -0
  113. package/dist/src/tools/definitions/session-management.js +41 -0
  114. package/dist/src/tools/definitions/session-management.js.map +1 -0
  115. package/dist/src/tools/definitions/system.d.ts +3 -0
  116. package/dist/src/tools/definitions/system.d.ts.map +1 -0
  117. package/dist/src/tools/definitions/system.js +143 -0
  118. package/dist/src/tools/definitions/system.js.map +1 -0
  119. package/dist/src/tools/definitions.d.ts +12 -0
  120. package/dist/src/tools/definitions.d.ts.map +1 -0
  121. package/dist/src/tools/definitions.js +26 -0
  122. package/dist/src/tools/definitions.js.map +1 -0
  123. package/dist/src/tools/handlers.d.ts +212 -0
  124. package/dist/src/tools/handlers.d.ts.map +1 -0
  125. package/dist/src/tools/handlers.js +712 -0
  126. package/dist/src/tools/handlers.js.map +1 -0
  127. package/dist/src/tools/index.d.ts +8 -0
  128. package/dist/src/tools/index.d.ts.map +1 -0
  129. package/dist/src/tools/index.js +8 -0
  130. package/dist/src/tools/index.js.map +1 -0
  131. package/dist/src/types.d.ts +88 -0
  132. package/dist/src/types.d.ts.map +1 -0
  133. package/dist/src/types.js +5 -0
  134. package/dist/src/types.js.map +1 -0
  135. package/dist/src/utils/auth-manager.d.ts +2 -0
  136. package/dist/src/utils/auth-manager.d.ts.map +1 -0
  137. package/dist/src/utils/auth-manager.js +25 -0
  138. package/dist/src/utils/auth-manager.js.map +1 -0
  139. package/dist/src/utils/cleanup-manager.d.ts +133 -0
  140. package/dist/src/utils/cleanup-manager.d.ts.map +1 -0
  141. package/dist/src/utils/cleanup-manager.js +673 -0
  142. package/dist/src/utils/cleanup-manager.js.map +1 -0
  143. package/dist/src/utils/cli-handler.d.ts +16 -0
  144. package/dist/src/utils/cli-handler.d.ts.map +1 -0
  145. package/dist/src/utils/cli-handler.js +102 -0
  146. package/dist/src/utils/cli-handler.js.map +1 -0
  147. package/dist/src/utils/logger.d.ts +61 -0
  148. package/dist/src/utils/logger.d.ts.map +1 -0
  149. package/dist/src/utils/logger.js +92 -0
  150. package/dist/src/utils/logger.js.map +1 -0
  151. package/dist/src/utils/page-utils.d.ts +54 -0
  152. package/dist/src/utils/page-utils.d.ts.map +1 -0
  153. package/dist/src/utils/page-utils.js +381 -0
  154. package/dist/src/utils/page-utils.js.map +1 -0
  155. package/dist/src/utils/rate-limit-handler.d.ts +42 -0
  156. package/dist/src/utils/rate-limit-handler.d.ts.map +1 -0
  157. package/dist/src/utils/rate-limit-handler.js +88 -0
  158. package/dist/src/utils/rate-limit-handler.js.map +1 -0
  159. package/dist/src/utils/rate-limit-handler.test.d.ts +7 -0
  160. package/dist/src/utils/rate-limit-handler.test.d.ts.map +1 -0
  161. package/dist/src/utils/rate-limit-handler.test.js +86 -0
  162. package/dist/src/utils/rate-limit-handler.test.js.map +1 -0
  163. package/dist/src/utils/settings-manager.d.ts +37 -0
  164. package/dist/src/utils/settings-manager.d.ts.map +1 -0
  165. package/dist/src/utils/settings-manager.js +121 -0
  166. package/dist/src/utils/settings-manager.js.map +1 -0
  167. package/dist/src/utils/stealth-utils.d.ts +135 -0
  168. package/dist/src/utils/stealth-utils.d.ts.map +1 -0
  169. package/dist/src/utils/stealth-utils.js +396 -0
  170. package/dist/src/utils/stealth-utils.js.map +1 -0
  171. package/dist/src/utils/stealth-utils.test.d.ts +7 -0
  172. package/dist/src/utils/stealth-utils.test.d.ts.map +1 -0
  173. package/dist/src/utils/stealth-utils.test.js +72 -0
  174. package/dist/src/utils/stealth-utils.test.js.map +1 -0
  175. package/dist/tests/e2e/authenticated.spec.d.ts +2 -0
  176. package/dist/tests/e2e/authenticated.spec.d.ts.map +1 -0
  177. package/dist/tests/e2e/authenticated.spec.js +41 -0
  178. package/dist/tests/e2e/authenticated.spec.js.map +1 -0
  179. package/dist/tests/e2e/mocked.spec.d.ts +2 -0
  180. package/dist/tests/e2e/mocked.spec.d.ts.map +1 -0
  181. package/dist/tests/e2e/mocked.spec.js +32 -0
  182. package/dist/tests/e2e/mocked.spec.js.map +1 -0
  183. package/dist/tests/mocks/handlers.d.ts +4 -0
  184. package/dist/tests/mocks/handlers.d.ts.map +1 -0
  185. package/dist/tests/mocks/handlers.js +55 -0
  186. package/dist/tests/mocks/handlers.js.map +1 -0
  187. package/dist/tests/mocks/setup.d.ts +3 -0
  188. package/dist/tests/mocks/setup.d.ts.map +1 -0
  189. package/dist/tests/mocks/setup.js +77 -0
  190. package/dist/tests/mocks/setup.js.map +1 -0
  191. package/dist/tools/definitions/ask-question.d.ts +8 -0
  192. package/dist/tools/definitions/ask-question.d.ts.map +1 -0
  193. package/dist/tools/definitions/ask-question.js +211 -0
  194. package/dist/tools/definitions/ask-question.js.map +1 -0
  195. package/dist/tools/definitions/notebook-management.d.ts +3 -0
  196. package/dist/tools/definitions/notebook-management.d.ts.map +1 -0
  197. package/dist/tools/definitions/notebook-management.js +243 -0
  198. package/dist/tools/definitions/notebook-management.js.map +1 -0
  199. package/dist/tools/definitions/session-management.d.ts +3 -0
  200. package/dist/tools/definitions/session-management.d.ts.map +1 -0
  201. package/dist/tools/definitions/session-management.js +41 -0
  202. package/dist/tools/definitions/session-management.js.map +1 -0
  203. package/dist/tools/definitions/system.d.ts +3 -0
  204. package/dist/tools/definitions/system.d.ts.map +1 -0
  205. package/dist/tools/definitions/system.js +143 -0
  206. package/dist/tools/definitions/system.js.map +1 -0
  207. package/dist/tools/definitions.d.ts +12 -0
  208. package/dist/tools/definitions.d.ts.map +1 -0
  209. package/dist/tools/definitions.js +26 -0
  210. package/dist/tools/definitions.js.map +1 -0
  211. package/dist/tools/handlers.d.ts +212 -0
  212. package/dist/tools/handlers.d.ts.map +1 -0
  213. package/dist/tools/handlers.js +712 -0
  214. package/dist/tools/handlers.js.map +1 -0
  215. package/dist/tools/index.d.ts +8 -0
  216. package/dist/tools/index.d.ts.map +1 -0
  217. package/dist/tools/index.js +8 -0
  218. package/dist/tools/index.js.map +1 -0
  219. package/dist/types.d.ts +82 -0
  220. package/dist/types.d.ts.map +1 -0
  221. package/dist/types.js +5 -0
  222. package/dist/types.js.map +1 -0
  223. package/dist/utils/cleanup-manager.d.ts +133 -0
  224. package/dist/utils/cleanup-manager.d.ts.map +1 -0
  225. package/dist/utils/cleanup-manager.js +673 -0
  226. package/dist/utils/cleanup-manager.js.map +1 -0
  227. package/dist/utils/cli-handler.d.ts +16 -0
  228. package/dist/utils/cli-handler.d.ts.map +1 -0
  229. package/dist/utils/cli-handler.js +102 -0
  230. package/dist/utils/cli-handler.js.map +1 -0
  231. package/dist/utils/logger.d.ts +61 -0
  232. package/dist/utils/logger.d.ts.map +1 -0
  233. package/dist/utils/logger.js +92 -0
  234. package/dist/utils/logger.js.map +1 -0
  235. package/dist/utils/page-utils.d.ts +54 -0
  236. package/dist/utils/page-utils.d.ts.map +1 -0
  237. package/dist/utils/page-utils.js +381 -0
  238. package/dist/utils/page-utils.js.map +1 -0
  239. package/dist/utils/rate-limit-handler.d.ts +42 -0
  240. package/dist/utils/rate-limit-handler.d.ts.map +1 -0
  241. package/dist/utils/rate-limit-handler.js +88 -0
  242. package/dist/utils/rate-limit-handler.js.map +1 -0
  243. package/dist/utils/rate-limit-handler.test.d.ts +7 -0
  244. package/dist/utils/rate-limit-handler.test.d.ts.map +1 -0
  245. package/dist/utils/rate-limit-handler.test.js +91 -0
  246. package/dist/utils/rate-limit-handler.test.js.map +1 -0
  247. package/dist/utils/settings-manager.d.ts +37 -0
  248. package/dist/utils/settings-manager.d.ts.map +1 -0
  249. package/dist/utils/settings-manager.js +121 -0
  250. package/dist/utils/settings-manager.js.map +1 -0
  251. package/dist/utils/stealth-utils.d.ts +135 -0
  252. package/dist/utils/stealth-utils.d.ts.map +1 -0
  253. package/dist/utils/stealth-utils.js +396 -0
  254. package/dist/utils/stealth-utils.js.map +1 -0
  255. package/dist/utils/stealth-utils.test.d.ts +7 -0
  256. package/dist/utils/stealth-utils.test.d.ts.map +1 -0
  257. package/dist/utils/stealth-utils.test.js +72 -0
  258. package/dist/utils/stealth-utils.test.js.map +1 -0
  259. package/docs/01_configuration.md +94 -0
  260. package/docs/02_tools.md +34 -0
  261. package/docs/03_troubleshooting.md +59 -0
  262. package/docs/04_usage-guide.md +245 -0
  263. package/docs/05_project-analysis.qmd +309 -0
  264. package/docs/06_integration-analysis.html +914 -0
  265. package/docs/06_integration-analysis.qmd +255 -0
  266. package/docs/06_integration-analysis_files/libs/bootstrap/bootstrap-4f0954b6b0dd6bf39f4bb9151ba984db.min.css +12 -0
  267. package/docs/06_integration-analysis_files/libs/bootstrap/bootstrap-icons.css +2106 -0
  268. package/docs/06_integration-analysis_files/libs/bootstrap/bootstrap-icons.woff +0 -0
  269. package/docs/06_integration-analysis_files/libs/bootstrap/bootstrap.min.js +7 -0
  270. package/docs/06_integration-analysis_files/libs/clipboard/clipboard.min.js +7 -0
  271. package/docs/06_integration-analysis_files/libs/quarto-html/anchor.min.js +9 -0
  272. package/docs/06_integration-analysis_files/libs/quarto-html/axe/axe-check.js +145 -0
  273. package/docs/06_integration-analysis_files/libs/quarto-html/popper.min.js +6 -0
  274. package/docs/06_integration-analysis_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css +236 -0
  275. package/docs/06_integration-analysis_files/libs/quarto-html/quarto.js +847 -0
  276. package/docs/06_integration-analysis_files/libs/quarto-html/tabsets/tabsets.js +95 -0
  277. package/docs/06_integration-analysis_files/libs/quarto-html/tippy.css +1 -0
  278. package/docs/06_integration-analysis_files/libs/quarto-html/tippy.umd.min.js +2 -0
  279. package/docs/07_e2e-testing-safety.qmd +754 -0
  280. package/docs/08_project-re-evaluation.html +609 -0
  281. package/docs/08_project-re-evaluation.qmd +86 -0
  282. package/docs/08_project-re-evaluation_files/libs/bootstrap/bootstrap-4f0954b6b0dd6bf39f4bb9151ba984db.min.css +12 -0
  283. package/docs/08_project-re-evaluation_files/libs/bootstrap/bootstrap-icons.css +2106 -0
  284. package/docs/08_project-re-evaluation_files/libs/bootstrap/bootstrap-icons.woff +0 -0
  285. package/docs/08_project-re-evaluation_files/libs/bootstrap/bootstrap.min.js +7 -0
  286. package/docs/08_project-re-evaluation_files/libs/clipboard/clipboard.min.js +7 -0
  287. package/docs/08_project-re-evaluation_files/libs/quarto-html/anchor.min.js +9 -0
  288. package/docs/08_project-re-evaluation_files/libs/quarto-html/axe/axe-check.js +145 -0
  289. package/docs/08_project-re-evaluation_files/libs/quarto-html/popper.min.js +6 -0
  290. package/docs/08_project-re-evaluation_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css +236 -0
  291. package/docs/08_project-re-evaluation_files/libs/quarto-html/quarto.js +847 -0
  292. package/docs/08_project-re-evaluation_files/libs/quarto-html/tabsets/tabsets.js +95 -0
  293. package/docs/08_project-re-evaluation_files/libs/quarto-html/tippy.css +1 -0
  294. package/docs/08_project-re-evaluation_files/libs/quarto-html/tippy.umd.min.js +2 -0
  295. package/docs/notebooklm-mcp-usage.html +704 -0
  296. package/docs/notebooklm-mcp-usage.qmd +119 -0
  297. package/docs/notebooklm-mcp-usage_files/libs/bootstrap/bootstrap-6b71f2156b6a5230c6677325978bcf08.min.css +12 -0
  298. package/docs/notebooklm-mcp-usage_files/libs/bootstrap/bootstrap-icons.css +2106 -0
  299. package/docs/notebooklm-mcp-usage_files/libs/bootstrap/bootstrap-icons.woff +0 -0
  300. package/docs/notebooklm-mcp-usage_files/libs/bootstrap/bootstrap.min.js +7 -0
  301. package/docs/notebooklm-mcp-usage_files/libs/clipboard/clipboard.min.js +7 -0
  302. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/anchor.min.js +9 -0
  303. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/axe/axe-check.js +145 -0
  304. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/popper.min.js +6 -0
  305. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css +236 -0
  306. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/quarto.js +847 -0
  307. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/tabsets/tabsets.js +95 -0
  308. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/tippy.css +1 -0
  309. package/docs/notebooklm-mcp-usage_files/libs/quarto-html/tippy.umd.min.js +2 -0
  310. package/docs/repomix-usage_files/libs/bootstrap/bootstrap-6b71f2156b6a5230c6677325978bcf08.min.css +12 -0
  311. package/docs/repomix-usage_files/libs/bootstrap/bootstrap-icons.css +2106 -0
  312. package/docs/repomix-usage_files/libs/bootstrap/bootstrap-icons.woff +0 -0
  313. package/docs/repomix-usage_files/libs/bootstrap/bootstrap.min.js +7 -0
  314. package/docs/repomix-usage_files/libs/clipboard/clipboard.min.js +7 -0
  315. package/docs/repomix-usage_files/libs/quarto-html/anchor.min.js +9 -0
  316. package/docs/repomix-usage_files/libs/quarto-html/axe/axe-check.js +145 -0
  317. package/docs/repomix-usage_files/libs/quarto-html/popper.min.js +6 -0
  318. package/docs/repomix-usage_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css +236 -0
  319. package/docs/repomix-usage_files/libs/quarto-html/quarto.js +847 -0
  320. package/docs/repomix-usage_files/libs/quarto-html/tabsets/tabsets.js +95 -0
  321. package/docs/repomix-usage_files/libs/quarto-html/tippy.css +1 -0
  322. package/docs/repomix-usage_files/libs/quarto-html/tippy.umd.min.js +2 -0
  323. package/package.json +62 -0
@@ -0,0 +1,609 @@
1
+ <!DOCTYPE html>
2
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
+
4
+ <meta charset="utf-8">
5
+ <meta name="generator" content="quarto-1.8.26">
6
+
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
+
9
+ <meta name="author" content="Antigravity AI">
10
+ <meta name="dcterms.date" content="2026-01-02">
11
+
12
+ <title>NotebookLM MCP Project Re-evaluation Report</title>
13
+ <style>
14
+ code{white-space: pre-wrap;}
15
+ span.smallcaps{font-variant: small-caps;}
16
+ div.columns{display: flex; gap: min(4vw, 1.5em);}
17
+ div.column{flex: auto; overflow-x: auto;}
18
+ div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
19
+ ul.task-list{list-style: none;}
20
+ ul.task-list li input[type="checkbox"] {
21
+ width: 0.8em;
22
+ margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
23
+ vertical-align: middle;
24
+ }
25
+ </style>
26
+
27
+
28
+ <script src="08_project-re-evaluation_files/libs/clipboard/clipboard.min.js"></script>
29
+ <script src="08_project-re-evaluation_files/libs/quarto-html/quarto.js" type="module"></script>
30
+ <script src="08_project-re-evaluation_files/libs/quarto-html/tabsets/tabsets.js" type="module"></script>
31
+ <script src="08_project-re-evaluation_files/libs/quarto-html/axe/axe-check.js" type="module"></script>
32
+ <script src="08_project-re-evaluation_files/libs/quarto-html/popper.min.js"></script>
33
+ <script src="08_project-re-evaluation_files/libs/quarto-html/tippy.umd.min.js"></script>
34
+ <script src="08_project-re-evaluation_files/libs/quarto-html/anchor.min.js"></script>
35
+ <link href="08_project-re-evaluation_files/libs/quarto-html/tippy.css" rel="stylesheet">
36
+ <link href="08_project-re-evaluation_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css" rel="stylesheet" id="quarto-text-highlighting-styles">
37
+ <script src="08_project-re-evaluation_files/libs/bootstrap/bootstrap.min.js"></script>
38
+ <link href="08_project-re-evaluation_files/libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
39
+ <link href="08_project-re-evaluation_files/libs/bootstrap/bootstrap-4f0954b6b0dd6bf39f4bb9151ba984db.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
40
+
41
+
42
+ </head>
43
+
44
+ <body class="quarto-light">
45
+
46
+ <div id="quarto-content" class="page-columns page-rows-contents page-layout-article">
47
+ <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
48
+ <nav id="TOC" role="doc-toc" class="toc-active">
49
+ <h2 id="toc-title">Table of contents</h2>
50
+
51
+ <ul>
52
+ <li><a href="#개요" id="toc-개요" class="nav-link active" data-scroll-target="#개요"><span class="header-section-number">1</span> 개요</a></li>
53
+ <li><a href="#gemini-3-도입-타당성-분석" id="toc-gemini-3-도입-타당성-분석" class="nav-link" data-scroll-target="#gemini-3-도입-타당성-분석"><span class="header-section-number">2</span> Gemini 3 도입 타당성 분석</a>
54
+ <ul class="collapse">
55
+ <li><a href="#현황" id="toc-현황" class="nav-link" data-scroll-target="#현황"><span class="header-section-number">2.1</span> 현황</a></li>
56
+ <li><a href="#분석-결과" id="toc-분석-결과" class="nav-link" data-scroll-target="#분석-결과"><span class="header-section-number">2.2</span> 분석 결과</a></li>
57
+ <li><a href="#권장-사항" id="toc-권장-사항" class="nav-link" data-scroll-target="#권장-사항"><span class="header-section-number">2.3</span> 권장 사항</a></li>
58
+ </ul></li>
59
+ <li><a href="#코드-품질-및-아키텍처-재평가" id="toc-코드-품질-및-아키텍처-재평가" class="nav-link" data-scroll-target="#코드-품질-및-아키텍처-재평가"><span class="header-section-number">3</span> 코드 품질 및 아키텍처 재평가</a>
60
+ <ul class="collapse">
61
+ <li><a href="#type-safety-타입-안전성" id="toc-type-safety-타입-안전성" class="nav-link" data-scroll-target="#type-safety-타입-안전성"><span class="header-section-number">3.1</span> 1. Type Safety (타입 안전성)</a></li>
62
+ <li><a href="#linting-style" id="toc-linting-style" class="nav-link" data-scroll-target="#linting-style"><span class="header-section-number">3.2</span> 2. Linting &amp; Style</a></li>
63
+ <li><a href="#esm-호환성" id="toc-esm-호환성" class="nav-link" data-scroll-target="#esm-호환성"><span class="header-section-number">3.3</span> 3. ESM 호환성</a></li>
64
+ </ul></li>
65
+ <li><a href="#종합-개선-로드맵" id="toc-종합-개선-로드맵" class="nav-link" data-scroll-target="#종합-개선-로드맵"><span class="header-section-number">4</span> 종합 개선 로드맵</a></li>
66
+ <li><a href="#결론" id="toc-결론" class="nav-link" data-scroll-target="#결론"><span class="header-section-number">5</span> 결론</a></li>
67
+ </ul>
68
+ </nav>
69
+ </div>
70
+ <main class="content" id="quarto-document-content">
71
+
72
+ <header id="title-block-header" class="quarto-title-block default">
73
+ <div class="quarto-title">
74
+ <h1 class="title">NotebookLM MCP Project Re-evaluation Report</h1>
75
+ </div>
76
+
77
+
78
+
79
+ <div class="quarto-title-meta">
80
+
81
+ <div>
82
+ <div class="quarto-title-meta-heading">Author</div>
83
+ <div class="quarto-title-meta-contents">
84
+ <p>Antigravity AI </p>
85
+ </div>
86
+ </div>
87
+
88
+ <div>
89
+ <div class="quarto-title-meta-heading">Published</div>
90
+ <div class="quarto-title-meta-contents">
91
+ <p class="date">January 2, 2026</p>
92
+ </div>
93
+ </div>
94
+
95
+
96
+ </div>
97
+
98
+
99
+
100
+ </header>
101
+
102
+
103
+ <section id="개요" class="level1" data-number="1">
104
+ <h1 data-number="1"><span class="header-section-number">1</span> 개요</h1>
105
+ <p>본 문서는 현재 NotebookLM MCP 프로젝트의 상태를 재평가하고, Google의 최신 모델 업데이트(Gemini 3) 반영 여부 및 코드 품질 개선 사항을 분석합니다.</p>
106
+ <hr>
107
+ </section>
108
+ <section id="gemini-3-도입-타당성-분석" class="level1" data-number="2">
109
+ <h1 data-number="2"><span class="header-section-number">2</span> Gemini 3 도입 타당성 분석</h1>
110
+ <section id="현황" class="level2" data-number="2.1">
111
+ <h2 data-number="2.1" class="anchored" data-anchor-id="현황"><span class="header-section-number">2.1</span> 현황</h2>
112
+ <p>현재 프로젝트의 문서와 코드(<code>ask-question.ts</code>, <code>index.ts</code> 등)는 <strong>“Gemini 2.5”</strong>를 명시적으로 언급하고 있습니다.</p>
113
+ </section>
114
+ <section id="분석-결과" class="level2" data-number="2.2">
115
+ <h2 data-number="2.2" class="anchored" data-anchor-id="분석-결과"><span class="header-section-number">2.2</span> 분석 결과</h2>
116
+ <p>외부 조사 결과, Google은 <strong>2025년 12월 NotebookLM의 백엔드 모델을 Gemini 3(Flash)로 공식 업그레이드</strong>했습니다. 사용자가 별도로 설정할 필요 없이, NotebookLM 서비스 자체가 이미 Gemini 3 기반으로 동작하고 있습니다.</p>
117
+ </section>
118
+ <section id="권장-사항" class="level2" data-number="2.3">
119
+ <h2 data-number="2.3" class="anchored" data-anchor-id="권장-사항"><span class="header-section-number">2.3</span> 권장 사항</h2>
120
+ <ul>
121
+ <li><strong>문서 업데이트</strong>: <code>README.md</code>, <code>CHANGELOG.md</code>, 소스 코드 내의 “Gemini 2.5” 언급을 모두 <strong>“Gemini 3”</strong>로 수정해야 합니다.</li>
122
+ <li><strong>기능 영향</strong>:
123
+ <ul>
124
+ <li>Gemini 3는 추론 능력과 멀티모달 이해력이 크게 향상됨.</li>
125
+ <li>MCP 서버 자체의 로직 변경은 불필요하나, 사용자에게 “더 똑똑한 모델”을 사용 중임을 알리는 것이 중요.</li>
126
+ </ul></li>
127
+ </ul>
128
+ <hr>
129
+ </section>
130
+ </section>
131
+ <section id="코드-품질-및-아키텍처-재평가" class="level1" data-number="3">
132
+ <h1 data-number="3"><span class="header-section-number">3</span> 코드 품질 및 아키텍처 재평가</h1>
133
+ <section id="type-safety-타입-안전성" class="level2" data-number="3.1">
134
+ <h2 data-number="3.1" class="anchored" data-anchor-id="type-safety-타입-안전성"><span class="header-section-number">3.1</span> 1. Type Safety (타입 안전성)</h2>
135
+ <p><code>src/types.ts</code> 및 주요 파일에서 <code>any</code> 타입이 과도하게 사용되고 있어, 런타임 안정성을 해칠 우려가 있습니다.</p>
136
+ <ul>
137
+ <li><strong>발견된 <code>any</code> 사용 사례</strong>:
138
+ <ul>
139
+ <li><code>ServerState</code> 인터페이스: <code>playwright: any</code>, <code>sessionManager: any</code> 등</li>
140
+ <li><code>BrowserSession</code>: <code>catch (error: any)</code> (이건 허용 가능범위이나, 커스텀 에러 타입 권장)</li>
141
+ <li><code>ResourceHandlers</code>: <code>const resources: any[]</code></li>
142
+ <li><code>ToolHandlers</code>: 리턴 타입 <code>Promise&lt;ToolResult&lt;{ notebook: any }&gt;&gt;</code></li>
143
+ </ul></li>
144
+ </ul>
145
+ <p><strong>개선 제안</strong>: - <code>playwright</code>, <code>sessionManager</code> 등의 구체적인 인터페이스 정의 - <code>notebook</code> 객체에 대한 스키마 정의 (최소한의 필드라도)</p>
146
+ </section>
147
+ <section id="linting-style" class="level2" data-number="3.2">
148
+ <h2 data-number="3.2" class="anchored" data-anchor-id="linting-style"><span class="header-section-number">3.2</span> 2. Linting &amp; Style</h2>
149
+ <p>ESLint 설정이 프로젝트에 존재하나, <code>src</code> 디렉토리 내에서 실행 시 일부 규칙 위반이 예상됩니다. (실행 시도 시 의존성 설치 필요)</p>
150
+ <p><strong>개선 제안</strong>: - CI/CD 파이프라인에 <code>npm run lint</code> 추가 - <code>unused-vars</code> 정리 (이전 작업에서 일부 수행함)</p>
151
+ </section>
152
+ <section id="esm-호환성" class="level2" data-number="3.3">
153
+ <h2 data-number="3.3" class="anchored" data-anchor-id="esm-호환성"><span class="header-section-number">3.3</span> 3. ESM 호환성</h2>
154
+ <p>이전 분석에서 지적된 <code>require()</code> 사용은 대부분 해결된 것으로 보이나, <code>tsconfig.json</code>의 <code>moduleResolution</code>이 <code>node16</code> 또는 <code>nodenext</code>일 때 import 경로에 <code>.js</code> 확장자를 명시하는 규칙을 철저히 지켜야 합니다.</p>
155
+ <hr>
156
+ </section>
157
+ </section>
158
+ <section id="종합-개선-로드맵" class="level1" data-number="4">
159
+ <h1 data-number="4"><span class="header-section-number">4</span> 종합 개선 로드맵</h1>
160
+ <table class="caption-top table">
161
+ <colgroup>
162
+ <col style="width: 27%">
163
+ <col style="width: 22%">
164
+ <col style="width: 27%">
165
+ <col style="width: 22%">
166
+ </colgroup>
167
+ <thead>
168
+ <tr class="header">
169
+ <th style="text-align: center;">우선순위</th>
170
+ <th style="text-align: left;">작업 항목</th>
171
+ <th style="text-align: center;">난이도</th>
172
+ <th style="text-align: left;">기대 효과</th>
173
+ </tr>
174
+ </thead>
175
+ <tbody>
176
+ <tr class="odd">
177
+ <td style="text-align: center;">1 (즉시)</td>
178
+ <td style="text-align: left;"><strong>문서/텍스트 업데이트 (Gemini 2.5 -&gt; 3)</strong></td>
179
+ <td style="text-align: center;">하</td>
180
+ <td style="text-align: left;">사용자에게 정확한 정보 제공 및 최신성 강조</td>
181
+ </tr>
182
+ <tr class="even">
183
+ <td style="text-align: center;">2 (높음)</td>
184
+ <td style="text-align: left;"><strong><code>any</code> 타입 제거 및 인터페이스 정의</strong></td>
185
+ <td style="text-align: center;">중</td>
186
+ <td style="text-align: left;">코드 안정성 향상, 개발자 경험 개선 (자동완성)</td>
187
+ </tr>
188
+ <tr class="odd">
189
+ <td style="text-align: center;">3 (중감)</td>
190
+ <td style="text-align: left;"><strong>Rate Limit 테스트 커버리지 확대</strong></td>
191
+ <td style="text-align: center;">중</td>
192
+ <td style="text-align: left;">안정성 확보 (이미 구현됨, 검증만 지속)</td>
193
+ </tr>
194
+ </tbody>
195
+ </table>
196
+ </section>
197
+ <section id="결론" class="level1" data-number="5">
198
+ <h1 data-number="5"><span class="header-section-number">5</span> 결론</h1>
199
+ <p>이 프로젝트는 기능적으로 우수하나, <strong>Gemini 3로의 브랜딩 업데이트</strong>가 시급하며, 장기적인 유지보수를 위해 <strong>타입 정의 강화</strong>가 필요합니다.</p>
200
+ </section>
201
+
202
+ </main>
203
+ <!-- /main column -->
204
+ <script id="quarto-html-after-body" type="application/javascript">
205
+ window.document.addEventListener("DOMContentLoaded", function (event) {
206
+ const icon = "";
207
+ const anchorJS = new window.AnchorJS();
208
+ anchorJS.options = {
209
+ placement: 'right',
210
+ icon: icon
211
+ };
212
+ anchorJS.add('.anchored');
213
+ const isCodeAnnotation = (el) => {
214
+ for (const clz of el.classList) {
215
+ if (clz.startsWith('code-annotation-')) {
216
+ return true;
217
+ }
218
+ }
219
+ return false;
220
+ }
221
+ const onCopySuccess = function(e) {
222
+ // button target
223
+ const button = e.trigger;
224
+ // don't keep focus
225
+ button.blur();
226
+ // flash "checked"
227
+ button.classList.add('code-copy-button-checked');
228
+ var currentTitle = button.getAttribute("title");
229
+ button.setAttribute("title", "Copied!");
230
+ let tooltip;
231
+ if (window.bootstrap) {
232
+ button.setAttribute("data-bs-toggle", "tooltip");
233
+ button.setAttribute("data-bs-placement", "left");
234
+ button.setAttribute("data-bs-title", "Copied!");
235
+ tooltip = new bootstrap.Tooltip(button,
236
+ { trigger: "manual",
237
+ customClass: "code-copy-button-tooltip",
238
+ offset: [0, -8]});
239
+ tooltip.show();
240
+ }
241
+ setTimeout(function() {
242
+ if (tooltip) {
243
+ tooltip.hide();
244
+ button.removeAttribute("data-bs-title");
245
+ button.removeAttribute("data-bs-toggle");
246
+ button.removeAttribute("data-bs-placement");
247
+ }
248
+ button.setAttribute("title", currentTitle);
249
+ button.classList.remove('code-copy-button-checked');
250
+ }, 1000);
251
+ // clear code selection
252
+ e.clearSelection();
253
+ }
254
+ const getTextToCopy = function(trigger) {
255
+ const outerScaffold = trigger.parentElement.cloneNode(true);
256
+ const codeEl = outerScaffold.querySelector('code');
257
+ for (const childEl of codeEl.children) {
258
+ if (isCodeAnnotation(childEl)) {
259
+ childEl.remove();
260
+ }
261
+ }
262
+ return codeEl.innerText;
263
+ }
264
+ const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
265
+ text: getTextToCopy
266
+ });
267
+ clipboard.on('success', onCopySuccess);
268
+ if (window.document.getElementById('quarto-embedded-source-code-modal')) {
269
+ const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
270
+ text: getTextToCopy,
271
+ container: window.document.getElementById('quarto-embedded-source-code-modal')
272
+ });
273
+ clipboardModal.on('success', onCopySuccess);
274
+ }
275
+ var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
276
+ var mailtoRegex = new RegExp(/^mailto:/);
277
+ var filterRegex = new RegExp('/' + window.location.host + '/');
278
+ var isInternal = (href) => {
279
+ return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
280
+ }
281
+ // Inspect non-navigation links and adorn them if external
282
+ var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
283
+ for (var i=0; i<links.length; i++) {
284
+ const link = links[i];
285
+ if (!isInternal(link.href)) {
286
+ // undo the damage that might have been done by quarto-nav.js in the case of
287
+ // links that we want to consider external
288
+ if (link.dataset.originalHref !== undefined) {
289
+ link.href = link.dataset.originalHref;
290
+ }
291
+ }
292
+ }
293
+ function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
294
+ const config = {
295
+ allowHTML: true,
296
+ maxWidth: 500,
297
+ delay: 100,
298
+ arrow: false,
299
+ appendTo: function(el) {
300
+ return el.parentElement;
301
+ },
302
+ interactive: true,
303
+ interactiveBorder: 10,
304
+ theme: 'quarto',
305
+ placement: 'bottom-start',
306
+ };
307
+ if (contentFn) {
308
+ config.content = contentFn;
309
+ }
310
+ if (onTriggerFn) {
311
+ config.onTrigger = onTriggerFn;
312
+ }
313
+ if (onUntriggerFn) {
314
+ config.onUntrigger = onUntriggerFn;
315
+ }
316
+ window.tippy(el, config);
317
+ }
318
+ const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
319
+ for (var i=0; i<noterefs.length; i++) {
320
+ const ref = noterefs[i];
321
+ tippyHover(ref, function() {
322
+ // use id or data attribute instead here
323
+ let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
324
+ try { href = new URL(href).hash; } catch {}
325
+ const id = href.replace(/^#\/?/, "");
326
+ const note = window.document.getElementById(id);
327
+ if (note) {
328
+ return note.innerHTML;
329
+ } else {
330
+ return "";
331
+ }
332
+ });
333
+ }
334
+ const xrefs = window.document.querySelectorAll('a.quarto-xref');
335
+ const processXRef = (id, note) => {
336
+ // Strip column container classes
337
+ const stripColumnClz = (el) => {
338
+ el.classList.remove("page-full", "page-columns");
339
+ if (el.children) {
340
+ for (const child of el.children) {
341
+ stripColumnClz(child);
342
+ }
343
+ }
344
+ }
345
+ stripColumnClz(note)
346
+ if (id === null || id.startsWith('sec-')) {
347
+ // Special case sections, only their first couple elements
348
+ const container = document.createElement("div");
349
+ if (note.children && note.children.length > 2) {
350
+ container.appendChild(note.children[0].cloneNode(true));
351
+ for (let i = 1; i < note.children.length; i++) {
352
+ const child = note.children[i];
353
+ if (child.tagName === "P" && child.innerText === "") {
354
+ continue;
355
+ } else {
356
+ container.appendChild(child.cloneNode(true));
357
+ break;
358
+ }
359
+ }
360
+ if (window.Quarto?.typesetMath) {
361
+ window.Quarto.typesetMath(container);
362
+ }
363
+ return container.innerHTML
364
+ } else {
365
+ if (window.Quarto?.typesetMath) {
366
+ window.Quarto.typesetMath(note);
367
+ }
368
+ return note.innerHTML;
369
+ }
370
+ } else {
371
+ // Remove any anchor links if they are present
372
+ const anchorLink = note.querySelector('a.anchorjs-link');
373
+ if (anchorLink) {
374
+ anchorLink.remove();
375
+ }
376
+ if (window.Quarto?.typesetMath) {
377
+ window.Quarto.typesetMath(note);
378
+ }
379
+ if (note.classList.contains("callout")) {
380
+ return note.outerHTML;
381
+ } else {
382
+ return note.innerHTML;
383
+ }
384
+ }
385
+ }
386
+ for (var i=0; i<xrefs.length; i++) {
387
+ const xref = xrefs[i];
388
+ tippyHover(xref, undefined, function(instance) {
389
+ instance.disable();
390
+ let url = xref.getAttribute('href');
391
+ let hash = undefined;
392
+ if (url.startsWith('#')) {
393
+ hash = url;
394
+ } else {
395
+ try { hash = new URL(url).hash; } catch {}
396
+ }
397
+ if (hash) {
398
+ const id = hash.replace(/^#\/?/, "");
399
+ const note = window.document.getElementById(id);
400
+ if (note !== null) {
401
+ try {
402
+ const html = processXRef(id, note.cloneNode(true));
403
+ instance.setContent(html);
404
+ } finally {
405
+ instance.enable();
406
+ instance.show();
407
+ }
408
+ } else {
409
+ // See if we can fetch this
410
+ fetch(url.split('#')[0])
411
+ .then(res => res.text())
412
+ .then(html => {
413
+ const parser = new DOMParser();
414
+ const htmlDoc = parser.parseFromString(html, "text/html");
415
+ const note = htmlDoc.getElementById(id);
416
+ if (note !== null) {
417
+ const html = processXRef(id, note);
418
+ instance.setContent(html);
419
+ }
420
+ }).finally(() => {
421
+ instance.enable();
422
+ instance.show();
423
+ });
424
+ }
425
+ } else {
426
+ // See if we can fetch a full url (with no hash to target)
427
+ // This is a special case and we should probably do some content thinning / targeting
428
+ fetch(url)
429
+ .then(res => res.text())
430
+ .then(html => {
431
+ const parser = new DOMParser();
432
+ const htmlDoc = parser.parseFromString(html, "text/html");
433
+ const note = htmlDoc.querySelector('main.content');
434
+ if (note !== null) {
435
+ // This should only happen for chapter cross references
436
+ // (since there is no id in the URL)
437
+ // remove the first header
438
+ if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
439
+ note.children[0].remove();
440
+ }
441
+ const html = processXRef(null, note);
442
+ instance.setContent(html);
443
+ }
444
+ }).finally(() => {
445
+ instance.enable();
446
+ instance.show();
447
+ });
448
+ }
449
+ }, function(instance) {
450
+ });
451
+ }
452
+ let selectedAnnoteEl;
453
+ const selectorForAnnotation = ( cell, annotation) => {
454
+ let cellAttr = 'data-code-cell="' + cell + '"';
455
+ let lineAttr = 'data-code-annotation="' + annotation + '"';
456
+ const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
457
+ return selector;
458
+ }
459
+ const selectCodeLines = (annoteEl) => {
460
+ const doc = window.document;
461
+ const targetCell = annoteEl.getAttribute("data-target-cell");
462
+ const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
463
+ const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
464
+ const lines = annoteSpan.getAttribute("data-code-lines").split(",");
465
+ const lineIds = lines.map((line) => {
466
+ return targetCell + "-" + line;
467
+ })
468
+ let top = null;
469
+ let height = null;
470
+ let parent = null;
471
+ if (lineIds.length > 0) {
472
+ //compute the position of the single el (top and bottom and make a div)
473
+ const el = window.document.getElementById(lineIds[0]);
474
+ top = el.offsetTop;
475
+ height = el.offsetHeight;
476
+ parent = el.parentElement.parentElement;
477
+ if (lineIds.length > 1) {
478
+ const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
479
+ const bottom = lastEl.offsetTop + lastEl.offsetHeight;
480
+ height = bottom - top;
481
+ }
482
+ if (top !== null && height !== null && parent !== null) {
483
+ // cook up a div (if necessary) and position it
484
+ let div = window.document.getElementById("code-annotation-line-highlight");
485
+ if (div === null) {
486
+ div = window.document.createElement("div");
487
+ div.setAttribute("id", "code-annotation-line-highlight");
488
+ div.style.position = 'absolute';
489
+ parent.appendChild(div);
490
+ }
491
+ div.style.top = top - 2 + "px";
492
+ div.style.height = height + 4 + "px";
493
+ div.style.left = 0;
494
+ let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
495
+ if (gutterDiv === null) {
496
+ gutterDiv = window.document.createElement("div");
497
+ gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
498
+ gutterDiv.style.position = 'absolute';
499
+ const codeCell = window.document.getElementById(targetCell);
500
+ const gutter = codeCell.querySelector('.code-annotation-gutter');
501
+ gutter.appendChild(gutterDiv);
502
+ }
503
+ gutterDiv.style.top = top - 2 + "px";
504
+ gutterDiv.style.height = height + 4 + "px";
505
+ }
506
+ selectedAnnoteEl = annoteEl;
507
+ }
508
+ };
509
+ const unselectCodeLines = () => {
510
+ const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
511
+ elementsIds.forEach((elId) => {
512
+ const div = window.document.getElementById(elId);
513
+ if (div) {
514
+ div.remove();
515
+ }
516
+ });
517
+ selectedAnnoteEl = undefined;
518
+ };
519
+ // Handle positioning of the toggle
520
+ window.addEventListener(
521
+ "resize",
522
+ throttle(() => {
523
+ elRect = undefined;
524
+ if (selectedAnnoteEl) {
525
+ selectCodeLines(selectedAnnoteEl);
526
+ }
527
+ }, 10)
528
+ );
529
+ function throttle(fn, ms) {
530
+ let throttle = false;
531
+ let timer;
532
+ return (...args) => {
533
+ if(!throttle) { // first call gets through
534
+ fn.apply(this, args);
535
+ throttle = true;
536
+ } else { // all the others get throttled
537
+ if(timer) clearTimeout(timer); // cancel #2
538
+ timer = setTimeout(() => {
539
+ fn.apply(this, args);
540
+ timer = throttle = false;
541
+ }, ms);
542
+ }
543
+ };
544
+ }
545
+ // Attach click handler to the DT
546
+ const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
547
+ for (const annoteDlNode of annoteDls) {
548
+ annoteDlNode.addEventListener('click', (event) => {
549
+ const clickedEl = event.target;
550
+ if (clickedEl !== selectedAnnoteEl) {
551
+ unselectCodeLines();
552
+ const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
553
+ if (activeEl) {
554
+ activeEl.classList.remove('code-annotation-active');
555
+ }
556
+ selectCodeLines(clickedEl);
557
+ clickedEl.classList.add('code-annotation-active');
558
+ } else {
559
+ // Unselect the line
560
+ unselectCodeLines();
561
+ clickedEl.classList.remove('code-annotation-active');
562
+ }
563
+ });
564
+ }
565
+ const findCites = (el) => {
566
+ const parentEl = el.parentElement;
567
+ if (parentEl) {
568
+ const cites = parentEl.dataset.cites;
569
+ if (cites) {
570
+ return {
571
+ el,
572
+ cites: cites.split(' ')
573
+ };
574
+ } else {
575
+ return findCites(el.parentElement)
576
+ }
577
+ } else {
578
+ return undefined;
579
+ }
580
+ };
581
+ var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
582
+ for (var i=0; i<bibliorefs.length; i++) {
583
+ const ref = bibliorefs[i];
584
+ const citeInfo = findCites(ref);
585
+ if (citeInfo) {
586
+ tippyHover(citeInfo.el, function() {
587
+ var popup = window.document.createElement('div');
588
+ citeInfo.cites.forEach(function(cite) {
589
+ var citeDiv = window.document.createElement('div');
590
+ citeDiv.classList.add('hanging-indent');
591
+ citeDiv.classList.add('csl-entry');
592
+ var biblioDiv = window.document.getElementById('ref-' + cite);
593
+ if (biblioDiv) {
594
+ citeDiv.innerHTML = biblioDiv.innerHTML;
595
+ }
596
+ popup.appendChild(citeDiv);
597
+ });
598
+ return popup.innerHTML;
599
+ });
600
+ }
601
+ }
602
+ });
603
+ </script>
604
+ </div> <!-- /content -->
605
+
606
+
607
+
608
+
609
+ </body></html>