├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── copyright │ ├── Knowledge_Copyright.xml │ └── profiles_settings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jsLinters │ └── eslint.xml ├── knowledge.iml ├── modules.xml ├── prettier.xml ├── scopes │ ├── HTML_Files.xml │ └── Typescript_Files.xml ├── vcs.xml └── watcherTasks.xml ├── .yarn ├── plugins │ └── @yarnpkg │ │ ├── plugin-interactive-tools.cjs │ │ ├── plugin-typescript.cjs │ │ └── plugin-workspace-tools.cjs └── releases │ └── yarn-3.2.4.cjs ├── .yarnrc.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── Resources ├── app.env ├── entitlements.mac.plist ├── examples_v3.json ├── icon.icns ├── icon.ico ├── icon.png ├── icon.svg └── notarize.js ├── package.json ├── src ├── kc_angular │ ├── .browserslistrc │ ├── .editorconfig │ ├── .gitignore │ ├── angular.json │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── animations.ts │ │ │ ├── app-routing.module.ts │ │ │ ├── app.component.html │ │ │ ├── app.component.scss │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── components │ │ │ │ ├── calendar.component.ts │ │ │ │ ├── chat-components │ │ │ │ │ ├── api.component.ts │ │ │ │ │ ├── chat.actions.component.ts │ │ │ │ │ ├── chat.input.component.ts │ │ │ │ │ ├── chat.message.component.ts │ │ │ │ │ ├── chat.toolbar.component.ts │ │ │ │ │ ├── chat.view.component.html │ │ │ │ │ ├── chat.view.component.scss │ │ │ │ │ └── chat.view.component.ts │ │ │ │ ├── chat.component.ts │ │ │ │ ├── graph-components │ │ │ │ │ ├── graph-search.component.ts │ │ │ │ │ ├── graph.canvas.component.ts │ │ │ │ │ ├── graph.controls.component.ts │ │ │ │ │ ├── graph.layouts.ts │ │ │ │ │ ├── graph.status.ts │ │ │ │ │ └── graph.styles.ts │ │ │ │ ├── graph.component.ts │ │ │ │ ├── grid.component.ts │ │ │ │ ├── history.component.ts │ │ │ │ ├── home.component.ts │ │ │ │ ├── project-components │ │ │ │ │ ├── project-breadcrumb.component.ts │ │ │ │ │ ├── project-calendar.component.ts │ │ │ │ │ ├── project-card.component.ts │ │ │ │ │ ├── project-creation-dialog.component.ts │ │ │ │ │ ├── project-details.component.ts │ │ │ │ │ ├── project-selector.component.ts │ │ │ │ │ └── projects-tree.component.ts │ │ │ │ ├── search.component.ts │ │ │ │ ├── settings │ │ │ │ │ ├── chat-settings.component.ts │ │ │ │ │ ├── display-settings.component.ts │ │ │ │ │ ├── graph-settings.component.ts │ │ │ │ │ ├── ingest-settings.component.ts │ │ │ │ │ ├── search-settings.component.ts │ │ │ │ │ ├── setting-template.component.ts │ │ │ │ │ ├── settings.component.ts │ │ │ │ │ └── storage-settings.component.ts │ │ │ │ ├── shared │ │ │ │ │ ├── create.component.ts │ │ │ │ │ ├── icon.component.ts │ │ │ │ │ ├── loading.component.ts │ │ │ │ │ ├── pro-tips.component.ts │ │ │ │ │ └── timeline.component.ts │ │ │ │ ├── source-components │ │ │ │ │ ├── ks-actions.component.ts │ │ │ │ │ ├── ks-card-list.component.html │ │ │ │ │ ├── ks-card-list.component.ts │ │ │ │ │ ├── ks-card.component.ts │ │ │ │ │ ├── ks-details.component.ts │ │ │ │ │ ├── ks-dropzone.component.ts │ │ │ │ │ ├── ks-export.component.ts │ │ │ │ │ ├── ks-icon.component.ts │ │ │ │ │ ├── ks-message.component.ts │ │ │ │ │ ├── ks-preview.component.ts │ │ │ │ │ ├── ks-table.component.ts │ │ │ │ │ ├── ks-thumbnail.component.ts │ │ │ │ │ ├── ks-viewport │ │ │ │ │ │ ├── browser-view.component.ts │ │ │ │ │ │ ├── file-view.component.ts │ │ │ │ │ │ └── viewport-header.component.ts │ │ │ │ │ ├── source.browser.component.ts │ │ │ │ │ ├── source.chat.component.ts │ │ │ │ │ ├── source.component.ts │ │ │ │ │ ├── source.details.component.ts │ │ │ │ │ ├── source.document.component.ts │ │ │ │ │ ├── source.metadata.component.ts │ │ │ │ │ ├── source.notes.component.ts │ │ │ │ │ ├── source.styles.scss │ │ │ │ │ ├── source.timeline.component.ts │ │ │ │ │ └── source.video.component.ts │ │ │ │ └── table.component.ts │ │ │ ├── directives │ │ │ │ ├── pro-tip.directive.ts │ │ │ │ └── recreate-view.directive.ts │ │ │ ├── models │ │ │ │ ├── cards.model.ts │ │ │ │ ├── chat.model.ts │ │ │ │ ├── knowledge.source.model.ts │ │ │ │ ├── project.model.ts │ │ │ │ └── project.tree.model.ts │ │ │ ├── pipes │ │ │ │ ├── countdown.pipe.ts │ │ │ │ ├── import-method.pipe.ts │ │ │ │ ├── ks-ingest-type-icon.pipe.ts │ │ │ │ ├── markdown.pipe.ts │ │ │ │ ├── project-as-tree-node.pipe.ts │ │ │ │ ├── project-breadcrumb.pipe.ts │ │ │ │ ├── project-name.pipe.ts │ │ │ │ ├── sanitize-html.pipe.ts │ │ │ │ ├── switch-label.pipe.ts │ │ │ │ ├── truncate.pipe.ts │ │ │ │ └── view-icon.pipe.ts │ │ │ ├── services │ │ │ │ ├── chat-services │ │ │ │ │ ├── chat.service.ts │ │ │ │ │ ├── guard.ts │ │ │ │ │ ├── project.ts │ │ │ │ │ ├── prompts.ts │ │ │ │ │ └── source.ts │ │ │ │ ├── command-services │ │ │ │ │ ├── ks-command.service.ts │ │ │ │ │ ├── pro-tip.service.ts │ │ │ │ │ └── project-command.service.ts │ │ │ │ ├── factory-services │ │ │ │ │ ├── chat-context-menu.service.ts │ │ │ │ │ ├── ks-context-menu.service.ts │ │ │ │ │ ├── ks-factory.service.ts │ │ │ │ │ ├── markdown.service.ts │ │ │ │ │ ├── project-context-menu.service.ts │ │ │ │ │ ├── project-tree-factory.service.ts │ │ │ │ │ ├── project.service.ts │ │ │ │ │ └── sidebar.service.ts │ │ │ │ ├── ingest-services │ │ │ │ │ ├── autoscan.service.ts │ │ │ │ │ ├── drag-and-drop.service.ts │ │ │ │ │ ├── extension.service.ts │ │ │ │ │ ├── extractor.service.ts │ │ │ │ │ ├── favicon.service.ts │ │ │ │ │ └── ingest.service.ts │ │ │ │ ├── ipc-services │ │ │ │ │ ├── browser-view-dialog.service.ts │ │ │ │ │ ├── electron-ipc.service.ts │ │ │ │ │ ├── settings.service.ts │ │ │ │ │ ├── startup.service.ts │ │ │ │ │ ├── storage.service.ts │ │ │ │ │ └── uuid.service.ts │ │ │ │ └── user-services │ │ │ │ │ ├── data.service.ts │ │ │ │ │ ├── event.service.ts │ │ │ │ │ ├── icon.service.ts │ │ │ │ │ ├── notifications.service.ts │ │ │ │ │ ├── search.service.ts │ │ │ │ │ ├── theme.service.ts │ │ │ │ │ └── topic.service.ts │ │ │ └── workers │ │ │ │ ├── graph.worker.ts │ │ │ │ └── tree.worker.ts │ │ ├── assets │ │ │ ├── .gitkeep │ │ │ ├── favicon.ico │ │ │ └── img │ │ │ │ ├── default.png │ │ │ │ ├── icons │ │ │ │ ├── chrome_icon.svg │ │ │ │ └── firefox_icon.svg │ │ │ │ ├── kc-icon-greyscale.png │ │ │ │ ├── kc-icon-transparent.png │ │ │ │ ├── kc-icon.png │ │ │ │ ├── kc-logo-transparent.svg │ │ │ │ └── kc-logo.svg │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── styles.scss │ │ └── styles │ │ │ ├── kc-styles.scss │ │ │ └── themes │ │ │ ├── arya-blue.scss │ │ │ ├── arya-green.scss │ │ │ ├── arya-orange.scss │ │ │ ├── arya-purple.scss │ │ │ ├── lara-dark-blue.scss │ │ │ ├── lara-dark-indigo.scss │ │ │ ├── lara-dark-purple.scss │ │ │ ├── lara-dark-teal.scss │ │ │ ├── lara-light-blue.scss │ │ │ ├── lara-light-indigo.scss │ │ │ ├── lara-light-purple.scss │ │ │ ├── lara-light-teal.scss │ │ │ ├── saga-blue.scss │ │ │ ├── saga-green.scss │ │ │ ├── saga-orange.scss │ │ │ ├── saga-purple.scss │ │ │ ├── vela-blue.scss │ │ │ ├── vela-green.scss │ │ │ ├── vela-orange.scss │ │ │ └── vela-purple.scss │ ├── tsconfig.json │ └── tsconfig.worker.json ├── kc_electron │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── ipc │ │ │ │ ├── index.ts │ │ │ │ ├── ipc-auto-update.ts │ │ │ │ ├── ipc-browser.ts │ │ │ │ ├── ipc-files.ts │ │ │ │ └── ipc-misc.ts │ │ │ └── services │ │ │ │ ├── auto.update.service.ts │ │ │ │ ├── autoscan.service.ts │ │ │ │ ├── extension.service.ts │ │ │ │ ├── index.ts │ │ │ │ ├── settings.service.ts │ │ │ │ └── window.service.ts │ │ ├── ipc │ │ │ └── chat.ipc.ts │ │ ├── local │ │ │ ├── autoscan.api.ts │ │ │ ├── browser.api.ts │ │ │ ├── chat.api.ts │ │ │ ├── constants │ │ │ │ └── source.prompts.ts │ │ │ ├── controllers │ │ │ │ ├── api.controller.ts │ │ │ │ ├── chat.controller.ts │ │ │ │ ├── project.controller.ts │ │ │ │ └── source.controller.ts │ │ │ ├── middleware │ │ │ │ ├── DocumentSummarizer.ts │ │ │ │ ├── ErrorHandler.ts │ │ │ │ ├── SourceLoader.ts │ │ │ │ └── SourceParser.ts │ │ │ ├── routes │ │ │ │ ├── api.routes.ts │ │ │ │ ├── chat.routes.ts │ │ │ │ └── source.routes.ts │ │ │ └── utils │ │ │ │ ├── chat.utils.ts │ │ │ │ ├── encrypt.utils.ts │ │ │ │ ├── ipc.utils.ts │ │ │ │ ├── response.util.ts │ │ │ │ ├── text.utils.ts │ │ │ │ └── tokenizer.utils.ts │ │ ├── main.ts │ │ ├── preload.js │ │ └── test │ │ │ ├── autoscan.spec.ts │ │ │ ├── browser.spec.ts │ │ │ ├── chat.spec.ts │ │ │ └── ipc.spec.ts │ ├── tsconfig.json │ ├── webpack.common.js │ ├── webpack.dev.js │ └── webpack.prod.js └── kc_shared │ └── models │ ├── author.model.ts │ ├── browser.view.model.ts │ ├── chat.model.ts │ ├── electron.ipc.model.ts │ ├── event.model.ts │ ├── file.source.model.ts │ ├── graph.model.ts │ ├── hashable.model.ts │ ├── knowledge.source.model.ts │ ├── markup.model.ts │ ├── project.model.ts │ ├── settings.model.ts │ ├── style.model.ts │ ├── topic.model.ts │ ├── uuid.model.ts │ └── web.source.model.ts ├── tsconfig.json └── yarn.lock /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report about: Create a report to help us improve title: '[Bug]: ' 3 | labels: 'bug' assignees: '' 4 | knowledge version: '' 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | --- 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | --- 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected to happen. 24 | 25 | --- 26 | 27 | **Screenshots** 28 | If applicable, add screenshots to help explain your problem. 29 | 30 | --- 31 | 32 | **Operating System (please complete the following information):** 33 | 34 | - OS: [e.g. MacOS /w Apple Slicion (M1), Windows 10, etc.] 35 | - Version: [e.g. Big Sur, 20.04, etc.] 36 | 37 | --- 38 | 39 | **Additional context** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template about: Describe this issue template's purpose here. title: '[Request]: ' 3 | labels: 'request' assignees: '' 4 | 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request about: Suggest an idea for this project title: '[Feature]: ' 3 | labels: 'feature' assignees: '' 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | 9 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 10 | 11 | --- 12 | 13 | **Describe the solution you'd like** 14 | 15 | A clear and concise description of what you want to happen. 16 | 17 | --- 18 | 19 | **Describe alternatives you've considered** 20 | 21 | A clear and concise description of any alternative solutions or features you've considered. 22 | 23 | --- 24 | 25 | **Additional context** 26 | 27 | Add any other context or screenshots about the feature request here. 28 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '43 6 * * 1' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript', 'typescript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v2 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v2 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # MacOS files 2 | .DS_Store 3 | 4 | # Angular files 5 | **/.angular 6 | 7 | 8 | # Jupyter notebook checkpoints 9 | **/*.ipynb_checkpoints 10 | 11 | # Node modules 12 | **/node_modules 13 | 14 | # Build artifacts 15 | **/dist 16 | 17 | # Python stuff 18 | __pycache__ 19 | 20 | # Secret stuff 21 | auth.json 22 | 23 | .pnp.* 24 | .yarn/* 25 | !.yarn/patches 26 | !.yarn/plugins 27 | !.yarn/releases 28 | !.yarn/sdks 29 | !.yarn/versions 30 | 31 | *.d.ts 32 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 15 | 16 | 23 | 24 | 27 | 28 | 35 | 36 | 43 | 44 | 51 | 52 | 57 | 58 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/copyright/Knowledge_Copyright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/jsLinters/eslint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/knowledge.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/prettier.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/scopes/HTML_Files.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/scopes/Typescript_Files.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/watcherTasks.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | plugins: 4 | - path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs 5 | spec: "@yarnpkg/plugin-typescript" 6 | - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs 7 | spec: "@yarnpkg/plugin-workspace-tools" 8 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 9 | spec: "@yarnpkg/plugin-interactive-tools" 10 | 11 | yarnPath: .yarn/releases/yarn-3.2.4.cjs 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this repository 2 | 3 | Please make sure you understand the Apache 2.0 license terms before contributing 4 | to this repository. 5 | 6 | # Conventional Commits 7 | 8 | Please read [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) and review the guidelines listed therein. 9 | 10 | We are using the `standard-version` package, which is a tool that automatically updates version numbers, changelog, etc. You can read more 11 | about `standard-version` [here](https://github.com/conventional-changelog/standard-version) 12 | 13 | ## Commit Message Structure 14 | 15 | Commits should use the following structure. This allows `standard-version` to craft a changelog based solely on commits, which should make things easier for us as the project 16 | expands. See [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#examples) for examples. 17 | 18 | ``` 19 | [optional scope]: 20 | 21 | [optional body] 22 | 23 | [optional footer(s)] 24 | ``` 25 | 26 | ## Commit Types 27 | 28 | The following is a non-exhaustive list of commit types (``): 29 | 30 | * `feat` 31 | * `fix` 32 | * `docs` 33 | * `refactor` 34 | * `style` 35 | * `chore` 36 | 37 | # Tags, Releases, and Changelog 38 | 39 | For each release, we create a new branch with the format `release-x.y.z`. 40 | Changes meant to be included in a specific release should be created within a 41 | new branch created from the release in question, and a pull request should be 42 | made to that release branch (not `main`). 43 | 44 | **Example Feature-to-Release Pull Requests** 45 | 46 | - `release-0.5.4 <- feat-ks-info` 47 | - `release-0.5.3 <- feat-extraction-pipeline` 48 | 49 | Once a release is ready for production, a pull request should be created from 50 | `release-x.y.z` to `main`. Then, if/when the release is approved and merged, 51 | an administrator will run the `release` command (as defined in package.json). 52 | This command searches for commit messages of the formats described above, 53 | automatically populates the CHANGELOG, increments the application version number 54 | accordingly, and creates a new tag/release. 55 | 56 | **Example Release-to-Production Pull Request** 57 | 58 | - `main <- release-0.5.4` 59 | 60 | # Installers and Auto-Update 61 | 62 | The final build is currently done manually using 63 | `yarn build -> yarn dist-all -> yarn publish-all`. This creates the relevant 64 | binaries and places them in the `dist` folder, as well as publishes the binaries 65 | to a publicly accessible AWS S3 bucket (requires secret API key to publish). We 66 | push the binaries to AWS S3 to take advantage of Electrons auto-update feature, 67 | which automatically checks for and installs new versions when the application 68 | starts. 69 | 70 | Previously, releases were uploaded to GitHub directly, but due to lack of 71 | transparency in GitHubs metrics and monitoring, we will henceforth link 72 | to the binaries stored on S3 in all of our GitHub releases. This give us a 73 | better insight into things like popularity metrics (total downloads) as well as 74 | more fine-grained control and convenience in distribution. 75 | -------------------------------------------------------------------------------- /Resources/app.env: -------------------------------------------------------------------------------- 1 | appTitle="Knowledge" 2 | settingsFilename="knowledge.settings.json" 3 | DEFAULT_WINDOW_WIDTH=1920 4 | DEFAULT_WINDOW_HEIGHT=1080 5 | STARTUP_WINDOW_WIDTH=1920 6 | STARTUP_WINDOW_HEIGHT=1080 7 | -------------------------------------------------------------------------------- /Resources/entitlements.mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.cs.disable-library-validation 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Resources/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/Resources/icon.icns -------------------------------------------------------------------------------- /Resources/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/Resources/icon.ico -------------------------------------------------------------------------------- /Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/Resources/icon.png -------------------------------------------------------------------------------- /Resources/notarize.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | require("dotenv").config(); 18 | const { notarize } = require("electron-notarize"); 19 | 20 | exports.default = async function notarizing(context) { 21 | const { electronPlatformName, appOutDir } = context; 22 | if (electronPlatformName !== "darwin") { 23 | return; 24 | } 25 | 26 | const appName = context.packager.appInfo.productFilename; 27 | const appleId = process.env.APPLEID; 28 | const password = process.env.APPLEPWD; 29 | const teamId = process.env.TEAMID; 30 | 31 | return await notarize({ 32 | appBundleId: "com.knowledge.canvas.app", 33 | appPath: `${appOutDir}/${appName}.app`, 34 | appleId: appleId, 35 | appleIdPassword: password, 36 | teamId: teamId, 37 | tool: "notarytool", 38 | }); 39 | }; 40 | -------------------------------------------------------------------------------- /src/kc_angular/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /src/kc_angular/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /src/kc_angular/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | 16 | # IDEs and editors 17 | /.idea 18 | .project 19 | .classpath 20 | .c9/ 21 | *.launch 22 | .settings/ 23 | *.sublime-workspace 24 | 25 | # IDE - VSCode 26 | .vscode/* 27 | !.vscode/settings.json 28 | !.vscode/tasks.json 29 | !.vscode/launch.json 30 | !.vscode/extensions.json 31 | .history/* 32 | 33 | # misc 34 | /.sass-cache 35 | /connect.lock 36 | /coverage 37 | /libpeerconnection.log 38 | npm-debug.log 39 | yarn-error.log 40 | testem.log 41 | /typings 42 | 43 | # System Files 44 | .DS_Store 45 | Thumbs.db 46 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/animations.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { 17 | animate, 18 | animateChild, 19 | group, 20 | query, 21 | state, 22 | style, 23 | transition, 24 | trigger, 25 | } from '@angular/animations'; 26 | 27 | export const fadeInAndOut = trigger('routeAnimations', [ 28 | transition('* <=> *', [ 29 | style({ position: 'relative' }), 30 | query(':enter, :leave', [ 31 | style({ 32 | position: 'absolute', 33 | top: 0, 34 | left: 0, 35 | width: '100%', 36 | }), 37 | ]), 38 | query(':enter', [style({ opacity: 0 })]), 39 | query(':leave', animateChild(), { optional: true }), 40 | group([ 41 | query(':leave', [animate('300ms ease-out', style({ opacity: 0 }))], { 42 | optional: true, 43 | }), 44 | query(':enter', [animate('500ms ease-out', style({ opacity: 1 }))]), 45 | query('@*', animateChild(), { optional: true }), 46 | ]), 47 | ]), 48 | ]); 49 | 50 | export const flyInOut = [ 51 | trigger('flyInOut', [ 52 | state( 53 | 'in', 54 | style({ 55 | transform: 'translateX(0)', 56 | }) 57 | ), 58 | transition('void => *', [ 59 | style({ 60 | transform: 'translateX(-100%)', 61 | }), 62 | animate(100), 63 | ]), 64 | transition('* => void', [ 65 | animate( 66 | 100, 67 | style({ 68 | transform: 'translateX(-100%)', 69 | }) 70 | ), 71 | ]), 72 | ]), 73 | ]; 74 | 75 | export const fadeIn = [ 76 | trigger('fadeIn', [ 77 | transition(':enter', [ 78 | style({ opacity: 0 }), 79 | animate('1000ms', style({ opacity: 1 })), 80 | ]), 81 | ]), 82 | ]; 83 | 84 | export const fadeOut = [ 85 | trigger('fadeOut', [ 86 | transition(':leave', [ 87 | style({ opacity: 1 }), 88 | animate('1000ms', style({ opacity: 0 })), 89 | ]), 90 | ]), 91 | ]; 92 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | ::ng-deep { 18 | .p-submenu-list { 19 | z-index: 99 !important; 20 | } 21 | 22 | .p-sidebar-content { 23 | height: 100%; 24 | } 25 | } 26 | 27 | .macos-window-button { 28 | height: 1rem; 29 | width: 1rem; 30 | margin-right: 0.6rem; 31 | border-radius: 50%; 32 | } 33 | 34 | .macos-window-button:hover { 35 | box-shadow: inset 0 0 3px 0 black; 36 | } 37 | 38 | .window-button { 39 | height: 32px; 40 | width: 45px; 41 | } 42 | 43 | .window-button-close { 44 | margin-left: 2px; 45 | background-color: #ff5f57; 46 | } 47 | 48 | .window-button-maximize { 49 | background-color: #2bc840; 50 | } 51 | 52 | .window-button-minimize { 53 | background-color: #ffbc2e; 54 | } 55 | 56 | #app-footer { 57 | height: 4rem; 58 | } 59 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/chat-components/api.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component } from '@angular/core'; 18 | import { DynamicDialogRef } from 'primeng/dynamicdialog'; 19 | import { ChatService } from '@services/chat-services/chat.service'; 20 | 21 | @Component({ 22 | selector: 'app-api', 23 | template: ` 24 |
25 |
26 | OpenAI API Key required to use the Chat feature. The key will be 27 | encrypted and stored locally. 28 |
29 |
30 | 39 |
40 |
41 | 42 |
43 |
44 | `, 45 | styles: [], 46 | }) 47 | export class ChatApiComponent { 48 | constructor(private ref: DynamicDialogRef, private chat: ChatService) {} 49 | 50 | async saveApiKey(apiKey: string) { 51 | this.chat.setApiKey(apiKey).subscribe( 52 | (result: { success: boolean }) => { 53 | this.ref.close(result.success); 54 | }, 55 | () => { 56 | this.ref.close(false); 57 | } 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/chat-components/chat.actions.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 18 | import { AgentType } from '@app/models/chat.model'; 19 | 20 | @Component({ 21 | selector: 'chat-actions', 22 | template: ` 23 |
24 | 34 | 41 | 51 |
52 | `, 53 | styles: [ 54 | ` 55 | .message-actions { 56 | display: flex; 57 | align-items: center; 58 | opacity: 0; 59 | transition: opacity 0.3s ease; 60 | } 61 | 62 | :host:hover .message-actions { 63 | opacity: 1; 64 | } 65 | 66 | .user-action { 67 | color: var(--primary-text-color) !important; 68 | } 69 | 70 | .agent-action { 71 | color: var(--primary-color) !important; 72 | } 73 | `, 74 | ], 75 | }) 76 | export class ChatActionsComponent { 77 | /** 78 | * The type of the message sender (determines the color of the action buttons) 79 | */ 80 | @Input() type!: AgentType; 81 | 82 | /** 83 | * Event emitted when the user clicks the delete button 84 | */ 85 | @Output() onDeleteMessage: EventEmitter = new EventEmitter(); 86 | 87 | /** 88 | * Event emitted when the user clicks the regenerate button 89 | */ 90 | @Output() onRegenerateMessage: EventEmitter = new EventEmitter(); 91 | 92 | /** 93 | * Event emitted when the user clicks the generate next question button 94 | */ 95 | @Output() onGenerateNextQuestion: EventEmitter = 96 | new EventEmitter(); 97 | } 98 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/chat-components/chat.view.component.html: -------------------------------------------------------------------------------- 1 | 16 | 17 |
22 | 26 | 27 |
31 |
35 | 36 | 37 |
43 | 56 | 57 |
58 |
59 |
60 |
61 | 62 | 67 |
68 | 69 | 77 | 78 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/chat-components/chat.view.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | .user-message { 18 | background-color: var(--primary-color) !important; 19 | color: var(--primary-color-text) !important; 20 | border-radius: 10px; 21 | padding: 0 10px 0 10px; 22 | margin: 10px; 23 | text-align: right; 24 | max-width: 80%; 25 | } 26 | 27 | .agent-message { 28 | color: var(--primary-color) !important; 29 | background-color: var(--primary-color-text) !important; 30 | border-radius: 10px; 31 | padding: 0 10px 0 10px; 32 | margin: 10px; 33 | text-align: left; 34 | max-width: 80%; 35 | } 36 | 37 | #chat-toolbar { 38 | height: 2rem; 39 | background-color: var(--surface-ground); 40 | } 41 | 42 | .next-question-suggestion:hover { 43 | opacity: 1 !important; 44 | } 45 | 46 | .html2canvas-container { 47 | width: 3000px !important; 48 | height: 3000px !important; 49 | } 50 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/graph-components/graph.status.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; 18 | 19 | @Component({ 20 | selector: 'graph-status', 21 | template: ` 22 |
23 |
26 |
27 | Running... ({{ runtime | number : '1.1' }}s elapsed) 28 |
29 | Done 30 |
31 |
32 | `, 33 | styles: [ 34 | ` 35 | .graph-status { 36 | height: 1rem; 37 | position: absolute; 38 | bottom: 5rem; 39 | padding-left: 0.5rem; 40 | } 41 | `, 42 | ], 43 | }) 44 | export class GraphStatusComponent implements OnChanges { 45 | @Input() running = false; 46 | 47 | runtime = 0; 48 | 49 | runtimeInterval?: NodeJS.Timer; 50 | 51 | ngOnChanges(changes: SimpleChanges) { 52 | if (changes?.running?.currentValue !== undefined) { 53 | if (changes?.running?.currentValue) { 54 | this.runtime = 0; 55 | this.runtimeInterval = setInterval(() => { 56 | this.runtime += 0.5; 57 | }, 500); 58 | } else { 59 | if (this.runtimeInterval) { 60 | clearInterval(this.runtimeInterval); 61 | } 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/grid.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component } from '@angular/core'; 17 | import { ActivatedRoute } from '@angular/router'; 18 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 19 | import { DataService } from '@services/user-services/data.service'; 20 | import { ProjectService } from '@services/factory-services/project.service'; 21 | import { NotificationsService } from '@services/user-services/notifications.service'; 22 | import { KsCommandService } from '@services/command-services/ks-command.service'; 23 | import { TopicService } from '@services/user-services/topic.service'; 24 | import { Observable } from 'rxjs'; 25 | 26 | @Component({ 27 | selector: 'app-grid', 28 | template: ` 29 |
30 |
33 | 39 | 40 |
41 |
42 | `, 43 | styles: [], 44 | }) 45 | export class GridComponent { 46 | sources: Observable; 47 | 48 | constructor( 49 | private data: DataService, 50 | private activated: ActivatedRoute, 51 | private command: KsCommandService, 52 | private notifications: NotificationsService, 53 | private projects: ProjectService, 54 | private topics: TopicService 55 | ) { 56 | this.sources = data.ksList; 57 | } 58 | 59 | onKsRemove($event: KnowledgeSource) { 60 | this.command.remove([$event]); 61 | } 62 | 63 | onTopicSearch($event: string) { 64 | this.topics.search($event); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/settings/setting-template.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component, Input } from '@angular/core'; 17 | 18 | @Component({ 19 | selector: 'app-setting-template', 20 | template: ` 21 |
24 |
25 |
26 |
27 | {{ label }} 28 |
29 |
30 |
37 |
38 |
39 |
40 | {{ labelSubtext }} 41 |
42 |
43 | 44 |
45 | 46 |
47 | 48 | 49 |
50 |
51 |
52 | `, 53 | styles: [ 54 | ` 55 | :host { 56 | margin-top: 1rem; 57 | } 58 | `, 59 | ], 60 | }) 61 | export class SettingTemplateComponent { 62 | @Input() label = ''; 63 | 64 | @Input() labelSubtext = ''; 65 | 66 | @Input() labelHelp = ''; 67 | 68 | @Input() labelHelpLink = ''; 69 | 70 | @Input() actionSubtext = ''; 71 | 72 | @Input() actionDisabled = false; 73 | 74 | helpClick() { 75 | if (this.labelHelpLink) { 76 | window.open(this.labelHelpLink); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/settings/settings.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component } from '@angular/core'; 17 | import { MenuItem } from 'primeng/api'; 18 | 19 | @Component({ 20 | selector: 'app-settings', 21 | template: ` 22 |
25 |
26 |
27 | 32 |
33 |
34 | 35 |
36 |
37 |
38 | `, 39 | styles: [ 40 | ` 41 | ::ng-deep { 42 | .p-menuitem-link-active { 43 | background-color: var(--primary-color) !important; 44 | 45 | .p-menuitem-icon, 46 | .p-menuitem-text { 47 | color: var(--primary-color-text) !important; 48 | } 49 | } 50 | } 51 | `, 52 | ], 53 | }) 54 | export class SettingsComponent { 55 | modules: MenuItem[] = [ 56 | { 57 | label: 'Display', 58 | icon: 'pi pi-fw pi-image', 59 | routerLinkActiveOptions: {}, 60 | routerLink: ['app', { outlets: { settings: ['display'] } }], 61 | }, 62 | { 63 | label: 'Search', 64 | icon: 'pi pi-fw pi-search', 65 | routerLink: ['app', { outlets: { settings: ['search'] } }], 66 | }, 67 | { 68 | label: 'Import', 69 | icon: 'pi pi-fw pi-arrow-circle-down', 70 | routerLink: ['app', { outlets: { settings: ['import'] } }], 71 | }, 72 | { 73 | label: 'Graph', 74 | icon: 'pi pi-fw pi-sitemap', 75 | routerLink: ['app', { outlets: { settings: ['graph'] } }], 76 | }, 77 | { 78 | label: 'Chat', 79 | icon: 'pi pi-fw pi-comments', 80 | routerLink: ['app', { outlets: { settings: ['chat'] } }], 81 | }, 82 | // { TODO: reinstate once storage settings component is implemented 83 | // label: 'Storage', 84 | // icon: 'pi pi-fw pi-database', 85 | // routerLink: ['app', {outlets: {settings: ['storage']}}] 86 | // } 87 | ]; 88 | } 89 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/shared/loading.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component } from '@angular/core'; 18 | import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; 19 | 20 | @Component({ 21 | selector: 'app-loading', 22 | template: ` 23 |
26 |
{{ message }}
27 |
{{ subMessage }}
28 | 34 |
35 | `, 36 | styles: [], 37 | }) 38 | export class LoadingComponent { 39 | message = 'Loading...'; 40 | subMessage = ''; 41 | progressBar = false; 42 | 43 | constructor( 44 | private ref: DynamicDialogRef, 45 | private config: DynamicDialogConfig 46 | ) { 47 | if (this.config.data) { 48 | this.message = this.config.data.message || this.message; 49 | this.subMessage = this.config.data.subMessage || this.subMessage; 50 | this.progressBar = this.config.data.progressBar || this.progressBar; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/shared/pro-tips.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | Component, 19 | EventEmitter, 20 | HostListener, 21 | OnDestroy, 22 | Output, 23 | } from '@angular/core'; 24 | import { SettingsService } from '@services/ipc-services/settings.service'; 25 | 26 | @Component({ 27 | selector: 'app-pro-tips', 28 | template: ` 29 |
30 |
31 |

{{ header }}

32 |
33 |

{{ body }}

34 |
35 | 53 |
54 | `, 55 | styles: [ 56 | ` 57 | .pro-tip { 58 | max-width: 30rem !important; 59 | } 60 | `, 61 | ], 62 | }) 63 | export class ProTipsComponent implements OnDestroy { 64 | header = 'Pro Tips'; 65 | 66 | body = ''; 67 | 68 | icon = 'pi pi-info-circle'; 69 | 70 | @Output() previous = new EventEmitter(); 71 | 72 | @Output() next = new EventEmitter(); 73 | 74 | @Output() close = new EventEmitter(); 75 | 76 | constructor(private settings: SettingsService) {} 77 | 78 | ngOnDestroy() { 79 | this.close.emit(); 80 | } 81 | 82 | /* Listen for left and right arrow keys, emit previous and next events */ 83 | @HostListener('window:keydown', ['$event']) 84 | handleKeyDown(event: KeyboardEvent) { 85 | if (event.key === 'ArrowRight') { 86 | this.next.emit(); 87 | } else if (event.key === 'ArrowLeft') { 88 | this.previous.emit(); 89 | } 90 | } 91 | 92 | showAgainChanged($event: { checked: boolean }) { 93 | console.log('Show again changed: ', $event.checked); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/shared/timeline.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component, Input } from '@angular/core'; 17 | import { EventModel } from '@shared/models/event.model'; 18 | import { KnowledgeSourceEvent } from '@app/models/knowledge.source.model'; 19 | 20 | @Component({ 21 | selector: 'app-timeline', 22 | template: ` 23 |
24 | 25 | 31 | 32 |
36 | 37 | {{ event.status }} 38 | 39 |
40 |
41 | 42 | 43 |
44 |
48 |
49 |
50 | 51 |
52 | 53 | 54 | {{ event.date ?? event.timestamp | date : 'short' }} 55 | 56 |
57 |
58 |
59 |
60 |
61 | `, 62 | }) 63 | export class TimelineComponent { 64 | @Input() events?: EventModel[] | KnowledgeSourceEvent[] = []; 65 | } 66 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/ks-dropzone.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component, Input } from '@angular/core'; 17 | import { 18 | animate, 19 | state, 20 | style, 21 | transition, 22 | trigger, 23 | } from '@angular/animations'; 24 | 25 | @Component({ 26 | selector: 'app-dropzone', 27 | template: ` 28 |
37 |
38 | {{ emptyMessage }} 39 |
40 |
41 |
{{ hintMessage }}
42 |
43 |
44 | `, 45 | styles: [ 46 | ` 47 | .dropzone { 48 | width: 100%; 49 | color: var(--text-color); 50 | background-image: linear-gradient( 51 | 225deg, 52 | var(--surface-b) 25%, 53 | var(--surface-c) 25%, 54 | var(--surface-c) 50%, 55 | var(--surface-b) 50%, 56 | var(--surface-b) 75%, 57 | var(--surface-c) 75%, 58 | var(--surface-c) 100% 59 | ); 60 | background-size: 64px 64px; 61 | display: flex; 62 | flex-direction: column; 63 | flex-wrap: nowrap; 64 | align-items: center; 65 | justify-content: center; 66 | align-content: center; 67 | } 68 | `, 69 | ], 70 | animations: [ 71 | trigger('dropzone-shorten', [ 72 | state('dropzone-lg', style({ height: '20vh', top: 0, left: 0 })), 73 | state('dropzone-sm', style({ height: '4rem', top: 0, left: 0 })), 74 | transition('dropzone-lg => dropzone-sm', [animate('0.1s')]), 75 | transition('dropzone-sm => dropzone-lg', [animate('0.1s')]), 76 | ]), 77 | ], 78 | }) 79 | export class KsDropzoneComponent { 80 | @Input() shouldShorten = false; 81 | 82 | @Input() supportedTypes: string[] = []; 83 | 84 | @Input() emptyMessage = 'Drag and drop here!'; 85 | 86 | @Input() hintMessage = 87 | 'Hint: You can drag files and links directly into this window.'; 88 | } 89 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/ks-viewport/file-view.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { 17 | Component, 18 | EventEmitter, 19 | Input, 20 | OnChanges, 21 | OnInit, 22 | Output, 23 | SimpleChanges, 24 | } from '@angular/core'; 25 | import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; 26 | import { 27 | BrowserViewHeaderConfig, 28 | BrowserViewHeaderEvent, 29 | FileViewClickEvent, 30 | FileViewConfig, 31 | } from '@shared/models/browser.view.model'; 32 | 33 | @Component({ 34 | selector: 'ks-lib-file-view', 35 | template: ` 36 | 41 | 42 | 43 | `, 44 | styles: [ 45 | ` 46 | .file-view { 47 | height: calc(100vh - 68px); 48 | width: 100%; 49 | } 50 | `, 51 | ], 52 | }) 53 | export class FileViewComponent implements OnInit, OnChanges { 54 | @Input() config!: FileViewConfig; 55 | @Input() showHeader = false; 56 | @Output() viewReady = new EventEmitter(); 57 | @Output() clickEvent = new EventEmitter(); 58 | @Output() fileError = new EventEmitter(); 59 | safeUrl: SafeUrl | undefined; 60 | headerConfig: BrowserViewHeaderConfig | undefined; 61 | ready = false; 62 | 63 | constructor(private sanitizer: DomSanitizer) {} 64 | 65 | ngOnInit(): void { 66 | this.headerConfig = { 67 | canCopy: true, 68 | canClose: this.config.isDialog, 69 | displayText: this.config.filePath, 70 | displayTextReadOnly: true, 71 | showActionButtons: true, 72 | showDisplayText: true, 73 | showCloseButton: true, 74 | showOpenButton: true, 75 | }; 76 | } 77 | 78 | ngOnChanges(changes: SimpleChanges) { 79 | const config: FileViewConfig = changes.config.currentValue; 80 | if (config) { 81 | if (config.filePath) { 82 | if (this.validateFileURI(config.filePath)) { 83 | this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl( 84 | 'file://' + encodeURI(config.filePath) 85 | ); 86 | this.ready = true; 87 | this.viewReady.emit(true); 88 | } else { 89 | this.fileError.emit( 90 | 'The file path contains invalid characters and cannot be previewed.' 91 | ); 92 | } 93 | } 94 | } 95 | } 96 | 97 | headerEvents(headerEvent: BrowserViewHeaderEvent) { 98 | this.clickEvent.emit(headerEvent); 99 | } 100 | 101 | validateFileURI(uri: string) { 102 | return !uri.includes('#'); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/source.document.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; 18 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 19 | import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; 20 | 21 | @Component({ 22 | selector: 'source-document', 23 | template: ` 24 |
25 |
26 | 33 |
34 |
35 | `, 36 | styles: [ 37 | ` 38 | :host { 39 | display: flex !important; 40 | flex-direction: column !important; 41 | height: 100% !important; 42 | width: 100% !important; 43 | overflow: auto !important; 44 | padding: 1.5rem !important; 45 | } 46 | 47 | .source-pdf-viewer { 48 | height: 100% !important; 49 | } 50 | `, 51 | ], 52 | }) 53 | export class SourceDocumentComponent implements OnInit { 54 | source!: KnowledgeSource; 55 | 56 | safeUrl: SafeUrl | undefined; 57 | 58 | style = { 59 | width: '100%', 60 | height: '100%', 61 | 'max-width': '100%', 62 | 'max-height': '100%', 63 | }; 64 | 65 | styles = { 66 | unset: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'tif'], 67 | full: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'], 68 | }; 69 | 70 | @ViewChild('document', { static: true }) document!: ElementRef; 71 | 72 | @ViewChild('documentContainer', { static: true }) 73 | documentContainer!: ElementRef; 74 | 75 | constructor(private sanitizer: DomSanitizer) {} 76 | 77 | ngOnInit(): void { 78 | setTimeout(() => { 79 | if (typeof this.source.accessLink === 'string') { 80 | this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl( 81 | 'file://' + encodeURI(this.source.accessLink) 82 | ); 83 | 84 | for (const type of this.styles.unset) { 85 | if (this.source.accessLink?.endsWith(type)) { 86 | this.style = { 87 | 'max-height': '100%', 88 | 'max-width': '100%', 89 | width: 'unset', 90 | height: 'unset', 91 | }; 92 | break; 93 | } 94 | } 95 | } 96 | }, 500); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/source.notes.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component } from '@angular/core'; 18 | 19 | @Component({ 20 | selector: 'source-notes', 21 | template: ``, 22 | styles: [``], 23 | }) 24 | export class SourceNotesComponent { 25 | constructor() {} 26 | } 27 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/source.styles.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/source.video.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component, OnInit, ViewChild } from '@angular/core'; 18 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 19 | import { SettingsService } from '@services/ipc-services/settings.service'; 20 | import { YouTubePlayer } from '@angular/youtube-player'; 21 | 22 | @Component({ 23 | selector: 'source-video', 24 | template: ` 25 |
26 |
27 | 28 | 29 |
30 |
31 | `, 32 | styleUrls: ['./source.styles.scss'], 33 | }) 34 | export class SourceVideoComponent implements OnInit { 35 | @ViewChild('youtubePlayer') youtubePlayer!: YouTubePlayer; 36 | 37 | source!: KnowledgeSource; 38 | 39 | ksYoutubeVideoId = 'y5icPgca8JI'; 40 | 41 | loaded = false; 42 | 43 | constructor(private settings: SettingsService) {} 44 | 45 | ngOnInit(): void { 46 | this.source.accessLink = new URL(this.source.accessLink); 47 | const urlParam = this.source.accessLink.searchParams.get('v'); 48 | if (this.source.accessLink.hostname === 'www.youtube.com' && urlParam) { 49 | this.loadYoutubeApi(urlParam); 50 | if (this.settings.get().display.autoplay) { 51 | setTimeout(() => { 52 | this.youtubePlayer.playVideo(); 53 | }, 1000); 54 | } 55 | } 56 | } 57 | 58 | loadYoutubeApi(urlParam: string) { 59 | this.ksYoutubeVideoId = urlParam; 60 | if (!this.loaded) { 61 | // This code loads the IFrame Player API code asynchronously, according to the instructions at 62 | // https://developers.google.com/youtube/iframe_api_reference#Getting_Started 63 | const tag = document.createElement('script'); 64 | tag.src = 'https://www.youtube.com/iframe_api'; 65 | document.body.appendChild(tag); 66 | this.loaded = true; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/table.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component, OnDestroy } from '@angular/core'; 17 | import { ActivatedRoute } from '@angular/router'; 18 | import { KnowledgeSource } from '../models/knowledge.source.model'; 19 | import { Observable, Subject, tap } from 'rxjs'; 20 | import { DataService } from '@services/user-services/data.service'; 21 | import { takeUntil } from 'rxjs/operators'; 22 | 23 | @Component({ 24 | selector: 'app-table', 25 | template: ` 26 |
27 |
30 | 34 |
35 |
36 | `, 37 | styles: [], 38 | }) 39 | export class TableComponent implements OnDestroy { 40 | sources: Observable; 41 | 42 | projectId = ''; 43 | 44 | private cleanUp: Subject = new Subject(); 45 | 46 | constructor(private data: DataService, private route: ActivatedRoute) { 47 | route.paramMap 48 | .pipe( 49 | takeUntil(this.cleanUp), 50 | tap((params) => { 51 | this.projectId = params.get('projectId') ?? ''; 52 | }) 53 | ) 54 | .subscribe(); 55 | 56 | this.sources = data.ksList; 57 | } 58 | 59 | ngOnDestroy() { 60 | this.cleanUp.next({}); 61 | this.cleanUp.complete(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/directives/recreate-view.directive.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | Directive, 19 | EmbeddedViewRef, 20 | Input, 21 | OnChanges, 22 | SimpleChanges, 23 | TemplateRef, 24 | ViewContainerRef, 25 | } from '@angular/core'; 26 | 27 | @Directive({ 28 | selector: '[appRecreateView]', 29 | }) 30 | export class RecreateViewDirective implements OnChanges { 31 | @Input('appRecreateView') key: any; 32 | 33 | viewRef: EmbeddedViewRef | null = null; 34 | 35 | constructor( 36 | private templateRef: TemplateRef, 37 | private viewContainer: ViewContainerRef 38 | ) {} 39 | 40 | ngOnChanges(changes: SimpleChanges) { 41 | if (changes.key) { 42 | if (this.viewRef) { 43 | this.destroyView(); 44 | } 45 | 46 | this.createView(); 47 | } 48 | } 49 | 50 | private destroyView() { 51 | this.viewRef?.destroy(); 52 | this.viewRef = null; 53 | } 54 | 55 | private createView() { 56 | this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/models/chat.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KcProject } from './project.model'; 18 | import { KnowledgeSource } from './knowledge.source.model'; 19 | 20 | export enum AgentType { 21 | Assistant = 'assistant', 22 | Knowledge = 'knowledge', 23 | Project = 'project', 24 | Source = 'source', 25 | System = 'system', 26 | User = 'user', 27 | } 28 | 29 | export type MessageRating = 'thumbs-up' | 'thumbs-down' | 'none'; 30 | 31 | export interface ChatMessage { 32 | id: string; 33 | sender: AgentType; 34 | recipient: AgentType; 35 | text: string; 36 | timestamp: Date; 37 | project?: KcProject; 38 | source?: KnowledgeSource; 39 | suggestion?: boolean; 40 | regenerated?: boolean; 41 | rating?: MessageRating; 42 | } 43 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/models/project.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { EventModel, ProjectCalendar } from '@shared/models/event.model'; 17 | import { KcProjectModel, KcProjectType } from '@shared/models/project.model'; 18 | import { KnowledgeSource } from './knowledge.source.model'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | import { PrimeIcons } from 'primeng/api'; 21 | 22 | export class KcProject implements KcProjectModel { 23 | readonly id: UUID; 24 | name = ''; 25 | authors: string[] = []; 26 | description = ''; 27 | parentId: UUID = { value: '' }; 28 | subprojects: string[] = []; 29 | topics: string[] = []; 30 | type: KcProjectType; 31 | expanded = false; 32 | icon?: string; 33 | 34 | // TODO: this needs to be changed to an array of UUID instead of KS. The KS should be looked up 35 | sources: UUID[]; 36 | knowledgeSource: KnowledgeSource[] = []; 37 | 38 | // TODO: Should we remove calendar, or events? 39 | calendar: ProjectCalendar; 40 | events?: EventModel[] = []; 41 | 42 | // TODO: these should be completely removed and replaced by calendar/events 43 | readonly dateCreated: Date; 44 | dateModified: Date; 45 | dateAccessed: Date; 46 | 47 | constructor(name: string, id: UUID, type?: KcProjectType, parentId?: UUID) { 48 | this.name = name; 49 | this.id = id; 50 | this.type = type ? type : 'default'; 51 | this.parentId = parentId ?? { value: '' }; 52 | this.dateCreated = new Date(); 53 | this.dateModified = new Date(); 54 | this.dateAccessed = new Date(); 55 | this.calendar = { events: [], start: null, end: null }; 56 | this.sources = []; 57 | this.icon = PrimeIcons.FOLDER; 58 | } 59 | } 60 | 61 | export interface ProjectCreationRequest { 62 | name: string; 63 | parentId: UUID; 64 | description: string; 65 | 66 | // TODO: this needs to be replaced with UUID[] 67 | knowledgeSource: KnowledgeSource[]; 68 | sources: UUID[]; 69 | authors: string[]; 70 | topics: string[]; 71 | type: KcProjectType; 72 | subProjects: ProjectCreationRequest[]; 73 | calendar: ProjectCalendar; 74 | icon?: string; 75 | } 76 | 77 | export type ProjectMoveRequest = { ks: KnowledgeSource; new: UUID }; 78 | 79 | export interface ProjectUpdateRequest { 80 | id: UUID; 81 | name?: string; 82 | description?: string; 83 | notes?: string; 84 | expanded?: boolean; 85 | parentId?: string; 86 | addSubprojects?: string[]; 87 | removeSubprojects?: string[]; 88 | authors?: string[]; 89 | addTopic?: string[]; 90 | removeTopic?: string[]; 91 | updateTopic?: string[]; 92 | overWriteTopics?: string[]; 93 | addKnowledgeSource?: KnowledgeSource[]; 94 | removeKnowledgeSource?: KnowledgeSource[]; 95 | updateKnowledgeSource?: KnowledgeSource[]; 96 | moveKnowledgeSource?: ProjectMoveRequest; 97 | } 98 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/models/project.tree.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ProjectGraphNode } from '@shared/models/graph.model'; 18 | 19 | export class ProjectTreeNode implements ProjectGraphNode { 20 | name: string; 21 | id: string; 22 | type: string; 23 | expanded = false; 24 | subprojects: ProjectTreeNode[]; 25 | icon?: string; 26 | parentId?: string; 27 | 28 | constructor( 29 | name: string, 30 | id: string, 31 | type: string, 32 | subprojects: ProjectTreeNode[], 33 | expanded: boolean, 34 | icon?: string 35 | ) { 36 | this.name = name ? name : ''; 37 | this.id = id ? id : ''; 38 | this.type = type ? type : ''; 39 | this.subprojects = subprojects ? subprojects : []; 40 | this.expanded = expanded; 41 | this.icon = icon; 42 | } 43 | } 44 | 45 | export class ProjectTree { 46 | root: ProjectTreeNode; 47 | 48 | constructor() { 49 | this.root = new ProjectTreeNode('root', '0', 'root', [], true); 50 | } 51 | 52 | asArray(): ProjectTreeNode[] { 53 | const arr: ProjectTreeNode[] = []; 54 | this.root.subprojects.forEach((value) => { 55 | arr.push(value); 56 | }); 57 | return arr; 58 | } 59 | 60 | add(node: ProjectTreeNode, parentId?: string): void { 61 | if (parentId) { 62 | this.addChild(node, parentId, this.root); 63 | } else { 64 | this.root.subprojects.push(node); 65 | } 66 | } 67 | 68 | find(id: string, node?: ProjectTreeNode): ProjectTreeNode | null { 69 | if (!node) { 70 | node = this.root; 71 | } 72 | 73 | if (node.id === id) { 74 | return node; 75 | } else { 76 | for (const sub of node.subprojects) { 77 | const found = this.find(id, sub); 78 | if (found) { 79 | return found; 80 | } 81 | } 82 | return null; 83 | } 84 | } 85 | 86 | private addChild( 87 | node: ProjectTreeNode, 88 | parentId: string, 89 | current: ProjectTreeNode 90 | ): void { 91 | if (current.id === parentId) { 92 | current.subprojects.push(node); 93 | } else { 94 | for (const sub of current.subprojects) { 95 | this.addChild(node, parentId, sub); 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/countdown.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | 19 | @Pipe({ 20 | name: 'countdown', 21 | }) 22 | export class CountdownPipe implements PipeTransform { 23 | transform(value: Date): unknown { 24 | const then = new Date(value); 25 | const now = new Date(); 26 | const diffTime = this.dateDiffInDays(then, now); 27 | let countdown; 28 | if (diffTime > 365 || diffTime <= -365) { 29 | countdown = `1yr+`; 30 | } else if (diffTime >= 90 || diffTime <= -90) { 31 | countdown = '90d+'; 32 | } else { 33 | countdown = `${Math.abs(diffTime)}d`; 34 | } 35 | return countdown; 36 | } 37 | 38 | // a and b are javascript Date objects 39 | dateDiffInDays(a: any, b: any) { 40 | const _MS_PER_DAY = 1000 * 60 * 60 * 24; 41 | // Discard the time and time-zone information. 42 | const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate()); 43 | const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate()); 44 | return Math.floor((utc2 - utc1) / _MS_PER_DAY); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/import-method.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | import { ImportMethod } from '@shared/models/knowledge.source.model'; 19 | 20 | @Pipe({ 21 | name: 'importMethod', 22 | }) 23 | export class ImportMethodPipe implements PipeTransform { 24 | transform(value?: ImportMethod): unknown { 25 | if (!value) { 26 | return ''; 27 | } 28 | switch (value) { 29 | case 'autoscan': 30 | return 'Autoscan'; 31 | case 'dnd': 32 | return 'Drag/Drop'; 33 | case 'extension': 34 | return 'Browser Extension'; 35 | case 'manual': 36 | return 'Manual'; 37 | case 'example': 38 | return 'Example'; 39 | case 'recommend': 40 | return 'Recommended'; 41 | default: 42 | return ''; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/ks-ingest-type-icon.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Pipe, PipeTransform } from '@angular/core'; 17 | 18 | @Pipe({ 19 | name: 'ksIngestTypeIcon', 20 | }) 21 | export class KsIngestTypeIconPipe implements PipeTransform { 22 | transform(type?: string): string { 23 | if (!type) { 24 | return ''; 25 | } 26 | switch (type) { 27 | case 'topic': 28 | return 'sitemap'; 29 | case 'website': 30 | return 'link'; 31 | case 'search': 32 | return 'search'; 33 | case 'file': 34 | return 'file'; 35 | case 'google': 36 | return 'google'; 37 | default: 38 | return ''; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/markdown.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { MarkdownService } from '@services/factory-services/markdown.service'; 18 | import { Pipe, PipeTransform } from '@angular/core'; 19 | 20 | @Pipe({ 21 | name: 'markdown', 22 | }) 23 | export class MarkdownPipe implements PipeTransform { 24 | constructor(private markdownService: MarkdownService) {} 25 | 26 | transform(markdown: string, topics?: string[]): string { 27 | return this.markdownService.parseMarkdown(markdown, topics) ?? markdown; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/project-as-tree-node.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Pipe, PipeTransform } from '@angular/core'; 17 | import { ProjectTreeFactoryService } from '@services/factory-services/project-tree-factory.service'; 18 | import { TreeNode } from 'primeng/api'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | 21 | @Pipe({ 22 | name: 'projectAsTreeNode', 23 | }) 24 | export class ProjectAsTreeNodePipe implements PipeTransform { 25 | constructor(private tree: ProjectTreeFactoryService) {} 26 | 27 | transform(id: UUID, treeNodes: TreeNode[]): TreeNode { 28 | return this.tree.findTreeNode(id.value, treeNodes) ?? {}; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/project-breadcrumb.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | import { ProjectService } from '@services/factory-services/project.service'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | 21 | @Pipe({ 22 | name: 'projectBreadcrumb', 23 | }) 24 | export class ProjectBreadcrumbPipe implements PipeTransform { 25 | constructor(private projectService: ProjectService) {} 26 | 27 | transform(id: UUID | string, ...args: unknown[]): string { 28 | if (typeof id === 'string') { 29 | id = { value: id }; 30 | } 31 | 32 | const ancestors = this.projectService.getAncestors(id.value); 33 | if (!ancestors) { 34 | return ''; 35 | } 36 | 37 | let start, end, prefix; 38 | 39 | const SEP = '>'; 40 | const ELLIPSIS = '...'; 41 | 42 | if (args && args.length > 0 && args[0] && args[0] == 'no-truncate') { 43 | start = 0; 44 | end = ancestors.length; 45 | prefix = ''; 46 | } else { 47 | start = Math.max(0, ancestors.length - 3); 48 | end = ancestors.length; 49 | 50 | if (args && args.length > 0 && args[0] && args[0] == 'no-ellipse') { 51 | prefix = ''; 52 | } else { 53 | prefix = 54 | start > 0 55 | ? `${ancestors[0].title} ${SEP} ${start > 1 ? ELLIPSIS : ''} ${ 56 | start > 1 ? SEP : '' 57 | } ` 58 | : ''; 59 | } 60 | } 61 | 62 | return ( 63 | prefix + 64 | ancestors 65 | .slice(start, end) 66 | .map((a) => a.title) 67 | .join(` ${SEP} `) 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/project-name.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | import { ProjectService } from '@services/factory-services/project.service'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | 21 | @Pipe({ 22 | name: 'projectName', 23 | }) 24 | export class ProjectNamePipe implements PipeTransform { 25 | constructor(private projectService: ProjectService) {} 26 | 27 | transform(id: UUID | string | null): string { 28 | if (!id) { 29 | return 'None'; 30 | } else { 31 | const pid: UUID = typeof id === 'string' ? { value: id } : id; 32 | return ( 33 | this.projectService.ProjectIdentifiers.find((p) => p.id === pid.value) 34 | ?.title ?? 'None' 35 | ); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/sanitize-html.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; 19 | 20 | @Pipe({ 21 | name: 'sanitizeHtml', 22 | }) 23 | export class SanitizeHtmlPipe implements PipeTransform { 24 | constructor(private _sanitizer: DomSanitizer) {} 25 | 26 | transform(v: string): SafeHtml { 27 | return this._sanitizer.bypassSecurityTrustHtml(v); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/switch-label.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | 19 | @Pipe({ 20 | name: 'switchLabel', 21 | }) 22 | export class SwitchLabelPipe implements PipeTransform { 23 | transform(value: boolean): string { 24 | return value ? 'Enabled' : 'Disabled'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/truncate.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | 19 | @Pipe({ 20 | name: 'truncate', 21 | }) 22 | export class TruncatePipe implements PipeTransform { 23 | transform(value: string | undefined, args: any[]): string { 24 | if (!value) return ''; 25 | const ELLIPSIS = '...'; 26 | const limit = args.length > 0 ? parseInt(args[0], 10) : 20; 27 | const trail = args.length > 1 ? args[1] : ELLIPSIS; 28 | return value.length > limit ? value.substring(0, limit) + trail : value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/view-icon.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Pipe, PipeTransform } from '@angular/core'; 17 | 18 | @Pipe({ 19 | name: 'viewIcon', 20 | }) 21 | export class ViewIconPipe implements PipeTransform { 22 | transform(viewLabel: string): string { 23 | switch (viewLabel) { 24 | case 'inbox': 25 | return 'pi pi-inbox'; 26 | case 'projects': 27 | return 'pi pi-list'; 28 | case 'chat': 29 | return 'pi pi-comments'; 30 | case 'table': 31 | return 'pi pi-table'; 32 | case 'grid': 33 | return 'pi pi-th-large'; 34 | case 'graph': 35 | return 'pi pi-sitemap'; 36 | case 'calendar': 37 | return 'pi pi-calendar'; 38 | default: 39 | return ''; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/chat-services/guard.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Injectable } from '@angular/core'; 18 | import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router'; 19 | import { ChatService } from '@services/chat-services/chat.service'; 20 | import { DialogService } from 'primeng/dynamicdialog'; 21 | import { NotificationsService } from '@services/user-services/notifications.service'; 22 | import { take, tap } from 'rxjs/operators'; 23 | 24 | @Injectable({ 25 | providedIn: 'root', 26 | }) 27 | export class ChatGuard implements CanActivate { 28 | constructor( 29 | private chat: ChatService, 30 | private dialog: DialogService, 31 | private notify: NotificationsService, 32 | private router: Router 33 | ) {} 34 | 35 | canActivate(route: ActivatedRouteSnapshot) { 36 | const canChat = this.chat.canChat(); 37 | 38 | if (canChat) { 39 | return true; 40 | } else { 41 | this.chat 42 | .getApiKeyDialog() 43 | .pipe( 44 | take(1), 45 | tap((result: boolean) => { 46 | if (result) { 47 | this.router.navigate([ 48 | 'app', 49 | route.url[0].path, 50 | route.url[1].path, 51 | ]); 52 | } 53 | }) 54 | ) 55 | .subscribe(); 56 | 57 | return false; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/ipc-services/browser-view-dialog.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { DialogService, DynamicDialogRef } from 'primeng/dynamicdialog'; 18 | import { Injectable } from '@angular/core'; 19 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 20 | import { 21 | KsPreviewComponent, 22 | KsPreviewInput, 23 | } from '@components/source-components/ks-preview.component'; 24 | 25 | export interface BrowserViewDialogConfig { 26 | ks: KnowledgeSource; 27 | } 28 | 29 | @Injectable({ 30 | providedIn: 'root', 31 | }) 32 | export class BrowserViewDialogService { 33 | constructor(public dialog: DialogService) {} 34 | 35 | open(options: BrowserViewDialogConfig): DynamicDialogRef | undefined { 36 | if (!this.validateURI(options.ks)) { 37 | return undefined; 38 | } 39 | 40 | const ksPreviewInput: KsPreviewInput = { 41 | ks: options.ks, 42 | }; 43 | 44 | return this.dialog.open(KsPreviewComponent, { 45 | width: '100vw', 46 | height: '100vh', 47 | contentStyle: { 'padding-left': 0, 'padding-right': 0 }, 48 | showHeader: false, 49 | data: ksPreviewInput, 50 | }); 51 | } 52 | 53 | validateURI(ks: KnowledgeSource) { 54 | if (ks.ingestType === 'file' && typeof ks.accessLink === 'string') { 55 | if (ks.accessLink.includes('#')) { 56 | return false; 57 | } 58 | } 59 | 60 | return true; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/ipc-services/startup.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Injectable } from '@angular/core'; 17 | import { ElectronIpcService } from './electron-ipc.service'; 18 | import { DialogService } from 'primeng/dynamicdialog'; 19 | 20 | @Injectable({ 21 | providedIn: 'root', 22 | }) 23 | export class StartupService { 24 | constructor(private dialog: DialogService, private ipc: ElectronIpcService) { 25 | this.ipc.version.subscribe((version) => { 26 | if (!version || version === '') { 27 | return; 28 | } 29 | 30 | let major, minor, patch; 31 | [major, minor, patch] = version.split('.'); 32 | 33 | // this.storage.getProjects().then((projects) => { 34 | // for (let project of projects) { 35 | // console.log('Analyzing project: ', project.name); 36 | // for (let ks of project.knowledgeSource) { 37 | // console.log('\t\tAnalyzing KS: ', ks.title); 38 | // 39 | // // First, check if KS exists in local storage. If it does, then we are done here. 40 | // const lookup = `ks-${ks.id.value}`; 41 | // const kstr = localStorage.getItem(lookup); 42 | // 43 | // // If it does not exist in local storage, save it 44 | // if (!kstr) { 45 | // const kson = JSON.stringify(ks); 46 | // if (kson) { 47 | // localStorage.setItem(lookup, kson); 48 | // } 49 | // } 50 | // 51 | // if (project.sources && !project.sources.find(k => k.value === ks.id.value)) { 52 | // project.sources.push(ks.id); 53 | // } else { 54 | // project.sources = [ks.id]; 55 | // } 56 | // } 57 | // 58 | // this.storage.saveProject(project); 59 | // } 60 | // }) 61 | }); 62 | 63 | this.ipc.getCurrentVersion(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/ipc-services/uuid.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Injectable } from '@angular/core'; 18 | import { ElectronIpcService } from './electron-ipc.service'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | 21 | declare global { 22 | interface Window { 23 | api?: any; 24 | } 25 | } 26 | 27 | @Injectable({ 28 | providedIn: 'root', 29 | }) 30 | export class UuidService { 31 | private uuidBuffer: UUID[] = []; 32 | 33 | constructor(private ipcService: ElectronIpcService) { 34 | this.asyncGenerate(); 35 | } 36 | 37 | generate(quantity: number): UUID[] { 38 | if (quantity < 1) { 39 | console.error('Requested less than 1 UUID.. which is invalid...'); 40 | return []; 41 | } 42 | 43 | const uuids: UUID[] = this.uuidBuffer.slice(0, quantity); 44 | this.uuidBuffer = this.uuidBuffer.slice(quantity); 45 | if (this.uuidBuffer.length <= 32) { 46 | this.asyncGenerate(); 47 | } 48 | return uuids; 49 | } 50 | 51 | private asyncGenerate() { 52 | this.ipcService.generateUuid(128).then((ids: UUID[]) => { 53 | if (ids) this.uuidBuffer = ids; 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/user-services/event.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Injectable } from '@angular/core'; 17 | import { KcProject } from '@app/models/project.model'; 18 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 19 | import { ProjectCalendarEvent } from '@components/project-components/project-calendar.component'; 20 | 21 | @Injectable({ 22 | providedIn: 'root', 23 | }) 24 | export class EventService { 25 | fromProject(project: KcProject) { 26 | const projectColor = 'yellow'; 27 | const projectTextColor = 'black'; 28 | return [ 29 | { 30 | title: `"${project.name}" (Created)`, 31 | start: project.dateCreated, 32 | color: projectColor, 33 | textColor: projectTextColor, 34 | url: 'project', 35 | }, 36 | { 37 | title: `"${project.name}" (Modified)`, 38 | start: project.dateModified, 39 | color: projectColor, 40 | textColor: projectTextColor, 41 | url: 'project', 42 | }, 43 | { 44 | title: `"${project.name}" (Accessed)`, 45 | start: project.dateAccessed, 46 | color: projectColor, 47 | textColor: projectTextColor, 48 | url: 'project', 49 | }, 50 | ]; 51 | } 52 | 53 | fromSourceList(sources: KnowledgeSource[]) { 54 | const createdColor = 'var(--green-500)'; 55 | const modifiedColor = 'var(--yellow-500)'; 56 | const accessedColor = 'var(--blue-500)'; 57 | const events: ProjectCalendarEvent[] = []; 58 | for (const ks of sources) { 59 | events.push({ 60 | title: `${ks.title}`, 61 | start: ks.dateCreated, 62 | url: ks.id.value, 63 | color: createdColor, 64 | }); 65 | ks.dateModified.forEach((d) => { 66 | events.push({ 67 | title: `${ks.title}`, 68 | start: d, 69 | url: ks.id.value, 70 | color: modifiedColor, 71 | }); 72 | }); 73 | ks.dateAccessed.forEach((d) => { 74 | events.push({ 75 | title: `${ks.title}`, 76 | start: d, 77 | url: ks.id.value, 78 | color: accessedColor, 79 | }); 80 | }); 81 | if (ks.dateDue) { 82 | events.push({ 83 | title: `${ks.title}`, 84 | start: ks.dateDue, 85 | color: 'var(--pink-500)', 86 | url: ks.id.value, 87 | }); 88 | } 89 | } 90 | return events; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/user-services/icon.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Injectable } from '@angular/core'; 18 | import { PrimeIcons } from 'primeng/api'; 19 | 20 | @Injectable({ 21 | providedIn: 'root', 22 | }) 23 | export class IconService { 24 | iconValues = Object.values(PrimeIcons); 25 | 26 | constructor() { 27 | // Replace several broken icons with working ones 28 | this.iconValues[this.iconValues.indexOf('pi pi-sort-numeric-alt-up')] = 29 | 'pi pi-sort-numeric-up-alt'; 30 | 31 | this.iconValues[this.iconValues.indexOf('pi pi-sort-numeric-alt-down')] = 32 | 'pi pi-sort-numeric-down-alt'; 33 | 34 | this.iconValues[this.iconValues.indexOf('pi pi-sort-alpha-alt-down')] = 35 | 'pi pi-sort-alpha-down-alt'; 36 | 37 | this.iconValues[this.iconValues.indexOf('pi pi-sort-alpha-alt-up')] = 38 | 'pi pi-sort-alpha-up-alt'; 39 | 40 | this.iconValues[this.iconValues.indexOf('pi pi-sort-slash')] = 41 | 'pi pi-sort-alt-slash'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/workers/graph.worker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /// 17 | 18 | import { KcProject } from '../models/project.model'; 19 | 20 | export function createGraph( 21 | projects: (KcProject & { level: number })[], 22 | root: string, 23 | showSources: boolean 24 | ): any[] { 25 | const data: any[] = []; 26 | 27 | for (const project of projects) { 28 | data.push({ 29 | group: 'nodes', 30 | data: { 31 | id: project.id.value, 32 | label: project.name, 33 | type: project.id.value === root ? 'root' : 'project', 34 | project: project, 35 | width: 64 / Math.pow(project.level, 1 / 2) + 4, 36 | height: 64 / Math.pow(project.level, 1 / 2), 37 | level: project.level, 38 | }, 39 | }); 40 | 41 | for (const sub of project.subprojects) { 42 | const edge = { 43 | group: 'edges', 44 | data: { 45 | id: `${project.id.value}-${sub}`, 46 | source: project.id.value, 47 | target: sub, 48 | }, 49 | }; 50 | data.push(edge); 51 | } 52 | 53 | if (showSources) { 54 | for (const ks of project.knowledgeSource) { 55 | data.push({ 56 | group: 'nodes', 57 | data: { 58 | id: ks.id.value, 59 | label: ks.title, 60 | type: 'ks', 61 | ks: ks, 62 | icon: ks.icon, 63 | }, 64 | }); 65 | 66 | data.push({ 67 | group: 'edges', 68 | data: { 69 | id: `${project.id.value}-${ks.id.value}`, 70 | source: project.id.value, 71 | target: ks.id.value, 72 | }, 73 | }); 74 | } 75 | } 76 | } 77 | return data; 78 | } 79 | 80 | addEventListener('message', (msg) => { 81 | if (!msg.data || !msg.data.projects || !msg.data.root) { 82 | return; 83 | } 84 | 85 | const projects: (KcProject & { level: number })[] = msg.data.projects; 86 | const root: string = msg.data.root; 87 | const showSources: boolean = msg.data.showSources; 88 | const data = createGraph(projects, root, showSources); 89 | postMessage(data); 90 | }); 91 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/workers/tree.worker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /// 17 | 18 | import { ProjectTreeNode } from '../models/project.tree.model'; 19 | import { TreeNode } from 'primeng/api'; 20 | 21 | export function constructTreeNodes( 22 | nodes: ProjectTreeNode[], 23 | collapsed: boolean, 24 | parent?: TreeNode 25 | ) { 26 | const treeNodes: TreeNode[] = []; 27 | for (const node of nodes) { 28 | const treeNode: TreeNode = { 29 | label: node.name, 30 | expanded: collapsed ? false : node.expanded, 31 | leaf: node.subprojects.length === 0, 32 | selectable: true, 33 | draggable: true, 34 | parent: parent, 35 | droppable: true, 36 | key: node.id, 37 | icon: node.icon, 38 | }; 39 | treeNode.children = 40 | node.subprojects.length > 0 41 | ? constructTreeNodes(node.subprojects, collapsed, treeNode) 42 | : []; 43 | treeNodes.push(treeNode); 44 | } 45 | return treeNodes; 46 | } 47 | 48 | addEventListener('message', (msg) => { 49 | if (!msg.data || !msg.data.nodes) { 50 | return; 51 | } 52 | 53 | const nodes = msg.data.nodes; 54 | const collapsed = msg.data.collapsed; 55 | const parent = msg.data.parent; 56 | const constructed = constructTreeNodes(nodes, collapsed, parent); 57 | postMessage(constructed); 58 | }); 59 | -------------------------------------------------------------------------------- /src/kc_angular/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/src/kc_angular/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/kc_angular/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/src/kc_angular/src/assets/favicon.ico -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/src/kc_angular/src/assets/img/default.png -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/icons/chrome_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/kc-icon-greyscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/src/kc_angular/src/assets/img/kc-icon-greyscale.png -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/kc-icon-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/src/kc_angular/src/assets/img/kc-icon-transparent.png -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/kc-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/src/kc_angular/src/assets/img/kc-icon.png -------------------------------------------------------------------------------- /src/kc_angular/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export const environment = { 18 | production: true, 19 | }; 20 | -------------------------------------------------------------------------------- /src/kc_angular/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // This file can be replaced during build by using the `fileReplacements` array. 18 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 19 | // The list of file replacements can be found in `angular.json`. 20 | 21 | export const environment = { 22 | production: false, 23 | }; 24 | 25 | /* 26 | * For easier debugging in development mode, you can import the following file 27 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 28 | * 29 | * This import should be commented out in production mode because it will have a negative impact 30 | * on performance if an error is thrown. 31 | */ 32 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 33 | -------------------------------------------------------------------------------- /src/kc_angular/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnowledgeCanvas/knowledge/1dacab52f773713c010052c5a5e327b71be3f49b/src/kc_angular/src/favicon.ico -------------------------------------------------------------------------------- /src/kc_angular/src/index.html: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 17 | 18 | 19 | Knowledge 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/kc_angular/src/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { enableProdMode } from '@angular/core'; 18 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 19 | 20 | import { AppModule } from '@app/app.module'; 21 | import { environment } from '@environments/environment'; 22 | 23 | if (environment.production) { 24 | enableProdMode(); 25 | } 26 | 27 | platformBrowserDynamic() 28 | .bootstrapModule(AppModule) 29 | .catch((err) => console.error(err)); 30 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/arya-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/arya-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/arya-green.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/arya-green/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/arya-orange.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/arya-orange/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/arya-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/arya-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-dark-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-dark-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-dark-indigo.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-dark-indigo/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-dark-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-dark-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-dark-teal.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-dark-teal/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-light-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-light-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-light-indigo.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-light-indigo/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-light-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-light-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-light-teal.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-light-teal/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/saga-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/saga-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/saga-green.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/saga-green/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/saga-orange.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/saga-orange/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/saga-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/saga-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/vela-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/vela-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/vela-green.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/vela-green/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/vela-orange.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/vela-orange/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/vela-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/vela-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "allowSyntheticDefaultImports": true, 7 | "outDir": "./dist/out-tsc", 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "sourceMap": true, 13 | "declaration": false, 14 | "downlevelIteration": true, 15 | "experimentalDecorators": true, 16 | "moduleResolution": "node", 17 | "importHelpers": true, 18 | "target": "es2020", 19 | "module": "es2020", 20 | "lib": [ 21 | "es2018", 22 | "dom" 23 | ], 24 | "paths": { 25 | "@app/*": [ 26 | "src/app/*" 27 | ], 28 | "@assets/*": [ 29 | "src/assets/*" 30 | ], 31 | "@environments/*": [ 32 | "src/environments/*" 33 | ], 34 | "@styles/*": [ 35 | "src/styles/*" 36 | ], 37 | "@components/*": [ 38 | "src/app/components/*" 39 | ], 40 | "@pipes/*": [ 41 | "src/app/pipes/*" 42 | ], 43 | "@shared/*": [ 44 | "../kc_shared/*" 45 | ], 46 | "@services/*": [ 47 | "src/app/services/*" 48 | ] 49 | } 50 | }, 51 | "files": [ 52 | "src/main.ts", 53 | "src/polyfills.ts" 54 | ], 55 | "include": [ 56 | "src/**/*.d.ts" 57 | ], 58 | "angularCompilerOptions": { 59 | "enableI18nLegacyMessageIdFormat": false, 60 | "strictInjectionParameters": true, 61 | "strictInputAccessModifiers": true, 62 | "strictTemplates": true 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/kc_angular/tsconfig.worker.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/worker", 6 | "lib": [ 7 | "dom" 8 | ], 9 | "types": [] 10 | }, 11 | "include": [ 12 | "**/*.worker.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/kc_electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kc_electron", 3 | "version": "0.8.4", 4 | "description": "This package contains the Electron portion of the Knowledge desktop application.", 5 | "main": "dist/main.js", 6 | "author": "Rob Royce (https://robroyce.dev)", 7 | "license": "Apache-2.0", 8 | "private": true, 9 | "scripts": { 10 | "build": "webpack --config webpack.prod.js", 11 | "build-dev": "webpack --config webpack.dev.js", 12 | "clean": "rm -rf dist", 13 | "purge": "rm -rf node_modules", 14 | "test": "echo \"Error: no test specified\" && exit 1", 15 | "watch-electron": "webpack --config webpack.prod.js --watch", 16 | "watch-electron-dev": "webpack --config webpack.dev.js --watch" 17 | }, 18 | "dependencies": { 19 | "@dqbd/tiktoken": "^1.0.7", 20 | "chokidar": "^3.5.3", 21 | "cors": "^2.8.5", 22 | "crypto-js": "^4.1.1", 23 | "dotenv": "^16.3.1", 24 | "electron": "^26.3.0", 25 | "electron-updater": "^6.1.4", 26 | "express-rate-limit": "^6.11.2", 27 | "lodash": "^4.17.21", 28 | "mime-types": "^2.1.35", 29 | "openai": "^4.12.4", 30 | "rxjs": "^7.8.1", 31 | "uuid": "^9.0.1" 32 | }, 33 | "devDependencies": { 34 | "@types/cors": "^2.8.17", 35 | "@types/crypto-js": "^4.1.3", 36 | "@types/lodash": "^4.14.200", 37 | "@types/mime-types": "^2.1.3", 38 | "electron-builder": "^24.6.4", 39 | "ts-loader": "^9.5.0", 40 | "typescript": "<4.9.0", 41 | "webpack": "^5.89.0", 42 | "webpack-cli": "^4.10.0", 43 | "webpack-merge": "^5.10.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/ipc/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const fileIpc = require("./ipc-files"); 18 | const browserIpc = require("./ipc-browser"); 19 | require("./ipc-misc"); 20 | const autoUpdateIpc = require("./ipc-auto-update"); 21 | 22 | module.exports = { 23 | autoUpdateIpc, 24 | fileIpc, 25 | browserIpc, 26 | }; 27 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/ipc/ipc-auto-update.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const share: any = (global as any).share; 18 | const ipcMain = share.ipcMain; 19 | const autoUpdater = share.autoUpdater; 20 | 21 | import { IpcMessage } from "../../../../kc_shared/models/electron.ipc.model"; 22 | 23 | const checkForUpdate = ipcMain.on("A2E:AutoUpdate:Check", (_: any) => { 24 | autoUpdater 25 | .checkForUpdates() 26 | .then((result: any) => { 27 | console.warn("Result from check for update: ", result); 28 | }) 29 | .catch((error: any) => { 30 | console.warn("Error from check for update: ", error); 31 | }); 32 | }); 33 | 34 | const getCurrentVersion = ipcMain.on("A2E:Version:Get", (_: any) => { 35 | const kcMainWindow: any = share.BrowserWindow.getAllWindows()[0]; 36 | const message: IpcMessage = { 37 | error: undefined, 38 | success: { 39 | data: autoUpdater.currentVersion.version, 40 | }, 41 | }; 42 | kcMainWindow.webContents.send("E2A:Version:Get", message); 43 | }); 44 | 45 | module.exports = { 46 | checkForUpdate, 47 | getCurrentVersion, 48 | }; 49 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/ipc/ipc-misc.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { 17 | IpcMessage, 18 | UuidRequest, 19 | } from "../../../../kc_shared/models/electron.ipc.model"; 20 | 21 | const share: any = (global as any).share; 22 | const ipcMain: any = share.ipcMain; 23 | const http: any = share.http; 24 | const uuid: any = share.uuid; 25 | 26 | let generateUuid; 27 | 28 | generateUuid = ipcMain.on("A2E:Uuid:Generate", (event: any, args: any) => { 29 | const kcMainWindow: any = share.BrowserWindow.getAllWindows()[0]; 30 | const response: IpcMessage = { 31 | error: undefined, 32 | success: undefined, 33 | }; 34 | if (!isKcUuidRequest(args)) { 35 | const message = `electron-generate-uuid argument does not conform to KcUuidRequest`; 36 | response.error = { 37 | code: 412, 38 | label: http.STATUS_CODES["412"], 39 | message: message, 40 | }; 41 | console.warn(response.error); 42 | kcMainWindow.webContents.send("E2A:BrowserView:Open", response); 43 | return; 44 | } 45 | let ids = []; 46 | for (let i = 0; i < args.quantity; i++) { 47 | const id = uuid.v4(); 48 | if (i === 0) ids = [id]; 49 | else ids.push(id); 50 | } 51 | response.success = { data: ids }; 52 | kcMainWindow.webContents.send("E2A:Uuid:Generate", response); 53 | }); 54 | 55 | function isKcUuidRequest(args: any): args is UuidRequest { 56 | const containsQuantity = args && args.quantity; 57 | const correctType = typeof args.quantity === "number"; 58 | const correctRange = 0 < args.quantity && args.quantity <= 128; 59 | return containsQuantity && correctType && correctRange; 60 | } 61 | 62 | module.exports = { generateUuid }; 63 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/services/auto.update.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const share: any = (global as any).share; 18 | const http: any = share.http; 19 | const autoUpdater = share.autoUpdater; 20 | 21 | import { IpcMessage } from "../../../../kc_shared/models/electron.ipc.model"; 22 | 23 | console.log( 24 | `[AutoUpdate] - Knowledge Version ${autoUpdater.currentVersion.version} - Initializing...` 25 | ); 26 | 27 | autoUpdater.on("checking-for-update", () => { 28 | const message: IpcMessage = { 29 | error: undefined, 30 | success: { 31 | data: "Auto updater checking for update...", 32 | }, 33 | }; 34 | console.log(message); 35 | }); 36 | 37 | autoUpdater.on("update-available", (info: any) => { 38 | const message: IpcMessage = { 39 | error: undefined, 40 | success: { 41 | data: info, 42 | message: "Auto updater found new update...", 43 | }, 44 | }; 45 | console.log(message); 46 | }); 47 | 48 | autoUpdater.on("update-not-available", (info: any) => { 49 | const message: IpcMessage = { 50 | error: undefined, 51 | success: { 52 | data: info, 53 | message: "No updates available...", 54 | }, 55 | }; 56 | console.log(message); 57 | }); 58 | 59 | autoUpdater.on("error", (err: any) => { 60 | const message: IpcMessage = { 61 | error: { 62 | code: 501, 63 | label: http.STATUS_CODES["501"], 64 | message: err, 65 | }, 66 | success: undefined, 67 | }; 68 | console.log(message); 69 | }); 70 | 71 | autoUpdater.on("download-progress", (progressObj: any) => { 72 | let log_message = "Download speed: " + progressObj.bytesPerSecond; 73 | log_message = log_message + " - Downloaded " + progressObj.percent + "%"; 74 | log_message = 75 | log_message + 76 | " (" + 77 | progressObj.transferred + 78 | "/" + 79 | progressObj.total + 80 | ")"; 81 | const message: IpcMessage = { 82 | error: undefined, 83 | success: { 84 | message: log_message, 85 | }, 86 | }; 87 | console.log(message); 88 | }); 89 | 90 | autoUpdater.on("update-downloaded", (info: any) => { 91 | const message: IpcMessage = { 92 | error: undefined, 93 | success: { 94 | data: info, 95 | message: "Update finished downloading...", 96 | }, 97 | }; 98 | console.log(message); 99 | }); 100 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/services/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | const autoscanService = require("./autoscan.service"); 17 | const extensionService = require("./extension.service"); 18 | const windowService = require("./window.service"); 19 | 20 | module.exports = { 21 | autoscan: autoscanService, 22 | extensions: extensionService, 23 | window: windowService, 24 | }; 25 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/services/window.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const share: any = (global as any).share; 18 | 19 | class WindowService { 20 | constructor() { 21 | share.ipcMain.on("A2E:Window:Minimize", (_: any) => { 22 | // TODO: this method of finding the main window is definitely broken... 23 | // there is no gaurantee that the main window will be first in this array when a second window is open... 24 | // this is preventing us from opening the Knowledge Graph in its own window 25 | const kcMainWindow = share.BrowserWindow.getAllWindows()[0]; 26 | if (kcMainWindow) { 27 | kcMainWindow.minimize(); 28 | } else { 29 | console.log("Unable to get main window..."); 30 | } 31 | }); 32 | 33 | share.ipcMain.on("A2E:Window:Maximize", (_: any) => { 34 | const kcMainWindow = share.BrowserWindow.getAllWindows()[0]; 35 | if (kcMainWindow) { 36 | kcMainWindow.fullScreen = !kcMainWindow.fullScreen; 37 | } else { 38 | console.log("Unable to get main window..."); 39 | } 40 | }); 41 | 42 | share.ipcMain.on("A2E:Window:ZoomIn", (_: any, zoomLevel: number) => { 43 | const kcMainWindow = share.BrowserWindow.getAllWindows()[0]; 44 | if (kcMainWindow) { 45 | kcMainWindow.webContents.setZoomFactor(zoomLevel / 100); 46 | } else { 47 | console.log("Unable to get main window..."); 48 | } 49 | }); 50 | 51 | share.ipcMain.on("A2E:Window:ZoomOut", (_: any, zoomLevel: number) => { 52 | const kcMainWindow = share.BrowserWindow.getAllWindows()[0]; 53 | if (kcMainWindow) { 54 | kcMainWindow.webContents.setZoomFactor(zoomLevel / 100); 55 | } else { 56 | console.log("Unable to get main window..."); 57 | } 58 | }); 59 | } 60 | } 61 | 62 | const electronWindowService = new WindowService(); 63 | module.exports = electronWindowService; 64 | -------------------------------------------------------------------------------- /src/kc_electron/src/ipc/chat.ipc.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { IpcChannelInterface } from "../local/utils/ipc.utils"; 18 | import { IpcMainEvent } from "electron"; 19 | import { IpcRequest } from "../../../kc_shared/models/electron.ipc.model"; 20 | 21 | export class ChatPrinterIpc implements IpcChannelInterface { 22 | getName(): string { 23 | return "ChatPrinter"; 24 | } 25 | 26 | handle(event: IpcMainEvent, request: IpcRequest): void { 27 | console.log("Chat printer handler", event, request); 28 | } 29 | 30 | private async createContainer(height: number, width: number, doc: Document) { 31 | const container = doc.createElement("div"); 32 | container.style.display = "block"; 33 | container.style.height = `${height}px`; 34 | container.style.width = `${width}px`; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/autoscan.api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import * as chokidar from "chokidar"; 17 | import * as fs from "fs-extra"; 18 | import * as path from "path"; 19 | 20 | /** 21 | * TODO: Not implemented yet. 22 | */ 23 | export default class Autoscan { 24 | private sourceDirectory = "./source"; 25 | private pendingDirectory = "./pending"; 26 | private locationMapFile = "fileLocationMap.json"; 27 | private fileLocationMap = new Map(); 28 | 29 | async processFile(filePath: string) { 30 | // Implement your custom post-processing logic here 31 | console.log(`Processing ${filePath}`); 32 | } 33 | 34 | async moveFileToPending(filePath: string) { 35 | const fileName = path.basename(filePath); 36 | const pendingFilePath = path.join(this.pendingDirectory, fileName); 37 | 38 | try { 39 | await fs.move(filePath, pendingFilePath); 40 | this.fileLocationMap.set(fileName, pendingFilePath); 41 | console.debug(`Moved ${filePath} to ${pendingFilePath}`); 42 | await this.saveFileLocationMap(); 43 | } catch (err) { 44 | console.error(`Failed to move ${filePath} to ${pendingFilePath}`, err); 45 | } 46 | } 47 | 48 | async handleNewFile(filePath: string) { 49 | await this.processFile(filePath); 50 | await this.moveFileToPending(filePath); 51 | } 52 | 53 | startWatching() { 54 | const watcher = chokidar.watch(this.sourceDirectory, { 55 | persistent: true, 56 | ignoreInitial: true, 57 | }); 58 | 59 | watcher.on("add", (filePath) => { 60 | console.debug(`New file detected: ${filePath}`); 61 | this.handleNewFile(filePath); 62 | }); 63 | 64 | watcher.on("error", (error) => console.error(`Watcher error: ${error}`)); 65 | } 66 | 67 | async saveFileLocationMap() { 68 | const data = JSON.stringify(Array.from(this.fileLocationMap.entries())); 69 | await fs.writeFile(this.locationMapFile, data, "utf8"); 70 | console.debug(`Saved file location map to ${this.locationMapFile}`); 71 | } 72 | 73 | async loadFileLocationMap() { 74 | if (await fs.pathExists(this.locationMapFile)) { 75 | const data = await fs.readFile(this.locationMapFile, "utf8"); 76 | const entries = JSON.parse(data) as [string, string][]; 77 | this.fileLocationMap.clear(); 78 | for (const [key, value] of entries) { 79 | this.fileLocationMap.set(key, value); 80 | } 81 | console.debug(`Loaded file location map from ${this.locationMapFile}`); 82 | } 83 | } 84 | 85 | async init() { 86 | await fs.ensureDir(this.sourceDirectory); 87 | await fs.ensureDir(this.pendingDirectory); 88 | 89 | await this.loadFileLocationMap(); 90 | this.startWatching(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/browser.api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/controllers/api.controller.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Request, Response } from "express"; 18 | import { OpenAI } from "openai"; 19 | 20 | import fs from "fs"; 21 | import chatEncrypt from "../utils/encrypt.utils"; 22 | 23 | const settings = require("../../app/services/settings.service"); 24 | 25 | export default class ApiKeyController { 26 | async checkApiKey(req: Request, res: Response): Promise { 27 | // Returns true if API key is set and works as expected, otherwise false 28 | const apiKey = await this.loadApiKey(); 29 | const apiKeyWorks = await this.testApiKey(apiKey); 30 | return res.json({ 31 | apiKeySet: apiKeyWorks, 32 | }); 33 | } 34 | 35 | async hasApiKey(req: Request, res: Response): Promise { 36 | // Returns true if API key is set, otherwise false 37 | try { 38 | const apiKey = await this.loadApiKey(); 39 | return res.json({ 40 | apiKeySet: apiKey && apiKey.length > 0, 41 | }); 42 | } catch { 43 | return res.json({ apiKeySet: false }); 44 | } 45 | } 46 | 47 | async deleteApiKey(req: Request, res: Response): Promise { 48 | const apiKeyPath = this.getApiKeyPath(); 49 | if (fs.existsSync(apiKeyPath)) { 50 | console.debug("Deleting API key at path: ", apiKeyPath); 51 | fs.unlinkSync(apiKeyPath); 52 | return res.json({ success: true }); 53 | } 54 | return res.json({ success: false }); 55 | } 56 | 57 | async setApiKey(req: Request, res: Response): Promise { 58 | const apiKeyWorks = await this.testApiKey(req.body.apiKey); 59 | if (!apiKeyWorks) { 60 | return res.status(400).json({ success: false }); 61 | } 62 | 63 | const saved = await this.saveApiKey(req.body.apiKey); 64 | return res.json({ success: saved }); 65 | } 66 | 67 | private getApiKeyPath(): string { 68 | const userDataPath = settings.getSettings().system.appPath; 69 | return `${userDataPath}/openai.encrypted`; 70 | } 71 | 72 | private async loadApiKey() { 73 | return chatEncrypt.readAndDecryptApiKey(this.getApiKeyPath(), "unsecured"); 74 | } 75 | 76 | private async saveApiKey(apiKey: string) { 77 | const encryptedApiKey = chatEncrypt.encryptApiKey(apiKey, "unsecured"); 78 | const filePath = this.getApiKeyPath(); 79 | fs.writeFileSync(filePath, encryptedApiKey); 80 | return true; 81 | } 82 | 83 | private async testApiKey(apiKey: string) { 84 | try { 85 | const openaiTest = new OpenAI({ 86 | apiKey: apiKey, 87 | }); 88 | const models = await openaiTest.models.list(); 89 | return models.data.length > 0; 90 | } catch (e) { 91 | return false; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/controllers/project.controller.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Request, Response } from "express"; 18 | 19 | export default class ProjectChatController { 20 | async chat(req: Request, res: Response): Promise { 21 | // Load the entire source here 22 | return res.status(500).json({ message: "Not implemented" }); 23 | } 24 | 25 | async intro(req: Request, res: Response): Promise { 26 | // Load the entire source here 27 | console.log("Got request on sources/intro..."); 28 | return res.status(500).json({ message: "Not implemented" }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/controllers/source.controller.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Request, Response } from "express"; 18 | import { introPrompts } from "../constants/source.prompts"; 19 | import { GlobalWorkerOptions } from "pdfjs-dist"; 20 | import ChatController from "./chat.controller"; 21 | import TokenizerUtils from "../utils/tokenizer.utils"; 22 | 23 | GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry"); 24 | 25 | export default class SourceChatController { 26 | constructor( 27 | private tokenizerUtils: TokenizerUtils, 28 | private chatController: ChatController 29 | ) {} 30 | 31 | getChatController() { 32 | return this.chatController; 33 | } 34 | 35 | async chat(req: Request, res: Response): Promise { 36 | return this.chatController.chat(req, res); 37 | } 38 | 39 | async intro(req: Request, res: Response): Promise { 40 | // If the summary already exists, simply return it as a ChatCompletion 41 | if (req.body.summary) { 42 | console.debug( 43 | "[Knowledge]: Source summary already exists, returning it..." 44 | ); 45 | return res.json({ 46 | choices: [ 47 | { 48 | message: { 49 | content: req.body.summary, 50 | role: "assistant", 51 | }, 52 | }, 53 | ], 54 | }); 55 | } 56 | 57 | const source = req.body.source; 58 | const messages = req.body.messages || []; 59 | const noPrompts = messages.length === 0; 60 | 61 | // Get Source prompts based on this specific source, prepend them to messages 62 | if (noPrompts) { 63 | const sourceIntroPrompts = introPrompts(source, "source"); 64 | sourceIntroPrompts.forEach((message) => { 65 | messages.push(message); 66 | }); 67 | } 68 | 69 | // Extract text from web page to feed into the API 70 | const text = this.tokenizerUtils.limitText(req.body.text); 71 | 72 | // Append the extracted text to the messages before sending 73 | messages.push({ 74 | role: "system", 75 | content: `The following is the text extracted from the Source: "${source.title}":\n=========\n"""${text}"""\n=========`, 76 | }); 77 | 78 | if (noPrompts) { 79 | messages.push({ 80 | role: "user", 81 | content: `Can you introduce me to "${source.title}"?`, 82 | }); 83 | } 84 | return this.chatController.chat(req, res); 85 | } 86 | 87 | async regenerate(req: Request, res: Response) { 88 | return undefined; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/middleware/DocumentSummarizer.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { NextFunction, Request, Response } from "express"; 18 | import ChatController from "../controllers/chat.controller"; 19 | 20 | export class DocumentSummarizer { 21 | private chatController: ChatController; 22 | constructor(chatController: ChatController) { 23 | console.log("DocumentSummarizer initializing..."); 24 | this.chatController = chatController; 25 | } 26 | 27 | summarize() { 28 | return async (req: Request, res: Response, next: NextFunction) => { 29 | // If the request already contains a summary, skip this middleware 30 | if (req.body.summary) { 31 | return next(); 32 | } 33 | 34 | let text = req.body.text; 35 | 36 | // Absolute limit of text length is 100,000 characters, truncate anything above 37 | if (text.length > 100000) { 38 | console.warn( 39 | `[DocumentSummarizer]: truncating text of size ${text.length} to 100,000 characters` 40 | ); 41 | req.body.text = text.substring(0, 100000); 42 | text = req.body.text; 43 | } 44 | 45 | // Generate a summary of the text 46 | const CHUNK_SIZE = 10000; 47 | const chunks = text.match(new RegExp(`.{1,${CHUNK_SIZE}}`, "g")); 48 | 49 | if (chunks) { 50 | const summaries = await Promise.all( 51 | chunks.map(this.chatController.summarize.bind(this.chatController)) 52 | ); 53 | const initialSummaries = summaries.join("\n").trim(); 54 | const summary = await this.chatController.summarize( 55 | initialSummaries, 56 | false, 57 | true 58 | ); 59 | req.body.summary = summary; 60 | next(); 61 | } else { 62 | console.warn("DocumentSummarizer: unable to split text into chunks..."); 63 | next(); 64 | } 65 | }; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/middleware/ErrorHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { NextFunction, Request, Response } from "express"; 18 | import { ResponseUtil } from "../utils/response.util"; 19 | 20 | export class ErrorHandler { 21 | static catchErrors(fn: any) { 22 | return (req: Request, res: Response, next: NextFunction) => { 23 | Promise.resolve(fn(req, res, next)).catch(next); 24 | }; 25 | } 26 | 27 | static handleErrors(err: any, req: Request, res: Response) { 28 | console.error(err); 29 | 30 | if (err.message === "Invalid file type") { 31 | return ResponseUtil.sendError(res, "Invalid file type", 422, null); 32 | } 33 | 34 | return res.status(500).send({ 35 | success: false, 36 | message: "Internal server error", 37 | }); 38 | } 39 | 40 | static formatErrors(error: any) { 41 | // Used in conjunction with class-validator to handle format errors 42 | const errors = {}; 43 | error.forEach((e: any) => { 44 | // @ts-ignore 45 | if (!errors[e.property]) { 46 | // @ts-ignore 47 | errors[e.property] = []; 48 | } 49 | // @ts-ignore 50 | errors[e.property].push(e.constraints[Object.keys(e.constraints)[0]]); 51 | }); 52 | return errors; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/middleware/SourceLoader.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { NextFunction, Request, Response } from "express"; 18 | import fs from "fs"; 19 | import path from "path"; 20 | 21 | const settingsService = require("../../app/services/settings.service"); 22 | 23 | export class SourceLoader { 24 | static async load(req: Request, res: Response, next: NextFunction) { 25 | const source = req.body.source; 26 | const id = source.id; 27 | const filename = `${id.value}.json`; 28 | 29 | const filepath = path.resolve( 30 | settingsService.getSettings().system.appPath, 31 | "storage", 32 | "sources", 33 | filename 34 | ); 35 | 36 | // Make sure the directory exists, if not create it 37 | const dirname = path.dirname(filepath); 38 | if (!fs.existsSync(dirname)) { 39 | fs.mkdirSync(dirname, { recursive: true }); 40 | } 41 | 42 | // Check for the Source in local JSON files. Append to req.body if found. 43 | if (fs.existsSync(filepath)) { 44 | const json = fs.readFileSync(filepath, "utf8"); 45 | const data = JSON.parse(json); 46 | req.body.text = data[0] ?? undefined; 47 | req.body.summary = data[1] ?? undefined; 48 | } else { 49 | console.debug("Source not found in local storage: ", req.body.source); 50 | } 51 | 52 | console.debug("Loaded source from local storage: ", req.body.source); 53 | console.debug( 54 | "Length of text loaded from local storage: ", 55 | req.body.text?.length 56 | ); 57 | console.debug( 58 | "Length of summary loaded from local storage: ", 59 | req.body.summary?.length 60 | ); 61 | 62 | next(); 63 | } 64 | 65 | static async store(req: Request, res: Response, next: NextFunction) { 66 | const source = req.body.source; 67 | const text = req.body.text; 68 | const summary = req.body.summary; 69 | 70 | const id = source.id; 71 | const filename = `${id.value}.json`; 72 | 73 | const filepath = path.resolve( 74 | settingsService.getSettings().system.appPath, 75 | "storage", 76 | "sources", 77 | filename 78 | ); 79 | 80 | // Make sure the directory exists, if not create it 81 | const dirname = path.dirname(filepath); 82 | if (!fs.existsSync(dirname)) { 83 | fs.mkdirSync(dirname, { recursive: true }); 84 | } 85 | 86 | console.debug("Storing source text and summary at: ", filepath); 87 | 88 | // Store the Source into local JSON file using ID as filename. 89 | const json = JSON.stringify([text, summary]); 90 | fs.writeFileSync(filepath, json, "utf8"); 91 | 92 | next(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/routes/api.routes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import ApiKeyController from "../controllers/api.controller"; 18 | import express from "express"; 19 | 20 | const router = express.Router(); 21 | 22 | export default class ApiRoutes { 23 | private apiKeyController: ApiKeyController; 24 | 25 | constructor(controller: ApiKeyController) { 26 | this.apiKeyController = controller; 27 | this.getRouter(); 28 | } 29 | 30 | get controller() { 31 | return this.apiKeyController; 32 | } 33 | 34 | getRouter() { 35 | router.post( 36 | "/key", 37 | this.apiKeyController.setApiKey.bind(this.apiKeyController) 38 | ); 39 | router.get( 40 | "/key", 41 | this.apiKeyController.hasApiKey.bind(this.apiKeyController) 42 | ); 43 | router.delete( 44 | "/key", 45 | this.apiKeyController.deleteApiKey.bind(this.apiKeyController) 46 | ); 47 | 48 | return router; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/routes/chat.routes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import express from "express"; 18 | import ChatController from "../controllers/chat.controller"; 19 | 20 | const router = express.Router(); 21 | 22 | export default class ChatRoutes { 23 | private chatController: ChatController; 24 | 25 | constructor(chatController: ChatController) { 26 | this.chatController = chatController; 27 | this.getRouter(); 28 | } 29 | 30 | get controller() { 31 | return this.chatController; 32 | } 33 | 34 | getRouter() { 35 | router.post("/", this.chatController.chat.bind(this.chatController)); 36 | router.post( 37 | "/tokens", 38 | this.chatController.tokens.bind(this.chatController) 39 | ); 40 | 41 | return router; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/routes/source.routes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import express from "express"; 18 | import SourceChatController from "../controllers/source.controller"; 19 | import { SourceParser } from "../middleware/SourceParser"; 20 | import { SourceLoader } from "../middleware/SourceLoader"; 21 | import { DocumentSummarizer } from "../middleware/DocumentSummarizer"; 22 | 23 | const router = express.Router(); 24 | 25 | export default class SourceRoutes { 26 | private sourceController: SourceChatController; 27 | private summarizer: DocumentSummarizer; 28 | 29 | constructor(controller: SourceChatController) { 30 | this.sourceController = controller; 31 | this.summarizer = new DocumentSummarizer(controller.getChatController()); 32 | this.getRouter(); 33 | } 34 | 35 | get controller() { 36 | return this.sourceController; 37 | } 38 | 39 | getRouter() { 40 | // Load the source from the database 41 | router.use(SourceLoader.load); 42 | 43 | // Parse the source into text (if necessary) 44 | router.use(SourceParser.getText); 45 | 46 | // Summarize the text (if necessary) 47 | router.use(this.summarizer.summarize()); 48 | 49 | // Store the source in the database 50 | router.use(SourceLoader.store); 51 | 52 | // Regular chat with the source 53 | router.post("/", this.controller.chat.bind(this.controller)); 54 | 55 | // Intro chat with the source (basically a summary) 56 | router.post("/intro", this.controller.intro.bind(this.controller)); 57 | 58 | // An endpoint to regenerate previous responses 59 | router.post( 60 | "/regenerate", 61 | this.controller.regenerate.bind(this.controller) 62 | ); 63 | 64 | return router; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/chat.utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Chat } from "openai/resources"; 18 | import CreateChatCompletionRequestMessage = Chat.CreateChatCompletionRequestMessage; 19 | 20 | const settings = require("../../app/services/settings.service"); 21 | 22 | export default class ChatUtils { 23 | constructor() {} 24 | 25 | /** TODO: 26 | * Reduce the messages to a single message while retaining as much information as possible 27 | * @param messages 28 | */ 29 | async reduce(messages: CreateChatCompletionRequestMessage[]) {} 30 | 31 | async refine(messages: CreateChatCompletionRequestMessage[]) {} 32 | 33 | /** 34 | * Split the text into chunks and summarize each chunk 35 | * @param text 36 | */ 37 | async mapReduce(text: string) { 38 | // const tokenizer = this.getTokenizer(); 39 | // const tokenCount = tokenizer.countTokens(text); 40 | // console.log("Token count: ", tokenCount); 41 | } 42 | 43 | private getTokenizer() { 44 | // const model = settings.getSettings().app.chat.model.name; 45 | // tokenizerUtils.setModel(model); 46 | // return tokenizerUtils; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/encrypt.utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import CryptoJS from "crypto-js"; 18 | import fs from "fs"; 19 | 20 | export class EncryptUtils { 21 | encryptApiKey(apiKey: string, secretKey: string): string { 22 | return CryptoJS.AES.encrypt(apiKey, secretKey).toString(); 23 | } 24 | 25 | decryptApiKey(encrypted: string, secret: string): string { 26 | const apiKey = CryptoJS.AES.decrypt(encrypted, secret); 27 | return apiKey.toString(CryptoJS.enc.Utf8); 28 | } 29 | 30 | async readAndDecryptApiKey(keyPath: string, secret: string): Promise { 31 | const filePath = keyPath; 32 | 33 | if (!fs.existsSync(filePath)) { 34 | return ""; 35 | } 36 | 37 | const encryptedApiKey = fs.readFileSync(filePath, "utf-8"); 38 | return this.decryptApiKey(encryptedApiKey, secret); 39 | } 40 | } 41 | 42 | const chatEncrypt = new EncryptUtils(); 43 | export default chatEncrypt; 44 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/ipc.utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ipcMain, IpcMainEvent } from "electron"; 18 | import { IpcRequest } from "../../../../kc_shared/models/electron.ipc.model"; 19 | import { ChatPrinterIpc } from "../../ipc/chat.ipc"; 20 | 21 | export interface IpcChannelInterface { 22 | getName(): string; 23 | 24 | handle(event: IpcMainEvent, request: IpcRequest): void; 25 | } 26 | 27 | export default class KnowledgeIpc { 28 | ipcChannels: IpcChannelInterface[] = [new ChatPrinterIpc()]; 29 | 30 | constructor() { 31 | this.registerIpcChannels(this.ipcChannels); 32 | } 33 | 34 | /** 35 | * Registers all IPC channels with the main process 36 | * @param ipcChannels 37 | */ 38 | private registerIpcChannels(ipcChannels: IpcChannelInterface[]) { 39 | ipcChannels.forEach((channel) => { 40 | console.log("Registering IPC Channel: " + channel.getName()); 41 | ipcMain.on(channel.getName(), (event, request) => { 42 | try { 43 | channel.handle(event, request); 44 | } catch (err) { 45 | console.log(err); 46 | } 47 | }); 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/response.util.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Response } from "express"; 18 | 19 | export class ResponseUtil { 20 | static sendResponse( 21 | res: Response, 22 | message: string, 23 | data: T, 24 | statusCode = 200, 25 | paginationInfo: any = null 26 | ): Response { 27 | return res.status(statusCode).json({ 28 | success: true, 29 | message, 30 | data, 31 | pagination: paginationInfo, 32 | status: statusCode, 33 | }); 34 | } 35 | 36 | static sendError( 37 | res: Response, 38 | message: string, 39 | statusCode = 500, 40 | error: T 41 | ): Response { 42 | return res.status(statusCode).json({ 43 | success: false, 44 | message, 45 | error, 46 | }); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/text.utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export default class TextUtils { 18 | constructor() { 19 | throw new Error("TextUtils is a static class and cannot be instantiated"); 20 | } 21 | 22 | static isPlainText(str: string) { 23 | // Verify that the string is plain text (i.e. ASCII characters only) 24 | return /^[\x00-\x7F]*$/.test(str); 25 | } 26 | 27 | static isNullOrWhitespace(text: string): boolean { 28 | return text === null || text.match(/^ *$/) !== null; 29 | } 30 | 31 | static isNullOrEmpty(text: string): boolean { 32 | return text === null || text === ""; 33 | } 34 | 35 | static isNullOrWhitespaceOrEmpty(text: string): boolean { 36 | return TextUtils.isNullOrWhitespace(text) || TextUtils.isNullOrEmpty(text); 37 | } 38 | 39 | static convertToAscii(text: string): string { 40 | return text.replace(/[^\x00-\x7F]/g, ""); 41 | } 42 | 43 | static convertToBase64(text: string): string { 44 | return Buffer.from(text).toString("base64"); 45 | } 46 | 47 | static convertFromBase64(text: string): string { 48 | return Buffer.from(text, "base64").toString(); 49 | } 50 | 51 | static convertToBase64Url(text: string): string { 52 | return TextUtils.convertToBase64(text) 53 | .replace(/\+/g, "-") 54 | .replace(/\//g, "_") 55 | .replace(/=/g, ""); 56 | } 57 | 58 | static chunk(text: string, size: number): string[] { 59 | const chunks = []; 60 | for (let i = 0; i < text.length; i += size) { 61 | chunks.push(text.substring(i, i + size - 1)); 62 | } 63 | return chunks; 64 | } 65 | 66 | static clean(text: string): string { 67 | text = text.replace(/(https?:\/\/[^\s]+)/g, ""); // Remove URLs 68 | text = text.replace(/(\r\n|\n|\r)/gm, ""); // Remove newlines 69 | text = text.replace(/(\t)/gm, ""); // Remove tabs 70 | text = text.replace(/(\s{2,})/g, " "); // Remove any double spaces 71 | text = text.replace(/[^a-zA-Z0-9 ]/g, ""); // Remove any non-alphanumeric characters 72 | 73 | // Remove any non-whitespace substrings longer than 32 characters 74 | // (this is to prevent the API from returning an error) 75 | text = text.replace(/(\S{32,})/g, " "); 76 | text = text.trim(); 77 | 78 | return text; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/kc_electron/src/test/autoscan.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/src/test/browser.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/src/test/chat.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/src/test/ipc.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/webpack.common.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const path = require("path"); 18 | 19 | let webpack_config = { 20 | entry: { 21 | main: path.join(__dirname, "src", "main.ts"), 22 | preload: path.join(__dirname, "src", "preload.js"), 23 | }, 24 | target: "electron-main", // Webpack knows about the electron main process specifically 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.ts$/, // This particular rule matches all .ts files 29 | use: [{ loader: "ts-loader" }], // Which loader to use when the rule matches 30 | }, 31 | { 32 | test: /\.node$/, 33 | loader: "node-loader", 34 | }, 35 | ], 36 | }, 37 | output: { 38 | path: path.join(process.cwd(), "dist"), // all output files are placed here 39 | filename: "[name].js", // Primary output bundle 40 | }, 41 | externals: { 42 | // NOTE: this had to be added after manually installing Chokidar 3.5 43 | // NOTE: https://github.com/yan-foto/electron-reload/issues/71 44 | fsevents: "require('fsevents')", 45 | express: "require('express')", 46 | }, 47 | resolve: { 48 | extensions: [".ts", ".js", ".json"], 49 | }, 50 | plugins: [], 51 | }; 52 | 53 | module.exports = webpack_config; 54 | -------------------------------------------------------------------------------- /src/kc_electron/webpack.dev.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // This file was generated following the guide provided at 18 | // https://www.sitepen.com/blog/getting-started-with-electron-typescript-react-and-webpack 19 | const { merge } = require("webpack-merge"); 20 | const common = require("./webpack.common"); 21 | 22 | module.exports = merge(common, { 23 | mode: "development", 24 | }); 25 | -------------------------------------------------------------------------------- /src/kc_electron/webpack.prod.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // This file was generated following the guide provided at 18 | // https://www.sitepen.com/blog/getting-started-with-electron-typescript-react-and-webpack 19 | const { merge } = require("webpack-merge"); 20 | const common = require("./webpack.common"); 21 | 22 | module.exports = merge(common, { 23 | mode: "production", 24 | }); 25 | -------------------------------------------------------------------------------- /src/kc_shared/models/author.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {UuidModel} from "./uuid.model"; 17 | 18 | export interface AuthorModel { 19 | firstName: string; 20 | lastName: string; 21 | id: UuidModel; 22 | } 23 | -------------------------------------------------------------------------------- /src/kc_shared/models/browser.view.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | export interface BrowserViewHeaderConfig { 17 | showOpenButton?: boolean; 18 | canClose?: boolean; 19 | canCopy?: boolean; 20 | canGoBack?: boolean; 21 | canGoForward?: boolean; 22 | canRefresh?: boolean; 23 | canSave?: boolean; 24 | displayText?: string; 25 | displayTextReadOnly?: boolean; 26 | backgroundColor?: string; 27 | showSaveButton?: boolean; 28 | showNavButtons?: boolean; 29 | showActionButtons?: boolean; 30 | showDisplayText?: boolean; 31 | showCloseButton?: boolean; 32 | showInvertButton?: boolean; 33 | } 34 | 35 | export interface BrowserViewHeaderEvent { 36 | backClicked?: boolean; 37 | forwardClicked?: boolean; 38 | refreshClicked?: boolean; 39 | closeClicked?: boolean; 40 | copyClicked?: boolean; 41 | saveClicked?: boolean; 42 | openClicked?: boolean; 43 | invertClicked?: boolean; 44 | } 45 | 46 | export interface FileViewConfig { 47 | filePath: string; 48 | isDialog?: true; 49 | } 50 | 51 | export type FileViewClickEvent = BrowserViewHeaderEvent; 52 | 53 | export interface BrowserViewConfig { 54 | url: URL; 55 | isDialog?: boolean; 56 | canSave?: boolean; 57 | } 58 | 59 | export interface BrowserViewNavEvent { 60 | urlChanged?: true; 61 | url?: URL; 62 | } 63 | 64 | export type BrowserViewClickEvent = BrowserViewHeaderEvent; 65 | -------------------------------------------------------------------------------- /src/kc_shared/models/chat.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Used for user settings and for the back-end chat controller. 19 | */ 20 | export interface ChatModel { 21 | /* The name of the model to use for the API call (see OpenAI API) */ 22 | name: "gpt-3.5-turbo" | "gpt-4"; 23 | 24 | /* The name of the model to display to the user */ 25 | label: string; 26 | 27 | /* A description of the model to display to the user */ 28 | description: string; 29 | 30 | /* A hard limit based on the given model */ 31 | token_limit: number; 32 | 33 | /* The cost per 1000 tokens for input to the API */ 34 | input_kilo_cost: number; 35 | 36 | /* The cost per 1000 tokens for output from the API */ 37 | output_kilo_cost: number; 38 | 39 | /* See OpenAI API Documentation */ 40 | temperature: number; 41 | 42 | /* See OpenAI API Documentation */ 43 | top_p: number; 44 | 45 | /* See OpenAI API Documentation */ 46 | max_tokens: number; 47 | 48 | /* See OpenAI API Documentation */ 49 | presence_penalty: number; 50 | 51 | /* See OpenAI API Documentation */ 52 | frequency_penalty: number; 53 | 54 | /* The upper bound on output tokens (used for UI slider) */ 55 | max_tokens_upper_bound: number; 56 | } 57 | 58 | const OpenAIDefaults = { 59 | temperature: 0.5, 60 | top_p: 1, 61 | presence_penalty: 0, 62 | frequency_penalty: 0, 63 | }; 64 | 65 | const GPT3p5Turbo: ChatModel = { 66 | name: "gpt-3.5-turbo", 67 | label: "GPT-3.5 Turbo", 68 | description: "GPT-3.5 Turbo is optimized for dialogue.", 69 | token_limit: 4096, 70 | input_kilo_cost: 0.0015, 71 | output_kilo_cost: 0.002, 72 | max_tokens_upper_bound: 2048, 73 | max_tokens: 512, // Default 74 | ...OpenAIDefaults, 75 | }; 76 | 77 | /*TODO: not available in tiktoken yet 78 | const GPT3p5Turbo16k: ChatModel = { 79 | name: "gpt-3.5-turbo-16k", 80 | label: "GPT-3.5 Turbo 16k", 81 | description: 82 | "GPT-3.5 Turbo is optimized for dialogue. This model has a larger token limit than GPT-3.5 Turbo, so you can enter more text at once.", 83 | tokenLimit: 16384, 84 | inputCostPer1k: 0.003, 85 | outputCostPer1k: 0.004, 86 | };*/ 87 | 88 | const GPT4: ChatModel = { 89 | name: "gpt-4", 90 | label: "GPT-4", 91 | description: 92 | "GPT-4 can follow complex instructions in natural language and solve difficult problems with accuracy.", 93 | token_limit: 8192, 94 | input_kilo_cost: 0.03, 95 | output_kilo_cost: 0.06, 96 | max_tokens_upper_bound: 4096, 97 | max_tokens: 1024, 98 | ...OpenAIDefaults, 99 | }; 100 | 101 | export const SupportedChatModels: ChatModel[] = [GPT3p5Turbo, GPT4]; 102 | -------------------------------------------------------------------------------- /src/kc_shared/models/event.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export type EventType = 18 | | "create" 19 | | "read" 20 | | "update" 21 | | "delete" 22 | | "reminder" 23 | | "checkPoint" 24 | | "dueDate"; 25 | 26 | export interface EventModel { 27 | timestamp: string; 28 | type: EventType; 29 | description?: string; 30 | icon?: string; 31 | } 32 | 33 | export interface ProjectCalendar { 34 | events: EventModel[]; 35 | end: Date | string | null; 36 | start: Date | string | null; 37 | } 38 | -------------------------------------------------------------------------------- /src/kc_shared/models/file.source.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { UuidModel } from "./uuid.model"; 17 | 18 | export interface FileSourceModel { 19 | filename: string; 20 | size: number; 21 | path: string; 22 | id: UuidModel; 23 | type: string; 24 | accessTime: string; 25 | modificationTime: string; 26 | creationTime: string; 27 | pages?: number; 28 | words?: number; 29 | } 30 | 31 | export interface FileWatcherUpdate { 32 | id: string; 33 | method: "add" | "remove" | "delay"; 34 | } 35 | 36 | export interface PendingFileTransfer { 37 | id: string; 38 | filename: string; 39 | oldPath: string; 40 | newPath: string; 41 | } 42 | -------------------------------------------------------------------------------- /src/kc_shared/models/graph.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | export interface ProjectGraphNode { 17 | name: string; 18 | id: string; 19 | type: string; 20 | expanded: boolean; 21 | subprojects: ProjectGraphNode[]; 22 | } 23 | 24 | export interface SourceGraphNode { 25 | name: string; 26 | id: string; 27 | icon: string; 28 | } 29 | -------------------------------------------------------------------------------- /src/kc_shared/models/hashable.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | export interface Hashable { 18 | hash: string 19 | } 20 | -------------------------------------------------------------------------------- /src/kc_shared/models/knowledge.source.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { WebSourceModel } from "./web.source.model"; 17 | import { FileSourceModel } from "./file.source.model"; 18 | import { UuidModel } from "./uuid.model"; 19 | import { EventModel } from "./event.model"; 20 | 21 | export interface KnowledgeSourceModel { 22 | title: string; 23 | id: UuidModel; 24 | type: "file" | "web"; 25 | source: FileSourceModel | WebSourceModel; 26 | associatedProjects?: UuidModel[]; 27 | events?: EventModel[]; 28 | icon?: UuidModel; 29 | thumbnail?: UuidModel; 30 | markup?: UuidModel[]; 31 | topics?: UuidModel[]; 32 | authors?: UuidModel[]; 33 | flagged: boolean; 34 | } 35 | 36 | export type KnowledgeSource = KnowledgeSourceModel; 37 | 38 | export interface KnowledgeSourceImage { 39 | id: UuidModel; 40 | data: string; 41 | } 42 | 43 | export interface KnowledgeSourceIcon extends KnowledgeSourceImage { 44 | link?: string; 45 | } 46 | 47 | export interface KnowledgeSourceThumbnail extends KnowledgeSourceImage { 48 | height: number; 49 | width: number; 50 | link?: string; 51 | } 52 | 53 | export interface KnowledgeSourceIngestTask { 54 | method: ImportMethod; 55 | callback: (method: "add" | "remove" | "delay") => void; 56 | id: string; 57 | } 58 | 59 | export type ImportMethod = 60 | | "autoscan" 61 | | "dnd" 62 | | "extension" 63 | | "manual" 64 | | "example" 65 | | "recommend"; 66 | -------------------------------------------------------------------------------- /src/kc_shared/models/markup.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {EventModel} from "./event.model"; 17 | 18 | export type MarkupType = 'note' | 'highlight' | 'underline' | 'sticker'; 19 | 20 | export interface KnowledgeSourceMarkup { 21 | type: MarkupType 22 | event: EventModel 23 | } 24 | 25 | export interface MarkupColor { 26 | color: string 27 | } 28 | 29 | export interface MarkupFont { 30 | weight: number 31 | } 32 | 33 | export interface MarkupData { 34 | data: string 35 | } 36 | 37 | export interface MarkupNote extends KnowledgeSourceMarkup { 38 | title?: string 39 | body: string 40 | } 41 | 42 | export interface MarkupSticker extends KnowledgeSourceMarkup, MarkupData { 43 | link?: string 44 | } 45 | 46 | export interface MarkupUnderline extends KnowledgeSourceMarkup, MarkupColor, MarkupFont, Partial { 47 | } 48 | 49 | export interface MarkupHighlight extends KnowledgeSourceMarkup, MarkupColor, MarkupFont, Partial { 50 | opacity: number 51 | } 52 | 53 | export interface FileSourceMarkup extends KnowledgeSourceMarkup { 54 | pos?: { x: Number, y: Number, width: Number, height: Number } 55 | } 56 | 57 | export interface WebSourceMarkup { 58 | notes?: MarkupNote[] 59 | highlights?: MarkupHighlight[] 60 | stickers?: MarkupSticker[] 61 | } 62 | -------------------------------------------------------------------------------- /src/kc_shared/models/project.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {KnowledgeSource} from "kc_angular/src/app/models/knowledge.source.model"; 17 | import {UUID} from "./uuid.model"; 18 | import {EventModel} from "./event.model"; 19 | 20 | export type KcProjectType = 'default' | 'school' | 'work' | 'hobby' | 'research'; 21 | 22 | export interface KcProjectModel { 23 | readonly id: UUID; 24 | name: string; 25 | type: KcProjectType; 26 | description: string; 27 | events?: EventModel[]; 28 | authors: string[]; 29 | parentId: UUID; 30 | subprojects: string[]; 31 | topics: string[]; 32 | sources: UUID[]; 33 | 34 | // TODO: this needs to be removed 35 | knowledgeSource: KnowledgeSource[]; 36 | } 37 | -------------------------------------------------------------------------------- /src/kc_shared/models/style.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | export class KcTheme { 18 | name: string = 'Lara Light Indigo'; 19 | code: string = 'lara-light-indigo'; 20 | isDark: boolean = false; 21 | isDual: boolean = true; 22 | items?: KcTheme[] 23 | } 24 | -------------------------------------------------------------------------------- /src/kc_shared/models/topic.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {UuidModel} from "./uuid.model"; 17 | 18 | export interface TopicModel { 19 | id: UuidModel 20 | label: string 21 | } 22 | -------------------------------------------------------------------------------- /src/kc_shared/models/uuid.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | export type UuidModel = { 18 | value: string 19 | } 20 | 21 | export interface UUID extends UuidModel {} 22 | -------------------------------------------------------------------------------- /src/kc_shared/models/web.source.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {WebSourceMarkup} from "./markup.model"; 17 | 18 | export interface WebSourceModel { 19 | accessLink: string, 20 | iconUrl?: string, 21 | topics?: string[], 22 | metadata?: WebsiteMetadataModel, 23 | markup?: WebSourceMarkup, 24 | flagged?: boolean, 25 | rawText?: string, 26 | thumbnail?: string, 27 | title?: string, 28 | description?: string 29 | } 30 | 31 | export interface WebsiteMetadataModel { 32 | title?: string, 33 | meta?: WebsiteMetaTagsModel[], 34 | icon?: any, 35 | article?: ArticleModel, 36 | code?: CodeModel[], 37 | links?: string[] 38 | } 39 | 40 | export interface WebsiteMetaTagsModel { 41 | key?: string | null, 42 | value?: string | null, 43 | property?: string | null 44 | } 45 | 46 | export interface WebsiteContentModel { 47 | title?: string, 48 | type?: string, 49 | text?: string, 50 | html?: string 51 | } 52 | 53 | export interface ArticleModel extends WebsiteContentModel { 54 | 55 | } 56 | 57 | export interface CodeModel extends WebsiteContentModel { 58 | 59 | } 60 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "strict": true, 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "strictTemplates": true, 11 | "forceConsistentCasingInFileNames": true 12 | }, 13 | "angularCompilerOptions": { 14 | "strictTemplates": true 15 | }, 16 | "$schema": "https://json.schemastore.org/tsconfig", 17 | "display": "Recommended" 18 | } 19 | --------------------------------------------------------------------------------