diff --git a/.VirtualBox/VirtualBox.xml b/.VirtualBox/VirtualBox.xml
new file mode 100644
index 00000000..26a1da9e
--- /dev/null
+++ b/.VirtualBox/VirtualBox.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.bashrc b/.bashrc
index 72c01c3b..0a8f01be 100644
--- a/.bashrc
+++ b/.bashrc
@@ -94,4 +94,3 @@ if [ "$BASH_SUPPORT" = 'true' ]; then
complete -C vault vault
fi
fi
-
diff --git a/.config/Code/User/extensions.json b/.config/Code/User/extensions.json
new file mode 100644
index 00000000..578d0f17
--- /dev/null
+++ b/.config/Code/User/extensions.json
@@ -0,0 +1,43 @@
+{
+ "recommendations": [
+ "chrmarti.regex",
+ "DavidAnson.vscode-markdownlint",
+ "dbaeumer.vscode-eslint",
+ "eamodio.gitlens",
+ "EditorConfig.EditorConfig",
+ "esbenp.prettier-vscode",
+ "ericadamski.carbon-now-sh",
+ "formulahendry.code-runner",
+ "GitHub.vscode-pull-request-github",
+ "GitLab.gitlab-workflow",
+ "GoogleCloudTools.cloudcode",
+ "HashiCorp.terraform",
+ "hediet.vscode-drawio",
+ "IBM.output-colorizer",
+ "Kelvin.vscode-sshfs",
+ "mads-hartmann.bash-ide-vscode",
+ "ms-azuretools.vscode-docker",
+ "ms-kubernetes-tools.vscode-kubernetes-tools",
+ "ms-vscode-remote.remote-containers",
+ "ms-vscode-remote.remote-ssh",
+ "ms-vscode-remote.remote-wsl",
+ "ms-vscode.PowerShell",
+ "MS-vsliveshare.vsliveshare",
+ "MS-vsliveshare.vsliveshare-audio",
+ "philnash.ngrok-for-vscode",
+ "PKief.material-icon-theme",
+ "redhat.ansible",
+ "redhat.vscode-yaml",
+ "richie5um2.vscode-sort-json",
+ "Rubymaniac.vscode-paste-and-indent",
+ "shd101wyy.markdown-preview-enhanced",
+ "softwaredotcom.swdc-vscode",
+ "timonwong.shellcheck",
+ "tyriar.sort-lines",
+ "usernamehw.errorlens",
+ "valentjn.vscode-ltex",
+ "vsls-contrib.codetour",
+ "vsls-contrib.gistfs",
+ "wayou.vscode-todo-highlight"
+ ]
+}
diff --git a/.config/Code/User/extensions/theme-betelgeuse-vscode/README.md b/.config/Code/User/extensions/theme-betelgeuse-vscode/README.md
new file mode 100644
index 00000000..7691b94d
--- /dev/null
+++ b/.config/Code/User/extensions/theme-betelgeuse-vscode/README.md
@@ -0,0 +1 @@
+The Betelgeuse VS Code theme created using [themer.dev](https://themer.dev).
diff --git a/.config/Code/User/extensions/theme-betelgeuse-vscode/icon.svg b/.config/Code/User/extensions/theme-betelgeuse-vscode/icon.svg
new file mode 100644
index 00000000..2994a04c
--- /dev/null
+++ b/.config/Code/User/extensions/theme-betelgeuse-vscode/icon.svg
@@ -0,0 +1,48 @@
+
+
+
\ No newline at end of file
diff --git a/.config/Code/User/extensions/theme-betelgeuse-vscode/package.json b/.config/Code/User/extensions/theme-betelgeuse-vscode/package.json
new file mode 100644
index 00000000..1807045a
--- /dev/null
+++ b/.config/Code/User/extensions/theme-betelgeuse-vscode/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "betelgeuse-vscode",
+ "displayName": "Betelgeuse VS Code Theme",
+ "description": "Betelgeuse theme generated by Themer.dev",
+ "version": "2.4.0",
+ "publisher": "Megabyte Labs",
+ "engines": {
+ "vscode": "^1.14.0"
+ },
+ "categories": [
+ "Themes"
+ ],
+ "icon": "icon.svg",
+ "contributes": {
+ "themes": [
+ {
+ "label": "Betelgeuse Dark",
+ "uiTheme": "vs-dark",
+ "path": "themes/themer-dark-color-theme.json"
+ },
+ {
+ "label": "Betelgeuse Light",
+ "uiTheme": "vs",
+ "path": "themes/themer-light-color-theme.json"
+ }
+ ]
+ }
+}
diff --git a/.config/Code/User/extensions/theme-betelgeuse-vscode/themes/themer-dark-color-theme.json b/.config/Code/User/extensions/theme-betelgeuse-vscode/themes/themer-dark-color-theme.json
new file mode 100644
index 00000000..3792f2d2
--- /dev/null
+++ b/.config/Code/User/extensions/theme-betelgeuse-vscode/themes/themer-dark-color-theme.json
@@ -0,0 +1,614 @@
+{
+ "name": "Betelgeuse Dark",
+ "type": "dark",
+ "colors": {
+ "focusBorder": "#c3c7d1",
+ "foreground": "#c3c7d1",
+ "widget.shadow": "#161925",
+ "selection.background": "#474b56",
+ "descriptionForeground": "#aaaeb8",
+ "errorForeground": "#ed254e",
+ "icon.foreground": "#aaaeb8",
+ "sash.hoverBorder": "#7cb7ff",
+ "textBlockQuote.background": "#2f323e",
+ "textBlockQuote.border": "#2f323e",
+ "textCodeBlock.background": "#161925",
+ "textLink.activeForeground": "#00c1e4",
+ "textLink.foreground": "#7cb7ff",
+ "textPreformat.foreground": "#dcdfe4",
+ "textSeparator.foreground": "#797c87",
+ "button.background": "#7cb7ff",
+ "button.foreground": "#161925",
+ "button.hoverBackground": "#00c1e4",
+ "button.secondaryForeground": "#161925",
+ "button.secondaryBackground": "#aaaeb8",
+ "button.secondaryHoverBackground": "#9295a0",
+ "checkbox.background": "#7cb7ff",
+ "checkbox.foreground": "#161925",
+ "checkbox.border": "#2f323e",
+ "dropdown.background": "#2f323e",
+ "dropdown.listBackground": "#2f323e",
+ "dropdown.border": "#2f323e",
+ "dropdown.foreground": "#aaaeb8",
+ "input.background": "#2f323e",
+ "input.border": "#2f323e",
+ "input.foreground": "#aaaeb8",
+ "input.placeholderForeground": "#474b56",
+ "inputOption.activeBackground": "#474b56",
+ "inputOption.activeBorder": "#00c1e4",
+ "inputOption.activeForeground": "#c3c7d1",
+ "inputValidation.errorBackground": "#2f323e",
+ "inputValidation.errorForeground": "#ed254e",
+ "inputValidation.errorBorder": "#ed254e",
+ "inputValidation.infoBackground": "#2f323e",
+ "inputValidation.infoForeground": "#7cb7ff",
+ "inputValidation.infoBorder": "#7cb7ff",
+ "inputValidation.warningBackground": "#2f323e",
+ "inputValidation.warningForeground": "#dcdfe4",
+ "inputValidation.warningBorder": "#dcdfe4",
+ "scrollbar.shadow": "#161925",
+ "scrollbarSlider.activeBackground": "#9295a07f",
+ "scrollbarSlider.background": "#60646f7f",
+ "scrollbarSlider.hoverBackground": "#797c877f",
+ "badge.foreground": "#161925",
+ "badge.background": "#c3c7d1",
+ "progressBar.background": "#71f79f",
+ "list.activeSelectionBackground": "#c3c7d133",
+ "list.activeSelectionForeground": "#c3c7d1",
+ "list.dropBackground": "#2f323e",
+ "list.focusBackground": "#60646f3f",
+ "list.focusForeground": "#c3c7d1",
+ "list.highlightForeground": "#f9dc5c",
+ "list.hoverBackground": "#2f323e33",
+ "list.hoverForeground": "#c3c7d1",
+ "list.inactiveSelectionBackground": "#474b563f",
+ "list.inactiveSelectionForeground": "#aaaeb8",
+ "list.inactiveFocusBackground": "#2f323e3f",
+ "list.invalidItemForeground": "#ed254e",
+ "list.errorForeground": "#ed254e",
+ "list.warningForeground": "#f9dc5c",
+ "listFilterWidget.background": "#2f323e",
+ "listFilterWidget.outline": "#7cb7ff",
+ "listFilterWidget.noMatchesOutline": "#ed254e",
+ "list.filterMatchBackground": "#f9dc5c33",
+ "list.filterMatchBorder": "#f9dc5c33",
+ "tree.indentGuidesStroke": "#2f323e",
+ "list.deemphasizedForeground": "#797c87",
+ "activityBar.background": "#161925",
+ "activityBar.dropBorder": "#7cb7ff",
+ "activityBar.foreground": "#9295a0",
+ "activityBar.inactiveForeground": "#797c87",
+ "activityBar.border": "#161925",
+ "activityBarBadge.background": "#c3c7d1",
+ "activityBarBadge.foreground": "#161925",
+ "activityBar.activeBorder": "#aaaeb8",
+ "activityBar.activeBackground": "#2f323e33",
+ "activityBar.activeFocusBorder": "#c3c7d1",
+ "sideBar.background": "#161925",
+ "sideBar.foreground": "#aaaeb8",
+ "sideBar.border": "#2f323e",
+ "sideBar.dropBackground": "#2f323e3f",
+ "sideBarTitle.foreground": "#9295a0",
+ "sideBarSectionHeader.background": "#474b56",
+ "sideBarSectionHeader.foreground": "#aaaeb8",
+ "sideBarSectionHeader.border": "#161925",
+ "minimap.findMatchHighlight": "#f9dc5c",
+ "minimap.selectionHighlight": "#7cb7ff80",
+ "minimap.errorHighlight": "#ed254e80",
+ "minimap.warningHighlight": "#dcdfe480",
+ "minimap.background": "#161925",
+ "minimapSlider.background": "#2f323e33",
+ "minimapSlider.hoverBackground": "#474b5633",
+ "minimapSlider.activeBackground": "#60646f33",
+ "minimapGutter.addedBackground": "#71f79f80",
+ "minimapGutter.modifiedBackground": "#f9dc5c80",
+ "minimapGutter.deletedBackground": "#ed254e80",
+ "editorGroup.border": "#2f323e",
+ "editorGroup.dropBackground": "#474b567f",
+ "editorGroupHeader.noTabsBackground": "#161925",
+ "editorGroupHeader.tabsBackground": "#161925",
+ "editorGroupHeader.tabsBorder": "#161925",
+ "editorGroupHeader.border": "#161925",
+ "editorGroup.emptyBackground": "#161925",
+ "editorGroup.focusedEmptyBorder": "#2f323e",
+ "tab.activeBackground": "#161925",
+ "tab.unfocusedActiveBackground": "#161925",
+ "tab.activeForeground": "#aaaeb8",
+ "tab.border": "#161925",
+ "tab.lastPinnedBorder": "#c74d89",
+ "tab.inactiveBackground": "#2f323e",
+ "tab.unfocusedInactiveBackground": "#2f323e",
+ "tab.inactiveForeground": "#60646f",
+ "tab.unfocusedActiveForeground": "#60646f",
+ "tab.unfocusedInactiveForeground": "#474b56",
+ "tab.hoverBackground": "#2f323e80",
+ "tab.unfocusedHoverBackground": "#2f323e80",
+ "tab.hoverForeground": "#9295a0",
+ "tab.unfocusedHoverForeground": "#797c87",
+ "tab.activeModifiedBorder": "#f9dc5c",
+ "tab.inactiveModifiedBorder": "#f9dc5c",
+ "tab.unfocusedActiveModifiedBorder": "#f9dc5c",
+ "tab.unfocusedInactiveModifiedBorder": "#f9dc5c",
+ "editorPane.background": "#161925",
+ "editor.background": "#161925",
+ "editor.foreground": "#c3c7d1",
+ "editorLineNumber.foreground": "#474b56",
+ "editorLineNumber.activeForeground": "#797c87",
+ "editorCursor.background": "#161925",
+ "editorCursor.foreground": "#c3c7d1",
+ "editor.selectionBackground": "#7cb7ff33",
+ "editor.selectionForeground": "#c3c7d1",
+ "editor.inactiveSelectionBackground": "#7cb7ff33",
+ "editor.selectionHighlightBackground": "#2f323e",
+ "editor.wordHighlightBackground": "#c3c7d133",
+ "editor.wordHighlightStrongBackground": "#c74d8933",
+ "editor.findMatchBackground": "#f9dc5c3f",
+ "editor.findMatchHighlightBackground": "#f9dc5c33",
+ "editor.findRangeHighlightBackground": "#2f323e",
+ "editor.hoverHighlightBackground": "#474b567f",
+ "editor.lineHighlightBackground": "#161925",
+ "editor.lineHighlightBorder": "#2f323e",
+ "editorLink.activeForeground": "#00c1e4",
+ "editor.rangeHighlightBackground": "#f9dc5c33",
+ "editor.symbolHighlightBackground": "#c3c7d133",
+ "editorWhitespace.foreground": "#2f323e",
+ "editorIndentGuide.background": "#2f323e",
+ "editorIndentGuide.activeBackground": "#474b56",
+ "editorRuler.foreground": "#2f323e",
+ "editorCodeLens.foreground": "#9295a0",
+ "editorLightBulb.foreground": "#f9dc5c",
+ "editorLightBulbAutoFix.foreground": "#7cb7ff",
+ "editorBracketMatch.background": "#2f323e",
+ "editorBracketMatch.border": "#474b56",
+ "editorBracketHighlight.foreground1": "#c3c7d1",
+ "editorBracketHighlight.foreground2": "#f9dc5c",
+ "editorBracketHighlight.foreground3": "#00c1e4",
+ "editorBracketHighlight.foreground4": "#c3c7d1",
+ "editorBracketHighlight.foreground5": "#71f79f",
+ "editorBracketHighlight.foreground6": "#7cb7ff",
+ "editorBracketHighlight.unexpectedBracket": "#ed254e",
+ "editor.foldBackground": "#2f323e66",
+ "editorOverviewRuler.border": "#2f323e",
+ "editorOverviewRuler.findMatchForeground": "#f9dc5cbf",
+ "editorOverviewRuler.rangeHighlightForeground": "#474b56bf",
+ "editorOverviewRuler.selectionHighlightForeground": "#2f323ebf",
+ "editorOverviewRuler.wordHighlightForeground": "#474b56bf",
+ "editorOverviewRuler.wordHighlightStrongForeground": "#60646fbf",
+ "editorOverviewRuler.modifiedForeground": "#f9dc5c7f",
+ "editorOverviewRuler.addedForeground": "#71f79f7f",
+ "editorOverviewRuler.deletedForeground": "#ed254e7f",
+ "editorOverviewRuler.errorForeground": "#ed254e7f",
+ "editorOverviewRuler.warningForeground": "#dcdfe47f",
+ "editorOverviewRuler.infoForeground": "#7cb7ff7f",
+ "editorOverviewRuler.bracketMatchForeground": "#60646f",
+ "editorError.foreground": "#ed254e",
+ "editorError.border": "#c3c7d1",
+ "editorWarning.foreground": "#dcdfe4",
+ "editorWarning.border": "#aaaeb8",
+ "editorInfo.foreground": "#7cb7ff",
+ "editorInfo.border": "#9295a0",
+ "editorHint.foreground": "#c74d89",
+ "editorHint.border": "#797c87",
+ "problemsErrorIcon.foreground": "#ed254e",
+ "problemsWarningIcon.foreground": "#dcdfe4",
+ "problemsInfoIcon.foreground": "#7cb7ff",
+ "editorUnnecessaryCode.opacity": "#0000007f",
+ "editorGutter.background": "#161925",
+ "editorGutter.modifiedBackground": "#f9dc5c",
+ "editorGutter.addedBackground": "#71f79f",
+ "editorGutter.deletedBackground": "#ed254e",
+ "editorGutter.commentRangeForeground": "#60646f",
+ "editorGutter.foldingControlForeground": "#9295a0",
+ "diffEditor.insertedTextBackground": "#71f79f20",
+ "diffEditor.removedTextBackground": "#ed254e20",
+ "diffEditor.border": "#2f323e",
+ "diffEditor.diagonalFill": "#2f323e7f",
+ "editorWidget.foreground": "#aaaeb8",
+ "editorWidget.background": "#2f323e",
+ "editorWidget.border": "#2f323e",
+ "editorWidget.resizeBorder": "#7cb7ff",
+ "editorSuggestWidget.background": "#2f323e",
+ "editorSuggestWidget.border": "#2f323e",
+ "editorSuggestWidget.foreground": "#aaaeb8",
+ "editorSuggestWidget.highlightForeground": "#c74d89",
+ "editorSuggestWidget.selectedBackground": "#474b56",
+ "editorHoverWidget.foreground": "#aaaeb8",
+ "editorHoverWidget.background": "#2f323e",
+ "editorHoverWidget.border": "#2f323e",
+ "editorHoverWidget.statusBarBackground": "#7cb7ff33",
+ "debugExceptionWidget.background": "#2f323e",
+ "debugExceptionWidget.border": "#2f323e",
+ "editorMarkerNavigation.background": "#2f323e",
+ "editorMarkerNavigationError.background": "#ed254e",
+ "editorMarkerNavigationWarning.background": "#dcdfe4",
+ "editorMarkerNavigationInfo.background": "#7cb7ff",
+ "peekView.border": "#c74d89",
+ "peekViewEditor.background": "#2f323e7f",
+ "peekViewEditorGutter.background": "#2f323e7f",
+ "peekViewEditor.matchHighlightBackground": "#f9dc5c7f",
+ "peekViewResult.background": "#2f323e",
+ "peekViewResult.fileForeground": "#aaaeb8",
+ "peekViewResult.lineForeground": "#474b56",
+ "peekViewResult.matchHighlightBackground": "#f9dc5c",
+ "peekViewResult.selectionBackground": "#60646f",
+ "peekViewResult.selectionForeground": "#c3c7d1",
+ "peekViewTitle.background": "#2f323e",
+ "peekViewTitleDescription.foreground": "#9295a0",
+ "peekViewTitleLabel.foreground": "#c3c7d1",
+ "merge.currentHeaderBackground": "#00c1e44c",
+ "merge.currentContentBackground": "#00c1e44c",
+ "merge.incomingHeaderBackground": "#7cb7ff4c",
+ "merge.incomingContentBackground": "#7cb7ff4c",
+ "merge.border": "#797c87",
+ "merge.commonContentBackground": "#c3c7d14c",
+ "merge.commonHeaderBackground": "#c3c7d14c",
+ "editorOverviewRuler.currentContentForeground": "#00c1e4",
+ "editorOverviewRuler.incomingContentForeground": "#7cb7ff",
+ "editorOverviewRuler.commonContentForeground": "#c3c7d1",
+ "panel.background": "#161925",
+ "panel.border": "#2f323e",
+ "panel.dropBorder": "#7cb7ff",
+ "panelTitle.activeBorder": "#60646f",
+ "panelTitle.activeForeground": "#aaaeb8",
+ "panelTitle.inactiveForeground": "#797c87",
+ "panelSection.border": "#2f323e",
+ "panelSection.dropBackground": "#2f323e3f",
+ "panelSectionHeader.background": "#474b56",
+ "panelSectionHeader.foreground": "#aaaeb8",
+ "panelSectionHeader.border": "#161925",
+ "imagePreview.border": "#2f323e",
+ "statusBar.background": "#7cb7ff",
+ "statusBar.foreground": "#161925",
+ "statusBar.border": "#161925",
+ "statusBar.debuggingBackground": "#dcdfe4",
+ "statusBar.debuggingForeground": "#161925",
+ "statusBar.debuggingBorder": "#161925",
+ "statusBar.noFolderBackground": "#c3c7d1",
+ "statusBar.noFolderForeground": "#161925",
+ "statusBar.noFolderBorder": "#161925",
+ "statusBarItem.activeBackground": "#00c1e4",
+ "statusBarItem.hoverBackground": "#71f79f",
+ "statusBarItem.prominentBackground": "#00c1e4",
+ "statusBarItem.prominentHoverBackground": "#71f79f",
+ "statusBarItem.remoteBackground": "#00c1e4",
+ "statusBarItem.remoteForeground": "#161925",
+ "statusBarItem.errorBackground": "#ed254e",
+ "statusBarItem.errorForeground": "#161925",
+ "titleBar.activeBackground": "#161925",
+ "titleBar.activeForeground": "#9295a0",
+ "titleBar.inactiveBackground": "#161925",
+ "titleBar.inactiveForeground": "#60646f",
+ "menubar.selectionForeground": "#c3c7d1",
+ "menubar.selectionBackground": "#2f323e",
+ "menu.foreground": "#aaaeb8",
+ "menu.background": "#161925",
+ "menu.selectionForeground": "#c3c7d1",
+ "menu.selectionBackground": "#2f323e",
+ "menu.separatorBackground": "#474b56",
+ "notificationCenterHeader.foreground": "#aaaeb8",
+ "notificationCenterHeader.background": "#474b56",
+ "notificationToast.border": "#60646f",
+ "notifications.foreground": "#c3c7d1",
+ "notifications.background": "#2f323e",
+ "notifications.border": "#60646f",
+ "notificationLink.foreground": "#7cb7ff",
+ "notificationsErrorIcon.foreground": "#ed254e",
+ "notificationsWarningIcon.foreground": "#dcdfe4",
+ "notificationsInfoIcon.foreground": "#7cb7ff",
+ "extensionButton.prominentForeground": "#161925",
+ "extensionButton.prominentBackground": "#7cb7ff",
+ "extensionButton.prominentHoverBackground": "#00c1e4",
+ "extensionBadge.remoteBackground": "#c74d89",
+ "extensionBadge.remoteForeground": "#161925",
+ "pickerGroup.border": "#474b56",
+ "pickerGroup.foreground": "#797c87",
+ "quickInput.background": "#2f323e",
+ "quickInput.foreground": "#c3c7d1",
+ "quickInputTitle.background": "#474b56",
+ "terminal.background": "#161925",
+ "terminal.foreground": "#aaaeb8",
+ "terminal.ansiBlack": "#161925",
+ "terminal.ansiBlue": "#7cb7ff",
+ "terminal.ansiBrightBlack": "#2f323e",
+ "terminal.ansiBrightBlue": "#7cb7ff",
+ "terminal.ansiBrightCyan": "#00c1e4",
+ "terminal.ansiBrightGreen": "#00c1e4",
+ "terminal.ansiBrightMagenta": "#c74d89",
+ "terminal.ansiBrightRed": "#dcdfe4",
+ "terminal.ansiBrightWhite": "#c3c7d1",
+ "terminal.ansiBrightYellow": "#f9dc5c",
+ "terminal.ansiCyan": "#00c1e4",
+ "terminal.ansiGreen": "#71f79f",
+ "terminal.ansiMagenta": "#c74d89",
+ "terminal.ansiRed": "#ed254e",
+ "terminal.ansiWhite": "#aaaeb8",
+ "terminal.ansiYellow": "#f9dc5c",
+ "terminal.selectionBackground": "#7cb7ff7f",
+ "terminalCursor.background": "#2f323e",
+ "terminalCursor.foreground": "#9295a0",
+ "debugToolBar.background": "#2f323e",
+ "debugToolBar.border": "#474b56",
+ "editor.stackFrameHighlightBackground": "#00c1e43f",
+ "editor.focusedStackFrameHighlightBackground": "#71f79f3f",
+ "debugView.exceptionLabelForeground": "#f9dc5c",
+ "debugView.exceptionLabelBackground": "#2f323e",
+ "debugView.stateLabelForeground": "#7cb7ff",
+ "debugView.stateLabelBackground": "#2f323e",
+ "debugView.valueChangedHighlight": "#f9dc5c33",
+ "debugTokenExpression.name": "#7cb7ff",
+ "debugTokenExpression.value": "#c3c7d1",
+ "debugTokenExpression.string": "#71f79f",
+ "debugTokenExpression.boolean": "#c3c7d1",
+ "debugTokenExpression.number": "#c74d89",
+ "debugTokenExpression.error": "#ed254e",
+ "testing.iconFailed": "#dcdfe4",
+ "testing.iconErrored": "#ed254e",
+ "testing.iconPassed": "#71f79f",
+ "testing.runAction": "#7cb7ff",
+ "testing.iconQueued": "#00c1e4",
+ "testing.iconUnset": "#9295a0",
+ "testing.iconSkipped": "#797c87",
+ "testing.peekBorder": "#60646f",
+ "testing.message.error.decorationForeground": "#ed254e",
+ "testing.message.error.lineBackground": "#ed254e3f",
+ "testing.message.warning.decorationForeground": "#dcdfe4",
+ "testing.message.warning.lineBackground": "#dcdfe43f",
+ "testing.message.info.decorationForeground": "#7cb7ff",
+ "testing.message.info.lineBackground": "#7cb7ff3f",
+ "testing.message.hint.decorationForeground": "#c74d89",
+ "testing.message.hint.lineBackground": "#c74d893f",
+ "welcomePage.background": "#161925",
+ "welcomePage.buttonBackground": "#2f323e",
+ "welcomePage.buttonHoverBackground": "#474b56",
+ "welcomePage.progress.background": "#7cb7ff",
+ "welcomePage.progress.foreground": "#161925",
+ "walkThrough.embeddedEditorBackground": "#161925",
+ "scm.providerBorder": "#474b56",
+ "gitDecoration.addedResourceForeground": "#71f79f",
+ "gitDecoration.modifiedResourceForeground": "#f9dc5c",
+ "gitDecoration.stageModifiedResourceForeground": "#00c1e4",
+ "gitDecoration.deletedResourceForeground": "#ed254e",
+ "gitDecoration.stageDeletedResourceForeground": "#ed254e",
+ "gitDecoration.untrackedResourceForeground": "#c3c7d1",
+ "gitDecoration.ignoredResourceForeground": "#60646f",
+ "gitDecoration.conflictingResourceForeground": "#00c1e4",
+ "gitDecoration.submoduleResourceForeground": "#c74d89",
+ "settings.headerForeground": "#c3c7d1",
+ "settings.modifiedItemIndicator": "#00c1e4",
+ "settings.dropdownBackground": "#2f323e",
+ "settings.dropdownForeground": "#aaaeb8",
+ "settings.dropdownListBorder": "#474b56",
+ "settings.checkboxBackground": "#7cb7ff",
+ "settings.checkboxForeground": "#161925",
+ "settings.checkboxBorder": "#7cb7ff",
+ "settings.textInputBackground": "#2f323e",
+ "settings.textInputForeground": "#aaaeb8",
+ "settings.numberInputBackground": "#2f323e",
+ "settings.numberInputForeground": "#aaaeb8",
+ "settings.focusedRowBackground": "#161925",
+ "notebook.focusedRowBorder": "#c3c7d1",
+ "notebook.rowHoverBackground": "#2f323e7f",
+ "breadcrumb.foreground": "#9295a0",
+ "breadcrumb.background": "#161925",
+ "breadcrumb.focusForeground": "#aaaeb8",
+ "breadcrumb.activeSelectionForeground": "#c3c7d1",
+ "breadcrumbPicker.background": "#161925",
+ "editor.snippetTabstopHighlightBackground": "#2f323e7f",
+ "editor.snippetFinalTabstopHighlightBackground": "#474b567f",
+ "symbolIcon.arrayForeground": "#c74d89",
+ "symbolIcon.booleanForeground": "#c3c7d1",
+ "symbolIcon.classForeground": "#7cb7ff",
+ "symbolIcon.colorForeground": "#00c1e4",
+ "symbolIcon.constantForeground": "#71f79f",
+ "symbolIcon.constructorForeground": "#c3c7d1",
+ "symbolIcon.enumeratorForeground": "#00c1e4",
+ "symbolIcon.enumeratorMemberForeground": "#7cb7ff",
+ "symbolIcon.eventForeground": "#dcdfe4",
+ "symbolIcon.fieldForeground": "#ed254e",
+ "symbolIcon.fileForeground": "#aaaeb8",
+ "symbolIcon.folderForeground": "#9295a0",
+ "symbolIcon.functionForeground": "#c3c7d1",
+ "symbolIcon.interfaceForeground": "#ed254e",
+ "symbolIcon.keyForeground": "#f9dc5c",
+ "symbolIcon.keywordForeground": "#7cb7ff",
+ "symbolIcon.methodForeground": "#00c1e4",
+ "symbolIcon.moduleForeground": "#00c1e4",
+ "symbolIcon.namespaceForeground": "#7cb7ff",
+ "symbolIcon.nullForeground": "#ed254e",
+ "symbolIcon.numberForeground": "#dcdfe4",
+ "symbolIcon.objectForeground": "#c3c7d1",
+ "symbolIcon.operatorForeground": "#ed254e",
+ "symbolIcon.packageForeground": "#dcdfe4",
+ "symbolIcon.propertyForeground": "#00c1e4",
+ "symbolIcon.referenceForeground": "#dcdfe4",
+ "symbolIcon.snippetForeground": "#9295a0",
+ "symbolIcon.stringForeground": "#71f79f",
+ "symbolIcon.structForeground": "#7cb7ff",
+ "symbolIcon.textForeground": "#c3c7d1",
+ "symbolIcon.typeParameterForeground": "#7cb7ff",
+ "symbolIcon.unitForeground": "#f9dc5c",
+ "symbolIcon.variableForeground": "#dcdfe4",
+ "debugIcon.breakpointForeground": "#ed254e",
+ "debugIcon.breakpointDisabledForeground": "#797c87",
+ "debugIcon.breakpointUnverifiedForeground": "#9295a0",
+ "debugIcon.breakpointCurrentStackframeForeground": "#71f79f",
+ "debugIcon.breakpointStackframeForeground": "#f9dc5c",
+ "debugIcon.startForeground": "#71f79f",
+ "debugIcon.pauseForeground": "#7cb7ff",
+ "debugIcon.stopForeground": "#ed254e",
+ "debugIcon.disconnectForeground": "#dcdfe4",
+ "debugIcon.restartForeground": "#c74d89",
+ "debugIcon.stepOverForeground": "#c3c7d1",
+ "debugIcon.stepIntoForeground": "#c3c7d1",
+ "debugIcon.stepOutForeground": "#c3c7d1",
+ "debugIcon.continueForeground": "#71f79f",
+ "debugIcon.stepBackForeground": "#c3c7d1",
+ "debugConsole.infoForeground": "#7cb7ff",
+ "debugConsole.warningForeground": "#dcdfe4",
+ "debugConsole.errorForeground": "#ed254e",
+ "debugConsole.sourceForeground": "#c3c7d1",
+ "debugConsoleInputIcon.foreground": "#797c87",
+ "notebook.cellBorderColor": "#2f323e3f",
+ "notebook.focusedEditorBorder": "#2f323e",
+ "notebookStatusSuccessIcon.foreground": "#71f79f",
+ "notebookStatusErrorIcon.foreground": "#ed254e",
+ "notebookStatusRunningIcon.foreground": "#7cb7ff",
+ "notebook.outputContainerBackgroundColor": "#161925",
+ "notebook.cellToolbarSeparator": "#2f323e3f",
+ "notebook.focusedCellBackground": "#2f323e7f",
+ "notebook.cellHoverBackground": "#2f323e3f",
+ "notebook.focusedCellBorder": "#c3c7d1",
+ "notebook.focusedCellShadow": "#0000003f",
+ "notebook.selectedCellBorder": "#797c87",
+ "notebook.cellStatusBarItemHoverBackground": "#2f323e3f",
+ "notebook.cellInsertionIndicator": "#71f79f",
+ "notebookScrollbarSlider.background": "#60646f7f",
+ "notebookScrollbarSlider.hoverBackground": "#797c877f",
+ "notebookScrollbarSlider.activeBackground": "#9295a07f",
+ "notebook.symbolHighlightBackground": "#c3c7d13f",
+ "notebook.inactiveFocusedCellBorder": "#9295a0",
+ "charts.foreground": "#aaaeb8",
+ "charts.lines": "#60646f",
+ "charts.red": "#ed254e",
+ "charts.blue": "#7cb7ff",
+ "charts.yellow": "#f9dc5c",
+ "charts.orange": "#dcdfe4",
+ "charts.green": "#71f79f",
+ "charts.purple": "#c3c7d1"
+ },
+ "tokenColors": [
+ {
+ "settings": {
+ "background": "#161925",
+ "foreground": "#aaaeb8",
+ "selectionBorder": "#9295a0",
+ "findHighlight": "#f9dc5c",
+ "findHighlightForeground": "#161925",
+ "activeGuide": "#dcdfe4",
+ "bracketsForeground": "#aaaeb87F",
+ "bracketsOptions": "stippled_underline",
+ "bracketsContentsForeground": "#aaaeb87F",
+ "tagsOptions": "stippled_underline"
+ }
+ },
+ {
+ "name": "Comment",
+ "scope": "comment",
+ "settings": {
+ "foreground": "#60646f"
+ }
+ },
+ {
+ "name": "Constant",
+ "scope": "constant",
+ "settings": {
+ "foreground": "#c74d89"
+ }
+ },
+ {
+ "name": "Entity",
+ "scope": "entity",
+ "settings": {
+ "foreground": "#00c1e4"
+ }
+ },
+ {
+ "name": "Invalid",
+ "scope": "invalid",
+ "settings": {
+ "foreground": "#ed254e"
+ }
+ },
+ {
+ "name": "Keyword",
+ "scope": "keyword",
+ "settings": {
+ "foreground": "#c3c7d1"
+ }
+ },
+ {
+ "name": "Storage",
+ "scope": "storage",
+ "settings": {
+ "foreground": "#c74d89"
+ }
+ },
+ {
+ "name": "String",
+ "scope": "string",
+ "settings": {
+ "foreground": "#71f79f"
+ }
+ },
+ {
+ "name": "Support",
+ "scope": "support",
+ "settings": {
+ "foreground": "#00c1e4"
+ }
+ },
+ {
+ "name": "Variable",
+ "scope": "variable",
+ "settings": {
+ "foreground": "#c3c7d1"
+ }
+ },
+ {
+ "name": "Markup Heading",
+ "scope": "markup.heading",
+ "settings": {
+ "foreground": "#00c1e4"
+ }
+ },
+ {
+ "name": "Markup Deleted",
+ "scope": "markup.deleted",
+ "settings": {
+ "foreground": "#ed254e"
+ }
+ },
+ {
+ "name": "Markup Inserted",
+ "scope": "markup.inserted",
+ "settings": {
+ "foreground": "#71f79f"
+ }
+ },
+ {
+ "name": "Markup Changed",
+ "scope": "markup.changed",
+ "settings": {
+ "foreground": "#f9dc5c"
+ }
+ },
+ {
+ "name": "Markup Underline",
+ "scope": "markup.underline",
+ "settings": {
+ "fontStyle": "underline"
+ }
+ },
+ {
+ "name": "Markup Underline Link",
+ "scope": "markup.underline.link",
+ "settings": {
+ "foreground": "#7cb7ff"
+ }
+ },
+ {
+ "name": "Markup List",
+ "scope": "markup.list",
+ "settings": {
+ "foreground": "#c3c7d1"
+ }
+ },
+ {
+ "name": "Markup Raw",
+ "scope": "markup.raw",
+ "settings": {
+ "foreground": "#c74d89"
+ }
+ }
+ ]
+}
diff --git a/.config/Code/User/extensions/theme-betelgeuse-vscode/themes/themer-light-color-theme.json b/.config/Code/User/extensions/theme-betelgeuse-vscode/themes/themer-light-color-theme.json
new file mode 100644
index 00000000..509cd1d9
--- /dev/null
+++ b/.config/Code/User/extensions/theme-betelgeuse-vscode/themes/themer-light-color-theme.json
@@ -0,0 +1,614 @@
+{
+ "name": "Betelgeuse Light",
+ "type": "light",
+ "colors": {
+ "focusBorder": "#4c5058",
+ "foreground": "#4c5058",
+ "widget.shadow": "#4c505866",
+ "selection.background": "#cccdcf",
+ "descriptionForeground": "#666970",
+ "errorForeground": "#ff4972",
+ "icon.foreground": "#666970",
+ "sash.hoverBorder": "#a0dbff",
+ "textBlockQuote.background": "#e5e6e7",
+ "textBlockQuote.border": "#e5e6e7",
+ "textCodeBlock.background": "#ffffff",
+ "textLink.activeForeground": "#24e5ff",
+ "textLink.foreground": "#a0dbff",
+ "textPreformat.foreground": "#dcdfe4",
+ "textSeparator.foreground": "#999ba0",
+ "button.background": "#a0dbff",
+ "button.foreground": "#ffffff",
+ "button.hoverBackground": "#24e5ff",
+ "button.secondaryForeground": "#ffffff",
+ "button.secondaryBackground": "#666970",
+ "button.secondaryHoverBackground": "#7f8288",
+ "checkbox.background": "#a0dbff",
+ "checkbox.foreground": "#ffffff",
+ "checkbox.border": "#e5e6e7",
+ "dropdown.background": "#e5e6e7",
+ "dropdown.listBackground": "#e5e6e7",
+ "dropdown.border": "#e5e6e7",
+ "dropdown.foreground": "#666970",
+ "input.background": "#e5e6e7",
+ "input.border": "#e5e6e7",
+ "input.foreground": "#666970",
+ "input.placeholderForeground": "#cccdcf",
+ "inputOption.activeBackground": "#cccdcf",
+ "inputOption.activeBorder": "#24e5ff",
+ "inputOption.activeForeground": "#4c5058",
+ "inputValidation.errorBackground": "#e5e6e7",
+ "inputValidation.errorForeground": "#ff4972",
+ "inputValidation.errorBorder": "#ff4972",
+ "inputValidation.infoBackground": "#e5e6e7",
+ "inputValidation.infoForeground": "#a0dbff",
+ "inputValidation.infoBorder": "#a0dbff",
+ "inputValidation.warningBackground": "#e5e6e7",
+ "inputValidation.warningForeground": "#dcdfe4",
+ "inputValidation.warningBorder": "#dcdfe4",
+ "scrollbar.shadow": "#4c505866",
+ "scrollbarSlider.activeBackground": "#7f82887f",
+ "scrollbarSlider.background": "#b2b4b77f",
+ "scrollbarSlider.hoverBackground": "#999ba07f",
+ "badge.foreground": "#ffffff",
+ "badge.background": "#4c5058",
+ "progressBar.background": "#95ffc3",
+ "list.activeSelectionBackground": "#4c505833",
+ "list.activeSelectionForeground": "#4c5058",
+ "list.dropBackground": "#e5e6e7",
+ "list.focusBackground": "#b2b4b73f",
+ "list.focusForeground": "#4c5058",
+ "list.highlightForeground": "#ffff80",
+ "list.hoverBackground": "#e5e6e733",
+ "list.hoverForeground": "#4c5058",
+ "list.inactiveSelectionBackground": "#cccdcf3f",
+ "list.inactiveSelectionForeground": "#666970",
+ "list.inactiveFocusBackground": "#e5e6e73f",
+ "list.invalidItemForeground": "#ff4972",
+ "list.errorForeground": "#ff4972",
+ "list.warningForeground": "#ffff80",
+ "listFilterWidget.background": "#e5e6e7",
+ "listFilterWidget.outline": "#a0dbff",
+ "listFilterWidget.noMatchesOutline": "#ff4972",
+ "list.filterMatchBackground": "#ffff8033",
+ "list.filterMatchBorder": "#ffff8033",
+ "tree.indentGuidesStroke": "#e5e6e7",
+ "list.deemphasizedForeground": "#999ba0",
+ "activityBar.background": "#ffffff",
+ "activityBar.dropBorder": "#a0dbff",
+ "activityBar.foreground": "#7f8288",
+ "activityBar.inactiveForeground": "#999ba0",
+ "activityBar.border": "#ffffff",
+ "activityBarBadge.background": "#4c5058",
+ "activityBarBadge.foreground": "#ffffff",
+ "activityBar.activeBorder": "#666970",
+ "activityBar.activeBackground": "#e5e6e733",
+ "activityBar.activeFocusBorder": "#4c5058",
+ "sideBar.background": "#ffffff",
+ "sideBar.foreground": "#666970",
+ "sideBar.border": "#e5e6e7",
+ "sideBar.dropBackground": "#e5e6e73f",
+ "sideBarTitle.foreground": "#7f8288",
+ "sideBarSectionHeader.background": "#cccdcf",
+ "sideBarSectionHeader.foreground": "#666970",
+ "sideBarSectionHeader.border": "#ffffff",
+ "minimap.findMatchHighlight": "#ffff80",
+ "minimap.selectionHighlight": "#a0dbff80",
+ "minimap.errorHighlight": "#ff497280",
+ "minimap.warningHighlight": "#dcdfe480",
+ "minimap.background": "#ffffff",
+ "minimapSlider.background": "#e5e6e733",
+ "minimapSlider.hoverBackground": "#cccdcf33",
+ "minimapSlider.activeBackground": "#b2b4b733",
+ "minimapGutter.addedBackground": "#95ffc380",
+ "minimapGutter.modifiedBackground": "#ffff8080",
+ "minimapGutter.deletedBackground": "#ff497280",
+ "editorGroup.border": "#e5e6e7",
+ "editorGroup.dropBackground": "#cccdcf7f",
+ "editorGroupHeader.noTabsBackground": "#ffffff",
+ "editorGroupHeader.tabsBackground": "#ffffff",
+ "editorGroupHeader.tabsBorder": "#ffffff",
+ "editorGroupHeader.border": "#ffffff",
+ "editorGroup.emptyBackground": "#ffffff",
+ "editorGroup.focusedEmptyBorder": "#e5e6e7",
+ "tab.activeBackground": "#ffffff",
+ "tab.unfocusedActiveBackground": "#ffffff",
+ "tab.activeForeground": "#666970",
+ "tab.border": "#ffffff",
+ "tab.lastPinnedBorder": "#eb71ad",
+ "tab.inactiveBackground": "#e5e6e7",
+ "tab.unfocusedInactiveBackground": "#e5e6e7",
+ "tab.inactiveForeground": "#b2b4b7",
+ "tab.unfocusedActiveForeground": "#b2b4b7",
+ "tab.unfocusedInactiveForeground": "#cccdcf",
+ "tab.hoverBackground": "#e5e6e780",
+ "tab.unfocusedHoverBackground": "#e5e6e780",
+ "tab.hoverForeground": "#7f8288",
+ "tab.unfocusedHoverForeground": "#999ba0",
+ "tab.activeModifiedBorder": "#ffff80",
+ "tab.inactiveModifiedBorder": "#ffff80",
+ "tab.unfocusedActiveModifiedBorder": "#ffff80",
+ "tab.unfocusedInactiveModifiedBorder": "#ffff80",
+ "editorPane.background": "#ffffff",
+ "editor.background": "#ffffff",
+ "editor.foreground": "#4c5058",
+ "editorLineNumber.foreground": "#cccdcf",
+ "editorLineNumber.activeForeground": "#999ba0",
+ "editorCursor.background": "#ffffff",
+ "editorCursor.foreground": "#4c5058",
+ "editor.selectionBackground": "#a0dbff33",
+ "editor.selectionForeground": "#4c5058",
+ "editor.inactiveSelectionBackground": "#a0dbff33",
+ "editor.selectionHighlightBackground": "#e5e6e7",
+ "editor.wordHighlightBackground": "#4c505833",
+ "editor.wordHighlightStrongBackground": "#eb71ad33",
+ "editor.findMatchBackground": "#ffff803f",
+ "editor.findMatchHighlightBackground": "#ffff8033",
+ "editor.findRangeHighlightBackground": "#e5e6e7",
+ "editor.hoverHighlightBackground": "#cccdcf7f",
+ "editor.lineHighlightBackground": "#ffffff",
+ "editor.lineHighlightBorder": "#e5e6e7",
+ "editorLink.activeForeground": "#24e5ff",
+ "editor.rangeHighlightBackground": "#ffff8033",
+ "editor.symbolHighlightBackground": "#4c505833",
+ "editorWhitespace.foreground": "#e5e6e7",
+ "editorIndentGuide.background": "#e5e6e7",
+ "editorIndentGuide.activeBackground": "#cccdcf",
+ "editorRuler.foreground": "#e5e6e7",
+ "editorCodeLens.foreground": "#7f8288",
+ "editorLightBulb.foreground": "#ffff80",
+ "editorLightBulbAutoFix.foreground": "#a0dbff",
+ "editorBracketMatch.background": "#e5e6e7",
+ "editorBracketMatch.border": "#cccdcf",
+ "editorBracketHighlight.foreground1": "#4c5058",
+ "editorBracketHighlight.foreground2": "#ffff80",
+ "editorBracketHighlight.foreground3": "#24e5ff",
+ "editorBracketHighlight.foreground4": "#4c5058",
+ "editorBracketHighlight.foreground5": "#95ffc3",
+ "editorBracketHighlight.foreground6": "#a0dbff",
+ "editorBracketHighlight.unexpectedBracket": "#ff4972",
+ "editor.foldBackground": "#e5e6e766",
+ "editorOverviewRuler.border": "#e5e6e7",
+ "editorOverviewRuler.findMatchForeground": "#ffff80bf",
+ "editorOverviewRuler.rangeHighlightForeground": "#cccdcfbf",
+ "editorOverviewRuler.selectionHighlightForeground": "#e5e6e7bf",
+ "editorOverviewRuler.wordHighlightForeground": "#cccdcfbf",
+ "editorOverviewRuler.wordHighlightStrongForeground": "#b2b4b7bf",
+ "editorOverviewRuler.modifiedForeground": "#ffff807f",
+ "editorOverviewRuler.addedForeground": "#95ffc37f",
+ "editorOverviewRuler.deletedForeground": "#ff49727f",
+ "editorOverviewRuler.errorForeground": "#ff49727f",
+ "editorOverviewRuler.warningForeground": "#dcdfe47f",
+ "editorOverviewRuler.infoForeground": "#a0dbff7f",
+ "editorOverviewRuler.bracketMatchForeground": "#b2b4b7",
+ "editorError.foreground": "#ff4972",
+ "editorError.border": "#4c5058",
+ "editorWarning.foreground": "#dcdfe4",
+ "editorWarning.border": "#666970",
+ "editorInfo.foreground": "#a0dbff",
+ "editorInfo.border": "#7f8288",
+ "editorHint.foreground": "#eb71ad",
+ "editorHint.border": "#999ba0",
+ "problemsErrorIcon.foreground": "#ff4972",
+ "problemsWarningIcon.foreground": "#dcdfe4",
+ "problemsInfoIcon.foreground": "#a0dbff",
+ "editorUnnecessaryCode.opacity": "#0000007f",
+ "editorGutter.background": "#ffffff",
+ "editorGutter.modifiedBackground": "#ffff80",
+ "editorGutter.addedBackground": "#95ffc3",
+ "editorGutter.deletedBackground": "#ff4972",
+ "editorGutter.commentRangeForeground": "#b2b4b7",
+ "editorGutter.foldingControlForeground": "#7f8288",
+ "diffEditor.insertedTextBackground": "#95ffc320",
+ "diffEditor.removedTextBackground": "#ff497220",
+ "diffEditor.border": "#e5e6e7",
+ "diffEditor.diagonalFill": "#e5e6e77f",
+ "editorWidget.foreground": "#666970",
+ "editorWidget.background": "#e5e6e7",
+ "editorWidget.border": "#e5e6e7",
+ "editorWidget.resizeBorder": "#a0dbff",
+ "editorSuggestWidget.background": "#e5e6e7",
+ "editorSuggestWidget.border": "#e5e6e7",
+ "editorSuggestWidget.foreground": "#666970",
+ "editorSuggestWidget.highlightForeground": "#eb71ad",
+ "editorSuggestWidget.selectedBackground": "#cccdcf",
+ "editorHoverWidget.foreground": "#666970",
+ "editorHoverWidget.background": "#e5e6e7",
+ "editorHoverWidget.border": "#e5e6e7",
+ "editorHoverWidget.statusBarBackground": "#a0dbff33",
+ "debugExceptionWidget.background": "#e5e6e7",
+ "debugExceptionWidget.border": "#e5e6e7",
+ "editorMarkerNavigation.background": "#e5e6e7",
+ "editorMarkerNavigationError.background": "#ff4972",
+ "editorMarkerNavigationWarning.background": "#dcdfe4",
+ "editorMarkerNavigationInfo.background": "#a0dbff",
+ "peekView.border": "#eb71ad",
+ "peekViewEditor.background": "#e5e6e77f",
+ "peekViewEditorGutter.background": "#e5e6e77f",
+ "peekViewEditor.matchHighlightBackground": "#ffff807f",
+ "peekViewResult.background": "#e5e6e7",
+ "peekViewResult.fileForeground": "#666970",
+ "peekViewResult.lineForeground": "#cccdcf",
+ "peekViewResult.matchHighlightBackground": "#ffff80",
+ "peekViewResult.selectionBackground": "#b2b4b7",
+ "peekViewResult.selectionForeground": "#4c5058",
+ "peekViewTitle.background": "#e5e6e7",
+ "peekViewTitleDescription.foreground": "#7f8288",
+ "peekViewTitleLabel.foreground": "#4c5058",
+ "merge.currentHeaderBackground": "#24e5ff4c",
+ "merge.currentContentBackground": "#24e5ff4c",
+ "merge.incomingHeaderBackground": "#a0dbff4c",
+ "merge.incomingContentBackground": "#a0dbff4c",
+ "merge.border": "#999ba0",
+ "merge.commonContentBackground": "#4c50584c",
+ "merge.commonHeaderBackground": "#4c50584c",
+ "editorOverviewRuler.currentContentForeground": "#24e5ff",
+ "editorOverviewRuler.incomingContentForeground": "#a0dbff",
+ "editorOverviewRuler.commonContentForeground": "#4c5058",
+ "panel.background": "#ffffff",
+ "panel.border": "#e5e6e7",
+ "panel.dropBorder": "#a0dbff",
+ "panelTitle.activeBorder": "#b2b4b7",
+ "panelTitle.activeForeground": "#666970",
+ "panelTitle.inactiveForeground": "#999ba0",
+ "panelSection.border": "#e5e6e7",
+ "panelSection.dropBackground": "#e5e6e73f",
+ "panelSectionHeader.background": "#cccdcf",
+ "panelSectionHeader.foreground": "#666970",
+ "panelSectionHeader.border": "#ffffff",
+ "imagePreview.border": "#e5e6e7",
+ "statusBar.background": "#a0dbff",
+ "statusBar.foreground": "#ffffff",
+ "statusBar.border": "#ffffff",
+ "statusBar.debuggingBackground": "#dcdfe4",
+ "statusBar.debuggingForeground": "#ffffff",
+ "statusBar.debuggingBorder": "#ffffff",
+ "statusBar.noFolderBackground": "#4c5058",
+ "statusBar.noFolderForeground": "#ffffff",
+ "statusBar.noFolderBorder": "#ffffff",
+ "statusBarItem.activeBackground": "#24e5ff",
+ "statusBarItem.hoverBackground": "#95ffc3",
+ "statusBarItem.prominentBackground": "#24e5ff",
+ "statusBarItem.prominentHoverBackground": "#95ffc3",
+ "statusBarItem.remoteBackground": "#24e5ff",
+ "statusBarItem.remoteForeground": "#ffffff",
+ "statusBarItem.errorBackground": "#ff4972",
+ "statusBarItem.errorForeground": "#ffffff",
+ "titleBar.activeBackground": "#ffffff",
+ "titleBar.activeForeground": "#7f8288",
+ "titleBar.inactiveBackground": "#ffffff",
+ "titleBar.inactiveForeground": "#b2b4b7",
+ "menubar.selectionForeground": "#4c5058",
+ "menubar.selectionBackground": "#e5e6e7",
+ "menu.foreground": "#666970",
+ "menu.background": "#ffffff",
+ "menu.selectionForeground": "#4c5058",
+ "menu.selectionBackground": "#e5e6e7",
+ "menu.separatorBackground": "#cccdcf",
+ "notificationCenterHeader.foreground": "#666970",
+ "notificationCenterHeader.background": "#cccdcf",
+ "notificationToast.border": "#b2b4b7",
+ "notifications.foreground": "#4c5058",
+ "notifications.background": "#e5e6e7",
+ "notifications.border": "#b2b4b7",
+ "notificationLink.foreground": "#a0dbff",
+ "notificationsErrorIcon.foreground": "#ff4972",
+ "notificationsWarningIcon.foreground": "#dcdfe4",
+ "notificationsInfoIcon.foreground": "#a0dbff",
+ "extensionButton.prominentForeground": "#ffffff",
+ "extensionButton.prominentBackground": "#a0dbff",
+ "extensionButton.prominentHoverBackground": "#24e5ff",
+ "extensionBadge.remoteBackground": "#eb71ad",
+ "extensionBadge.remoteForeground": "#ffffff",
+ "pickerGroup.border": "#cccdcf",
+ "pickerGroup.foreground": "#999ba0",
+ "quickInput.background": "#e5e6e7",
+ "quickInput.foreground": "#4c5058",
+ "quickInputTitle.background": "#cccdcf",
+ "terminal.background": "#ffffff",
+ "terminal.foreground": "#666970",
+ "terminal.ansiBlack": "#ffffff",
+ "terminal.ansiBlue": "#a0dbff",
+ "terminal.ansiBrightBlack": "#e5e6e7",
+ "terminal.ansiBrightBlue": "#a0dbff",
+ "terminal.ansiBrightCyan": "#24e5ff",
+ "terminal.ansiBrightGreen": "#24e5ff",
+ "terminal.ansiBrightMagenta": "#eb71ad",
+ "terminal.ansiBrightRed": "#dcdfe4",
+ "terminal.ansiBrightWhite": "#4c5058",
+ "terminal.ansiBrightYellow": "#ffff80",
+ "terminal.ansiCyan": "#24e5ff",
+ "terminal.ansiGreen": "#95ffc3",
+ "terminal.ansiMagenta": "#eb71ad",
+ "terminal.ansiRed": "#ff4972",
+ "terminal.ansiWhite": "#666970",
+ "terminal.ansiYellow": "#ffff80",
+ "terminal.selectionBackground": "#a0dbff7f",
+ "terminalCursor.background": "#e5e6e7",
+ "terminalCursor.foreground": "#7f8288",
+ "debugToolBar.background": "#e5e6e7",
+ "debugToolBar.border": "#cccdcf",
+ "editor.stackFrameHighlightBackground": "#24e5ff3f",
+ "editor.focusedStackFrameHighlightBackground": "#95ffc33f",
+ "debugView.exceptionLabelForeground": "#ffff80",
+ "debugView.exceptionLabelBackground": "#e5e6e7",
+ "debugView.stateLabelForeground": "#a0dbff",
+ "debugView.stateLabelBackground": "#e5e6e7",
+ "debugView.valueChangedHighlight": "#ffff8033",
+ "debugTokenExpression.name": "#a0dbff",
+ "debugTokenExpression.value": "#4c5058",
+ "debugTokenExpression.string": "#95ffc3",
+ "debugTokenExpression.boolean": "#4c5058",
+ "debugTokenExpression.number": "#eb71ad",
+ "debugTokenExpression.error": "#ff4972",
+ "testing.iconFailed": "#dcdfe4",
+ "testing.iconErrored": "#ff4972",
+ "testing.iconPassed": "#95ffc3",
+ "testing.runAction": "#a0dbff",
+ "testing.iconQueued": "#24e5ff",
+ "testing.iconUnset": "#7f8288",
+ "testing.iconSkipped": "#999ba0",
+ "testing.peekBorder": "#b2b4b7",
+ "testing.message.error.decorationForeground": "#ff4972",
+ "testing.message.error.lineBackground": "#ff49723f",
+ "testing.message.warning.decorationForeground": "#dcdfe4",
+ "testing.message.warning.lineBackground": "#dcdfe43f",
+ "testing.message.info.decorationForeground": "#a0dbff",
+ "testing.message.info.lineBackground": "#a0dbff3f",
+ "testing.message.hint.decorationForeground": "#eb71ad",
+ "testing.message.hint.lineBackground": "#eb71ad3f",
+ "welcomePage.background": "#ffffff",
+ "welcomePage.buttonBackground": "#e5e6e7",
+ "welcomePage.buttonHoverBackground": "#cccdcf",
+ "welcomePage.progress.background": "#a0dbff",
+ "welcomePage.progress.foreground": "#ffffff",
+ "walkThrough.embeddedEditorBackground": "#ffffff",
+ "scm.providerBorder": "#cccdcf",
+ "gitDecoration.addedResourceForeground": "#95ffc3",
+ "gitDecoration.modifiedResourceForeground": "#ffff80",
+ "gitDecoration.stageModifiedResourceForeground": "#24e5ff",
+ "gitDecoration.deletedResourceForeground": "#ff4972",
+ "gitDecoration.stageDeletedResourceForeground": "#ff4972",
+ "gitDecoration.untrackedResourceForeground": "#4c5058",
+ "gitDecoration.ignoredResourceForeground": "#b2b4b7",
+ "gitDecoration.conflictingResourceForeground": "#24e5ff",
+ "gitDecoration.submoduleResourceForeground": "#eb71ad",
+ "settings.headerForeground": "#4c5058",
+ "settings.modifiedItemIndicator": "#24e5ff",
+ "settings.dropdownBackground": "#e5e6e7",
+ "settings.dropdownForeground": "#666970",
+ "settings.dropdownListBorder": "#cccdcf",
+ "settings.checkboxBackground": "#a0dbff",
+ "settings.checkboxForeground": "#ffffff",
+ "settings.checkboxBorder": "#a0dbff",
+ "settings.textInputBackground": "#e5e6e7",
+ "settings.textInputForeground": "#666970",
+ "settings.numberInputBackground": "#e5e6e7",
+ "settings.numberInputForeground": "#666970",
+ "settings.focusedRowBackground": "#ffffff",
+ "notebook.focusedRowBorder": "#4c5058",
+ "notebook.rowHoverBackground": "#e5e6e77f",
+ "breadcrumb.foreground": "#7f8288",
+ "breadcrumb.background": "#ffffff",
+ "breadcrumb.focusForeground": "#666970",
+ "breadcrumb.activeSelectionForeground": "#4c5058",
+ "breadcrumbPicker.background": "#ffffff",
+ "editor.snippetTabstopHighlightBackground": "#e5e6e77f",
+ "editor.snippetFinalTabstopHighlightBackground": "#cccdcf7f",
+ "symbolIcon.arrayForeground": "#eb71ad",
+ "symbolIcon.booleanForeground": "#4c5058",
+ "symbolIcon.classForeground": "#a0dbff",
+ "symbolIcon.colorForeground": "#24e5ff",
+ "symbolIcon.constantForeground": "#95ffc3",
+ "symbolIcon.constructorForeground": "#4c5058",
+ "symbolIcon.enumeratorForeground": "#24e5ff",
+ "symbolIcon.enumeratorMemberForeground": "#a0dbff",
+ "symbolIcon.eventForeground": "#dcdfe4",
+ "symbolIcon.fieldForeground": "#ff4972",
+ "symbolIcon.fileForeground": "#666970",
+ "symbolIcon.folderForeground": "#7f8288",
+ "symbolIcon.functionForeground": "#4c5058",
+ "symbolIcon.interfaceForeground": "#ff4972",
+ "symbolIcon.keyForeground": "#ffff80",
+ "symbolIcon.keywordForeground": "#a0dbff",
+ "symbolIcon.methodForeground": "#24e5ff",
+ "symbolIcon.moduleForeground": "#24e5ff",
+ "symbolIcon.namespaceForeground": "#a0dbff",
+ "symbolIcon.nullForeground": "#ff4972",
+ "symbolIcon.numberForeground": "#dcdfe4",
+ "symbolIcon.objectForeground": "#4c5058",
+ "symbolIcon.operatorForeground": "#ff4972",
+ "symbolIcon.packageForeground": "#dcdfe4",
+ "symbolIcon.propertyForeground": "#24e5ff",
+ "symbolIcon.referenceForeground": "#dcdfe4",
+ "symbolIcon.snippetForeground": "#7f8288",
+ "symbolIcon.stringForeground": "#95ffc3",
+ "symbolIcon.structForeground": "#a0dbff",
+ "symbolIcon.textForeground": "#4c5058",
+ "symbolIcon.typeParameterForeground": "#a0dbff",
+ "symbolIcon.unitForeground": "#ffff80",
+ "symbolIcon.variableForeground": "#dcdfe4",
+ "debugIcon.breakpointForeground": "#ff4972",
+ "debugIcon.breakpointDisabledForeground": "#999ba0",
+ "debugIcon.breakpointUnverifiedForeground": "#7f8288",
+ "debugIcon.breakpointCurrentStackframeForeground": "#95ffc3",
+ "debugIcon.breakpointStackframeForeground": "#ffff80",
+ "debugIcon.startForeground": "#95ffc3",
+ "debugIcon.pauseForeground": "#a0dbff",
+ "debugIcon.stopForeground": "#ff4972",
+ "debugIcon.disconnectForeground": "#dcdfe4",
+ "debugIcon.restartForeground": "#eb71ad",
+ "debugIcon.stepOverForeground": "#4c5058",
+ "debugIcon.stepIntoForeground": "#4c5058",
+ "debugIcon.stepOutForeground": "#4c5058",
+ "debugIcon.continueForeground": "#95ffc3",
+ "debugIcon.stepBackForeground": "#4c5058",
+ "debugConsole.infoForeground": "#a0dbff",
+ "debugConsole.warningForeground": "#dcdfe4",
+ "debugConsole.errorForeground": "#ff4972",
+ "debugConsole.sourceForeground": "#4c5058",
+ "debugConsoleInputIcon.foreground": "#999ba0",
+ "notebook.cellBorderColor": "#e5e6e73f",
+ "notebook.focusedEditorBorder": "#e5e6e7",
+ "notebookStatusSuccessIcon.foreground": "#95ffc3",
+ "notebookStatusErrorIcon.foreground": "#ff4972",
+ "notebookStatusRunningIcon.foreground": "#a0dbff",
+ "notebook.outputContainerBackgroundColor": "#ffffff",
+ "notebook.cellToolbarSeparator": "#e5e6e73f",
+ "notebook.focusedCellBackground": "#e5e6e77f",
+ "notebook.cellHoverBackground": "#e5e6e73f",
+ "notebook.focusedCellBorder": "#4c5058",
+ "notebook.focusedCellShadow": "#0000003f",
+ "notebook.selectedCellBorder": "#999ba0",
+ "notebook.cellStatusBarItemHoverBackground": "#e5e6e73f",
+ "notebook.cellInsertionIndicator": "#95ffc3",
+ "notebookScrollbarSlider.background": "#b2b4b77f",
+ "notebookScrollbarSlider.hoverBackground": "#999ba07f",
+ "notebookScrollbarSlider.activeBackground": "#7f82887f",
+ "notebook.symbolHighlightBackground": "#4c50583f",
+ "notebook.inactiveFocusedCellBorder": "#7f8288",
+ "charts.foreground": "#666970",
+ "charts.lines": "#b2b4b7",
+ "charts.red": "#ff4972",
+ "charts.blue": "#a0dbff",
+ "charts.yellow": "#ffff80",
+ "charts.orange": "#dcdfe4",
+ "charts.green": "#95ffc3",
+ "charts.purple": "#4c5058"
+ },
+ "tokenColors": [
+ {
+ "settings": {
+ "background": "#ffffff",
+ "foreground": "#666970",
+ "selectionBorder": "#7f8288",
+ "findHighlight": "#ffff80",
+ "findHighlightForeground": "#ffffff",
+ "activeGuide": "#dcdfe4",
+ "bracketsForeground": "#6669707F",
+ "bracketsOptions": "stippled_underline",
+ "bracketsContentsForeground": "#6669707F",
+ "tagsOptions": "stippled_underline"
+ }
+ },
+ {
+ "name": "Comment",
+ "scope": "comment",
+ "settings": {
+ "foreground": "#b2b4b7"
+ }
+ },
+ {
+ "name": "Constant",
+ "scope": "constant",
+ "settings": {
+ "foreground": "#eb71ad"
+ }
+ },
+ {
+ "name": "Entity",
+ "scope": "entity",
+ "settings": {
+ "foreground": "#24e5ff"
+ }
+ },
+ {
+ "name": "Invalid",
+ "scope": "invalid",
+ "settings": {
+ "foreground": "#ff4972"
+ }
+ },
+ {
+ "name": "Keyword",
+ "scope": "keyword",
+ "settings": {
+ "foreground": "#4c5058"
+ }
+ },
+ {
+ "name": "Storage",
+ "scope": "storage",
+ "settings": {
+ "foreground": "#eb71ad"
+ }
+ },
+ {
+ "name": "String",
+ "scope": "string",
+ "settings": {
+ "foreground": "#95ffc3"
+ }
+ },
+ {
+ "name": "Support",
+ "scope": "support",
+ "settings": {
+ "foreground": "#24e5ff"
+ }
+ },
+ {
+ "name": "Variable",
+ "scope": "variable",
+ "settings": {
+ "foreground": "#4c5058"
+ }
+ },
+ {
+ "name": "Markup Heading",
+ "scope": "markup.heading",
+ "settings": {
+ "foreground": "#24e5ff"
+ }
+ },
+ {
+ "name": "Markup Deleted",
+ "scope": "markup.deleted",
+ "settings": {
+ "foreground": "#ff4972"
+ }
+ },
+ {
+ "name": "Markup Inserted",
+ "scope": "markup.inserted",
+ "settings": {
+ "foreground": "#95ffc3"
+ }
+ },
+ {
+ "name": "Markup Changed",
+ "scope": "markup.changed",
+ "settings": {
+ "foreground": "#ffff80"
+ }
+ },
+ {
+ "name": "Markup Underline",
+ "scope": "markup.underline",
+ "settings": {
+ "fontStyle": "underline"
+ }
+ },
+ {
+ "name": "Markup Underline Link",
+ "scope": "markup.underline.link",
+ "settings": {
+ "foreground": "#a0dbff"
+ }
+ },
+ {
+ "name": "Markup List",
+ "scope": "markup.list",
+ "settings": {
+ "foreground": "#4c5058"
+ }
+ },
+ {
+ "name": "Markup Raw",
+ "scope": "markup.raw",
+ "settings": {
+ "foreground": "#eb71ad"
+ }
+ }
+ ]
+}
diff --git a/.config/Code/User/keybindings.json b/.config/Code/User/keybindings.json
new file mode 100644
index 00000000..cebb44f5
--- /dev/null
+++ b/.config/Code/User/keybindings.json
@@ -0,0 +1,48 @@
+[
+ {
+ "key": "tab",
+ "command": "selectNextQuickFix",
+ "when": "editorFocus && quickFixWidgetVisible"
+ },
+ {
+ "key": "shift+tab",
+ "command": "selectPrevQuickFix",
+ "when": "editorFocus && quickFixWidgetVisible"
+ },
+ {
+ "key": "tab",
+ "command": "selectNextSuggestion",
+ "when": "editorTextFocus && suggestWidgetMultipleSuggestions && suggestWidgetVisible"
+ },
+ {
+ "key": "shift+tab",
+ "command": "selectPrevSuggestion",
+ "when": "editorTextFocus && suggestWidgetMultipleSuggestions && suggestWidgetVisible"
+ },
+ {
+ "key": "ctrl+j",
+ "command": "editor.action.inlineSuggest.commit",
+ "when": "inlineSuggestionHasIndentationLessThanTabSize && inlineSuggestionVisible && !editorTabMovesFocus"
+ },
+ {
+ "key": "tab",
+ "command": "-editor.action.inlineSuggest.commit",
+ "when": "inlineSuggestionHasIndentationLessThanTabSize && inlineSuggestionVisible && !editorTabMovesFocus"
+ },
+ {
+ "key": "alt+right",
+ "command": "workbench.action.nextEditor"
+ },
+ {
+ "key": "ctrl+pagedown",
+ "command": "-workbench.action.nextEditor"
+ },
+ {
+ "key": "alt+left",
+ "command": "workbench.action.previousEditor"
+ },
+ {
+ "key": "ctrl+pageup",
+ "command": "-workbench.action.previousEditor"
+ }
+]
\ No newline at end of file
diff --git a/.config/Code/User/settings.json b/.config/Code/User/settings.json
new file mode 100644
index 00000000..6c476eca
--- /dev/null
+++ b/.config/Code/User/settings.json
@@ -0,0 +1,170 @@
+{
+ "[html]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[javascript]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[javascriptreact]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[json5]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[json]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[jsonc]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[markdown]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[toml]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[typescript]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[typescriptreact]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[vue]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[yaml]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "codetour.customTourDirectory": ".config/codetour.yml",
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ "editor.fontFamily": "'Hack Nerd Font', Menlo, Monaco, 'Courier New', monospace",
+ "editor.formatOnPaste": false,
+ "editor.formatOnSave": true,
+ "editor.inlineSuggest.enabled": true,
+ "editor.minimap.enabled": false,
+ "editor.scrollBeyondLastLine": false,
+ "eslint.alwaysShowStatus": true,
+ "eslint.format.enable": true,
+ "eslint.lintTask.enable": true,
+ "eslint.lintTask.options": "-c package.json --no-eslintrc --cache --cache-location .cache/eslintcache .",
+ "eslint.packageManager": "pnpm",
+ "eslint.validate": [
+ "html",
+ "javascript",
+ "javascriptreact",
+ "json",
+ "jsonc",
+ "json5",
+ "markdown",
+ "toml",
+ "typescript",
+ "typescriptreact",
+ "vue",
+ "yaml"
+ ],
+ "explorer.confirmDelete": false,
+ "extensions.ignoreRecommendations": true,
+ "files.trimTrailingWhitespace": true,
+ "git.autofetch": true,
+ "git.autoStash": true,
+ "github.codespaces.showPerformanceExplorer": true,
+ "gitlab.showPipelineUpdateNotifications": true,
+ "gitlens.showWelcomeOnInstall": false,
+ "gitlens.showWhatsNewAfterUpgrades": false,
+ "go.lintFlags": ["--fast"],
+ "go.lintTool": "golangci-lint",
+ "html.format.endWithNewline": true,
+ "html.format.indentHandlebars": true,
+ "html.format.indentInnerHtml": true,
+ "html.format.templating": true,
+ "javascript.format.semicolons": "remove",
+ "javascript.suggest.completeFunctionCalls": true,
+ "ltex.additionalRules.enablePickyRules": true,
+ "ltex.completionEnabled": true,
+ "markdown-preview-enhanced.previewTheme": "solarized-light.css",
+ "material-icon-theme.showWelcomeMessage": false,
+ "merge-conflict.autoNavigateNextConflict.enabled": true,
+ "npm.enableRunFromFolder": true,
+ "npm.packageManager": "pnpm",
+ "prettier.printWidth": 120,
+ "prettier.singleQuote": true,
+ "python.languageServer": "Pylance",
+ "security.workspace.trust.banner": "never",
+ "security.workspace.trust.enabled": false,
+ "telemetry.telemetryLevel": "crash",
+ "terminal.integrated.sendKeybindingsToShell": true,
+ "typescript.enablePromptUseWorkspaceTsdk": true,
+ "typescript.format.semicolons": "remove",
+ "typescript.implementationsCodeLens.enabled": true,
+ "typescript.inlayHints.enumMemberValues.enabled": true,
+ "typescript.inlayHints.functionLikeReturnTypes.enabled": true,
+ "typescript.inlayHints.parameterTypes.enabled": true,
+ "typescript.inlayHints.variableTypes.enabled": true,
+ "typescript.preferences.quoteStyle": "single",
+ "typescript.referencesCodeLens.enabled": true,
+ "typescript.referencesCodeLens.showOnAllFunctions": true,
+ "typescript.suggest.completeFunctionCalls": true,
+ "typescript.tsdk": "node_modules/typescript/lib",
+ "typescript.updateImportsOnFileMove.enabled": "always",
+ "vim.enableNeovim": true,
+ "vim.handleKeys": {
+ "": false,
+ "": false
+ },
+ "vim.leader": "",
+ "vim.neovimPath": "/usr/bin/nvim",
+ "vim.normalModeKeyBindings": [
+ {
+ "before": [""],
+ "commands": [":nohl"]
+ },
+ {
+ "before": ["leader", "w"],
+ "commands": ["workbench.action.files.save"]
+ },
+ {
+ "before": ["leader", "b", "d"],
+ "commands": ["workbench.action.closeActiveEditor"]
+ },
+ {
+ "before": ["leader", "l", "n"],
+ "commands": ["editor.action.marker.next"]
+ },
+ {
+ "before": ["leader", "l", "p"],
+ "commands": ["editor.action.marker.prev"]
+ }
+ ],
+ "vscode-neovim.neovimClean": true,
+ "vscode-neovim.neovimExecutablePaths.linux": "/usr/bin/nvim",
+ "vsicons.dontShowNewVersionMessage": true,
+ "window.menuBarVisibility": "toggle",
+ "workbench.colorCustomizations": {
+ "terminal.foreground": "#708284",
+ "terminal.background": "#001e27",
+ "terminal.ansiBlack": "#002831",
+ "terminal.ansiBlue": "#2176c7",
+ "terminal.ansiCyan": "#259286",
+ "terminal.ansiGreen": "#738a05",
+ "terminal.ansiMagenta": "#c61c6f",
+ "terminal.ansiRed": "#d11c24",
+ "terminal.ansiWhite": "#eae3cb",
+ "terminal.ansiYellow": "#a57706",
+ "terminal.ansiBrightBlack": "#475b62",
+ "terminal.ansiBrightBlue": "#708284",
+ "terminal.ansiBrightCyan": "#819090",
+ "terminal.ansiBrightGreen": "#475b62",
+ "terminal.ansiBrightMagenta": "#5956ba",
+ "terminal.ansiBrightRed": "#bd3613",
+ "terminal.ansiBrightWhite": "#fcf4dc",
+ "terminal.ansiBrightYellow": "#536870",
+ "terminal.selectionBackground": "#002831",
+ "terminalCursor.foreground": "#708284"
+ },
+ "workbench.colorTheme": "Betelgeuse Dark",
+ "workbench.iconTheme": "sweet-vscode-icons",
+ "workbench.startupEditor": "readme",
+ "workbench.welcomePage.walkthroughs.openOnInstall": false,
+ "yaml.format.printWidth": 160,
+ "yaml.format.singleQuote": true
+}
diff --git a/.config/asdf/default-npm-packages b/.config/asdf/default-npm-packages
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/.config/asdf/default-npm-packages
@@ -0,0 +1 @@
+
diff --git a/.config/bashtop/bashtop.cfg b/.config/bashtop/bashtop.cfg
index 729c4ee7..a99705d5 100644
--- a/.config/bashtop/bashtop.cfg
+++ b/.config/bashtop/bashtop.cfg
@@ -1 +1 @@
-color_theme="betelgeuse"
+color_theme="Betelgeuse"
diff --git a/.config/bat/config b/.config/bat/config
new file mode 100644
index 00000000..ce7d6687
--- /dev/null
+++ b/.config/bat/config
@@ -0,0 +1,11 @@
+# Set the theme to "TwoDark"
+--theme="TwoDark"
+
+# Show line numbers, Git modifications and file header (but no grid)
+--style="numbers,changes,header"
+
+# Use italic text on the terminal (not supported on all terminals)
+--italic-text=always
+
+# Use C++ syntax for Arduino .ino files
+--map-syntax "*.ino:C++"
diff --git a/.config/brew/whalebrew b/.config/brew/whalebrew
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/.config/brew/whalebrew
@@ -0,0 +1 @@
+
diff --git a/.config/chromium-flags.conf b/.config/chromium-flags.conf
new file mode 100644
index 00000000..a584570c
--- /dev/null
+++ b/.config/chromium-flags.conf
@@ -0,0 +1,11 @@
+# enable wayland
+--ozone-platform-hint=auto
+# force GPU acceleration
+--enable-gpu-rasterization
+--enable-zero-copy
+# enable vulkan
+--use-vulkan
+--enable-features=UseOzonePlatform,WebRTCPipeWireCapturer,VaapiVideoDecoder,VaapiVideoEncoder,WebUIDarkMode,WaylandWindowDecorations
+# custom settings
+--force-dark-mode
+--password-store=basic
diff --git a/.config/crontab/config b/.config/crontab/config
new file mode 100644
index 00000000..2e12672d
--- /dev/null
+++ b/.config/crontab/config
@@ -0,0 +1,14 @@
+
+
+PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin
+
+# 0 8 * * 0 $HOME/.scripts/domingobot.sh 2>&1 >> $HOME/.log/cron.log
+
+# * * * * * command to be executed
+# ┯ ┯ ┯ ┯ ┯
+# │ │ │ │ │
+# │ │ │ │ ╰───── day of week (0 - 6) (Sunday=0)
+# │ │ │ ╰─────── month (1 - 12)
+# │ │ ╰───────── day of month (1 - 31)
+# │ ╰─────────── hour (0 - 23)
+# ╰───────────── min (0 - 59)
diff --git a/.config/direnv/direnv.toml b/.config/direnv/direnv.toml
new file mode 100644
index 00000000..89ac394c
--- /dev/null
+++ b/.config/direnv/direnv.toml
@@ -0,0 +1,2 @@
+[global]
+load_dotenv = true
diff --git a/.config/fd/ignore b/.config/fd/ignore
new file mode 100644
index 00000000..f0355806
--- /dev/null
+++ b/.config/fd/ignore
@@ -0,0 +1,6 @@
+# EXCLUDE BACKUP FILES
+*.bak
+
+# EXCLUDE LIBRARIES ON MACOS
+/Library/**
+/Users/Library/**
diff --git a/.config/firejail/bitwarden.local b/.config/firejail/bitwarden.local
new file mode 100644
index 00000000..0578a0be
--- /dev/null
+++ b/.config/firejail/bitwarden.local
@@ -0,0 +1 @@
+seccomp !chroot
diff --git a/.config/firejail/chromium.local b/.config/firejail/chromium.local
new file mode 100644
index 00000000..ca40b6bd
--- /dev/null
+++ b/.config/firejail/chromium.local
@@ -0,0 +1,14 @@
+include whitelist-runuser-common.inc
+dbus-user.talk org.freedesktop.Notifications
+dbus-user.talk org.freedesktop.portal.Desktop
+ignore noroot
+whitelist ${RUNUSER}/pipewire-0
+whitelist /usr/share/pipewire/client.conf
+dbus-user.talk org.freedesktop.portal.*
+
+whitelist ${HOME}/pictures
+whitelist ${HOME}/go
+whitelist ${HOME}/git
+whitelist ${HOME}/documents
+whitelist ${HOME}/work
+whitelist /usr/share/pipewire/
diff --git a/.config/firejail/code.local b/.config/firejail/code.local
new file mode 100644
index 00000000..2977968c
--- /dev/null
+++ b/.config/firejail/code.local
@@ -0,0 +1,12 @@
+whitelist ${HOME}
+whitelist ${HOME}/.local/share
+noblacklist ${HOME}
+noblacklist ${PATH}/bash
+noblacklist ${PATH}/fish
+ignore private-bin
+ignore private-cache
+ignore private-dev
+ignore private-tmp
+ignore noroot
+ignore nosound
+ignore noexec /tmp
diff --git a/.config/firejail/gcloud.local b/.config/firejail/gcloud.local
new file mode 100644
index 00000000..c04579b8
--- /dev/null
+++ b/.config/firejail/gcloud.local
@@ -0,0 +1,4 @@
+# noblacklist ${HOME}
+# noblacklist ${HOME}/.ssh/
+# include allow-ssh.inc
+# whitelist /tmp/ssh-*
diff --git a/.config/firejail/google-chrome-stable.local b/.config/firejail/google-chrome-stable.local
new file mode 100644
index 00000000..ca40b6bd
--- /dev/null
+++ b/.config/firejail/google-chrome-stable.local
@@ -0,0 +1,14 @@
+include whitelist-runuser-common.inc
+dbus-user.talk org.freedesktop.Notifications
+dbus-user.talk org.freedesktop.portal.Desktop
+ignore noroot
+whitelist ${RUNUSER}/pipewire-0
+whitelist /usr/share/pipewire/client.conf
+dbus-user.talk org.freedesktop.portal.*
+
+whitelist ${HOME}/pictures
+whitelist ${HOME}/go
+whitelist ${HOME}/git
+whitelist ${HOME}/documents
+whitelist ${HOME}/work
+whitelist /usr/share/pipewire/
diff --git a/.config/firejail/slack.local b/.config/firejail/slack.local
new file mode 100644
index 00000000..de794c72
--- /dev/null
+++ b/.config/firejail/slack.local
@@ -0,0 +1,13 @@
+noblacklist ${PATH}/bash
+noblacklist ${PATH}/csh
+noblacklist ${PATH}/dash
+noblacklist ${PATH}/fish
+noblacklist ${PATH}/ksh
+noblacklist ${PATH}/sh
+noblacklist ${PATH}/tclsh
+noblacklist ${PATH}/tcsh
+noblacklist ${PATH}/zsh
+ignore private-bin
+ignore private-cache
+ignore private-dev
+ignore private-tmp
\ No newline at end of file
diff --git a/.config/firejail/thunderbird.local b/.config/firejail/thunderbird.local
new file mode 100644
index 00000000..3e198b59
--- /dev/null
+++ b/.config/firejail/thunderbird.local
@@ -0,0 +1,19 @@
+noblacklist /var/mail
+noblacklist /var/spool/mail
+whitelist /var/mail
+whitelist /var/spool/mail
+writable-var
+
+noblacklist ${PATH}/bash
+noblacklist ${PATH}/csh
+noblacklist ${PATH}/dash
+noblacklist ${PATH}/fish
+noblacklist ${PATH}/ksh
+noblacklist ${PATH}/sh
+noblacklist ${PATH}/tclsh
+noblacklist ${PATH}/tcsh
+noblacklist ${PATH}/zsh
+ignore private-bin
+ignore private-cache
+ignore private-dev
+ignore private-tmp
diff --git a/.config/git/attributes b/.config/git/attributes
new file mode 100644
index 00000000..e69de29b
diff --git a/.config/git/commit-template b/.config/git/commit-template
new file mode 100644
index 00000000..bfa2797d
--- /dev/null
+++ b/.config/git/commit-template
@@ -0,0 +1,14 @@
+# [optional scope]: (not more than 72 chars)
+#
+# [optional body] (not more than 72 chars)
+#
+# [optional footer(s)] (not more than 72 chars)
+#-------------------------------EXAMPLE----------------------------------
+# feat!(frontend): new button added in dashboard
+#
+# A new "Follow Us" button is added in your Account dashboard.
+# If you don't see it, please delete your browser cache and reload the
+# webpage.
+#
+# BREAKING CHANGE: this button replaces the custom button you have,
+# you need to reconfigure your custom button.
\ No newline at end of file
diff --git a/.config/git/ignore b/.config/git/ignore
new file mode 100644
index 00000000..8c20089b
--- /dev/null
+++ b/.config/git/ignore
@@ -0,0 +1,30 @@
+# COMPILED SOURCE
+*.o
+*.so
+*.com
+*.dll
+*.exe
+*.class
+
+# BINARY ARCHIVE FILES
+*.7z
+*.gz
+*.dmg
+*.iso
+*.jar
+*.rar
+*.tar
+*.zip
+*.war
+
+# LOGS
+*.log
+
+# OS RELATED FILES
+._*
+.Trashes
+Thumbs.db
+.DS_Store
+.DS_Store?
+ehthumbs.db
+.Spotlight-V100
diff --git a/.config/gtk-3.0/settings.ini b/.config/gtk-3.0/settings.ini
index 5e83eb1e..284af514 100644
--- a/.config/gtk-3.0/settings.ini
+++ b/.config/gtk-3.0/settings.ini
@@ -4,7 +4,7 @@ gtk-button-images=1
gtk-cursor-theme-name=Betelgeuse
gtk-decoration-layout=icon:minimize,maximize,close
gtk-enable-animations=1
-gtk-font-name=Montserrat Medium, Medium 10
+gtk-font-name=Montserrat Medium, Medium 11
gtk-icon-theme-name=Betelgeuse
gtk-menu-images=1
gtk-modules=appmenu-gtk-module
diff --git a/.config/k9s/plugin.yml b/.config/k9s/plugin.yml
new file mode 100644
index 00000000..32185fa6
--- /dev/null
+++ b/.config/k9s/plugin.yml
@@ -0,0 +1,70 @@
+plugin:
+ # dive image layers
+ dive:
+ shortCut: d
+ confirm: false
+ description: "Dive image"
+ scopes:
+ - containers
+ command: dive
+ background: false
+ args:
+ - $COL-IMAGE
+ # get all resources in a namespace using the krew get-all plugin
+ get-all:
+ shortCut: g
+ confirm: false
+ description: get-all
+ scopes:
+ - all
+ command: sh
+ background: false
+ args:
+ - -c
+ - "kubectl get-all -n $NAMESPACE | less"
+ edit-secret:
+ shortCut: Ctrl-X
+ confirm: false
+ description: "Edit Decoded Secret"
+ scopes:
+ - secrets
+ command: kubectl
+ background: false
+ args:
+ - modify-secret
+ - --namespace
+ - $NAMESPACE
+ - --context
+ - $CONTEXT
+ - $NAME
+ # View resource logs using stern
+ stern:
+ shortCut: Ctrl-L
+ confirm: false
+ description: "Logs "
+ scopes:
+ - pods
+ command: stern
+ background: false
+ args:
+ - --tail
+ - 50
+ - $FILTER
+ - -n
+ - $NAMESPACE
+ - --context
+ - $CONTEXT
+ # watch events on selected resources
+ # requires linux "watch" command
+ # change '-n' to adjust refresh time in seconds
+ watch-events:
+ shortCut: Shift-E
+ confirm: false
+ description: Get Events
+ scopes:
+ - all
+ command: sh
+ background: false
+ args:
+ - -c
+ - "watch -n 5 kubectl get events --context $CONTEXT --namespace $NAMESPACE --field-selector involvedObject.name=$NAME"
diff --git a/.config/mimeapps.list b/.config/mimeapps.list
new file mode 100644
index 00000000..eea471c0
--- /dev/null
+++ b/.config/mimeapps.list
@@ -0,0 +1,44 @@
+[Default Applications]
+application/json=text.desktop
+application/pdf=pdf.desktop
+application/x-extension-htm=firefox.desktop
+application/x-extension-html=firefox.desktop
+application/x-extension-shtml=firefox.desktop
+application/x-extension-xht=firefox.desktop
+application/x-extension-xhtml=firefox.desktop
+application/x-xpinstall=firefox.desktop
+application/xhtml+xml=firefox.desktop
+application/xml=firefox.desktop
+image/bmp=imv.desktop
+image/gif=imv.desktop
+image/heif=imv.desktop
+image/jpeg=imv.desktop
+image/png=imv.desktop
+image/tiff=imv.desktop
+image/vnd.zbrush.pcx=imv.desktop
+image/x-portable-anymap=imv.desktop
+image/x-portable-bitmap=imv.desktop
+image/x-portable-graymap=imv.desktop
+image/x-portable-pixmap=imv.desktop
+image/x-tga=imv.desktop
+image/x-xbitmap=imv.desktop
+text/html=firefox.desktop
+text/html=text.desktop
+text/plain=text.desktop
+text/tcl=text.desktop
+text/x-c++hdr=text.desktop
+text/x-c++src=text.desktop
+text/x-chdr=text.desktop
+text/x-csrc=text.desktop
+text/x-google-video-pointer=text.desktop
+text/x-java=text.desktop
+text/x-makefile=text.desktop
+text/x-moc=text.desktop
+text/x-pascal=text.desktop
+text/x-tex=text.desktop
+x-scheme-handler/chrome=firefox.desktop
+x-scheme-handler/http=firefox.desktop
+x-scheme-handler/http=firefox.desktop
+x-scheme-handler/https=firefox.desktop
+x-scheme-handler/https=firefox.desktop
+x-scheme-handler/terminal=kitty.desktop
diff --git a/.config/npm/npmrc.tmpl.TODO b/.config/npm/npmrc.tmpl.TODO
new file mode 100644
index 00000000..25ff83fa
--- /dev/null
+++ b/.config/npm/npmrc.tmpl.TODO
@@ -0,0 +1,6 @@
+cache=${XDG_CACHE_HOME}/npm
+init.license=MIT
+init.version=0.0.1
+init-module=${XDG_CONFIG_HOME}/npm/config/npm-init.js
+prefix=${XDG_DATA_HOME}/npm
+store-dir=${XDG_DATA_HOME}/pnpm-store
diff --git a/.config/oh-my-posh/Betelgeuse-minimal.omp.json b/.config/oh-my-posh/Betelgeuse-minimal.omp.json
new file mode 100644
index 00000000..3926e60b
--- /dev/null
+++ b/.config/oh-my-posh/Betelgeuse-minimal.omp.json
@@ -0,0 +1,111 @@
+{
+ "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
+ "console_title_template": "{{if .Segments.Git.RepoName}} {{.Segments.Git.RepoName}} {{else}} {{.Folder}} {{end}}",
+ "blocks": [
+ {
+ "type": "prompt",
+ "alignment": "left",
+ "newline": true,
+ "segments": [
+ {
+ "type": "session",
+ "foreground": "#757575",
+ "properties": {
+ "display_host": true
+ },
+ "style": "plain",
+ "template": "\u250c {{ if .SSHSession }}\uf817 {{ end }}{{ .UserName }}@{{ .HostName }} "
+ },
+ {
+ "type": "path",
+ "background": "#91ddff",
+ "foreground": "#100e23",
+ "powerline_symbol": "\ue0b0",
+ "properties": {
+ "style": "agnoster_full"
+ },
+ "style": "powerline",
+ "template": " {{ .Path }} "
+ },
+ {
+ "type": "git",
+ "style": "powerline",
+ "powerline_symbol": "\ue0b0",
+ "foreground": "#100e23",
+ "background": "#95ffa4",
+ "background_templates": [
+ "{{ if or (.Working.Changed) (.Staging.Changed) }}#ff9248{{ end }}",
+ "{{ if and (gt .Ahead 0) (gt .Behind 0) }}#f26d50{{ end }}",
+ "{{ if gt .Ahead 0 }}#89d1dc{{ end }}",
+ "{{ if gt .Behind 0 }}#c5b6ad{{ end }}"
+ ],
+ "template": " {{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }} {{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} \u2502{{ end }}{{ if .Staging.Changed }} {{ .Staging.String }}{{ end }}{{ if gt .StashCount 0 }} {{ .StashCount }}{{ end }} ",
+ "properties": {
+ "branch_ahead_icon": "\u2191",
+ "branch_behind_icon": "\u2193",
+ "branch_gone": "\u2262",
+ "branch_icon": "\ue0a0 ",
+ "branch_identical_icon": "\u2261",
+ "cherry_pick_icon": "\u2713 ",
+ "commit_icon": "\u25b7 ",
+ "fetch_stash_count": true,
+ "fetch_status": true,
+ "merge_icon": "\u25f4 ",
+ "no_commits_icon": "[no commits]",
+ "rebase_icon": "\u2c62 ",
+ "tag_icon": "\u25b6 ",
+ "untracked_modes": {
+ "/Users/user/Projects/oh-my-posh/": "no"
+ }
+ }
+ },
+ {
+ "type": "terraform",
+ "background": "#ffee58",
+ "foreground": "#100e23",
+ "powerline_symbol": "\ue0b0",
+ "style": "powerline",
+ "template": " {{ .WorkspaceName }}{{ if .Version }} {{ .Version }}{{ end }} "
+ },
+ {
+ "type": "exit",
+ "background": "#ff8080",
+ "foreground": "#ffffff",
+ "powerline_symbol": "\ue0b0",
+ "style": "powerline",
+ "template": " {{ if gt .Code 0 }}error{{ else }}\uf42e{{ end }} "
+ },
+ {
+ "type": "time",
+ "foreground": "#689f38",
+ "properties": {
+ "time_format": "15:04:05"
+ },
+ "style": "plain",
+ "template": " <#757575,>|> {{ .CurrentDate | date .Format }}"
+ }
+ ]
+ },
+ {
+ "type": "prompt",
+ "alignment": "left",
+ "newline": true,
+ "segments": [
+ {
+ "type": "text",
+ "foreground": "#757575",
+ "style": "plain",
+ "template": "\u2514"
+ },
+ {
+ "type": "text",
+ "foreground": "#ffffff",
+ "style": "plain",
+ "template": "$"
+ }
+ ]
+ }
+ ],
+ "final_space": true,
+ "version": 2
+}
diff --git a/.config/oh-my-posh/Betelgeuse.omp.json b/.config/oh-my-posh/Betelgeuse.omp.json
new file mode 100644
index 00000000..72555fa0
--- /dev/null
+++ b/.config/oh-my-posh/Betelgeuse.omp.json
@@ -0,0 +1,126 @@
+{
+ "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
+ "blocks": [
+ {
+ "alignment": "left",
+ "segments": [
+ {
+ "background": "#2e9599",
+ "foreground": "#ffffff",
+ "leading_diamond": "\ue0b6",
+ "powerline_symbol": "\ue0b0",
+ "style": "diamond",
+ "template": "\uf91c {{ .HostName }} ",
+ "type": "session"
+ },
+ {
+ "background": "#D51111",
+ "foreground": "#ffffff",
+ "powerline_symbol": "\ue0b0",
+ "properties": {
+ "home_icon": "\uf46d",
+ "folder_separator_icon": " \ue0b1> ",
+ "folder_icon": "\uf115",
+ "style": "agnoster"
+ },
+ "style": "powerline",
+ "template": " {{ path .Path .Location }} ",
+ "type": "path"
+ },
+ {
+ "background": "#c19c00",
+ "background_templates": [
+ "{{ if or (.Working.Changed) (.Staging.Changed) }}#FFEB3B{{ end }}",
+ "{{ if and (gt .Ahead 0) (gt .Behind 0) }}#FFA300{{ end }}",
+ "{{ if gt .Ahead 0 }}#FF7070{{ end }}",
+ "{{ if gt .Behind 0 }}#90F090{{ end }}"
+ ],
+ "foreground": "#000000",
+ "powerline_symbol": "\ue0b0",
+ "properties": {
+ "fetch_stash_count": true,
+ "fetch_status": true,
+ "fetch_upstream_icon": true
+ },
+ "style": "powerline",
+ "template": " \uf113 {{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }} \uf044 {{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} |{{ end }}{{ if .Staging.Changed }} \uf046 {{ .Staging.String }}{{ end }}{{ if gt .StashCount 0 }} \uf692 {{ .StashCount }}{{ end }} ",
+ "type": "git"
+ }
+ ],
+ "type": "prompt"
+ },
+ {
+ "alignment": "right",
+ "segments": [
+ {
+ "background": "#303030",
+ "foreground": "#3C873A",
+ "leading_diamond": "\ue0b6",
+ "properties": {
+ "fetch_package_manager": true,
+ "npm_icon": " <#cc3a3a>\ue5fa> ",
+ "yarn_icon": " <#348cba>\uf61a>"
+ },
+ "style": "diamond",
+ "template": "\ue718 {{ if .PackageManagerIcon }}{{ .PackageManagerIcon }} {{ end }}{{ .Full }}",
+ "trailing_diamond": "\ue0b4 ",
+ "type": "node"
+ },
+ {
+ "background": "#306998",
+ "foreground": "#FFE873",
+ "leading_diamond": "\ue0b6",
+ "style": "diamond",
+ "template": "\ue235 {{ if .Error }}{{ .Error }}{{ else }}{{ if .Venv }}{{ .Venv }} {{ end }}{{ .Full }}{{ end }}",
+ "trailing_diamond": "\ue0b4 ",
+ "type": "python"
+ },
+ {
+ "background": "#ffffff",
+ "foreground": "#06aad5",
+ "leading_diamond": "\ue0b6",
+ "style": "diamond",
+ "template": "\ufcd1 {{ if .Error }}{{ .Error }}{{ else }}{{ .Full }}{{ end }}",
+ "trailing_diamond": "\ue0b4 ",
+ "type": "go"
+ },
+ {
+ "background": "#2e9599",
+ "foreground": "#fff",
+ "background_templates": [
+ "{{ if gt .Code 0 }}#D51111{{ end }}"
+ ],
+ "leading_diamond": "\ue0b6",
+ "properties": {
+ "time_format": "_2, 15:04:05"
+ },
+ "style": "diamond",
+ "template": " \uf5ef {{ .CurrentDate | date .Format }} ",
+ "trailing_diamond": "\ue0b4",
+ "type": "time"
+ }
+ ],
+ "type": "prompt"
+ },
+ {
+ "alignment": "left",
+ "newline": true,
+ "segments": [
+ {
+ "foreground": "#FFF",
+ "foreground_templates": [
+ "{{ if gt .Code 0 }}#D51111{{ end }}"
+ ],
+ "style": "plain",
+ "template": " \uf0a4 ",
+ "type": "text"
+ }
+ ],
+ "type": "prompt"
+ }
+ ],
+ "console_title_template": "{{ .Folder }}",
+ "final_space": true,
+ "osc99": true,
+ "version": 2
+}
diff --git a/.config/pgcli/config b/.config/pgcli/config
new file mode 100644
index 00000000..60ba948f
--- /dev/null
+++ b/.config/pgcli/config
@@ -0,0 +1,188 @@
+# vi: ft=dosini
+[main]
+
+# Enables context sensitive auto-completion. If this is disabled the all
+# possible completions will be listed.
+smart_completion = True
+
+# Display the completions in several columns. (More completions will be
+# visible.)
+wider_completion_menu = False
+
+# Multi-line mode allows breaking up the sql statements into multiple lines. If
+# this is set to True, then the end of the statements must have a semi-colon.
+# If this is set to False then sql statements can't be split into multiple
+# lines. End of line (return) is considered as the end of the statement.
+multi_line = False
+
+# If multi_line_mode is set to "psql", in multi-line mode, [Enter] will execute
+# the current input if the input ends in a semicolon.
+# If multi_line_mode is set to "safe", in multi-line mode, [Enter] will always
+# insert a newline, and [Esc] [Enter] or [Alt]-[Enter] must be used to execute
+# a command.
+multi_line_mode = psql
+
+# Destructive warning mode will alert you before executing a sql statement
+# that may cause harm to the database such as "drop table", "drop database"
+# or "shutdown".
+destructive_warning = True
+
+# Enables expand mode, which is similar to `\x` in psql.
+expand = False
+
+# Enables auto expand mode, which is similar to `\x auto` in psql.
+auto_expand = False
+
+# If set to True, table suggestions will include a table alias
+generate_aliases = False
+
+# log_file location.
+# In Unix/Linux: ~/.config/pgcli/log
+# In Windows: %USERPROFILE%\AppData\Local\dbcli\pgcli\log
+# %USERPROFILE% is typically C:\Users\{username}
+log_file = default
+
+# keyword casing preference. Possible values "lower", "upper", "auto"
+keyword_casing = auto
+
+# casing_file location.
+# In Unix/Linux: ~/.config/pgcli/casing
+# In Windows: %USERPROFILE%\AppData\Local\dbcli\pgcli\casing
+# %USERPROFILE% is typically C:\Users\{username}
+casing_file = default
+
+# If generate_casing_file is set to True and there is no file in the above
+# location, one will be generated based on usage in SQL/PLPGSQL functions.
+generate_casing_file = False
+
+# Casing of column headers based on the casing_file described above
+case_column_headers = True
+
+# history_file location.
+# In Unix/Linux: ~/.config/pgcli/history
+# In Windows: %USERPROFILE%\AppData\Local\dbcli\pgcli\history
+# %USERPROFILE% is typically C:\Users\{username}
+history_file = default
+
+# Default log level. Possible values: "CRITICAL", "ERROR", "WARNING", "INFO"
+# and "DEBUG". "NONE" disables logging.
+log_level = INFO
+
+# Order of columns when expanding * to column list
+# Possible values: "table_order" and "alphabetic"
+asterisk_column_order = table_order
+
+# Whether to qualify with table alias/name when suggesting columns
+# Possible values: "always", never" and "if_more_than_one_table"
+qualify_columns = if_more_than_one_table
+
+# When no schema is entered, only suggest objects in search_path
+search_path_filter = False
+
+# Default pager.
+# By default 'PAGER' environment variable is used
+# pager = less -SRXF
+
+# Timing of sql statments and table rendering.
+timing = True
+
+# Table format. Possible values: psql, plain, simple, grid, fancy_grid, pipe,
+# ascii, double, github, orgtbl, rst, mediawiki, html, latex, latex_booktabs,
+# textile, moinmoin, jira, vertical, tsv, csv.
+# Recommended: psql, fancy_grid and grid.
+table_format = psql
+
+# Syntax Style. Possible values: manni, igor, xcode, vim, autumn, vs, rrt,
+# native, perldoc, borland, tango, emacs, friendly, monokai, paraiso-dark,
+# colorful, murphy, bw, pastie, paraiso-light, trac, default, fruity
+syntax_style = default
+
+# Keybindings:
+# When Vi mode is enabled you can use modal editing features offered by Vi in the REPL.
+# When Vi mode is disabled emacs keybindings such as Ctrl-A for home and Ctrl-E
+# for end are available in the REPL.
+vi = True
+
+# Error handling
+# When one of multiple SQL statements causes an error, choose to either
+# continue executing the remaining statements, or stopping
+# Possible values "STOP" or "RESUME"
+on_error = STOP
+
+# Set threshold for row limit. Use 0 to disable limiting.
+row_limit = 1000
+
+# Skip intro on startup and goodbye on exit
+less_chatty = True
+
+# Postgres prompt
+# \t - Current date and time
+# \u - Username
+# \h - Short hostname of the server (up to first '.')
+# \H - Hostname of the server
+# \d - Database name
+# \p - Database port
+# \i - Postgres PID
+# \# - "@" sign if logged in as superuser, '>' in other case
+# \n - Newline
+# \dsn_alias - name of dsn alias if -D option is used (empty otherwise)
+# \x1b[...m - insert ANSI escape sequence
+# eg: prompt = '\x1b[35m\u@\x1b[32m\h:\x1b[36m\d>'
+prompt = '\u@\h:\d> '
+
+# Number of lines to reserve for the suggestion menu
+min_num_menu_lines = 4
+
+# Character used to left pad multi-line queries to match the prompt size.
+multiline_continuation_char = ''
+
+# The string used in place of a null value.
+null_string = ''
+
+# manage pager on startup
+enable_pager = True
+
+# Use keyring to automatically save and load password in a secure manner
+keyring = False
+
+# Custom colors for the completion menu, toolbar, etc.
+[colors]
+completion-menu.completion.current = 'bg:#ffffff #000000'
+completion-menu.completion = 'bg:#008888 #ffffff'
+completion-menu.meta.completion.current = 'bg:#44aaaa #000000'
+completion-menu.meta.completion = 'bg:#448888 #ffffff'
+completion-menu.multi-column-meta = 'bg:#aaffff #000000'
+scrollbar.arrow = 'bg:#003333'
+scrollbar = 'bg:#00aaaa'
+selected = '#ffffff bg:#6666aa'
+search = '#ffffff bg:#4444aa'
+search.current = '#ffffff bg:#44aa44'
+bottom-toolbar = 'bg:#222222 #aaaaaa'
+bottom-toolbar.off = 'bg:#222222 #888888'
+bottom-toolbar.on = 'bg:#222222 #ffffff'
+search-toolbar = 'noinherit bold'
+search-toolbar.text = 'nobold'
+system-toolbar = 'noinherit bold'
+arg-toolbar = 'noinherit bold'
+arg-toolbar.text = 'nobold'
+bottom-toolbar.transaction.valid = 'bg:#222222 #00ff5f bold'
+bottom-toolbar.transaction.failed = 'bg:#222222 #ff005f bold'
+
+# style classes for colored table output
+output.header = "#00ff5f bold"
+output.odd-row = ""
+output.even-row = ""
+
+# Named queries are queries you can execute by name.
+[named queries]
+
+# DSN to call by -D option
+[alias_dsn]
+# example_dsn = postgresql://[user[:password]@][netloc][:port][/dbname]
+
+# Format for number representation
+# for decimal "d" - 12345678, ",d" - 12,345,678
+# for float "g" - 123456.78, ",g" - 123,456.78
+[data_formats]
+decimal = ""
+float = ""
diff --git a/.config/plasma/plasmoids.yml b/.config/plasma/plasmoids.yml
new file mode 100644
index 00000000..98d17ec5
--- /dev/null
+++ b/.config/plasma/plasmoids.yml
@@ -0,0 +1,24 @@
+---
+plasmoids:
+ - name: Application Title
+ link: https://store.kde.org/p/1199712/
+ - name: Command Output
+ link: https://store.kde.org/p/1166510/
+ - name: Compact Shutdown
+ link: https://store.kde.org/p/1483671
+ - name: Configurable Button
+ link: https://store.kde.org/p/1297839
+ - name: Event Calendar
+ link: https://store.kde.org/p/998901
+ - name: Netspeed Widget
+ link: https://store.kde.org/p/998895/
+ - name: Server Status
+ link: https://store.kde.org/p/1190292
+ - name: Plasma Configuration Saver
+ link: https://store.kde.org/p/1298955/
+ - name: Webslice
+ link: https://store.kde.org/p/998902
+ - name: Window Title
+ link: https://store.kde.org/p/1274218/
+ - name: Wunderground Extended
+ link: https://store.kde.org/p/1756638/
diff --git a/.config/plasmarc b/.config/plasmarc
index 597e9c56..0e4024fb 100644
--- a/.config/plasmarc
+++ b/.config/plasmarc
@@ -1,2 +1,2 @@
[Theme]
-name=Betelgeuse
\ No newline at end of file
+name=Betelgeuse
diff --git a/.config/rclone/merge_rclone.conf b/.config/rclone/merge_rclone.conf
new file mode 100644
index 00000000..3ee32905
--- /dev/null
+++ b/.config/rclone/merge_rclone.conf
@@ -0,0 +1,29 @@
+{{- if and (ne .user.CLOUDFLARE_ACCESS_KEY_ID "") (ne .user.CLOUDFLARE_SECRET_ACCESS_KEY "") (ne .user.CLOUDFLARE_R2_ACCOUNT_ID "") }}
+#!/usr/bin/env bash
+
+# Consider https://github.com/dustinsand/blockinfile
+CONFIG_FILE="$HOME/.config/rclone/rclone.conf"
+if cat "$CONFIG_FILE" | grep '# MEGABYTE LABS MANAGED r2-user'; then
+ # TODO: Remove old block
+ START_LINE="$(echo `grep -n -m 1 "# MEGABYTE LABS MANAGED r2-user" .zshrc | cut -f1 -d ":"`)"
+ END_LINE="$(echo `grep -n -m 1 "# MEGABYTE LABS MANAGED r2-user" .zshrc | cut -f1 -d ":"`)"
+ if command -v gsed > /dev/null; then
+ gsed -i "$START_LINE,$END_LINEd" "$CONFIG_FILE"
+ else
+ sed -i "$START_LINE,$END_LINEd" "$CONFIG_FILE"
+ fi
+fi
+
+tee -a "$CONFIG_FILE" > /dev/null < /dev/null 2>&1
+ asdf plugin update --all > /dev/null 2>&1
+ diff <(cat ~/.tool-versions | awk '{print $1}' | xargs -I {} bash -c 'echo {} $(asdf latest {})') <(cat ~/.tool-versions)
+}
+
+# Change directories and view contents at the same time
+cl() {
+ DIR="$*"
+ # if no DIR given, go home
+ if [ $# -lt 1 ]; then
+ DIR=$HOME
+ fi
+ builtin cd "${DIR}" &&
+ # use your preferred ls command
+ ls -F --color=auto
+}
+
+# Safer cp with progress bar and backup to /tmp
+cpv() {
+ rsync -pogbr -hhh --backup-dir="/tmp/rsync-${USERNAME}" -e /dev/null --progress "$@"
+}
+
+# Checks status of a website on downforeveryoneorjustme.com
+down4me() {
+ curl -s "http://www.downforeveryoneorjustme.com/$1" | sed '/just you/!d;s/<[^>]*>//g'
+}
+
+# Easier version of find command
+find() {
+ if [ $# = 1 ]; then
+ # shellcheck disable=SC2145
+ command find . -iname "*$@*"
+ else
+ command find "$@"
+ fi
+}
+
+# Opens current repository in browser
+gitopen() {
+ git remote -v | head -n 1 | awk -F "@" '{print $2}' | awk -F " " '{print $1}' | sed 's/:/\//g' | sed 's/.git//g' | awk '{print "http://"$1}' | xargs open
+}
+
+# Open Mac OS X desktop on a Linux machine
+macosx() {
+ docker run -it --device /dev/kvm -p 50922:10022 -v /tmp/.X11-unix:/tmp/.X11-unix -e "DISPLAY=${DISPLAY:-:0.0}" sickcodes/docker-osx:big-sur
+}
+
+# Generate a random string of X length
+randomstring() {
+ if [ -z "$1" ]; then
+ head /dev/urandom | tr -dc A-Za-z0-9 | head -c "$1"
+ else
+ echo "Pass the number of characters you would like the string to be. Example: randomstring 14"
+ fi
+}
+
+# Reset Docker to factory settings
+resetdocker() {
+ set +e
+ CONTAINER_COUNT="$(docker ps -a -q | wc -l)"
+ if [ "$CONTAINER_COUNT" -gt 0 ]; then
+ docker stop "$(docker ps -a -q)"
+ docker rm "$(docker ps -a -q)"
+ fi
+ VOLUME_COUNT="$(docker volume ls -q | wc -l)"
+ if [ "$VOLUME_COUNT" -gt 0 ]; then
+ docker volume rm "$(docker volume ls -q)"
+ fi
+ NETWORK_COUNT="$(docker network ls -q | wc -l)"
+ if [ "$NETWORK_COUNT" -gt 0 ]; then
+ docker network rm "$(docker network ls -q)"
+ fi
+ docker system prune -a --force
+}
+
+# ripgrep-all
+rgafzf() {
+ RG_PREFIX="rga --files-with-matches"
+ local file
+ file="$(
+ FZF_DEFAULT_COMMAND="$RG_PREFIX '$1'" \
+ fzf --sort --preview="[[ ! -z {} ]] && rga --pretty --context 5 {q} {}" \
+ --phony -q "$1" \
+ --bind "change:reload:$RG_PREFIX {q}" \
+ --preview-window="70%:wrap"
+ )" &&
+ echo "opening $file" &&
+ xdg-open "$file"
+}
+
+# Easy file sharing from the command line, using transfer.sh
+transfer() {
+ if [ $# -eq 0 ]; then
+ echo -e "No arguments specified.\nUsage:\n transfer \n ... | transfer " >&2
+ return 1
+ fi
+ if tty -s; then
+ file="$1"
+ file_name=$(basename "$file")
+ if [ ! -e "$file" ]; then
+ echo "$file: No such file or directory" >&2
+ return 1
+ fi
+ if [ -d "$file" ]; then
+ file_name="$file_name.zip"
+ (cd "$file" && zip -r -q - .) | curl --progress-bar --upload-file "-" "https://transfer.sh/$file_name" | tee /dev/null,
+ else
+ curl --progress-bar --upload-file "-" "https://transfer.sh/$file_name" <"$file" | tee /dev/null
+ fi
+ else
+ file_name=$1
+ curl --progress-bar --upload-file "-" "https://transfer.sh/$file_name" | tee /dev/null
+ fi
+}
+
+update-all() {
+ brew update
+ brew upgrade
+ brew upgrade --cask --greedy
+ brew cleanup --prune=1
+ asdf update || true
+ asdf plugin-update --all
+ rustup self update || true
+ rustup update || true
+ npm update -g || true
+ chezmoi upgrade
+ z4h update
+}
diff --git a/.config/shell/motd b/.config/shell/motd
new file mode 100644
index 00000000..5f45edcc
--- /dev/null
+++ b/.config/shell/motd
@@ -0,0 +1,25 @@
+### MOTD
+# Add file named .hushlogin in the user's home directory to disable the MOTD
+if [ "$BASH_SUPPORT" = 'true' ] && [ ! -f ~/.hushlogin ] && [ "$SHLVL" -eq 1 ]; then
+ if [ -f "$HOME/.local/scripts/motd.bash" ] && { [ -n "$SSH_CONNECTION" ] && [[ $- == *i* ]]; } || command -v qubes-vmexec > /dev/null || command -v qubes-dom0-update > /dev/null || { [ -d /Applications ] && [ -d /System ]; }; then
+ if { [ -z "$MOTD" ] || [ "$MOTD" -ne 0 ]; } && [[ "$(hostname)" != *'-minimal' ]]; then
+ . "$HOME/.local/scripts/motd.bash"
+ # TODO - -- services
+ if [ -n "$SSH_CONNECTION" ]; then
+ # SSH
+ bash_motd --banner --processor --memory --diskspace --docker --updates --letsencrypt --login
+ elif command -v qubes-vmexec > /dev/null; then
+ # Qubes AppVM
+ bash_motd --banner --memory --diskspace --docker --updates
+ elif command -v qubes-dom0-update > /dev/null; then
+ # Qubes dom0
+ bash_motd --banner --updates
+ elif [ -d /Applications ] && [ -d /System ]; then
+ # macOS
+ bash_motd --banner
+ else
+ bash_motd --banner --processor --memory --diskspace --docker --updates --letsencrypt --login
+ fi
+ fi
+ fi
+fi
diff --git a/.config/shell/profile b/.config/shell/profile
new file mode 100644
index 00000000..2d5f38d0
--- /dev/null
+++ b/.config/shell/profile
@@ -0,0 +1,149 @@
+# shellcheck disable=SC1090,SC1091
+
+# Aliases / Functions / Exports
+export XDG_CONFIG_HOME="$HOME/.config"
+if [ -f "$XDG_CONFIG_HOME/shell/exports" ]; then
+ . "$XDG_CONFIG_HOME/shell/exports"
+fi
+if [ -f "$XDG_CONFIG_HOME/shell/aliases" ]; then
+ . "$XDG_CONFIG_HOME/shell/aliases"
+fi
+if [ -f "$XDG_CONFIG_HOME/shell/functions" ]; then
+ . "$XDG_CONFIG_HOME/shell/functions"
+fi
+
+### Colorize
+alias grep='grep --color=auto'
+alias fgrep='fgrep --color=auto'
+alias egrep='egrep --color=auto'
+alias diff='diff --color=auto'
+alias ip='ip --color=auto'
+alias pacman='pacman --color=auto'
+
+### Aliases (better defaults for simple commands)
+alias cp='cp -v'
+alias rm='rm -I'
+alias mv='mv -iv'
+alias ln='ln -sriv'
+alias xclip='xclip -selection c'
+command -v vim > /dev/null && alias vi='vim'
+
+### TOP - order based on preference of "top" application (last item will always be chosen if installed, e.g. glances)
+command -v htop > /dev/null && alias top='htop'
+command -v gotop > /dev/null && alias top='gotop -p $([ "$COLOR_SCHEME" = "light" ] && echo "-c default-dark")'
+command -v ytop > /dev/null && alias top='ytop -p $([ "$COLOR_SCHEME" = "light" ] && echo "-c default-dark")'
+command -v btm > /dev/null && alias top='btm $([ "$COLOR_SCHEME" = "light" ] && echo "--color default-light")'
+# themes for light/dark color-schemes inside ~/.config/bashtop; Press ESC to open the menu and change the theme
+command -v bashtop > /dev/null && alias top='bashtop'
+command -v bpytop > /dev/null && alias top='bpytop'
+command -v glances > /dev/null && alias top='glances'
+
+### Bash / ZSH
+if [ "$BASH_SUPPORT" = 'true' ]; then
+ ### OS Detection
+ if [ -f /etc/os-release ]; then
+ . /etc/os-release
+ if [ "$ID" = 'alpine' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'arch' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'centos' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'coreos' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'debian' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'deepin' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'elementary' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'endeavour' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'freebsd' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'gentoo' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'kali' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'linuxmint' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'manjaro' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'nixos' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'openbsd' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'opensuse' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'parrot' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'pop_os' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'raspberry_pi' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'redhat' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'fedora' ]; then
+ OS_ICON=""
+ elif [ "$ID" = 'ubuntu' ]; then
+ OS_ICON=""
+ else
+ OS_ICON=""
+ fi
+ else
+ if [ -d /Applications ] && [ -d /Library ] && [ -d /System ]; then
+ # macOS
+ OS_ICON=""
+ else
+ OS_ICON=""
+ fi
+ fi
+
+ ### ASDF
+ if [ -f "$ASDF_DIR/asdf.sh" ]; then
+ . "$ASDF_DIR/asdf.sh"
+ fi
+
+ ### Directory Colors
+ if [ -f "$XDG_CONFIG_HOME/shell/lscolors.sh" ]; then
+ . "$XDG_CONFIG_HOME/shell/lscolors.sh"
+ fi
+
+ ### fzf-git
+ if [ -f "$HOME/.local/scripts/fzf-git.bash" ]; then
+ . "$HOME/.local/scripts/fzf-git.bash"
+ fi
+
+ ### MOTD
+ if [ -f "$XDG_CONFIG_HOME/shell/motd" ]; then
+ . "$XDG_CONFIG_HOME/shell/motd"
+ fi
+fi
+
+### Cargo
+if [ -f "$CARGO_HOME/env" ]; then
+ . "$CARGO_HOME/env"
+fi
+
+### Docker Functions / Aliases
+if [ -f "$HOME/.local/scripts/docker-functions.bash" ]; then
+ . "$HOME/.local/scripts/docker-functions.bash"
+fi
+
+### fzf-tmux
+if [ -f "$HOME/.local/scripts/fzf-tmux.bash" ]; then
+ . "$HOME/.local/scripts/fzf-tmux.bash"
+fi
+
+### SDKMan
+if command -v brew > /dev/null && command -v sdkman-cli > /dev/null; then
+ export SDKMAN_DIR="$(brew --prefix sdkman-cli)/libexec"
+ . "$SDKMAN_DIR/bin/sdkman-init.sh"
+elif [ -f "$SDKMAN_DIR/bin/sdkman-init.sh" ]; then
+ export SDKMAN_DIR="$XDG_DATA_HOME/sdkman"
+ . "$SDKMAN_DIR/bin/sdkman-init.sh"
+fi
+
+### VIM
+export GVIMINIT='let $MYGVIMRC="$XDG_CONFIG_HOME/vim/gvimrc" | source $MYGVIMRC'
+export VIMINIT='let $MYVIMRC="$XDG_CONFIG_HOME/vim/vimrc" | source $MYVIMRC'
diff --git a/.config/wget/wgetrc b/.config/wget/wgetrc
new file mode 100644
index 00000000..eb531a17
--- /dev/null
+++ b/.config/wget/wgetrc
@@ -0,0 +1,38 @@
+# Use the server-provided last modification date, if available
+timestamping = on
+
+# Do not go up in the directory structure when downloading recursively
+no_parent = on
+
+# Wait 60 seconds before timing out. This applies to all timeouts: DNS, connect and read. (The default read timeout is 15 minutes!)
+timeout = 60
+
+# Retry a few times when a download fails, but don’t overdo it. (The default is 20!)
+tries = 3
+
+# Retry even when the connection was refused
+retry_connrefused = on
+
+# Use the last component of a redirection URL for the local file name
+trust_server_names = on
+
+# Follow FTP links from HTML documents by default
+follow_ftp = on
+
+# Add a `.html` extension to `text/html` or `application/xhtml+xml` files that lack one, or a `.css` extension to `text/css` files that lack one
+adjust_extension = on
+
+# Use UTF-8 as the default system encoding
+# Disabled as it makes `wget` builds that don’t support this feature unusable.
+# Does anyone know how to conditionally configure a wget setting?
+# http://unix.stackexchange.com/q/34730/6040
+#local_encoding = UTF-8
+
+# Ignore `robots.txt` and ``
+robots = off
+
+# Print the HTTP and FTP server responses
+server_response = on
+
+# Disguise as IE 9 on Windows 7
+user_agent = Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
diff --git a/.config/youtube-dl/config b/.config/youtube-dl/config
new file mode 100644
index 00000000..c90e8e6f
--- /dev/null
+++ b/.config/youtube-dl/config
@@ -0,0 +1,6 @@
+# saner output
+-o %(title)s.%(ext)s
+
+# Aira2c
+--external-downloader aria2c
+--external-downloader-args '-c -j 6 -x 6 -s 6 -k 1M'
diff --git a/.gnupg/public/linux.wazuh.sig b/.gnupg/public/linux.wazuh.sig
new file mode 100644
index 00000000..e69de29b
diff --git a/.gnupg/public/qubes.uman.sig b/.gnupg/public/qubes.uman.sig
new file mode 100644
index 00000000..3a30c78d
--- /dev/null
+++ b/.gnupg/public/qubes.uman.sig
@@ -0,0 +1,85 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBFdt07cBEADGBsfWMKLODNkW8ro4ltREGK7KVgI1ETvgc1inGa79lW33F5/z
+cP8vwVTwn1ntb6hFvQPDkrU2ewy0pYyXahSRPKsGn8ldKzjA5O/iACkpLdEgl8//
+3xw5XUKF16KO16w/OdcfR+6bxveMN4tr5yxEFSkpoviLzJdCcOfduaLlKijGsDhW
+Ay36UWrbNiV5HsplM3hQy6CTjYe1/1psvf0B1QM7OXJMKgGtY6BSDoZ8etnhVYHy
+/yGSDuof2cx9WTX3hnkX9db1YucSwUHq2BVqpjv5osUilEjMNPcMybpxv4UHZ25k
+kh73QEqrwMhodFvwBW6M3h5nG7YbgBFPMMftVJExpbvwoKxFVclY0u+oGCxvxE2f
+X5vA418ehF8ILN8NJA5DVv38bVN7SG1w7PUcpXuG1GL3SP7gDqdEJ2MOqIqSokAw
+uMtDo3pRBkrVjbIxiJ1z37fVcl17ZI6s/Fg3IEd61VAgwObD5mOEmkJt1m8tsqGx
+iVdr16yR7LfdBXZplCDBYzRcWlslSbSwG7878bLJoc05eXxgr8jq3nlRYbCjXgHM
+FnfDVLbeyyfyGNqA5AMlQB9o5Iv12iHFuN9z15Ie6d2ds59Cw5d5SOyya9vLUIfD
+W+V5ypCW/4sf1w8KQhPUu49OLwgcyeXPismEpSj3XIPF0LUFFrfAbPHlMQARAQAB
+tDl1bm1hbiAoUXViZXMgT1Mgc2lnbmluZyBrZXkpIDx1bm1hbkB0aGlyZGV5ZXNl
+Y3VyaXR5Lm9yZz6JAjcEEwEIACECGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AF
+Ald0ZXgACgkQiz8w+cjAwu/cmw/+LLkkSf0QfiSiKhqWQiXFRYngKxAAaiLZV3kc
+LCQsZeg7eS8GZYJx19vplBhpGarPGw0REZrvPMfZBcK1YKM7Dt7VfUv49Cd3jPb0
+7W6pMfOOcuQO1UV1mqskziWvW1ooikc/HUJA2kIoTzxr0McFySPdoKtH8MsoEecK
+fMqYIjNp31w6JEsQRVzNVmaVrEj8+w1e6miVNpKvokMSNF/x44tpt/Y2C4g1Gxw6
+lPZYunJsTJK69taJbVDVCRvwwhJwHwbIqJWNIpoVDOpZjOvQlz0GPjTiBrA15AtG
+eU6NmMJ5qc9Sw/l3gTfh5SCANo5Q/7s+CX5xFpeGwJx6YDpjZCvR78SGi5cjetmT
+iWC1coGxjSSoqJb4T1Kbv/ErJellN1MO6+zmioCgx84qJjU3SuqNKdmc3hWRlbCS
+CrwKcVZnjLRmlI7XygndpPB9hM/GB9Wn5+/5j0IFmeCECUtzEmod2l+vTUeutReb
+uR+/1FD/p7NL8VfA/tq4d6GTSr6vYSYIL89PpO8Sh5G5PsahjATkv/yUJDmtT+14
+nkV+HmQfvT9xrV9tvKbLWcv1RTQf+j3Lk2fXyjxbLsDXIBB2/FfZEFE9E/2uA+Zm
+y/o5wkG+xe4Vlx4eRoEM7SLJoXUxkVVAi26sAmYYAh+LkvcAy1IzYaTkS2hU+3Rm
+iemoD4e5Ag0EV23TtwEQAMNa9zUDTt9bT2nja+isou+9DJZZQVl46Lx2My780FVo
+WWyFjd6vX04TlybLhlD3njg4PQAo7xQ909BRSqKxCkdbwoJfHYNC1FIfOdV+9caw
+yaIl5xBc/B7D0+2NdzRc73W0stikNdnkS1lL4rD1TjsUMh/8roiUzNwcU8tIuluw
+2U+jiqbPJ2QLL3Sp4uIcsGb4j7Kf9zUtPVw9JuUscBFkRNFr4U8EWjM4zXBm1jFR
+CGZ/EI6b2I8W5TjK2RmJXR1gwr8f6gSJqiirjKAqxq4kc7puOFlkRXAknu597aT1
+eNBpQPqMX0K9S/vnPSUqjWYLZQ4+YjXYZTpg18tkoxGyDn3jGuFlv+NncL2v3SKM
+ejmN4Tyb+184GqcDZ5T91XWXjV2Fz7UgFtoqLPtRG5EQPAMlEottKHNaOgEsdxy8
+Cf8G1E58BVpVtPGY1qdYD55AjOaBGrdYDzW2iWWcaRr8nMJp6ur9hzrIubYSwRvJ
+KHH5k7/e+MLJooZkJF7IQwvbzQk7Jgp3DcK4ALXHJdprNHl1BOB+L5vzCXAL+544
+wwMgptCjEurLC1q4K3Cg3u36EVRTqkmUATdyhl24coHvC8kwHUQMQOUTQEi06TZO
+bLeg2QMPkMG5Ub3Bu+7Aly7UQApYK7SLmamzw9foG4hKrQ3N4YG53oUKORgxyt9l
+ABEBAAGJAh8EGAEIAAkFAldt07cCGwwACgkQiz8w+cjAwu8FOw/+LHybBicGuQlv
+kRIIABa9Yz/GoL3w7GzExzbndWWw9wgY40ZwlfCugODHeRZEvSi/Yq+PV3UTJWJm
+vxh3N4YpcQE1W6aBaT3ILT06HNQgufc3CFs9ePQZzRTIo4C13FphV+4AhgTnyAKc
+uRNwdb/QGwf1sUELg92PuBEtb9tq1XnRdsnpncHQuj6+zOvNceXPxqHtw4DcNzZ3
+Cz2rnsAjKUd4Se/h53MZChwkp14897XIbATbTGuN6i9Dftezw3kuYvpm3h1QnXAN
+KHQzr8YW5p2SHTnxHYu8hX+BqKyBoldhVWcCKVrhDQH6SrZi4B22/mzOsQKFfCfp
+dJUAhPvFvq0mEajf+Rxo9/wcq3vEGPnnJzV8exERCfjW9cDi/+7BvbnpIdikZJhL
+XGq8/NXi8K+2VwLUW5HzuSVXSe73quWV9OXMpNnh0GiGsR5DT8BQgV8LTO59CXfY
+4ZYWIdP5ClH1fYehc/I/8ZCM/QV8Gtot/EWxTy3dxCBSP2Z4IdaZqH5aCUip906L
+Wtjodp9YCt/f9pyKjuA1hoKaHIaf8L8M2qDFE5OoLDcrAh9m+QrVQRmtFHaMFcej
+85SLnQw83PUsMBH0mdDUYiNaRnWiQs1/I1iJKOt6p0/2jNHx7CaxoEoXqznu9o/X
+bcr+2Sg6D6+XamPTmG687Ow7101hdp25Ag0EV3BtIwEQAL3DM3RBLdxEe3PK8sK0
+PjZPrCeB/aflFoQxAKMOweYcP72ipuCfuKa3Zxxd6o2OfiuO5w9JPn5s92vCbL8f
+ZpBJ7SAF5TNOGESBUI18lGVBIb/PCz2kN1qkTPDIKnxoDKW0AEna12LgzhTQBPTh
+XX37bx3UlH5uMRZUYF+wl/wfD1UaFaY7EwObNQL9WQzMV7AkhIoA8XKyK2cNsOL5
+S87eLpWwffjaE8oZKcYNIPq0x6DuiOuAPLnc7eUDqogjo0suN10uGnvaOvlWIwly
+8/8XRwKPHOVlDHU4kEtMnbfbPXNaFrABrF/ApeaOxg1JSSHOPdzqI5ifscAYYXr5
+xREn5Hh+Se7o1I8zXyHXPd/RTulFykbdmat9w0kVLgor4ahfQeoCj0PwbANlrk1t
+burh2r16CzeR30sNAcuJqKLKwmjfdjPPBwCqLZbIQIDtpJ/4tSx8l1TWJ04JSQeQ
+qJZkUpqnOMJup8Baktzbznpy9ac30aHpWL95VXI7hCGa0kbhi7yeDFbLJuMhIli8
+z5aDRKbT18M3bgoOMWgkFKxi2JMDRbchdsu5bS4GjUnovkq5HxqFI6SRh1TEflqB
+GiGaBPmCT3d9OTZeyK1y/j7N2dh/3d9Z6dmYs+ppG3749kg0rYpdl3kqHUxlNABu
+JKcaPQdNJuDnnPMc+6b0Z8pjABEBAAGJBFsEGAEIACYCGwIWIQRLH0AN8lZRtTxB
+QbOLPzD5yMDC7wUCYrCMvAUJDxEHGQIpwV0gBBkBCAAGBQJXcG0jAAoJEP3RuCRH
+MbNs6CwP/AnUBcsrvYLskStJ7c75vsM1IUQ60gYd8HR2kLAlaG5kkdMVrH7J2lkD
+ZYMoT0ZBV2jpMTe6DpSl6+51t0VCrxYjRAt0xCkchNtFrWmbFlbzX8SjdLxuQboH
+171vYboVS580mK2SNnExif57mga0sfMc9nPOpzwzqlt2h0q4wbOANPUv7Hz0Vb8I
+awWoppR8ztif2zj4NxzFAbw4LloxFlllinbqtTatFn962naz86owCalopxqqJt+f
+Gw4aFFwL7Q0vAJoBO94WooEQ4a5YfiICF02RszOm/LkI/uMGlekhRXek97BKWD5f
+v7KjCLYexFF2Vnzjr2nzi7gWvO0bVlFeVGY6NfT+2Pv+NFapeDLOJe1488eeXpF5
+T0iBERh42f3PwGPMaLCvmgCps6u4h5YBiohpsjuYv5mYok9CwEquOPKG86iBfPtL
+kcXf4I3rkjwYteed2WyCTnpQRuHMzeI19WOs/bFuNPCXiRVVAn1KB/mHQKIxZKut
+cEZMgAtD//ruhTTvsUBSloDSb/3efm2cZHrix6TjrePbji5nFq7FMClP2Ro1u0wA
+ZURkhzDKEkXC94RhUXO0HukUQwFzNRXyVVV8jmTGGiuqO8Q3cijmFO054tDxiLD6
+V5BRnxyQOeQdyxNI8rFEIF4HQn/I28HAl/KDXWcRSMUG2jD5jIGNCRCLPzD5yMDC
+7x0DD/9Umr0Rc9Un9koCQgmhj97WOjZhuKOVPxyGzwyjMYs0ii3pSNYYxUQ7mO6X
+sycDs0YwstUZ0GtanF6ebOHZF1vQwp3RY9zGuBV3gLGo5A6FWcCbWjh6409hKe3J
+tSiIEOOeEV/wcc2BiGfj2DWOi/063gzBfrwRmbCao5/Saw+yhfe7BmTneoYjzHbN
+Ttd+xhDT0ybTMvvMHkR7Aazy7zfl1OdQhfi+T2NWRZdsKWV12pQo8DTeTIUQUKp6
+pmbMazYx5uV6HlCo4Mx+A0z3IBodln/QoE2Glphqn1vGkJWmEA0g2gcMRafzZ5xE
+Y5WHiB4fhJ2kM/xjj/XBUpBSX2R13kvc6aYBTXKCny6CUmFyLpgpPh8udQLazbAs
+uwTdSNVkqgJsV/Mf9onMvMvAuBZME9EyzTK85O0HUZVj1NYNINsdYiFh1qHrdAN0
+RGJkkOKfrYtl/3ER+MI6PeHuaj8akQEmmyvs65tq38VBBnYjIpCbmqVJAJ/fKwuI
+aBoCTnTKDuMumLVTxZOlnUXJ/uBvd/SEXd5TuOdDiw/zbtR0XaLLMhmlQwX7XFiW
+PRmrTsEr8wluewET8fekxMosM8cMwn43agCc1IjfB6pGP1CyCoN6T3EnNcu8UxoY
+CjpmiHZg3mKwE2cDs5WvAt+3Oxww1IiIAKUm2/siNZeshUpBmw==
+=qJcP
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/.local/Taskfile-local.yml b/.local/Taskfile-local.yml
new file mode 100644
index 00000000..ee35536c
--- /dev/null
+++ b/.local/Taskfile-local.yml
@@ -0,0 +1,10 @@
+---
+version: '3'
+
+# This is your local Taskfile.yml file. You can define tasks and scripts while leveraging some of the nifty
+# features of https://taskfile.dev. You can safely place your scripts here and they will be combined with
+# a veteran stack of Taskfile.yml files. You can access the tasks defined here by running
+# `run local:default` for example. You must keep all the tasks in this file without including other files
+# because the main Taskfile.yml is a symlinked one. Anyway, try `run local:default`.
+tasks:
+ default: echo "Get started on https://taskfile.dev"
diff --git a/.local/assets/Betelgeuse.macOS.terminal b/.local/assets/Betelgeuse.macOS.terminal
new file mode 100644
index 00000000..cad43730
--- /dev/null
+++ b/.local/assets/Betelgeuse.macOS.terminal
@@ -0,0 +1,55 @@
+
+
+
+
+
+ name
+ Betelgeuse
+ type
+ Window Settings
+ BackgroundColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjA4NjI3NDUwOTggMC4wOTgwMzkyMTU3IDAuMTQ1MDk4MDM5MgAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ TextColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjY2NjY2NjY2NjcgMC42ODIzNTI5NDEyIDAuNzIxNTY4NjI3NQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ BoldTextColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc2NDcwNTg4MjQgMC43ODAzOTIxNTY5IDAuODE5NjA3ODQzMQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ CursorColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc2NDcwNTg4MjQgMC43ODAzOTIxNTY5IDAuODE5NjA3ODQzMQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ SelectionColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc4MDM5MjE1NjkgMC4zMDE5NjA3ODQzIDAuNTM3MjU0OTAyMAAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBlackColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjA4NjI3NDUwOTggMC4wOTgwMzkyMTU3IDAuMTQ1MDk4MDM5MgAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIRedColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjkyOTQxMTc2NDcgMC4xNDUwOTgwMzkyIDAuMzA1ODgyMzUyOQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIGreenColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjQ0MzEzNzI1NDkgMC45Njg2Mjc0NTEwIDAuNjIzNTI5NDExOAAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIYellowColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjk3NjQ3MDU4ODIgMC44NjI3NDUwOTgwIDAuMzYwNzg0MzEzNwAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBlueColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjQ4NjI3NDUwOTggMC43MTc2NDcwNTg4IDEuMDAwMDAwMDAwMAAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIMagentaColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc4MDM5MjE1NjkgMC4zMDE5NjA3ODQzIDAuNTM3MjU0OTAyMAAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSICyanColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjAwMDAwMDAwMDAgMC43NTY4NjI3NDUxIDAuODk0MTE3NjQ3MQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIWhiteColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjY2NjY2NjY2NjcgMC42ODIzNTI5NDEyIDAuNzIxNTY4NjI3NQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBrightBlackColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjE4NDMxMzcyNTUgMC4xOTYwNzg0MzE0IDAuMjQzMTM3MjU0OQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBrightRedColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjg5MDE5NjA3ODQgMC4zMDU4ODIzNTI5IDAuNDM1Mjk0MTE3NgAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBrightGreenColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjUyNTQ5MDE5NjEgMC45MjE1Njg2Mjc1IDAuNjc0NTA5ODAzOQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBrightYellowColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjkyNTQ5MDE5NjEgMC44NDMxMzcyNTQ5IDAuNDc0NTA5ODAzOQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBrightBlueColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjU1Njg2Mjc0NTEgMC43MzMzMzMzMzMzIDAuOTU2ODYyNzQ1MQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBrightMagentaColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc3NjQ3MDU4ODIgMC40MjM1Mjk0MTE4IDAuNjA3ODQzMTM3MwAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBrightCyanColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjE5MjE1Njg2MjcgMC43NjQ3MDU4ODI0IDAuODc0NTA5ODAzOQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ ANSIBrightWhiteColor
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc2NDcwNTg4MjQgMC43ODAzOTIxNTY5IDAuODE5NjA3ODQzMQAQAYAC0hAREhNaJGNsYXNzbmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCVoKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA2Q==
+ Font
+ YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGkCwwVFlUkbnVsbNQNDg8QERITFFZOU1NpemVYTlNmRmxhZ3NWTlNOYW1lViRjbGFzcyNAJgAAAAAAABAQgAKAA18QGUhhY2tOZXJkRm9udENvbXBsZXRlLUJvbGTSFxgZGlokY2xhc3NuYW1lWCRjbGFzc2VzVk5TRm9udKIZG1hOU09iamVjdAgRGiQpMjdJTFFTWF5nbnd+hY6QkpSwtcDJ0NMAAAAAAAABAQAAAAAAAAAcAAAAAAAAAAAAAAAAAAAA3A==
+
+
diff --git a/.local/bin/bwc b/.local/bin/bwc
new file mode 100644
index 00000000..0918160c
--- /dev/null
+++ b/.local/bin/bwc
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# Exit on error
+set -e
+
+# Command to copy to clipboard
+COPY="wl-copy"
+
+# Get list of all logins as json
+logins="$(bw list items)"
+# Grab the name of every login and pip them into fzf
+name="$(echo "$logins" | jq -r '.[].name' | fzf)"
+# Find the login with the selected name (as a json)
+selected="$(echo "$logins" | jq -r ".[] | select(.name == \"$name\")")"
+# Print the name of the selected login
+echo "Name: $(echo "$selected" | jq -r '.name')"
+echo "> Copying Username"
+# Copy the username to the clipboard
+printf '%s' "$(echo "$selected" | jq -r '.login.username')" | $COPY
+echo "Press any key to copy password..."
+# Wait for user input before coping the password
+read -r
+echo "> Copying Password"
+# Copy the password to the clipboard
+printf '%s' "$(echo "$selected" | jq -r '.login.password')" | $COPY
diff --git a/.local/bin/chrome-profile-export b/.local/bin/chrome-profile-export
index 04acb24a..8b137891 100644
--- a/.local/bin/chrome-profile-export
+++ b/.local/bin/chrome-profile-export
@@ -1,348 +1 @@
-#!/usr/bin/env bash
-#
-# This script will spawn a new Chrome process restricted to a profile that
-# is created on demand and (optionally) deleted on exit. If a root profile
-# directory is given, it will be used as the template for the newly created
-# profile.
-#
-# NOTES:
-#
-# Chrome spawning takes place irrespective of any currently running Chrome
-# processes. The script will always spawn a new Chrome process.
-#
-# If a root profile directory is not configured/passed-in as an argument, the
-# created profile will be a fresh, first-time profile that does not contain
-# any configuration data or extensions that may be present in a different
-# profile for the same installed Chrome browser.
-#
-# To create a root profile, execute `chrome-private.sh --name name --keep',
-# and after installing extensions and modifying browser configuration, you
-# can copy/rename its directory and set it as ROOT_PROFILE_DIR (or pass it
-# as an argument with --root-profile).
-#
-# This is free and unencumbered software released into the public domain.
-# xristos@sdf.org
-set -em
-
-
-#
-# Configuration
-#
-
-
-CONFIG=~/.chrome-private.rc
-
-if [ -f "${CONFIG}" ]; then
- source "${CONFIG}"
-fi
-
-# All of the following user configuration variables can be set in
-# ~/.chrome-private.rc
-
-: "${CHROME:=google-chrome}"
-: "${TMP:=/tmp}"
-
-# A root chrome profile directory, if it exists it will be used as a template
-: "${ROOT_PROFILE_DIR:=}"
-
-# GNU mktemp is required, set this to gmktemp (coreutils) on macOS
-: "${MKTEMP:=mktemp}"
-: "${PROFILE_MKTEMP:=chrome.priv.prof_XXXXXXXXXX}"
-
-: "${PROXY=socks5://127.0.0.1:5060}"
-
-# Using a ramdisk rather than TMP is a good idea, but doubly so if you're going
-# to go heavy on number of disposable profiles. hdiutil can be used to create
-# a ramdisk on macOS.
-: "${RAMDISK:=}"
-
-# Remote debugging port
-: "${DEBUG_PORT:=}"
-
-
-#
-# End of user configuration
-#
-
-
-CHROME_ARGS=(--disable-bundled-ppapi-flash --disable-offline-load-stale-cache
- --disk-cache-size=1 --media-cache-size=1 --disk-cache-dir=/dev/null
- --no-first-run --no-referrers --save-page-as-mhtml --no-default-browser-check)
-
-CHROME_NO_GPU_ARGS=(--disable-gpu)
-CHROME_NO_3D_ARGS=(--disable-3d-apis --disable-webgl)
-
-keep=0
-delete=0
-incognito=0
-use_gpu=0
-use_3d=0
-use_proxy=0
-profile=
-profile_name=
-chrome_pid=0
-color=0
-start_color="\e[1;34m"
-end_color="\e[0m"
-basename="$(basename "${ROOT_PROFILE_DIR}")"
-
-if [ -t 1 ]; then
- color=1
-fi
-
-
-#
-# Functions
-#
-
-
-function usage {
- echo "Usage: $0 [--name name] [--temp-name (${PROFILE_MKTEMP})] [--keep] [--delete] [--gpu] [--3d] [--incognito] [--root-profile dir] [--profile dir] [--port port] [--proxy (${PROXY})] -- chrome-arguments"
- echo -e " --name name of created profile directory"
- echo -e " this will override --temp-name if given"
- echo -e " --temp-name this will be passed to mktemp(1) to generate a"
- echo -e " disposable profile directory name"
- echo
- echo -e " --keep do not delete/rename profile directory on exit"
- echo -e " (implied with --profile)"
- echo -e " --delete delete rather than rename profile directory"
- echo -e " (ignored with --keep / --profile)"
- echo
- echo -e " --gpu enable gpu acceleration"
- echo -e " --3d enable WebGL / 3D APIs"
- echo
- echo -e " --incognito start Chrome in incognito mode"
- echo -e " --root-profile use given directory as root profile directory"
- echo -e " --profile dir use given directory as profile directory (needs to exist)"
- echo -e " (--root-profile, --name and --temp-name are ignored)"
- echo -e " --proxy if given, Chrome will use a proxy (default or specified)"
- echo -e " --port use given port as remote debugging port"
- echo
-}
-
-function msg {
- if [ "${color}" -eq 1 ]; then
- printf "${start_color}$1${end_color}\n"
- else
- printf "%s\n" "$1"
- fi
-}
-
-function err {
- echo "Error: $*" >&2
-}
-
-function setup {
- # Optional, executed first when --profile is not given.
- # Currently used to setup the ram disk (if configured).
- if [ -d "${RAMDISK}" ]; then
- if [ -d "${ROOT_PROFILE_DIR}" ]; then
- if [ ! -d "${RAMDISK}/${basename}" ]; then
- # Copy the root profile to ramdisk
- msg "Copying reference profile from: ${ROOT_PROFILE_DIR} to: ${RAMDISK}/${basename}"
- cp -R "${ROOT_PROFILE_DIR}/." "${RAMDISK}/${basename}"
- fi
- ROOT_PROFILE_DIR="${RAMDISK}/${basename}"
- fi
- TMP="${RAMDISK}"
- fi
-}
-
-function cleanup {
- if [ -d "${profile}" ]; then
- if [ "${keep}" -eq 0 ]; then
- if [ "${delete}" -eq 0 ]; then
- mv "${profile}" "${profile}.deleted"
- msg "Renamed: ${profile}"
- else
- rm -rf "${profile}"
- msg "Deleted: ${profile}"
- fi
- fi
- else
- err "Directory ${profile} does not exist"
- fi
-}
-
-function interrupt {
- if [ "${chrome_pid}" -ne 0 ] && ps "${chrome_pid}" &>/dev/null; then
- kill "${chrome_pid}"
- wait
- fi
-}
-
-
-#
-# Argument parsing
-#
-
-
-while :; do
- case "$1" in
- -h|--help)
- usage
- exit 0
- ;;
- --keep)
- keep=1
- ;;
- --delete)
- delete=1
- ;;
- --gpu)
- use_gpu=1
- ;;
- --3d)
- use_3d=1
- ;;
- --incognito)
- incognito=1
- ;;
- --name)
- if [ "$2" ] && [[ "$2" != --* ]]; then
- profile_name="$2"
- shift
- else
- err "--name requires an argument"
- exit 1
- fi
- ;;
- --temp-name)
- if [ "$2" ] && [[ "$2" != --* ]]; then
- PROFILE_MKTEMP="$2"
- shift
- else
- err "--temp-name requires an argument"
- exit 1
- fi
- ;;
- --root-profile)
- if [ "$2" ] && [[ "$2" != --* ]]; then
- ROOT_PROFILE_DIR="$2"
- basename="$(basename "${ROOT_PROFILE_DIR}")"
- shift
- else
- err "--root-profile requires a profile directory"
- exit 1
- fi
- ;;
- --profile)
- if [ "$2" ] && [[ "$2" != --* ]]; then
- profile="$2"
- shift
- else
- err "--profile requires a profile directory"
- exit 1
- fi
- ;;
- --proxy)
- use_proxy=1
- if [ "$2" ] && [[ "$2" != --* ]]; then
- PROXY="$2"
- shift
- fi
- ;;
- --port)
- if [ "$2" ] && [[ "$2" != --* ]]; then
- DEBUG_PORT="$2"
- shift
- fi
- ;;
- --)
- shift
- break
- ;;
- -?*)
- err "Unknown option: $1"
- exit 1
- ;;
- *)
- break
- esac
- shift
-done
-
-
-#
-# End of argument parsing
-#
-
-
-builtin type -P "${CHROME}" &>/dev/null || { err "${CHROME}" not found; exit 1; }
-
-if [ "${profile}" ]; then
- keep=1
- if [ -d "${profile}" ]; then
- msg "Using existing profile dir: ${profile}"
- else
- err "Directory ${profile} does not exist"
- exit 1
- fi
-else
- setup
- if [ "${profile_name}" ]; then
- profile="${profile_name}"
- else
- profile="$("${MKTEMP}" -d -p "${TMP}" "${PROFILE_MKTEMP}")"
- fi
-
- if [ -d "${ROOT_PROFILE_DIR}" ]; then
- msg "Copying reference profile from: ${ROOT_PROFILE_DIR} to: ${profile}"
- cp -R "${ROOT_PROFILE_DIR}/." "${profile}"
- else
- msg "Using new profile dir: ${profile}"
- fi
-fi
-
-MY_ARGS=(--user-data-dir="${profile}")
-
-if [ "${use_proxy}" -eq 1 ]; then
- msg "Using proxy: ${PROXY}"
- MY_ARGS+=(--proxy-server="${PROXY}")
-fi
-
-if [ "${incognito}" -eq 1 ]; then
- msg "Incognito mode enabled"
-
- MY_ARGS+=(--incognito)
-fi
-
-if [ "${use_gpu}" -eq 0 ]; then
- CHROME_ARGS=("${CHROME_ARGS[@]}" "${CHROME_NO_GPU_ARGS[@]}")
-else
- msg "GPU enabled"
-fi
-
-if [ "${use_3d}" -eq 0 ]; then
- CHROME_ARGS=("${CHROME_ARGS[@]}" "${CHROME_NO_3D_ARGS[@]}")
-else
- msg "3D APIs enabled"
-fi
-
-if [ "${DEBUG_PORT}" ]; then
- MY_ARGS+=(--remote-debugging-port="${DEBUG_PORT}")
- msg "Remote debugging port: ${DEBUG_PORT}"
-fi
-
-
-#
-# Execution
-#
-
-
-trap cleanup EXIT
-trap interrupt INT
-
-"${CHROME}" "${CHROME_ARGS[@]}" "${MY_ARGS[@]}" "$@" 2>/dev/null &
-
-
-#
-# Post-execution
-#
-
-
-chrome_pid=$!
-msg "Chrome PID: ${chrome_pid}"
-
-wait
diff --git a/.local/bin/chrome-profile-import b/.local/bin/chrome-profile-import
new file mode 100644
index 00000000..e69de29b
diff --git a/.local/bin/firefox-profile-export b/.local/bin/firefox-profile-export
index 59b00c27..e69de29b 100644
--- a/.local/bin/firefox-profile-export
+++ b/.local/bin/firefox-profile-export
@@ -1,151 +0,0 @@
-#!/usr/bin/env bash
-
-
-## Author: Tommy Miland (@tmiland) - Copyright (c) 2019
-
-
-######################################################################
-#### Firefox Backup.sh ####
-#### Script to backup your firefox profile ####
-#### Maintained by @tmiland ####
-######################################################################
-
-
-version='1.0.0'
-
-#------------------------------------------------------------------------------#
-#
-# MIT License
-#
-# Copyright (c) 2019 Tommy Miland
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-#------------------------------------------------------------------------------#
-#
-# Script credits:
-# Mozilla Firefox profile (w/ bookmarks, history and addons) backup Bash script
-# for Mac OS X - https://gist.github.com/PMK/22a0fde46bf497fd7d732baa07504071
-# ghacks user.js - https://github.com/ghacksuserjs/ghacks-user.js
-#
-
-readonly CURRDIR=$(pwd)
-
-sfp=$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || greadlink -f "${BASH_SOURCE[0]}" 2>/dev/null)
-if [ -z "$sfp" ]; then sfp=${BASH_SOURCE[0]}; fi
-readonly SCRIPT_DIR=$(dirname "${sfp}")
-
-# Icons used for printing
-ARROW='➜'
-DONE='✔'
-ERROR='✗'
-WARNING='⚠'
-# Colors used for printing
-RED='\033[0;31m'
-BLUE='\033[0;34m'
-BBLUE='\033[1;34m'
-GREEN='\033[0;32m'
-ORANGE='\033[0;33m'
-DARKORANGE="\033[38;5;208m"
-CYAN='\033[0;36m'
-DARKGREY="\033[48;5;236m"
-NC='\033[0m' # No Color
-# Text formatting used for printing
-BOLD="\033[1m"
-DIM="\033[2m"
-UNDERLINED="\033[4m"
-INVERT="\033[7m"
-HIDDEN="\033[8m"
-
-DEST=$1
-
-if [ -z "$DEST" ]; then
- DEST=${CURRDIR}
-fi
-
-if [ ! -d "$DEST" ]; then
- mkdir $DEST
-fi
-
-readIniFile () { # expects one argument: absolute path of profiles.ini
- declare -r inifile="$1"
- declare -r tfile=$(mktemp)
-
- if [ $(grep '^\[Profile' "$inifile" | wc -l) == "1" ]; then ### only 1 profile found
- grep '^\[Profile' -A 4 "$inifile" | grep -v '^\[Profile' > $tfile
- else
- grep -E -v '^\[General\]|^StartWithLastProfile=|^IsRelative=' "$inifile"
- echo -e "${GREEN}"
- read -p 'Select the profile number ( 0 for Profile0, 1 for Profile1, etc ) : ' -r
- echo -e "\n${NC}"
- if [[ $REPLY =~ ^(0|[1-9][0-9]*)$ ]]; then
- grep '^\[Profile'${REPLY} -A 4 "$inifile" | grep -v '^\[Profile'${REPLY} > $tfile
- if [[ "$?" != "0" ]]; then
- echo -e "${RED}${ERROR}Profile${REPLY} does not exist!${NC}" && exit 1
- fi
- else
- echo -e "${RED}${ERROR} Invalid selection!${NC}" && exit 1
- fi
- fi
-
- declare -r profpath=$(grep '^Path=' $tfile)
- declare -r pathisrel=$(grep '^IsRelative=' $tfile)
-
- rm "$tfile"
-
- # update global variable
- if [[ ${pathisrel#*=} == "1" ]]; then
- PROFILE_PATH="$(dirname "$inifile")/${profpath#*=}"
- PROFILE_ID="${profpath#*=}"
- else
- PROFILE_PATH="${profpath#*=}"
- fi
-}
-
-getProfilePath() {
- declare -r f1=~/Library/Application\ Support/Firefox/profiles.ini
- declare -r f2=~/.mozilla/firefox/profiles.ini
-
- local ini=''
- if [[ -f "$f1" ]]; then
- ini="$f1"
- elif [[ -f "$f2" ]]; then
- ini="$f2"
- else
- echo -e "${RED}${ERROR}Error: Sorry, -l is not supported for your OS${NC}"
- exit 1
- fi
- readIniFile "$ini" # updates PROFILE_PATH or exits on error
-}
-
-backupProfile() {
- BACKUP_FILE_NAME=${PROFILE_ID}-$(date +"%Y-%m-%d_%H%M").tar.gz
-
- tar -zcf $BACKUP_FILE_NAME $PROFILE_PATH > /dev/null 2>&1
-
- mv $BACKUP_FILE_NAME $DEST
-
- echo -e "${GREEN}${DONE} Done! ${NC}"
- echo ""
- echo -e "${ORANGE}${ARROW} Firefox profile successfully backed up to $DEST ${NC}"
- echo ""
-}
-
-getProfilePath # updates PROFILE_PATH or exits on error
-backupProfile
diff --git a/.local/bin/fonttest b/.local/bin/fonttest
new file mode 100644
index 00000000..39dd841c
--- /dev/null
+++ b/.local/bin/fonttest
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# FONTTEST SCRIPT
+# -----------------
+# Print all avaliable variants of chosen terminal font
+
+echo -en "regular "
+echo -en "\e[3m italic \e[0m"
+echo -en "\e[1m bold \e[0m"
+echo -en "\e[3m\e[1m bold-italic \e[0m"
+echo -en " \e[4munderline\e[0m "
+echo -e " \e[9mstrikethrough\e[0m"
diff --git a/.local/bin/install-gnome-extensions b/.local/bin/install-gnome-extensions
new file mode 100644
index 00000000..03defce6
--- /dev/null
+++ b/.local/bin/install-gnome-extensions
@@ -0,0 +1,314 @@
+#!/bin/bash
+
+#################################################################
+# #
+# GNOME Shell Extension Installer v1.2.1 #
+# #
+# A simple (scriptable) way to install GNOME Shell Extensions! #
+# #
+# Author: Cyrus Frost #
+# License: MIT #
+# #
+# https://github.com/cyfrost/install-gnome-extensions #
+# #
+#################################################################
+
+#vars
+script_revision="v1.2.1"
+args_count="$#"
+dependencies=(wget curl jq unzip tput sed egrep sed awk gnome-shell cut basename)
+deps_install_apt="sudo apt install -y wget curl jq unzip sed"
+deps_install_dnf="sudo dnf install -y wget curl jq unzip sed"
+EXTENSIONS_TO_INSTALL=()
+OVERWRITE_EXISTING=false
+ENABLE_ALL=false
+INSTALLED_EXT_COUNT=''
+INSTALLED_EXTs=''
+
+# message colors.
+info_text_blue=$(tput setaf 7)
+normal_text=$(tput sgr0)
+error_text=$(tput setaf 1)
+status_text_yellow=$(tput setaf 3)
+
+# Bail immediately if running as root.
+function CheckIfRunningAsRoot() {
+ if [ "$(id -u)" = 0 ]; then
+ printf "
+%s Running this script as root is discouraged and won't work since it needs user directories to operate. Retry as normal user.
+Note: If you're trying to install extensions for another user on this computer, try 'su ' and proceed.
+Abort.
+%s" "$error_text" "$normal_text"
+
+ exit 1
+ fi
+}
+
+# Bail immediately if running as root.
+CheckIfRunningAsRoot
+
+# Trap SIGINT and SIGTERM.
+function _term() {
+ printf "\n\n%s" "$normal_text"
+ trap - INT TERM # clear the trap
+ kill -- -$$
+}
+
+# Trap SIGINT and SIGTERM for cleanup.
+trap _term INT TERM
+
+# This function can check for binaries/commands to be available in Env PATH and report otherwise.
+function CheckDependencies() {
+
+ # echo -en "\n${info_text_blue}Checking dependencies...${normal_text}";
+ dependencies=("$@")
+ for name in "${dependencies[@]}"; do
+ command -v "$name" >/dev/null 2>&1 || {
+ echo -en "${error_text}\n[Error] Command not found: \"$name\"${normal_text}"
+ deps=1
+ }
+ done
+ [[ $deps -ne 1 ]] || {
+ echo -en "${error_text}\n\nOne or more dependencies is unavailable. Please make sure the above commands are available and re-run this script.\n\n${status_text_yellow}For Ubuntu and similar distros, try: $deps_install_apt\n\nFor Fedora and similar distros, try: $deps_install_dnf\n\n${normal_text}"
+ exit 1
+ }
+}
+
+# Fail if dependencies unmet.
+CheckDependencies "${dependencies[@]}"
+
+function confirm_action() {
+ while true; do
+ printf "\n%s" "$normal_text"
+ read -r -p "$1" -n 1 yn
+ case $yn in
+ [Yy]*) return 0 ;;
+ [Nn]*) return 1 ;;
+ *) printf "\nPlease answer with 'y' or 'n'." ;;
+ esac
+ done
+}
+
+# check if current (active) desktop instance is GNOME.
+function IsEnvGNOME() {
+
+ if [ "$XDG_CURRENT_DESKTOP" = "" ]; then
+ desktop=$(echo "$XDG_DATA_DIRS" | grep -Po '(xfce|kde|gnome)' | tail -n 1)
+ #sed 's/.*\(xfce\|kde\|gnome\).*/\1/')
+ else
+ desktop=$XDG_CURRENT_DESKTOP
+ fi
+
+ desktop=${desktop,,}
+
+ if [[ $desktop == *"gnome"* ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+function enable_extension() {
+ ext_uuid="$1"
+ gnome-extensions enable "$ext_uuid" >/dev/null 2>&1
+}
+
+function disable_extension() {
+ ext_uuid="$1"
+ gnome-extensions disable "$ext_uuid" >/dev/null 2>&1
+}
+
+function get_installed_extensions_list() {
+ user_extensions_path="/home/$USER/.local/share/gnome-shell/extensions"
+ array=()
+ while IFS="" read -r line; do array+=("$line"); done < <(find "$user_extensions_path" -maxdepth 1 -mindepth 1 -type d -not -path '*/\.*' -printf "%f\n")
+ ext_list=$(printf "'%s'," "${array[@]}")
+ ext_list=${ext_list%,}
+ INSTALLED_EXT_COUNT="${#array[@]}"
+ INSTALLED_EXTs=$(printf '%s\n' "${array[@]}")
+ # echo $ext_list
+}
+
+function install_shell_extensions() {
+
+ for ext_id in "${EXTENSIONS_TO_INSTALL[@]}"; do
+
+ request_url="https://extensions.gnome.org/extension-info/?pk=$ext_id&shell_version=$GNOME_SHELL_VERSION"
+ http_response="$(curl -s -o /dev/null -I -w "%{http_code}" "$request_url")"
+
+ if [ "$http_response" = 404 ]; then
+ printf "\n%sError: No extension exists matching the ID: %s and GNOME Shell version %s (Skipping this).\n" "$error_text" "$ext_id" "$GNOME_SHELL_VERSION"
+ continue
+ fi
+
+ printf "%s\n" "$normal_text"
+ ext_info="$(curl -s "$request_url")"
+ extension_name="$(echo "$ext_info" | jq -r '.name')"
+ direct_dload_url="$(echo "$ext_info" | jq -r '.download_url')"
+ ext_uuid="$(echo "$ext_info" | jq -r '.uuid')"
+ ext_version="$(echo "$ext_info" | jq -r '.version')"
+ ext_homepage="$(echo "$ext_info" | jq -r '.link')"
+ ext_description="$(echo "$ext_info" | jq -r '.description')"
+ download_url="https://extensions.gnome.org"$direct_dload_url
+ target_installation_dir="/home/$USER/.local/share/gnome-shell/extensions/$ext_uuid"
+ printf "%s\nDownloading and installing extension \"%s\"%s" "$status_text_yellow" "$extension_name" "$normal_text"
+ printf "%s" "$info_text_blue"
+ printf "\nDescription: %s" "$ext_description"
+ printf "\nExtension ID: %s" "$ext_id"
+ printf "\nExtension Version: v%s" "$ext_version"
+ printf "\nHomepage: https://extensions.gnome.org%s" "$ext_homepage"
+ printf "\nUUID: \"%s\"" "$ext_uuid"
+ printf "\nInstalling to: \"%s\"" "$target_installation_dir"
+
+ if [ -d "$target_installation_dir" ] && [ "$OVERWRITE_EXISTING" = "false" ]; then
+ confirm_action "${normal_text}This extension is already installed. Do you want to overwrite it? (y/n): " || continue
+ fi
+
+ printf "\n%sPlease wait...\n" "$info_text_blue"
+ filename="$(basename "$download_url")"
+ wget -q "$download_url" \
+ && mkdir -p "$target_installation_dir" \
+ && unzip -o -q "$filename" -d "$target_installation_dir" \
+ && sleep 1 \
+ && rm "$filename"
+ schemas_dir="$target_installation_dir/schemas"
+
+ if [ -d "$schemas_dir" ]; then
+ printf "%sInstall GLib Schemas for dconf storage, this step will require sudo access...\n" "$info_text_blue"
+ cd "$schemas_dir" || {
+ echo "$0: Directory do not exist"
+ exit 1
+ }
+ sudo cp ./*.xml "/usr/share/glib-2.0/schemas/"
+ sudo glib-compile-schemas /usr/share/glib-2.0/schemas/ >/dev/null 2>&1
+ fi
+
+ if [ ! "$ENABLE_ALL" = "false" ]; then
+ enable_extension "$ext_uuid"
+ fi
+
+ printf "%sDone!\n%s" "$info_text_blue" "$normal_text"
+ done
+ printf "\n"
+}
+
+# Check if arg is number.
+function IsNumber() {
+ re='^[0-9]+$'
+ if [[ "$1" =~ $re ]]; then
+ return 0
+ fi
+ return 1
+}
+
+function print_usage() {
+ print_banner
+
+ # -u, --update Updates existing extensions to latest available versions.
+ printf "
+Usage: ./install-gnome-extensions.sh [options] | [links_file]
+Options:
+ -e, --enable Enable extension after installing it.
+ -o, --overwrite Overwrites existing extensions.
+ -l. --list Lists the UUIDs of installed extensions.
+ -f, --file Specify a file containing extension links to install.
+ -h, --help Display this help message.
+Example usages:
+---------------
+1) ./install-gnome-extensions.sh 6 8 19 --enable
+
+ Installs and enables extensions with IDs 6, 8, and 19.
+2) ./install-gnome-extensions.sh -e --file links.txt
+ Installs and enables the extensions from the URLs specified in \"links.txt\" file.
+"
+}
+
+function print_banner() {
+ printf "%s
+===========================================================
+ GNOME Shell Extensions Installer %s
+A simple (scriptable) way to install GNOME Shell extensions.
+https://github.com/cyfrost/install-gnome-extensions
+===========================================================\n" "$normal_text" "$script_revision"
+}
+
+function trim_file() {
+ file="$1"
+ sed -i '/^[[:blank:]]*$/ d' "$file" && awk '{$1=$1};1' "$file" >tmp && mv tmp "$file"
+}
+
+function install_exts_from_links_file() {
+
+ file="$1"
+ if [ ! -f "$file" ] || [ ! -s "$file" ]; then
+ printf "\n%sError: Supplied argument (\"%s\") is either not a valid file or is empty. %s\n\nPlease gather all extension links in a text file (line-by-line) and try again.\n\nSample usage: ./install-gnome-extensions --file links.txt\n\n" "$error_text" "$1" "$normal_text"
+ exit 1
+ fi
+
+ trim_file "$file"
+
+ printf "\nParsing file \"%s\" for extension links...\n" "$file"
+
+ while IFS="" read -r p || [ -n "$p" ]; do
+ url="$(echo "$p" | sed '/^[[:space:]]*$/d')"
+ ext_id="$(echo "$url" | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | awk '{print $1;}')"
+ IsNumber "$ext_id" && EXTENSIONS_TO_INSTALL+=("$ext_id") || printf "\n%sError: Invalid URL: %s (Skipping this).%s" "$error_text" "$url" "$normal_text"
+ done <"$file"
+ printf "\n"
+}
+
+function begin_install() {
+
+ exts_list="$(printf '%s, ' "${EXTENSIONS_TO_INSTALL[@]}")"
+ exts_list=${exts_list%, }
+
+ print_banner
+ printf "\n%s[Info] Detected GNOME Shell version: %s\n\nInstalling %s extensions (%s)...\n%s" "$info_text_blue" "$GNOME_SHELL_VERSION" "$extensions_count" "$exts_list" "$normal_text"
+ install_shell_extensions
+ printf "\n%sComplete!\n\n" "$normal_text"
+ IsEnvGNOME || printf "%sPlease login to GNOME desktop to see the installed/enabled extensions.\n\n" "$normal_text"
+}
+
+# Obtain GNOME Shell version.
+GNOME_SHELL_VERSION="$(gnome-shell --version | cut --delimiter=' ' --fields=3 | cut --delimiter='.' --fields=1,2)"
+
+while test $# -gt 0; do
+ case "$1" in
+ -e | --enable)
+ ENABLE_ALL=true
+ ;;
+ # -u|--update)
+ # UPDATE=true
+ # ;;
+ -o | --overwrite)
+ OVERWRITE_EXISTING=true
+ ;;
+ -h | --help)
+ print_usage
+ exit 0
+ ;;
+ -l | --list)
+ get_installed_extensions_list
+ printf "\n============================\nInstalled extensions (UUIDs)\n============================\n\n%s\n\n%s extensions are installed.\n\nDone!\n\n" "$INSTALLED_EXTs" "$INSTALLED_EXT_COUNT"
+ exit 0
+ ;;
+ -f | --file)
+ install_exts_from_links_file "$2"
+ ;;
+ esac
+ IsNumber "$1" && EXTENSIONS_TO_INSTALL+=("$1")
+ shift
+done
+
+extensions_count="${#EXTENSIONS_TO_INSTALL[@]}"
+
+if [ "$args_count" -eq 0 ]; then
+ printf "\n%sInvalid usage.\n%s" "$error_text" "$normal_text"
+ print_usage
+
+elif [ "$extensions_count" -eq 0 ]; then
+ printf "\n%sError: Could not find any valid extension IDs or URLs for installation.\n%s\n" "$error_text" "$normal_text"
+ exit 1
+else
+ begin_install
+fi
diff --git a/.local/bin/install-software b/.local/bin/install-software
new file mode 100644
index 00000000..c108cc56
--- /dev/null
+++ b/.local/bin/install-software
@@ -0,0 +1,648 @@
+#!/usr/bin/env zx
+
+const execSync = require('child_process').execSync
+
+$.log = (entry) => {
+ if (entry.kind === 'cmd' && entry.cmd.substring(0, 4) === 'logg') {
+ //execSync(entry.cmd, {stdio: 'inherit', shell: true})
+ } else {
+ log(entry)
+ }
+}
+
+let installData
+const installOrders = {};
+const installOrdersPre = [];
+const installOrdersPost = [];
+const osType = await OSType();
+let osID = osType
+if(osType === 'linux') {
+ osID = await realeaseID()
+}
+
+// Download the installation map
+async function downloadInstallData() {
+ const response = await fetch(
+ "https://gitlab.com/megabyte-labs/misc/dotfiles/-/raw/master/dotfiles/.local/share/chezmoi/software.yml"
+ );
+ if (response.ok) {
+ const text = await response.text()
+ return YAML.parse(text)
+ } else {
+ await $`logg error 'Failed to download the installation map'`
+ }
+}
+
+// Creates the installOrders object which maps package managers to arrays of packages to install
+async function generateInstallOrders() {
+ const packagesToInstall = process.argv.slice(3);
+ const installerPreference = await OSTypeInstallerKey()
+ await $`logg info 'Installer preference category detected as ${installerPreference}'`
+ const preferenceOrder = installData.installerPreference[installerPreference];
+ await $`logg info 'Preference order acquired:'`
+ console.log(preferenceOrder)
+ const softwarePackages = installData.softwarePackages;
+ for (let pkg of packagesToInstall) {
+ let packageKey;
+ if (softwarePackages[pkg + ":" + osID]) {
+ packageKey = pkg + ":" + osID;
+ } else if (softwarePackages[pkg + ":" + osType]) {
+ packageKey = pkg + ":" + osType;
+ } else if (softwarePackages[pkg]) {
+ packageKey = pkg
+ } else {
+ await $`logg warn 'The package \`${pkg}\` was not found in the installation map'`
+ continue;
+ }
+ for (let preference of preferenceOrder) {
+ if (softwarePackages[packageKey][preference + ":" + osID]) {
+ await updateInstallMaps(
+ preference,
+ softwarePackages[packageKey],
+ preference + ":" + osID,
+ pkg,
+ packageKey
+ );
+ break
+ } else if (softwarePackages[packageKey][preference + ":" + osType]) {
+ await updateInstallMaps(
+ preference,
+ softwarePackages[packageKey],
+ preference + ":" + osType,
+ pkg,
+ packageKey
+ );
+ break
+ } else if (softwarePackages[packageKey][preference]) {
+ await updateInstallMaps(preference, softwarePackages[packageKey], preference, pkg, packageKey);
+ break
+ }
+ }
+ }
+ return installOrders;
+}
+
+// Update install, pre-hook, and post-hook objects
+async function updateInstallMaps(preference, packages, scopedPreference, pkg, packageKey) {
+ const preHook = getHook(packages, "pre", scopedPreference, preference);
+ if (preHook) {
+ installOrdersPre.concat(typeof preHook === "string" ? [preHook] : preHook);
+ }
+ const postHook = getHook(packages, "post", scopedPreference, preference);
+ if (postHook) {
+ installOrdersPost.concat(
+ typeof postHook === "string" ? [postHook] : postHook
+ );
+ }
+ if (!installOrders[preference]) {
+ installOrders[preference] = [];
+ }
+ await $`logg info 'Found a match for the package \`${pkg}\` (${packageKey} via ${scopedPreference})'`
+ const newPackages = packages[scopedPreference];
+ installOrders[preference] = installOrders[preference].concat(
+ typeof newPackages === "string" ? [newPackages] : newPackages
+ );
+}
+
+// Get pre / post install hooks
+function getHook(packages, hook, scopedPreference, preference) {
+ const hookLabel = "_" + hook + ":";
+ if (packages[hookLabel + scopedPreference]) {
+ return packages[hookLabel + scopedPreference];
+ } else if (packages[hookLabel + preference]) {
+ return packages[hookLabel + preference];
+ } else if (packages[hookLabel + osID]) {
+ return packages;
+ } else if (packages[hookLabel + osType]) {
+ return packages[hookLabel + osType];
+ } else if (packages["_" + hook]) {
+ return packages["_" + hook];
+ }
+}
+
+// Acquire OS type installer key (for the installerPreference data key)
+async function OSTypeInstallerKey() {
+ const apt = which.sync('apt-get', { nothrow: true })
+ const dnf = which.sync('dnf', { nothrow: true })
+ const freebsd = which.sync('pkg', { nothrow: true })
+ const pacman = which.sync('pacman', { nothrow: true })
+ const yum = which.sync('yum', { nothrow: true })
+ const zypper = which.sync('zypper', { nothrow: true })
+ if (apt) {
+ return 'apt'
+ } else if (dnf || yum) {
+ return 'dnf'
+ } else if(pacman) {
+ return 'pacman'
+ } else if(zypper) {
+ return 'zypper'
+ } else if (freebsd) {
+ return 'freebsd'
+ } else {
+ const macOS = await $`test -d /Applications && test -d Library`
+ if (macOS.exitCode === 0) {
+ return 'darwin'
+ } else {
+ return 'windows'
+ }
+ }
+}
+
+// Acquire OS type
+async function OSType() {
+ try {
+ await $`test -d /Applications && test -d /Library`
+ return 'darwin'
+ } catch(e) {
+ try {
+ await $`test -f /etc/os-release`
+ return 'linux'
+ } catch (e) {
+ return 'windows'
+ }
+ }
+}
+
+// Acquire release ID (for Linux)
+async function releaseID() {
+ const ID = await $`
+ if [ -f /etc/os-release ]; then
+ . /etc/os-release
+ echo -n $ID
+ fi
+ `;
+ return ID.stdout;
+}
+
+// Post-install hook
+async function afterInstall(packageManager) {
+ if (packageManager === 'appimage') {
+ } else if (packageManager === 'ansible') {
+ await $`logg info 'Ensuring temporary passwordless sudo privileges used by Ansible are removed'`
+ await $`sudo sed -i '/# TEMPORARY FOR ANSIBLE INSTALL/d' /etc/sudoers`
+ } else if (packageManager === 'apk') {
+ } else if (packageManager === 'apt') {
+ } else if (packageManager === 'basher') {
+ } else if (packageManager === 'binary') {
+ } else if (packageManager === 'brew' || packageManager === 'cask') {
+ } else if (packageManager === 'cargo') {
+ } else if (packageManager === 'choco') {
+ } else if (packageManager === 'crew') {
+ } else if (packageManager === 'dnf') {
+ } else if (packageManager === 'flatpak') {
+ } else if (packageManager === 'gem') {
+ } else if (packageManager === 'go') {
+ } else if (packageManager === 'nix') {
+ } else if (packageManager === 'npm') {
+ } else if (packageManager === 'pacman') {
+ } else if (packageManager === 'pipx') {
+ } else if (packageManager === 'pkg') {
+ } else if (packageManager === 'port') {
+ } else if (packageManager === 'scoop') {
+ } else if (packageManager === 'crew') {
+ } else if (packageManager === 'dnf') {
+ } else if (packageManager === 'flatpak') {
+ } else if (packageManager === 'snap') {
+ } else if (packageManager === 'whalebrew') {
+ } else if (packageManager === 'winget') {
+ } else if (packageManager === 'yay') {
+ } else if (packageManager === 'zypper') {
+ }
+}
+
+// Pre-install hook
+async function beforeInstall(packageManager) {
+ if (packageManager === 'appimage') {
+ } else if (packageManager === 'ansible') {
+ await $`logg info 'Temporarily enabling passwordless sudo for Ansible role installations'`
+ await $`sudo echo "$(whoami) ALL=(ALL:ALL) NOPASSWD: ALL # TEMPORARY FOR ANSIBLE INSTALL" > /etc/sudoers`
+ } else if (packageManager === 'apk') {
+ } else if (packageManager === 'apt') {
+ await $`sudo apt-get update`
+ } else if (packageManager === 'basher') {
+ } else if (packageManager === 'binary') {
+ } else if (packageManager === 'brew' || packageManager === 'cask') {
+ } else if (packageManager === 'cargo') {
+ } else if (packageManager === 'choco') {
+ } else if (packageManager === 'crew') {
+ } else if (packageManager === 'dnf') {
+ } else if (packageManager === 'flatpak') {
+ } else if (packageManager === 'gem') {
+ } else if (packageManager === 'go') {
+ } else if (packageManager === 'nix') {
+ } else if (packageManager === 'npm') {
+ } else if (packageManager === 'pacman') {
+ await $`sudo pacman -Syu`
+ } else if (packageManager === 'pipx') {
+ } else if (packageManager === 'pkg') {
+ } else if (packageManager === 'port') {
+ } else if (packageManager === 'scoop') {
+ } else if (packageManager === 'crew') {
+ } else if (packageManager === 'dnf') {
+ } else if (packageManager === 'flatpak') {
+ } else if (packageManager === 'snap') {
+ } else if (packageManager === 'whalebrew') {
+ } else if (packageManager === 'winget') {
+ } else if (packageManager === 'yay') {
+ } else if (packageManager === 'zypper') {
+ }
+}
+
+async function ensureInstalled(bin, callback) {
+ const installed = which.sync(bin, { nothrow: true })
+ if (installed) {
+ await $`logg info '\`${bin}\` is available'`
+ } else {
+ await $`logg warn '\`${bin}\` is not installed!'`
+ if (callback) {
+ await $`${callback}`
+ } else {
+ await $`logg error 'There does not appear to be an installation method available for \`${bin}\`'`
+ }
+ }
+}
+
+// Ensure the package manager is available
+let packageManagerInstalled = {};
+async function ensurePackageManager(packageManager) {
+ await $`logg info 'Ensuring \`${packageManager}\` is set up'`
+ if (packageManagerInstalled[packageManager]) {
+ return;
+ } else {
+ packageManagerInstalled[packageManager] = true;
+ }
+ if (packageManager === "ansible") {
+ await ensurePackageManager("pipx");
+ }
+ if (
+ packageManager === "gem" ||
+ packageManager === "go" ||
+ packageManager === "npm" ||
+ packageManager === "pipx" ||
+ packageManager === "whalebrew"
+ ) {
+ await ensurePackageManager("brew");
+ }
+ if (packageManager === 'appimage') {
+ } else if (packageManager === 'ansible') {
+ $`
+ if [ ! -f "$HOME/.cache/megabytelabs/ansible-installed" ] || ! command -v ansible > /dev/null; then
+ pipx install ansible
+ pipx inject ansible PyObjC PyObjC-core docker lxml netaddr pexpect python-vagrant pywinrm requests-credssp watchdog
+ touch "$HOME/.cache/megabytelabs/ansible-installed"
+ else
+ logg info '\`ansible\` and its supporting packages appear to be installed'
+ fi
+ `
+ } else if (packageManager === 'apk') {
+ await ensureInstalled('apk', false)
+ } else if (packageManager === 'apt') {
+ await ensureInstalled('apt', false)
+ } else if (packageManager === 'basher') {
+ await ensureInstalled('basher', `
+ # TODO
+ echo "Bash script that installs basher here"
+ `)
+ } else if (packageManager === 'binary') {
+ } else if (packageManager === 'bpkg') {
+ await ensureInstalled('bpkg', `
+ # TODO
+ echo "Bash script that installs bpkg here"
+ `)
+ } else if (packageManager === 'brew' || packageManager === 'cask') {
+ await ensureInstalled('brew', `
+ if command -v sudo > /dev/null && sudo -n true; then
+ echo | bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+ else
+ logg info 'Homebrew is not installed. Password may be required.'
+ bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?"
+ if [ -n "$BREW_EXIT_CODE" ]; then
+ if command -v brew > /dev/null; then
+ logg warn 'Homebrew was installed but part of the installation failed. Attempting to fix..'
+ BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d"
+ for BREW_DIR in $BREW_DIRS; do
+ if [ -d "$(brew --prefix)/$BREW_DIR" ]; then
+ sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR"
+ fi
+ done
+ brew update --force --quiet
+ fi
+ fi
+ fi
+ `)
+ } else if (packageManager === 'cargo') {
+ await ensureInstalled('cargo', `
+ # TODO Bash script that installs cargo
+ `)
+ } else if (packageManager === 'choco') {
+ await ensureInstalled('choco', `
+ powershell "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"
+ `)
+ } else if (packageManager === 'crew') {
+ await ensureInstalled('crew', `
+ # TODO Bash script that installs crew here
+ # Source: https://github.com/chromebrew/chromebrew
+ curl -Ls git.io/vddgY | bash
+ `)
+ } else if (packageManager === 'dnf') {
+ const dnf = which.sync('dnf', { nothrow: true })
+ const yum = which.sync('yum', { nothrow: true })
+ if (dnf) {
+ await $`logg info '\`dnf\` is available'`
+ } else if (yum) {
+ await $`logg info '\`yum\` is available'`
+ } else {
+ await $`logg error 'Both \`dnf\` and \`yum\` are not available'`
+ }
+ } else if (packageManager === 'flatpak') {
+ const flatpak = which.sync('flatpak', { nothrow: true })
+ if (flatpak) {
+ await $`logg info '\`flatpak\` is available'`
+ } else {
+ const apk = which.sync('apk', { nothrow: true })
+ const apt = which.sync('apt', { nothrow: true })
+ const dnf = which.sync('dnf', { nothrow: true })
+ const yum = which.sync('yum', { nothrow: true })
+ const pacman = which.sync('pacman', { nothrow: true })
+ const zypper = which.sync('zypper', { nothrow: true })
+ if (apk) {
+ $`sudo apk add flatpak`
+ } else if(apt) {
+ $`
+ sudo apt install -y flatpak
+ if [ -f /usr/bin/gnome-shell ]; then
+ sudo apt install -y gnome-software-plugin-flatpak
+ fi
+ if [ -f /usr/bin/plasmashell ]; then
+ sudo apt install -y plasmashell
+ fi
+ `
+ } else if(dnf) {
+ await $`sudo dnf install -y flatpak`
+ } else if(yum) {
+ await $`sudo yum install -y flatpak`
+ } else if (pacman) {
+ await $`sudo pacman -Sy flatpak`
+ } else if (zypper) {
+ await $`sudo zypper install -y flatpak`
+ }
+ const flatpakPost = which.sync('flatpak', { nothrow: true })
+ if (flatpakPost) {
+ await $`flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo`
+ } else {
+ await $`logg error '\`flatpak\` failed to install!'`
+ }
+ await $`logg info '\`flatpak\` was installed. It may require a reboot to function correctly.'`
+ }
+ } else if (packageManager === 'gem') {
+ await ensureInstalled('gem', `brew install ruby`)
+ } else if (packageManager === 'go') {
+ await ensureInstalled('gem', `brew install go`)
+ } else if (packageManager === 'nix') {
+ await ensureInstalled('nix', `
+ if [ -d /Applications ] && [ -d /Library ]; then
+ sh <(curl -L https://nixos.org/nix/install)
+ else
+ sh <(curl -L https://nixos.org/nix/install) --daemon
+ fi
+ `)
+ } else if (packageManager === 'npm') {
+ const npm = which('npm', { nothrow: true })
+ const node = which('node', { nothrow: true })
+ const volta = which('volta', { nothrow: true })
+ if (npm && node && volta) {
+ await $`logg info '\`npm\`, \`node\`, and \`volta\` are available'`
+ } else {
+ if (!volta) {
+ await $`brew install volta`
+ }
+ await $`
+ if [ -z "$VOLTA_HOME" ]; then
+ volta setup
+ fi
+ export PATH="$VOLTA_HOME/bin:$PATH"
+ volta install node
+ `
+ }
+ } else if (packageManager === 'pacman') {
+ await ensureInstalled('pacman', false)
+ } else if (packageManager === 'pipx') {
+ await ensureInstalled('pipx', `brew install pipx && pipx ensurepath`)
+ } else if (packageManager === 'pkg') {
+ await ensureInstalled('pkg', false)
+ } else if (packageManager === 'port') {
+ await ensureInstalled('port', `
+ echo "TODO - script that installs port on macOS here"
+ `)
+ } else if (packageManager === 'scoop') {
+ await ensureInstalled('scoop', `
+ powershell 'Set-ExecutionPolicy RemoteSigned -Scope CurrentUser'
+ powershell 'irm get.scoop.sh | iex
+ `)
+ } else if (packageManager === 'snap') {
+ const apk = which.sync('apk', { nothrow: true })
+ const apt = which.sync('apt-get', { nothrow: true })
+ const dnf = which.sync('dnf', { nothrow: true })
+ const yum = which.sync('yum', { nothrow: true })
+ const pacman = which.sync('pacman', { nothrow: true })
+ const zypper = which.sync('zypper', { nothrow: true })
+ if (apt) {
+ await $`
+ if [ -f /etc/apt/preferences.d/nosnap.pref ]; then
+ sudo mv /etc/apt/preferences.d/nosnap.pref /etc/apt/nosnap.pref.bak
+ fi
+ sudo apt install -y snapd
+ `
+ // TODO Following may be required on Kali -> https://snapcraft.io/docs/installing-snap-on-kali
+ // systemctl enable --now snapd apparmor
+ } else if (dnf) {
+ await $`
+ sudo dnf install -y snapd
+ if [ ! -d /snap ]; then
+ sudo ln -s /var/lib/snapd/snap /snap
+ fi
+ `
+ } else if (yum) {
+ await $`
+ sudo yum install -y snapd
+ sudo systemctl enable --now snapd.socket
+ if [ ! -d /snap ]; then
+ sudo ln -s /var/lib/snapd/snap /snap
+ fi
+ `
+ } else if (pacman) {
+ await $`
+ if [ -f /etc/arch-release ]; then
+ sudo git clone https://aur.archlinux.org/snapd.git /usr/local/src/snapd
+ cd /usr/local/src/snapd
+ sudo makepkg -si
+ else
+ sudo pacman -S snapd
+ sudo systemctl enable --now snapd.socket
+ if [ ! -d /snap ]; then
+ sudo ln -s /var/lib/snapd/snap /snap
+ fi
+ fi
+ `
+ } else if (zypper) {
+ // TODO See https://snapcraft.io/docs/installing-snap-on-opensuse
+ await $`
+ echo "TODO - Bash script that installs snap w/ zypper"
+ `
+ }
+ const snap = which.sync('snap', { nothrow: true })
+ if (snap) {
+ $`sudo snap install core`
+ }
+ } else if (packageManager === 'whalebrew') {
+ await ensureInstalled('whalebrew', `brew install whalebrew`)
+ } else if (packageManager === 'winget') {
+ await ensureInstalled('winget', `
+ echo "TODO - Script that installs winget here"
+ `)
+ } else if (packageManager === 'yay') {
+ const yay = which.sync('yay', { nothrow: true })
+ await $`sudo pacman -S --needed base-devel git`
+ await $`
+ if [ -d /usr/local/src ]; then
+ git clone https://aur.archlinux.org/yay.git /usr/local/src/yay
+ cd /usr/local/src/yay
+ makepkg -si
+ fi
+ `
+ } else if (packageManager === 'zypper') {
+ await ensureInstalled('zypper', false)
+ }
+}
+
+// Installs a list of packages via the specified package manager
+async function installPackageList(packageManager, packages) {
+ try {
+ if (packageManager === 'appimage') {
+ } else if (packageManager === 'ansible') {
+ for (const role of packages) {
+ await $`ansible localhost -m include_role -a name=${role}`
+ }
+ } else if (packageManager === 'apk') {
+ await $`sudo apk add ${packages}`
+ } else if (packageManager === 'apt') {
+ await $`sudo apt-get install -y ${packages}`
+ } else if (packageManager === 'basher') {
+ } else if (packageManager === 'binary') {
+ } else if (packageManager === 'brew') {
+ await $`brew install ${packages}`
+ } else if (packageManager === 'cask') {
+ await $`brew install --cask ${packages}`
+ } else if (packageManager === 'cargo') {
+ for (const cargoPkg of packages) {
+ await $`cargo install ${cargoPkg}`
+ }
+ } else if (packageManager === 'choco') {
+ await $`choco install -y ${packages}`
+ } else if (packageManager === 'crew') {
+ } else if (packageManager === 'dnf') {
+ const dnf = which.sync('dnf', { nothrow: true })
+ const yum = which.sync('yum', { nothrow: true })
+ if (dnf) {
+ await $`dnf install -y ${packages}`
+ } else if (yum) {
+ await $`yum install -y ${packages}`
+ }
+ } else if (packageManager === 'flatpak') {
+ for (const flatPkg of packages) {
+ await $`sudo flatpak install flathub ${flatPkg}`
+ }
+ } else if (packageManager === 'gem') {
+ for (const gem of packages) {
+ await $`gem install ${gem}`
+ }
+ } else if (packageManager === 'go') {
+ for (const goPkg of packages) {
+ await $`go install ${goPkg}`
+ }
+ } else if (packageManager === 'nix') {
+ } else if (packageManager === 'npm') {
+ for (const npmPkg of packages) {
+ await $`volta install ${npmPkg}`
+ }
+ } else if (packageManager === 'pacman') {
+ await $`sudo pacman -Sy --noconfirm --needed ${packages}`
+ } else if (packageManager === 'pipx') {
+ for (const pipxPkg of packages) {
+ await $`pipx install ${pipxPkg}`
+ }
+ } else if (packageManager === 'pkg') {
+ } else if (packageManager === 'port') {
+ for (const portPkg of packages) {
+ await $`sudo port install ${portPkg}`
+ }
+ } else if (packageManager === 'scoop') {
+ for (const scoopPkg of packages) {
+ await $`scoop install ${scoopPkg}`
+ }
+ } else if (packageManager === 'snap') {
+ for (const snapPkg of packages) {
+ await $`sudo snap install -y ${snapPkg}`
+ }
+ } else if (packageManager === 'whalebrew') {
+ for (const whalePkg of packages) {
+ await $`whalebrew install ${snapPkg}`
+ }
+ } else if (packageManager === 'winget') {
+ } else if (packageManager === 'yay') {
+ for (const yayPkg of packages) {
+ await $`yay -Sy --noconfirm --needed ${yayPkg}`
+ }
+ } else if (packageManager === 'zypper') {
+ await $`sudo zypper install -y ${zypPkg}`
+ }
+ } catch (e) {
+ await $`logg error 'Failed to install via \`${packageManager}\`'`
+ await $`logg info 'Proceeding with the installation..'`
+ }
+}
+
+// main process
+async function main() {
+ await $`logg info 'Fetching the latest version of the installation map'`
+ installData = await downloadInstallData();
+ await $`logg info 'Calculating the install orders'`
+ await generateInstallOrders();
+ await $`logg info 'Ensuring any package managers that will be used are installed / configured'`
+ const packageManagers = Object.keys(installOrders);
+ for (const packageManager of packageManagers) {
+ await ensurePackageManager(packageManager);
+ }
+ await $`logg info 'The install orders were generated:'`
+ console.log(installOrders)
+ await $`logg info 'Running package manager pre-installation steps'`
+ for (const packageManager of packageManagers) {
+ await beforeInstall(packageManager);
+ }
+ await $`logg info 'Running package-specific pre-installation steps'`
+ for (const script of installOrdersPre) {
+ await $`${script}`;
+ }
+ await $`logg info 'Installing the packages'`
+ for (const packageManager of packageManagers) {
+ const asyncOrders = [];
+ asyncOrders.push(
+ Promise.resolve(
+ installPackageList(packageManager, installOrders[packageManager])
+ )
+ );
+ await Promise.all(asyncOrders);
+ }
+ await $`logg info 'Running package-specific post-installation steps'`
+ for (const script of installOrdersPost) {
+ await $`${script}`;
+ }
+ await $`logg info 'Running package manager post-installation steps'`
+ for (const packageManager of packageManagers) {
+ await afterInstall(packageManager);
+ }
+ await $`logg success 'Done!'`
+}
+
+// Start the main process
+await main();
diff --git a/.local/bin/install-terminal-theme b/.local/bin/install-terminal-theme
index 6aa20ab5..3e5e6dd3 100644
--- a/.local/bin/install-terminal-theme
+++ b/.local/bin/install-terminal-theme
@@ -10,6 +10,9 @@
# Themer.dev: https://themer.dev/?calculateIntermediaryShades.dark=true&colors.dark.shade0=%23161925&colors.dark.shade7=%23C3C7D1&colors.dark.accent0=%23ED254E&colors.dark.accent3=%2371F79F&colors.dark.accent2=%23F9DC5C&colors.dark.accent4=%2300C1E4&colors.dark.accent5=%237CB7FF&colors.dark.accent7=%23C74D89&colors.dark.accent6=%23C3C7D1&colors.dark.accent1=%23DCDFE4&colors.light.accent0=%23FF4972&colors.light.accent3=%2395FFC3&colors.light.accent2=%23FFFF80&colors.light.accent5=%23A0DBFF&colors.light.accent7=%23EB71AD&colors.light.accent6=%234C5058&colors.light.shade7=%234C5058&colors.light.shade0=%23FFFFFF&colors.light.accent4=%2324E5FF&colors.light.accent1=%23DCDFE4&activeColorSet=dark
+# Required for styled logging
+{{- includeTemplate "universal/logg-compat" }}
+
export COLOR_01="#282C34" # Black
export COLOR_02="#ED254E" # Red
export COLOR_03="#71F79F" # Green
@@ -34,7 +37,9 @@ export CURSOR_COLOR="$FOREGROUND_COLOR" # Cursor color
export PROFILE_NAME="Betelgeuse"
if [ ! -e gconftool-2 ] && [ -f /etc/debian_version ]; then
+ logg 'Running `sudo apt-get update`'
sudo apt-get update
+ logg 'Running `sudo apt-get install -y gconf2`'
sudo apt-get install -y gconf2
fi
diff --git a/.local/bin/load-secrets b/.local/bin/load-secrets
new file mode 100644
index 00000000..13128300
--- /dev/null
+++ b/.local/bin/load-secrets
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+logg
\ No newline at end of file
diff --git a/.local/bin/logg b/.local/bin/logg
index 37566fbd..6c47d808 100644
--- a/.local/bin/logg
+++ b/.local/bin/logg
@@ -122,7 +122,7 @@ logger() {
if [ "$1" == 'error' ]; then
"$GUM_PATH" style --border="thick" "$("$GUM_PATH" style --foreground="#ff0000" "✖") $("$GUM_PATH" style --bold --background="#ff0000" --foreground="#ffffff" " ERROR ") $("$GUM_PATH" style --bold "$(format "$2")")"
elif [ "$1" == 'info' ]; then
- "$GUM_PATH" style " $("$GUM_PATH" style --foreground="#00ffff" "○") $2"
+ "$GUM_PATH" style " $("$GUM_PATH" style --foreground="#00ffff" "○") $("$GUM_PATH" style --faint "$(formatFaint "$2")")"
elif [ "$1" == 'md' ]; then
# @description Ensure glow is installed
if [ "${container:=}" != 'docker' ]; then
@@ -148,26 +148,44 @@ logger() {
elif [ "$1" == 'prompt' ]; then
"$GUM_PATH" style " $("$GUM_PATH" style --foreground="#00008b" "▶") $("$GUM_PATH" style --bold "$(format "$2")")"
elif [ "$1" == 'star' ]; then
- "$GUM_PATH" style " $("$GUM_PATH" style --foreground="#d1d100" "◆") $("$GUM_PATH" style --bold --underline "$(format "$2")")"
+ "$GUM_PATH" style " $("$GUM_PATH" style --foreground="#d1d100" "◆") $("$GUM_PATH" style --bold "$(format "$2")")"
elif [ "$1" == 'start' ]; then
"$GUM_PATH" style " $("$GUM_PATH" style --foreground="#00ff00" "▶") $("$GUM_PATH" style --bold "$(format "$2")")"
elif [ "$1" == 'success' ]; then
"$GUM_PATH" style "$("$GUM_PATH" style --foreground="#00ff00" "✔") $("$GUM_PATH" style --bold "$(format "$2")")"
elif [ "$1" == 'warn' ]; then
- "$GUM_PATH" style " $("$GUM_PATH" style --foreground="#d1d100" "◆") $("$GUM_PATH" style --bold --background="#ffff00" --foreground="#000000" " WARNING ") $("$GUM_PATH" style --bold --italic "$(format "$2")")"
+ "$GUM_PATH" style " $("$GUM_PATH" style --foreground="#d1d100" "◆") $("$GUM_PATH" style --bold --background="#ffff00" --foreground="#000000" " WARNING ") $("$GUM_PATH" style --bold "$(format "$2")")"
else
- echo "WARNING: Unknown log type"
- echo "$2"
+ "$GUM_PATH" style " $("$GUM_PATH" style --foreground="#00ff00" "▶") $("$GUM_PATH" style --bold "$(format "$2")")"
fi
}
format() {
# shellcheck disable=SC2001,SC2016
- ANSI_STR="$(echo "$1" | sed 's/^\([^`]*\)`\([^`]*\)`/\1\\u001b[47;1;30m \2 \\e[0;39m/')"
- if [[ $ANSI_STR == *'`'*'`'* ]]; then
- ANSI_STR="$(format "$ANSI_STR")"
+ ANSI_STR_FORMATTED="$(echo "$1" | sed 's/^\([^`]*\)`\([^`]*\)`.*/\1\\u001b[47;30m \2 \\e[49;m/')"
+ ANSI_STR="$(echo "$1" | sed 's/^\([^`]*\)`\([^`]*\)`\(.*\)$/\3/')"
+ if [ "$ANSI_STR_FORMATTED" != "$ANSI_STR" ]; then
+ if [[ $ANSI_STR == *'`'*'`'* ]]; then
+ ANSI_STR_FORMATTED="$ANSI_STR_FORMATTED$(format "$("$GUM_PATH" style --bold "$ANSI_STR")")"
+ else
+ ANSI_STR_FORMATTED="$("$GUM_PATH" style --bold "$ANSI_STR")"
+ fi
fi
- echo -e "$ANSI_STR"
+ echo -e "$ANSI_STR_FORMATTED"
+}
+
+formatFaint() {
+ # shellcheck disable=SC2001,SC2016
+ ANSI_STR_FORMATTED="$(echo "$1" | sed 's/^\([^`]*\)`\([^`]*\)`.*/\1\\u001b[47;30m \2 \\e[49;m/')"
+ ANSI_STR="$(echo "$1" | sed 's/^\([^`]*\)`\([^`]*\)`\(.*\)$/\3/')"
+ if [ "$ANSI_STR_FORMATTED" != "$ANSI_STR" ]; then
+ if [[ $ANSI_STR == *'`'*'`'* ]]; then
+ ANSI_STR_FORMATTED="$ANSI_STR_FORMATTED$(formatFaint "$("$GUM_PATH" style --faint "$ANSI_STR")")"
+ else
+ ANSI_STR_FORMATTED="$ANSI_STR_FORMATTED$("$GUM_PATH" style --faint "$ANSI_STR")"
+ fi
+ fi
+ echo -e "$ANSI_STR_FORMATTED"
}
# @description Display prompt that allows you to choose between options
@@ -389,5 +407,7 @@ elif [ -n "$1" ]; then
# Public functions that can run with only one argument passed to .config/log (i.e. `.config/log password`)
if [ "$1" == 'write' ] || [ "$1" == 'password' ] || [ "$1" == 'confirm' ] || [ "$1" == 'input' ]; then
"$1"
+ else
+ info "$1"
fi
fi
diff --git a/.local/bin/provision b/.local/bin/provision
index 74395635..4e6d6354 100644
--- a/.local/bin/provision
+++ b/.local/bin/provision
@@ -1,183 +1,30 @@
#!/usr/bin/env bash
-set -eo pipefail
-
-### Qubes dom0 specific code at top
-# The VM name that will manage the Ansible provisioning (for Qubes dom0)
-ANSIBLE_PROVISION_VM="provision"
-
-# Ensure sys-whonix is configured (for Qubes dom0)
-CONFIG_WIZARD_COUNT=0
-ENABLE_OBFSC='false'
-function configureWizard() {
- if xwininfo -root -tree | grep "Anon Connection Wizard"; then
- WINDOW_ID="$(xwininfo -root -tree | grep "Anon Connection Wizard" | sed 's/^ *\([^ ]*\) .*/\1/')"
- xdotool windowactivate "$WINDOW_ID" && sleep 1 && xdotool key 'Enter' && sleep 1 && xdotool key 'Tab Tab Enter' && sleep 24 && xdotool windowactivate "$WINDOW_ID" && sleep 1 && xdotool key 'Enter' && sleep 300
- qvm-shutdown --wait sys-whonix
- sleep 3
- qvm-start sys-whonix
- if xwininfo -root -tree | grep "systemcheck | Whonix" > /dev/null; then
- WINDOW_ID_SYSCHECK="$(xwininfo -root -tree | grep "systemcheck | Whonix" | sed 's/^ *\([^ ]*\) .*/\1/')"
- if xdotool windowactivate "$WINDOW_ID_SYS_CHECK"; then
- sleep 1
- xdotool key 'Enter'
- fi
- fi
+# Install Homebrew
+if ! type brew &> /dev/null; then
+ if type sudo &> /dev/null && sudo -n true; then
+ echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
else
- sleep 3
- CONFIG_WIZARD_COUNT=$((CONFIG_WIZARD_COUNT + 1))
- if [[ "$CONFIG_WIZARD_COUNT" == '4' ]]; then
- echo "The sys-whonix anon-connection-wizard utility did not open."
- else
- echo "Checking for anon-connection-wizard again.."
- configureWizard
- fi
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
-}
-
-### Update via system package manager and install Homebrew dependencies
-if command -v qubesctl > /dev/null; then
- # Qubes dom0
-
- ### Ensure dom0 is updated
- if [ ! -f /root/dom0-updated ]; then
- sudo qubesctl --show-output state.sls update.qubes-dom0
- sudo qubes-dom0-update --clean -y
- touch /root/dom0-updated
- fi
-
- ### Ensure sys-whonix is running
- if ! qvm-check --running sys-whonix; then
- qvm-start sys-whonix --skip-if-running
- configureWizard > /dev/null
- fi
-
- ### Ensure TemplateVMs are updated
- if [ ! -f /root/templatevms-updated ]; then
- # timeout of 10 minutes is added here because the whonix-gw VM does not like to get updated
- # with this method. Anyone know how to fix this?
- sudo timeout 600 qubesctl --show-output --skip-dom0 --templates state.sls update.qubes-vm &> /dev/null || EXIT_CODE=$?
- while read RESTART_VM; do
- qvm-shutdown --wait "$RESTART_VM"
- done< <(qvm-ls --all --no-spinner --fields=name,state | grep Running | grep -v sys-net | grep -v sys-firewall | grep -v sys-whonix | grep -v dom0 | awk '{print $1}')
- sudo touch /root/templatevms-updated
- fi
-
- ### Ensure provisioning VM can run commands on any VM
- echo "/bin/bash" | sudo tee /etc/qubes-rpc/qubes.VMShell
- sudo chmod 755 /etc/qubes-rpc/qubes.VMShell
- echo "$ANSIBLE_PROVISION_VM"' dom0 allow' | sudo tee /etc/qubes-rpc/policy/qubes.VMShell
- echo "$ANSIBLE_PROVISION_VM"' $anyvm allow' | sudo tee -a /etc/qubes-rpc/policy/qubes.VMShell
- sudo chown "$(whoami):$(whoami)" /etc/qubes-rpc/policy/qubes.VMShell
- sudo chmod 644 /etc/qubes-rpc/policy/qubes.VMShell
-
-
- ### Create provisioning VM and initialize the provisioning process from there
- qvm-create --label red --template debian-11 "$ANSIBLE_PROVISION_VM" &> /dev/null || EXIT_CODE=$?
- qvm-volume extend "$ANSIBLE_PROVISION_VM:private" "40G"
- if [ -f ~/.vaultpass ]; then
- qvm-run "$ANSIBLE_PROVISION_VM" 'rm -f ~/QubesIncoming/dom0/.vaultpass'
- qvm-copy-to-vm "$ANSIBLE_PROVISION_VM" ~/.vaultpass
- qvm-run "$ANSIBLE_PROVISION_VM" 'cp ~/QubesIncoming/dom0/.vaultpass ~/.vaultpass'
- fi
- qvm-run --pass-io "$ANSIBLE_PROVISION_VM" 'curl -sSL https://install.doctor/start > ~/start.sh && bash ~/start.sh'
- exit 0
-elif command -v apt-get > /dev/null; then
- # Debian / Ubuntu
- sudo apt-get update
- sudo apt-get install -y curl git
-elif command -v dnf > /dev/null; then
- # Fedora
- sudo dnf install -y curl git
-elif command -v yum > /dev/null; then
- # CentOS
- sudo yum install -y curl git
-elif command -v pacman > /dev/null; then
- # Archlinux
- sudo pacman update
- sudo pacman -Sy curl git
-elif command -v zypper > /dev/null; then
- # OpenSUSE
- sudo zypper install -y curl git nodejs
-elif command -v apk > /dev/null; then
- # Alpine
- apk add curl git
-elif [ -d /Applications ] && [ -d /Library ]; then
- # macOS
- sudo xcode-select -p >/dev/null 2>&1 || xcode-select --install
-elif command -v nix-env > /dev/null; then
- # NixOS
-elif [[ "$OSTYPE" == 'freebsd'* ]]; then
- # FreeBSD
-elif command -v pkg > /dev/null; then
- # Termux
-elif command -v xbps-install > /dev/null; then
- # Void
-elif [[ "$OSTYPE" == 'cygwin' ]] || [[ "$OSTYPE" == 'msys' ]] || [[ "$OSTYPE" == 'win32' ]]; then
- # Windows
- choco install -y curl git node
fi
-### Install Homebrew
-ensurePackageManagerHomebrew() {
- if ! command -v brew > /dev/null; then
- if command -v sudo > /dev/null && sudo -n true; then
- echo | bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- else
- logg info 'Homebrew is not installed. Password may be required.'
- bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?"
- if [ -n "$BREW_EXIT_CODE" ]; then
- if command -v brew > /dev/null; then
- logg warn 'Homebrew was installed but part of the installation failed. Attempting to fix..'
- BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d"
- for BREW_DIR in $BREW_DIRS; do
- if [ -d "$(brew --prefix)/$BREW_DIR" ]; then
- sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR"
- fi
- done
- brew update --force --quiet
- fi
- fi
- fi
- fi
-}
-ensurePackageManagerHomebrew
+# Install Homebrew bundle and go-task
+brew install go-task/tap/go-task
+brew install jq
+brew install yq
-### Install installer dependencies via Homebrew
-if command -v brew > /dev/null; then
- brew install chezmoi go-task/tap/go-task jq node yq zx
-fi
-
-### Ensure source files are present
-if [ -d /usr/local/src/hiawatha ] && [ ! -w /usr/local/src/hiawatha ]; then
- sudo chown -Rf "$USER":"$(id -g -n)" /usr/local/src/hiawatha
-fi
-if [ -d /usr/local/src/hiawatha/.git ]; then
- git config pull.rebase false
- git pull origin master
+# Ensure dotfiles are present
+if [ ! -f "$HOME/.local/bin/install-dotfiles" ]; then
+ bash <(curl -sSL https://gitlab.com/megabyte-labs/misc/dotfiles/-/raw/master/dotfiles/.local/bin/install-dotfiles)
else
- rm -rf /usr/local/src/hiawatha
- sudo git clone https://gitlab.com/megabyte-labs/dotfiles.git /usr/local/src/hiawatha
- chown -Rf "$USER":"$(id -g -n)" /usr/local/src/hiawatha
+ chmod +x "$HOME/.local/bin/install-dotfiles"
+ install-dotfiles
fi
-### Copy folders
-find /usr/local/src/hiawatha -maxdepth 1 -mindepth 1 -type d | while read FOLDER; do
- BASENAME="$(basename "$FOLDER")"
- if [ ! -d "$HOME/$BASENAME" ]; then
- mkdir -p "$HOME/$BASENAME"
- fi
- cp -rf "$FOLDER/"* "$HOME/$BASENAME"
-done
-
-### Copy files
-find /usr/local/src/hiawatha -maxdepth 1 -mindepth 1 -type f | while read FILE; do
- BASENAME="$(basename "$FILE")"
- cp "$FILE" "$HOME/$BASENAME"
- chmod 600 "$HOME/$BASENAME"
-done
-
-### Ensure ~/.local/bin files are executable
-find "$HOME/.local/bin" -maxdepth 1 -mindepth 1 -type f | while read BINFILE; do
- chmod +x "$BINFILE"
-done
+# Use run alias to invoke the `$HOME/.local/Taskfile.yml`
+if [ -z "$1" ]; then
+ run localhost:provision
+else
+ run "localhost:provision:$1"
+fi
diff --git a/.local/bin/run b/.local/bin/run
index 1ae2f2ee..4303285f 100644
--- a/.local/bin/run
+++ b/.local/bin/run
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
-task --taskfile $HOME/.local/common/shared/Taskfile.yml $@
+task --taskfile $HOME/.local/src/shared-common/Taskfile.yml $@
diff --git a/.local/bin/slack b/.local/bin/slack
new file mode 100644
index 00000000..a9e3aec4
--- /dev/null
+++ b/.local/bin/slack
@@ -0,0 +1,2 @@
+#!/bin/bash
+exec firejail /usr/bin/slack --enable-features=UseOzonePlatform,WebRTCPipeWireCapturer --ozone-platform=wayland &> /dev/null &
diff --git a/.local/scripts/motd.bash b/.local/scripts/motd.bash
new file mode 100644
index 00000000..acc35a3a
--- /dev/null
+++ b/.local/scripts/motd.bash
@@ -0,0 +1,669 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC1090,SC1091
+
+BAR_ELEMENT="-"
+BAR_HEALTHY_COLOR="32"
+BAR_WARNING_THRESHOLD=70
+BAR_WARNING_COLOR="33"
+BAR_CRITICAL_THRESHOLD=90
+BAR_CRITICAL_COLOR="31"
+
+BANNER_KERNEL_ICON=""
+BANNER_KERNEL_COLOR="33"
+BANNER_UPTIME_ICON=""
+BANNER_UPTIME_COLOR="94"
+BANNER_DEBIAN_ICON=""
+BANNER_DEBIAN_COLOR="95"
+BANNER_FEDORA_ICON=""
+BANNER_FEDORA_COLOR="34"
+BANNER_FONTPATH=""
+BANNER_TEXT="$(hostname -s)"
+
+PROCESSOR_LOADAVG_ICON="ﲯ"
+PROCESSOR_LOADAVG_HEALTHY_COLOR="32"
+PROCESSOR_LOADAVG_WARNING_THRESHOLD=2
+PROCESSOR_LOADAVG_WARNING_COLOR="33"
+PROCESSOR_LOADAVG_CRITICAL_THRESHOLD=4
+PROCESSOR_LOADAVG_CRITICAL_COLOR="31"
+PROCESSOR_MODEL_ICON=""
+
+MEMORY_ICON=""
+
+SWAP_ICON=""
+
+DISKSPACE_ICON=""
+
+SERVICES_UP_ICON=""
+SERVICES_UP_COLOR="32"
+SERVICES_DOWN_ICON=""
+SERVICES_DOWN_COLOR="31"
+SERVICES_FILE=".bashrc_motd_services.txt"
+
+# TODO - Fill this in if Podman is ever used
+PODMAN_VERSION_ICON="#"
+PODMAN_IMAGES_ICON="#"
+PODMAN_RUNNING_ICON="#"
+PODMAN_RUNNING_COLOR="32"
+PODMAN_OTHER_ICON="#"
+PODMAN_OTHER_COLOR="90"
+
+DOCKER_VERSION_ICON=""
+DOCKER_IMAGES_ICON=""
+DOCKER_RUNNING_ICON=""
+DOCKER_RUNNING_COLOR="32"
+DOCKER_OTHER_ICON=""
+DOCKER_OTHER_COLOR="90"
+
+UPDATES_ZERO_ICON=""
+UPDATES_ZERO_COLOR="32"
+UPDATES_AVAILIABLE_ICON="ﮮ"
+UPDATES_AVAILIABLE_COLOR="33"
+UPDATES_SECURITY_ICON="撚"
+UPDATES_SECURITY_COLOR="31"
+
+LETSENCRYPT_VALID_ICON="ﲘ"
+LETSENCRYPT_VALID_COLOR="32"
+LETSENCRYPT_WARNING_ICON="ﲙ"
+LETSENCRYPT_WARNING_COLOR="33"
+LETSENCRYPT_INVALID_ICON=""
+LETSENCRYPT_INVALID_COLOR="31"
+LETSENCRYPT_CERTPATH="/etc/letsencrypt/live"
+
+LOGIN_LOGIN_ICON=""
+LOGIN_LOGOUT_ICON=""
+LOGIN_IP_ICON="ﯱ"
+
+INCLUDE_FILE="ownscript.sh"
+
+generate_unit_byte() {
+ # 1 - unit in M
+
+ if [ "$1" -ge 1024 ]; then
+ unit_symbol="G"
+ unit_value=$(echo "$1/1024" | bc -l | LANG=C xargs printf "%.1f\n")
+ else
+ unit_symbol="M"
+ unit_value=$1
+ fi
+
+ echo "$unit_value$unit_symbol"
+}
+
+generate_space() {
+ # 1 - already used
+ # 2 - total
+
+ space_fill=$(($2 - ${#1}))
+ space_chars=""
+
+ while [ $space_fill -ge 0 ]; do
+ space_chars="$space_chars "
+ space_fill=$((space_fill - 1))
+ done
+
+ echo "$space_chars"
+}
+
+generate_bar() {
+ # 1 - icon
+ # 2 - total
+ # 3 - used_1
+ # 4 - [ used_2 ]
+
+ bar_percent=$(($3 * 100 / $2))
+ bar_separator=$(($3 * 100 * 10 / $2 / 25))
+
+ if [ $bar_percent -ge "$BAR_WARNING_THRESHOLD" ]; then
+ bar_color=$BAR_WARNING_COLOR
+ elif [ $bar_percent -ge "$BAR_CRITICAL_THRESHOLD" ]; then
+ bar_color=$BAR_CRITICAL_COLOR
+ else
+ bar_color=$BAR_HEALTHY_COLOR
+ fi
+
+ printf " %s \\033[%dm" "$1" "$bar_color"
+
+ if [ -z "$4" ]; then
+ bar_piece=0
+ while [ $bar_piece -le 40 ]; do
+ if [ "$bar_piece" -ne "$bar_separator" ]; then
+ printf "%s" "$BAR_ELEMENT"
+ else
+ printf "%s\\033[1;30m" "$BAR_ELEMENT"
+ fi
+
+ bar_piece=$((bar_piece + 1))
+ done
+ else
+ bar_cached_val=$(($3 + $4))
+ bar_cached_separator=$((bar_cached_val * 100 * 10 / $2 / 25))
+
+ bar_piece=0
+ while [ $bar_piece -le 40 ]; do
+ if [ $bar_piece -eq $bar_separator ]; then
+ printf "%s\\033[1;36m" "$BAR_ELEMENT"
+ elif [ $bar_piece -eq $bar_cached_separator ]; then
+ printf "%s\\033[1;30m" "$BAR_ELEMENT"
+ else
+ printf "%s" "$BAR_ELEMENT"
+ fi
+
+ bar_piece=$((bar_piece + 1))
+ done
+ fi
+
+ printf "\\033[0m\\n"
+}
+
+generate_bar_memory() {
+ # 1 - icon
+ # 2 - total memory in M
+ # 3 - used memory in M
+ # 4 - cached memory in M
+
+ bar_memory_used=$(generate_unit_byte "$3")
+ bar_memory_cached=$(generate_unit_byte "$4")
+ bar_memory_available=$(generate_unit_byte $(($2 - $3)))
+
+ printf " %s used / %s cached / %s available\\n" "$bar_memory_used" "$bar_memory_cached" "$bar_memory_available"
+ generate_bar "$1" "$2" "$3" "$4"
+}
+
+generate_bar_swap() {
+ # 1 - icon
+ # 2 - total swap in M
+ # 3 - used swap in M
+
+ bar_swap_used=$(generate_unit_byte "$3")
+
+ bar_swap_available=$(($2 - $3))
+ bar_swap_available=$(generate_unit_byte "$bar_swap_available")
+
+ printf " %s used / %s available\\n" "$bar_swap_used" "$bar_swap_available"
+ generate_bar "$1" "$2" "$3"
+}
+
+generate_bar_disk() {
+ # 1 - icon
+ # 2 - total size in M
+ # 3 - used space in M
+ # 4 - mount path
+
+ bar_disk_mount="$4$(generate_space "$4" 10)"
+
+ bar_disk_used="$(generate_unit_byte "$3")"
+ bar_disk_used="$(generate_space "$bar_disk_used" 5)$bar_disk_used used"
+
+ bar_disk_available="$(($2 - $3))"
+ bar_disk_available="$(generate_unit_byte "$bar_disk_available") available"
+
+ printf " %s%s / %s\\n" "$bar_disk_mount" "$bar_disk_used" "$bar_disk_available"
+
+ generate_bar "$1" "$2" "$3"
+}
+
+print_banner() {
+ if command -v lolcat >/dev/null && command -v figlet >/dev/null; then
+ if [[ "${#HOSTNAME}" -lt 14 ]]; then
+ figlet "$(hostname)" | lolcat -f
+ else
+ printf "\\n"
+ printf " \\033[1;37mHostname:\\033[0m %s\\n" "$(hostname)"
+ fi
+ elif command -v figlet >/dev/null; then
+ printf "\\n%s\\n" "$(figlet -t -f "$BANNER_FONTPATH" " $BANNER_TEXT")"
+ else
+ printf "\\n"
+ printf " \\033[1;37mHostname:\\033[0m %s\\n" "$(hostname)"
+ fi
+
+ if [ -f /etc/os-release ]; then
+ . /etc/os-release
+
+ if [ "$ID" = "debian" ]; then
+ banner_distro_icon="$BANNER_DEBIAN_ICON"
+ banner_distro_color="$BANNER_DEBIAN_COLOR"
+ banner_distro_name="Debian"
+ banner_distro_version="$(cat /etc/debian_version)"
+ elif [ "$ID" = "fedora" ]; then
+ banner_distro_icon="$BANNER_FEDORA_ICON"
+ banner_distro_color="$BANNER_FEDORA_COLOR"
+ banner_distro_name="Fedora"
+ banner_distro_version="$VERSION_ID"
+ else
+ banner_distro_icon="$OS_ICON"
+ banner_distro_color="0"
+ if [ -n "$NAME" ]; then
+ banner_distro_name="$NAME"
+ elif [ -n "$PRETTY_NAME" ]; then
+ banner_distro_name="$PRETTY_NAME"
+ else
+ banner_distro_name="Linux"
+ fi
+ if [ -n "$VERSION" ]; then
+ banner_distro_version="$VERSION"
+ elif [ -n "$VERSION_ID" ]; then
+ banner_distro_version="$VERSION_ID"
+ elif [ -n "$BUILD_ID" ]; then
+ banner_distro_version="$BUILD_ID"
+ else
+ banner_distro_version="Version Unknown"
+ fi
+ fi
+
+ banner_distro_space="$(generate_space "$banner_distro_name" 13)"
+ if [ "$(hostname)" = 'dom0' ]; then
+ # Qubes dom0
+ banner_distro_space="$(generate_space "$NAME" 13)"
+ printf " \\033[%sm%s %s\\033[0m%s%s\\n" "$banner_distro_color" "" "$NAME" "$banner_distro_space" "$VERSION"
+ else
+ printf " \\033[%sm%s %s\\033[0m%s%s\\n" "$banner_distro_color" "$banner_distro_icon" "$banner_distro_name" "$banner_distro_space" "$banner_distro_version"
+ fi
+ printf " \\033[%sm%s Linux\\033[0m %s\\n" "$BANNER_KERNEL_COLOR" "$BANNER_KERNEL_ICON" "$(cut -d ' ' -f 3 /dev/null | grep 'inet ' | cut -d ' ' -f 2)"
+ IP_ADDR_PUB="$(timeout 1 sh -c 'curl -sSL ifconfig.me')"
+ if [ -n "$IP_ADDR_PUB" ]; then
+ printf " \\033[%sm%s Public IP\\033[0m %s\\n" "$UPDATES_SECURITY_COLOR" "" "$IP_ADDR_PUB"
+ fi
+ fi
+ fi
+}
+
+print_processor() {
+ printf "\\n"
+ printf " \\033[1;37mProcessor:\\033[0m\\n"
+
+ processor_loadavg="$(cut -d " " -f 1,2,3 /dev/null; then
+ printf "\\n"
+ printf " \\033[1;37mDiskspace:\\033[0m\\n"
+
+ diskspace_devices=$(lsblk -Jlo NAME,MOUNTPOINT | jq -c '.blockdevices | sort_by(.mountpoint) | .[] | select( .mountpoint != null and .mountpoint != "[SWAP]" )')
+ diskspace_partitions=$(df -B M 2> /dev/null | sed -e "s/M//g")
+
+ diskspace_index=0
+ echo "$diskspace_devices" | while read -r line; do
+ diskspace_disk_name="$(echo "$line" | jq -r '.name')"
+ diskspace_disk_mount="$(echo "$line" | jq -r '.mountpoint')"
+
+ diskspace_disk_size="$(echo "$diskspace_partitions" | grep "$diskspace_disk_name " | awk '{ print $2 }')"
+ diskspace_disk_used="$(echo "$diskspace_partitions" | grep "$diskspace_disk_name " | awk '{ print $3 }')"
+ if [[ "$diskspace_disk_mount" != '/var/lib/snapd/snap'* ]] && [[ "$diskspace_disk_mount" != '/snap/'* ]]; then
+ if [ -z "$diskspace_disk_size" ]; then
+ diskspace_disk_size="$(echo "$diskspace_partitions" | grep "$diskspace_disk_mount" | awk '{ print $2 }')"
+ fi
+ if [ -z "$diskspace_disk_used" ]; then
+ diskspace_disk_used="$(echo "$diskspace_partitions" | grep "$diskspace_disk_mount" | awk '{ print $3 }')"
+ fi
+ if [ "$diskspace_index" -ne 0 ]; then
+ printf "\\n"
+ fi
+ diskspace_index=$((diskspace_index + 1))
+ generate_bar_disk "$DISKSPACE_ICON" "$diskspace_disk_size" "$diskspace_disk_used" "$diskspace_disk_mount"
+ fi
+ done
+ fi
+}
+
+print_services() {
+ if [ -f $SERVICES_FILE ] && [ "$(wc -l <$SERVICES_FILE)" != 0 ]; then
+ printf "\\n"
+ printf " \\033[1;37mServices:\\033[0m \\033[1;37mVersion:\\033[0m\\n"
+
+ while read -r line; do
+ service_description=$(echo "$line" | cut -d ';' -f 1)
+
+ service_name=$(echo "$line" | cut -d ';' -f 2)
+
+ service_package=$(echo "$line" | cut -d ';' -f 3)
+
+ if [ -n "$service_description" ] && [ -n "$service_name" ]; then
+ if systemctl is-active --quiet "$service_name".service; then
+ service_icon="$SERVICES_UP_ICON"
+ service_color="$SERVICES_UP_COLOR"
+ else
+ service_icon="$SERVICES_DOWN_ICON"
+ service_color="$SERVICES_DOWN_COLOR"
+ fi
+
+ service_space=$(generate_space "$service_description" 34)
+
+ if [ -n "$service_package" ]; then
+ if [ -f /usr/bin/apt ]; then
+ package_version=$(dpkg -s "$service_package" | grep '^Version:' | cut -d ' ' -f 2 | cut -d ':' -f 2 | cut -d '-' -f 1)
+ elif [ -f /usr/bin/rpm ]; then
+ package_version=$(rpm -q --queryformat '%{VERSION}' "$service_package")
+ else
+ package_version="?"
+ fi
+ else
+ package_version="--"
+ fi
+ fi
+
+ printf " \\033[%sm%s\\033[0m %s%s%s\\n" "$service_color" "$service_icon" "$service_description" "$service_space" "$package_version"
+ done <"$SERVICES_FILE" | grep -v '#'
+ fi
+}
+
+print_podman() {
+ if command -v jq >/dev/null; then
+ printf "\\n"
+ printf " \\033[1;37mPodman:\\033[0m\\n"
+
+ podman_version="$(sudo podman version --format json | jq -r '.Client.Version')"
+ podman_space="$(generate_space "$podman_version" 23)"
+ podman_images="$(sudo podman images --format json | jq '. | length')"
+
+ printf " %s Version %s%s%s %s Images\\n\\n" "$PODMAN_VERSION_ICON" "$podman_version" "$podman_space" "$PODMAN_IMAGES_ICON" "$podman_images"
+
+ podman_list=$(sudo podman pod ls --sort name --format json)
+ podman_pods=$(echo "$podman_list" | jq -r '.[] .Name')
+
+ echo "$podman_pods" | while read -r pod; do
+ if [ "$(echo "$podman_list" | jq -r ".[] | select(.Name == \"$pod\") | .Status")" = "Running" ]; then
+ pod_space=$(generate_space "$pod" 34)
+
+ pod_container_running="$(echo "$podman_list" | jq -r ".[] | select(.Name == \"$pod\") | .Containers[] | select(.Status == \"running\") | .Status" | wc -l)"
+
+ if [ "$pod_container_running" -ne 0 ]; then
+ pod_container_running=$(printf "\\033[%um%u Running\\033[0m" "$PODMAN_RUNNING_COLOR" "$pod_container_running")
+ fi
+
+ pod_container_other="$(echo "$podman_list" | jq -r ".[] | select(.Name == \"$pod\") | .Containers[] | select(.Status != \"running\") | .Status" | wc -l)"
+
+ if [ "$pod_container_other" -ne 0 ]; then
+ pod_container_other=$(printf ", \\033[%um%u Other\\033[0m" "$PODMAN_OTHER_COLOR" "$pod_container_other")
+ else
+ pod_container_other=""
+ fi
+
+ pod_status="$pod_container_running$pod_container_other"
+
+ printf " \\033[%um%s\\033[0m %s%s%s\\n" "$PODMAN_RUNNING_COLOR" "$PODMAN_RUNNING_ICON" "$pod" "$pod_space" "$pod_status"
+ else
+ printf " \\033[%um%s\\033[0m \\033[%um%s\\033[0m\\n" "$PODMAN_OTHER_COLOR" "$PODMAN_OTHER_ICON" "$PODMAN_OTHER_COLOR" "$pod"
+ fi
+ done
+ fi
+}
+
+print_docker() {
+ if command -v jq >/dev/null && [ "$(systemctl is-active docker.service)" = "active" ]; then
+ printf "\\n"
+ printf " \\033[1;37mDocker:\\033[0m\\n"
+
+ docker_info=$(sudo curl -sf --unix-socket /var/run/docker.sock http:/v1.40/info)
+
+ docker_version=$(echo "$docker_info" | jq -r '.ServerVersion')
+
+ docker_space=$(generate_space "$docker_version" 23)
+
+ docker_images=$(echo "$docker_info" | jq -r '.Images')
+
+ printf " %s Version %s%s%s %s Images\\n" "$DOCKER_VERSION_ICON" "$docker_version" "$docker_space" "$DOCKER_IMAGES_ICON" "$docker_images"
+
+ docker_list_curl="$(sudo curl -sf --unix-socket /var/run/docker.sock "http://v1.40/containers/json?all=true")"
+ docker_list_curl_length="$(echo "$docker_list_curl" | jq -c '. | length')"
+ docker_list="$(echo "$docker_list_curl" | jq -c ' .[]')"
+
+ if [ "$docker_list_curl_length" != '0' ]; then
+ echo "$docker_list" | while read -r line; do
+ container_name="$(echo "$line" | jq -r '.Names[]' | sed 's/\///')"
+ container_status="$(echo "$line" | jq -r '.Status' | sed 's/.*/\l&/')"
+ container_space=$(generate_space "$container_name" 34)
+ if [ "$(echo "$line" | jq -r '.State')" = "running" ]; then
+ printf " \\033[%um%s\\033[0m %s%s%s\\n" "$DOCKER_RUNNING_COLOR" "$DOCKER_RUNNING_ICON" "$container_name" "$container_space" "$container_status"
+ else
+ printf " \\033[%um%s\\033[0m \\033[%um%s\\033[0m%s\\033[%um%s\\033[0m\\n" "$DOCKER_OTHER_COLOR" "$DOCKER_OTHER_ICON" "$DOCKER_OTHER_COLOR" "$container_name" "$container_space" "$DOCKER_OTHER_COLOR" "$container_status"
+ fi
+ done
+ fi
+ fi
+}
+
+print_updates() {
+ printf "\\n"
+ printf " \\033[1;37mHealth:\\033[0m\\n"
+ if [ -f /usr/bin/apt ]; then
+ updates_count_regular=$(apt-get -qq -y --ignore-hold --allow-change-held-packages --allow-unauthenticated -s dist-upgrade | grep ^Inst | grep -c -v Security)
+ updates_count_security=$(apt-get -qq -y --ignore-hold --allow-change-held-packages --allow-unauthenticated -s dist-upgrade | grep ^Inst | grep -c Security)
+
+ if [ "$updates_count_regular" -ne 0 ]; then
+ if [ -n "$updates_count_security" ] && [ "$updates_count_security" -ne 0 ]; then
+ updates_icon=$UPDATES_SECURITY_ICON
+ updates_color=$UPDATES_SECURITY_COLOR
+ updates_message="$updates_count_regular packages can be updated, $updates_count_security are security updates."
+ else
+ updates_icon=$UPDATES_AVAILIABLE_ICON
+ updates_color=$UPDATES_AVAILIABLE_COLOR
+ updates_message="$updates_count_regular packages can be updated."
+ fi
+ else
+ updates_icon=$UPDATES_ZERO_ICON
+ updates_color=$UPDATES_ZERO_COLOR
+ updates_message="The system apt packages are up-to-date!"
+ fi
+
+ printf " \\033[%sm%s \\033[0m %s\\n" "$updates_color" "$updates_icon" "$updates_message"
+ elif [ -f /usr/bin/dnfTODO ]; then
+ # TODO - Find way of quickly acquiring details
+ mkdir -p "$HOME/.local/labs" > /dev/null
+ (command dnf list updates | grep updates | wc -l > "$HOME/.local/labs/dnf-updates-reg" &)
+ (command dnf updateinfo list --security --available | grep '/Sec. ' | wc -l > "$HOME/.local/labs/dnf-updates-sec" &)
+ updates_count_security="0"
+ updates_count_reg="0"
+ if [ -f "$HOME/.local/labs/dnf-updates-sec" ]; then
+ updates_count_security="$(cat "$HOME/.local/labs/dnf-updates-sec")"
+ fi
+ if [ -f "$HOME/.local/labs/dnf-updates-reg" ]; then
+ updates_count_reg="$(cat "$HOME/.local/labs/dnf-updates-reg")"
+ fi
+
+ if [ -n "$updates_count_regular" ] && [ "$updates_count_regular" -ne 0 ]; then
+ if [ -n "$updates_count_security" ] && [ "$updates_count_security" -ne 0 ]; then
+ updates_icon=$UPDATES_SECURITY_ICON
+ updates_color=$UPDATES_SECURITY_COLOR
+ updates_message="$(generate_space "$updates_count_regular" 5) packages can be updated, $updates_count_security are security updates."
+ else
+ updates_icon=$UPDATES_AVAILIABLE_ICON
+ updates_color=$UPDATES_AVAILIABLE_COLOR
+ updates_message="$(generate_space "$bar_disk_used" 5) packages can be updated."
+ fi
+ else
+ updates_icon=$UPDATES_ZERO_ICON
+ updates_color=$UPDATES_ZERO_COLOR
+ updates_message="The system dnf packages are up-to-date!"
+ fi
+
+ printf " \\033[%sm%s \\033[0m %s\\n" "$updates_color" "$updates_icon" "$updates_message"
+ fi
+ if command -v systemctl > /dev/null; then
+ running_services_count="$(systemctl --type=service --plain | grep 'active running' | wc -l)"
+ failed_services_count="$(systemctl --type=service --failed | grep 'failed failed' | wc -l)"
+
+ if [ "$failed_services_count" -eq 0 ]; then
+ printf " \\033[%sm%s \\033[0m All enabled services are running!\\n" "32" ""
+ elif [ "$failed_services_count" -eq 1 ]; then
+ printf " \\033[%sm%s \\033[0m %s services are are currently running\\n" "32" "" "$running_services_count"
+ printf " \\033[%sm%s \\033[0m 1 service failed to start (%s)\\n" "31" "" "$(systemctl --type=service --failed | grep 'failed failed' | sed 's/..\([^ ]*\).service.*/\1/')"
+ elif [ "$failed_services_count" -gt 1 ]; then
+ printf " \\033[%sm%s \\033[0m %s services are are currently running\\n" "32" "" "$running_services_count"
+ printf " \\033[%sm%s \\033[0m %s services failed to start (see \`systemctl --type=service\`)\\n" "31" "" "$failed_services_count"
+ fi
+ fi
+}
+
+print_letsencrypt() {
+ if [ -d $LETSENCRYPT_CERTPATH ] && [ "$(ls -a $LETSENCRYPT_CERTPATH)" ]; then
+ printf "\\n"
+ printf " \\033[1;37mSSL / let’s encrypt:\\033[0m\\n"
+
+ cert_list=$(sudo find $LETSENCRYPT_CERTPATH -name cert.pem)
+
+ for cert_file in $cert_list; do
+ sudo openssl x509 -checkend $((25 * 86400)) -noout -in "$cert_file" >>/dev/null
+ result=$?
+
+ cert_name=$(echo "$cert_file" | rev | cut -d '/' -f 2 | rev)
+
+ if [ "$result" -eq 0 ]; then
+ printf " \\033[%sm%s\\033[0m %s\\n" "$LETSENCRYPT_VALID_COLOR" "$LETSENCRYPT_VALID_ICON" "$cert_name"
+ else
+ sudo openssl x509 -checkend $((0 * 86400)) -noout -in "$cert_file" >>/dev/null
+ result=$?
+
+ if [ "$result" -eq 0 ]; then
+ printf " \\033[%sm%s\\033[0m %s\\n" "$LETSENCRYPT_WARNING_COLOR" "$LETSENCRYPT_WARNING_ICON" "$cert_name"
+ else
+ printf " \\033[%sm%s\\033[0m %s\\n" "$LETSENCRYPT_INVALID_COLOR" "$LETSENCRYPT_INVALID_ICON" "$cert_name"
+ fi
+ fi
+ done
+ fi
+}
+
+print_login() {
+ login_last="$(last -n 2 -a -d --time-format iso "$(whoami)" | head -n 2 | tail -n 1)"
+
+ if [ "$(echo "$login_last" | awk '{ print $1 }')" = "$(whoami)" ]; then
+ login_ip="$(echo "$login_last" | awk '{ print $7 }')"
+
+ login_login="$(date -d "$(echo "$login_last" | awk '{ print $3 }' | cut -d '+' -f 1 | sed "s/T/ /")" "+%a, %d.%m.%y %H:%M")"
+
+ login_space=$(generate_space "$login_login" 25)
+
+ if [ "$(echo "$login_last" | awk '{ print $4 }')" = "still" ]; then
+ login_logout="still connected"
+ else
+ login_logout="$(date -d "$(echo "$login_last" | awk '{ print $5 }' | cut -d '+' -f 1 | sed "s/T/ /")" "+%a, %d.%m.%y %H:%M")"
+ fi
+
+ printf "\\n"
+ printf " \\033[1;37mLast login for %s:\\033[0m\\n" "$(echo "$login_last" | awk '{ print $1 }')"
+ printf " %s %s%s%s %s\\n" "$LOGIN_LOGIN_ICON" "$login_login" "$login_space" "$LOGIN_LOGOUT_ICON" "$login_logout"
+ printf " %s %s\\n" "$LOGIN_IP_ICON" "$login_ip"
+ fi
+}
+
+print_include() {
+ . $INCLUDE_FILE
+}
+
+bash_motd() {
+ for module in "$@"; do
+ if [ "$module" = "--banner" ]; then
+ print_banner
+ elif [ "$module" = "--processor" ]; then
+ print_processor
+ elif [ "$module" = "--memory" ]; then
+ print_memory
+ elif [ "$module" = "--swap" ]; then
+ print_swap
+ elif [ "$module" = "--diskspace" ]; then
+ print_diskspace
+ elif [ "$module" = "--services" ]; then
+ print_services
+ elif [ "$module" = "--podman" ]; then
+ print_podman
+ elif [ "$module" = "--docker" ]; then
+ print_docker
+ elif [ "$module" = "--updates" ]; then
+ print_updates
+ elif [ "$module" = "--letsencrypt" ]; then
+ print_letsencrypt
+ elif [ "$module" = "--login" ]; then
+ print_login
+ elif [ "$module" = "--include" ]; then
+ print_include
+ fi
+ done
+ printf "\\n"
+}
diff --git a/.local/scripts/p10k.zsh b/.local/scripts/p10k.zsh
new file mode 100644
index 00000000..884e7241
--- /dev/null
+++ b/.local/scripts/p10k.zsh
@@ -0,0 +1,1641 @@
+# Generated by Powerlevel10k configuration wizard on 2022-10-29 at 08:32 EDT.
+# Based on romkatv/powerlevel10k/config/p10k-classic.zsh, checksum 52170.
+# Wizard options: nerdfont-complete + powerline, large icons, classic, unicode, dark,
+# 12h time, angled separators, sharp heads, flat tails, 2 lines, disconnected,
+# left frame, sparse, many icons, concise, transient_prompt, instant_prompt=verbose.
+# Type `p10k configure` to generate another config.
+#
+# Config for Powerlevel10k with classic powerline prompt style. Type `p10k configure` to generate
+# your own config based on it.
+#
+# Tip: Looking for a nice color? Here's a one-liner to print colormap.
+#
+# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done
+
+# Temporarily change options.
+'builtin' 'local' '-a' 'p10k_config_opts'
+[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases')
+[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob')
+[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand')
+'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
+
+() {
+ emulate -L zsh -o extended_glob
+
+ # Unset all configuration options. This allows you to apply configuration changes without
+ # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`.
+ unset -m '(POWERLEVEL9K_*|DEFAULT_USER)~POWERLEVEL9K_GITSTATUS_DIR'
+
+ # Zsh >= 5.1 is required.
+ autoload -Uz is-at-least && is-at-least 5.1 || return
+
+ # The list of segments shown on the left. Fill it with the most important segments.
+ typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
+ # =========================[ Line #1 ]=========================
+ os_icon # os identifier
+ dir # current directory
+ vcs # git status
+ # =========================[ Line #2 ]=========================
+ newline # \n
+ # prompt_char # prompt symbol
+ )
+
+ # The list of segments shown on the right. Fill it with less important segments.
+ # Right prompt on the last prompt line (where you are typing your commands) gets
+ # automatically hidden when the input line reaches it. Right prompt above the
+ # last prompt line gets hidden if it would overlap with left prompt.
+ typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
+ # =========================[ Line #1 ]=========================
+ status # exit code of the last command
+ command_execution_time # duration of the last command
+ background_jobs # presence of background jobs
+ direnv # direnv status (https://direnv.net/)
+ asdf # asdf version manager (https://github.com/asdf-vm/asdf)
+ virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html)
+ anaconda # conda environment (https://conda.io/)
+ # pyenv # python environment (https://github.com/pyenv/pyenv)
+ # goenv # go environment (https://github.com/syndbg/goenv)
+ # nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv)
+ # nvm # node.js version from nvm (https://github.com/nvm-sh/nvm)
+ # nodeenv # node.js environment (https://github.com/ekalinin/nodeenv)
+ node_version # node.js version
+ go_version # go version (https://golang.org)
+ rust_version # rustc version (https://www.rust-lang.org)
+ dotnet_version # .NET version (https://dotnet.microsoft.com)
+ php_version # php version (https://www.php.net/)
+ laravel_version # laravel php framework version (https://laravel.com/)
+ java_version # java version (https://www.java.com/)
+ package # name@version from package.json (https://docs.npmjs.com/files/package.json)
+ # rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv)
+ # rvm # ruby version from rvm (https://rvm.io)
+ # fvm # flutter version management (https://github.com/leoafarias/fvm)
+ # luaenv # lua version from luaenv (https://github.com/cehoffman/luaenv)
+ # jenv # java version from jenv (https://github.com/jenv/jenv)
+ # plenv # perl version from plenv (https://github.com/tokuhirom/plenv)
+ # phpenv # php version from phpenv (https://github.com/phpenv/phpenv)
+ # scalaenv # scala version from scalaenv (https://github.com/scalaenv/scalaenv)
+ # haskell_stack # haskell version from stack (https://haskellstack.org/)
+ kubecontext # current kubernetes context (https://kubernetes.io/)
+ terraform # terraform workspace (https://www.terraform.io)
+ terraform_version # terraform version (https://www.terraform.io)
+ aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html)
+ # aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/)
+ azure # azure account name (https://docs.microsoft.com/en-us/cli/azure)
+ gcloud # google cloud cli account and project (https://cloud.google.com/)
+ google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production)
+ toolbox # toolbox name (https://github.com/containers/toolbox)
+ context # user@hostname
+ # nordvpn # nordvpn connection status, linux only (https://nordvpn.com/)
+ # ranger # ranger shell (https://github.com/ranger/ranger)
+ nnn # nnn shell (https://github.com/jarun/nnn)
+ # xplr # xplr shell (https://github.com/sayanarijit/xplr)
+ vim_shell # vim shell indicator (:sh)
+ # midnight_commander # midnight commander shell (https://midnight-commander.org/)
+ # nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html)
+ vi_mode # vi mode (you don't need this if you've enabled prompt_char)
+ # vpn_ip # virtual private network indicator
+ # load # CPU load
+ # disk_usage # disk usage
+ ram # free RAM
+ # swap # used swap
+ # todo # todo items (https://github.com/todotxt/todo.txt-cli)
+ # timewarrior # timewarrior tracking status (https://timewarrior.net/)
+ # taskwarrior # taskwarrior task count (https://taskwarrior.org/)
+ time # current time
+ # =========================[ Line #2 ]=========================
+ # newline # \n
+ # ip # ip address and bandwidth usage for a specified network interface
+ # public_ip # public IP address
+ # proxy # system-wide http/https/ftp proxy
+ # battery # internal battery
+ # wifi # wifi speed
+ # example # example user-defined segment (see prompt_example function below)
+ )
+
+ # Defines character set used by powerlevel10k. It's best to let `p10k configure` set it for you.
+ typeset -g POWERLEVEL9K_MODE=nerdfont-complete
+ # When set to `moderate`, some icons will have an extra space after them. This is meant to avoid
+ # icon overlap when using non-monospace fonts. When set to `none`, spaces are not added.
+ typeset -g POWERLEVEL9K_ICON_PADDING=moderate
+
+ # When set to true, icons appear before content on both sides of the prompt. When set
+ # to false, icons go after content. If empty or not set, icons go before content in the left
+ # prompt and after content in the right prompt.
+ #
+ # You can also override it for a specific segment:
+ #
+ # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false
+ #
+ # Or for a specific segment in specific state:
+ #
+ # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false
+ typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT=
+
+ # Add an empty line before each prompt.
+ typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
+
+ # Connect left prompt lines with these symbols. You'll probably want to use the same color
+ # as POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND below.
+ typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX='%240F╭─'
+ typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX='%240F├─'
+ typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX='%240F╰─'
+ # Connect right prompt lines with these symbols.
+ typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX=
+ typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX=
+ typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX=
+
+ # Filler between left and right prompt on the first prompt line. You can set it to ' ', '·' or
+ # '─'. The last two make it easier to see the alignment between left and right prompt and to
+ # separate prompt from command output. You might want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false
+ # for more compact prompt if using this option.
+ typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' '
+ typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_BACKGROUND=
+ typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_GAP_BACKGROUND=
+ if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then
+ # The color of the filler. You'll probably want to match the color of POWERLEVEL9K_MULTILINE
+ # ornaments defined above.
+ typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=240
+ # Start filler from the edge of the screen if there are no left segments on the first line.
+ typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}'
+ # End filler on the edge of the screen if there are no right segments on the first line.
+ typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}'
+ fi
+
+ # Default background color.
+ typeset -g POWERLEVEL9K_BACKGROUND=236
+
+ # Separator between same-color segments on the left.
+ typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='%244F\uE0B1'
+ # Separator between same-color segments on the right.
+ typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='%244F\uE0B3'
+ # Separator between different-color segments on the left.
+ typeset -g POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR='\uE0B0'
+ # Separator between different-color segments on the right.
+ typeset -g POWERLEVEL9K_RIGHT_SEGMENT_SEPARATOR='\uE0B2'
+ # The right end of left prompt.
+ typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='\uE0B0'
+ # The left end of right prompt.
+ typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='\uE0B2'
+ # The left end of left prompt.
+ typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL=''
+ # The right end of right prompt.
+ typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL=''
+ # Left prompt terminator for lines without any segments.
+ typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=
+
+ #################################[ os_icon: os identifier ]##################################
+ # OS identifier color.
+ typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=255
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐'
+
+ ################################[ prompt_char: prompt symbol ]################################
+ # Transparent background.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_BACKGROUND=
+ # Green prompt symbol if the last command succeeded.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76
+ # Red prompt symbol if the last command failed.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196
+ # Default prompt symbol.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯'
+ # Prompt symbol in command vi mode.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮'
+ # Prompt symbol in visual vi mode.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='V'
+ # Prompt symbol in overwrite vi mode.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶'
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true
+ # No line terminator if prompt_char is the last segment.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=
+ # No line introducer if prompt_char is the first segment.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL=
+ # No surrounding whitespace.
+ typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_{LEFT,RIGHT}_WHITESPACE=
+
+ ##################################[ dir: current directory ]##################################
+ # Default current directory color.
+ typeset -g POWERLEVEL9K_DIR_FOREGROUND=31
+ # If directory is too long, shorten some of its segments to the shortest possible unique
+ # prefix. The shortened directory can be tab-completed to the original.
+ typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique
+ # Replace removed segment suffixes with this symbol.
+ typeset -g POWERLEVEL9K_SHORTEN_DELIMITER=
+ # Color of the shortened directory segments.
+ typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=103
+ # Color of the anchor directory segments. Anchor segments are never shortened. The first
+ # segment is always an anchor.
+ typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=39
+ # Display anchor directory segments in bold.
+ typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true
+ # Don't shorten directories that contain any of these files. They are anchors.
+ local anchor_files=(
+ .bzr
+ .citc
+ .git
+ .hg
+ .node-version
+ .python-version
+ .go-version
+ .ruby-version
+ .lua-version
+ .java-version
+ .perl-version
+ .php-version
+ .tool-version
+ .shorten_folder_marker
+ .svn
+ .terraform
+ CVS
+ Cargo.toml
+ composer.json
+ go.mod
+ package.json
+ stack.yaml
+ )
+ typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})"
+ # If set to "first" ("last"), remove everything before the first (last) subdirectory that contains
+ # files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is
+ # /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first)
+ # or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers
+ # and other directories don't.
+ #
+ # Optionally, "first" and "last" can be followed by ":" where is an integer.
+ # This moves the truncation point to the right (positive offset) or to the left (negative offset)
+ # relative to the marker. Plain "first" and "last" are equivalent to "first:0" and "last:0"
+ # respectively.
+ typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false
+ # Don't shorten this many last directory segments. They are anchors.
+ typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1
+ # Shorten directory if it's longer than this even if there is space for it. The value can
+ # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty,
+ # directory will be shortened only when prompt doesn't fit or when other parameters demand it
+ # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below).
+ # If set to `0`, directory will always be shortened to its minimum length.
+ typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80
+ # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this
+ # many columns for typing commands.
+ typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40
+ # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least
+ # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands.
+ typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50
+ # If set to true, embed a hyperlink into the directory. Useful for quickly
+ # opening a directory in the file manager simply by clicking the link.
+ # Can also be handy when the directory is shortened, as it allows you to see
+ # the full directory that was used in previous commands.
+ typeset -g POWERLEVEL9K_DIR_HYPERLINK=false
+
+ # Enable special styling for non-writable and non-existent directories. See POWERLEVEL9K_LOCK_ICON
+ # and POWERLEVEL9K_DIR_CLASSES below.
+ typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v3
+
+ # The default icon shown next to non-writable and non-existent directories when
+ # POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v3.
+ # typeset -g POWERLEVEL9K_LOCK_ICON='⭐'
+
+ # POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons and colors for different
+ # directories. It must be an array with 3 * N elements. Each triplet consists of:
+ #
+ # 1. A pattern against which the current directory ($PWD) is matched. Matching is done with
+ # extended_glob option enabled.
+ # 2. Directory class for the purpose of styling.
+ # 3. An empty string.
+ #
+ # Triplets are tried in order. The first triplet whose pattern matches $PWD wins.
+ #
+ # If POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v3, non-writable and non-existent directories
+ # acquire class suffix _NOT_WRITABLE and NON_EXISTENT respectively.
+ #
+ # For example, given these settings:
+ #
+ # typeset -g POWERLEVEL9K_DIR_CLASSES=(
+ # '~/work(|/*)' WORK ''
+ # '~(|/*)' HOME ''
+ # '*' DEFAULT '')
+ #
+ # Whenever the current directory is ~/work or a subdirectory of ~/work, it gets styled with one
+ # of the following classes depending on its writability and existence: WORK, WORK_NOT_WRITABLE or
+ # WORK_NON_EXISTENT.
+ #
+ # Simply assigning classes to directories doesn't have any visible effects. It merely gives you an
+ # option to define custom colors and icons for different directory classes.
+ #
+ # # Styling for WORK.
+ # typeset -g POWERLEVEL9K_DIR_WORK_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=31
+ # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=103
+ # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=39
+ #
+ # # Styling for WORK_NOT_WRITABLE.
+ # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=31
+ # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=103
+ # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=39
+ #
+ # # Styling for WORK_NON_EXISTENT.
+ # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_FOREGROUND=31
+ # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_SHORTENED_FOREGROUND=103
+ # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_ANCHOR_FOREGROUND=39
+ #
+ # If a styling parameter isn't explicitly defined for some class, it falls back to the classless
+ # parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls
+ # back to POWERLEVEL9K_DIR_FOREGROUND.
+ #
+ # typeset -g POWERLEVEL9K_DIR_CLASSES=()
+
+ # Custom prefix.
+ # typeset -g POWERLEVEL9K_DIR_PREFIX='%246Fin '
+
+ #####################################[ vcs: git status ]######################################
+ # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon.
+ typeset -g POWERLEVEL9K_VCS_BRANCH_ICON='\uF126 '
+
+ # Untracked files icon. It's really a question mark, your font isn't broken.
+ # Change the value of this parameter to show a different icon.
+ typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?'
+
+ # Formatter for Git status.
+ #
+ # Example output: master wip ⇣42⇡42 *42 merge ~42 +42 !42 ?42.
+ #
+ # You can edit the function to customize how Git status looks.
+ #
+ # VCS_STATUS_* parameters are set by gitstatus plugin. See reference:
+ # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh.
+ function my_git_formatter() {
+ emulate -L zsh
+
+ if [[ -n $P9K_CONTENT ]]; then
+ # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from
+ # gitstatus plugin). VCS_STATUS_* parameters are not available in this case.
+ typeset -g my_git_format=$P9K_CONTENT
+ return
+ fi
+
+ if (( $1 )); then
+ # Styling for up-to-date Git status.
+ local meta='%246F' # grey foreground
+ local clean='%76F' # green foreground
+ local modified='%178F' # yellow foreground
+ local untracked='%39F' # blue foreground
+ local conflicted='%196F' # red foreground
+ else
+ # Styling for incomplete and stale Git status.
+ local meta='%244F' # grey foreground
+ local clean='%244F' # grey foreground
+ local modified='%244F' # grey foreground
+ local untracked='%244F' # grey foreground
+ local conflicted='%244F' # grey foreground
+ fi
+
+ local res
+
+ if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then
+ local branch=${(V)VCS_STATUS_LOCAL_BRANCH}
+ # If local branch name is at most 32 characters long, show it in full.
+ # Otherwise show the first 12 … the last 12.
+ # Tip: To always show local branch name in full without truncation, delete the next line.
+ (( $#branch > 32 )) && branch[13,-13]="…" # <-- this line
+ res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}${branch//\%/%%}"
+ fi
+
+ if [[ -n $VCS_STATUS_TAG
+ # Show tag only if not on a branch.
+ # Tip: To always show tag, delete the next line.
+ && -z $VCS_STATUS_LOCAL_BRANCH # <-- this line
+ ]]; then
+ local tag=${(V)VCS_STATUS_TAG}
+ # If tag name is at most 32 characters long, show it in full.
+ # Otherwise show the first 12 … the last 12.
+ # Tip: To always show tag name in full without truncation, delete the next line.
+ (( $#tag > 32 )) && tag[13,-13]="…" # <-- this line
+ res+="${meta}#${clean}${tag//\%/%%}"
+ fi
+
+ # Display the current Git commit if there is no branch and no tag.
+ # Tip: To always display the current Git commit, delete the next line.
+ [[ -z $VCS_STATUS_LOCAL_BRANCH && -z $VCS_STATUS_TAG ]] && # <-- this line
+ res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}"
+
+ # Show tracking branch name if it differs from local branch.
+ if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then
+ res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}"
+ fi
+
+ # Display "wip" if the latest commit's summary contains "wip" or "WIP".
+ if [[ $VCS_STATUS_COMMIT_SUMMARY == (|*[^[:alnum:]])(wip|WIP)(|[^[:alnum:]]*) ]]; then
+ res+=" ${modified}wip"
+ fi
+
+ # ⇣42 if behind the remote.
+ (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}"
+ # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42.
+ (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" "
+ (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}"
+ # ⇠42 if behind the push remote.
+ (( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}"
+ (( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" "
+ # ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42.
+ (( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}"
+ # *42 if have stashes.
+ (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}"
+ # 'merge' if the repo is in an unusual state.
+ [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}"
+ # ~42 if have merge conflicts.
+ (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}"
+ # +42 if have staged changes.
+ (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}"
+ # !42 if have unstaged changes.
+ (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}"
+ # ?42 if have untracked files. It's really a question mark, your font isn't broken.
+ # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon.
+ # Remove the next line if you don't want to see untracked files at all.
+ (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}"
+ # "─" if the number of unstaged files is unknown. This can happen due to
+ # POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (see below) being set to a non-negative number lower
+ # than the number of files in the Git index, or due to bash.showDirtyState being set to false
+ # in the repository config. The number of staged and untracked files may also be unknown
+ # in this case.
+ (( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}─"
+
+ typeset -g my_git_format=$res
+ }
+ functions -M my_git_formatter 2>/dev/null
+
+ # Don't count the number of unstaged, untracked and conflicted files in Git repositories with
+ # more than this many files in the index. Negative value means infinity.
+ #
+ # If you are working in Git repositories with tens of millions of files and seeing performance
+ # sagging, try setting POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY to a number lower than the output
+ # of `git ls-files | wc -l`. Alternatively, add `bash.showDirtyState = false` to the repository's
+ # config: `git config bash.showDirtyState false`.
+ typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1
+
+ # Don't show Git status in prompt for repositories whose workdir matches this pattern.
+ # For example, if set to '~', the Git repository at $HOME/.git will be ignored.
+ # Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'.
+ typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~'
+
+ # Disable the default Git status formatting.
+ typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true
+ # Install our own Git status formatter.
+ typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}'
+ typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter(0)))+${my_git_format}}'
+ # Enable counters for staged, unstaged, etc.
+ typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1
+
+ # Icon color.
+ typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR=76
+ typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR=244
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # Custom prefix.
+ # typeset -g POWERLEVEL9K_VCS_PREFIX='%246Fon '
+
+ # Show status of repositories of these types. You can add svn and/or hg if you are
+ # using them. If you do, your prompt may become slow even when your current directory
+ # isn't in an svn or hg reposotiry.
+ typeset -g POWERLEVEL9K_VCS_BACKENDS=(git)
+
+ # These settings are used for repositories other than Git or when gitstatusd fails and
+ # Powerlevel10k has to fall back to using vcs_info.
+ typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=76
+ typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=76
+ typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=178
+
+ ##########################[ status: exit code of the last command ]###########################
+ # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and
+ # style them independently from the regular OK and ERROR state.
+ typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true
+
+ # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as
+ # it will signify success by turning green.
+ typeset -g POWERLEVEL9K_STATUS_OK=true
+ typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=70
+ typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔'
+
+ # Status when some part of a pipe command fails but the overall exit status is zero. It may look
+ # like this: 1|0.
+ typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true
+ typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=70
+ typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔'
+
+ # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as
+ # it will signify error by turning red.
+ typeset -g POWERLEVEL9K_STATUS_ERROR=true
+ typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=160
+ typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='✘'
+
+ # Status when the last command was terminated by a signal.
+ typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true
+ typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=160
+ # Use terse signal names: "INT" instead of "SIGINT(2)".
+ typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false
+ typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='✘'
+
+ # Status when some part of a pipe command fails and the overall exit status is also non-zero.
+ # It may look like this: 1|0.
+ typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true
+ typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=160
+ typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='✘'
+
+ ###################[ command_execution_time: duration of the last command ]###################
+ # Show duration of the last command if takes at least this many seconds.
+ typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3
+ # Show this many fractional digits. Zero means round to seconds.
+ typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0
+ # Execution time color.
+ typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=248
+ # Duration format: 1d 2h 3m 4s.
+ typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s'
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # Custom prefix.
+ # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='%246Ftook '
+
+ #######################[ background_jobs: presence of background jobs ]#######################
+ # Don't show the number of background jobs.
+ typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false
+ # Background jobs color.
+ typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=37
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #######################[ direnv: direnv status (https://direnv.net/) ]########################
+ # Direnv color.
+ typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=178
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]###############
+ # Default asdf color. Only used to display tools for which there is no color override (see below).
+ # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_FOREGROUND.
+ typeset -g POWERLEVEL9K_ASDF_FOREGROUND=66
+
+ # There are four parameters that can be used to hide asdf tools. Each parameter describes
+ # conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at
+ # least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to
+ # hide a tool, it gets shown.
+ #
+ # Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and
+ # POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands:
+ #
+ # asdf local python 3.8.1
+ # asdf global python 3.8.1
+ #
+ # After running both commands the current python version is 3.8.1 and its source is "local" as
+ # it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false,
+ # it'll hide python version in this case because 3.8.1 is the same as the global version.
+ # POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't
+ # contain "local".
+
+ # Hide tool versions that don't come from one of these sources.
+ #
+ # Available sources:
+ #
+ # - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable"
+ # - local `asdf current` says "set by /some/not/home/directory/file"
+ # - global `asdf current` says "set by /home/username/file"
+ #
+ # Note: If this parameter is set to (shell local global), it won't hide tools.
+ # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES.
+ typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global)
+
+ # If set to false, hide tool versions that are the same as global.
+ #
+ # Note: The name of this parameter doesn't reflect its meaning at all.
+ # Note: If this parameter is set to true, it won't hide tools.
+ # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW.
+ typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false
+
+ # If set to false, hide tool versions that are equal to "system".
+ #
+ # Note: If this parameter is set to true, it won't hide tools.
+ # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM.
+ typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true
+
+ # If set to non-empty value, hide tools unless there is a file matching the specified file pattern
+ # in the current directory, or its parent directory, or its grandparent directory, and so on.
+ #
+ # Note: If this parameter is set to empty value, it won't hide tools.
+ # Note: SHOW_ON_UPGLOB isn't specific to asdf. It works with all prompt segments.
+ # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_ON_UPGLOB.
+ #
+ # Example: Hide nodejs version when there is no package.json and no *.js files in the current
+ # directory, in `..`, in `../..` and so on.
+ #
+ # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.js|package.json'
+ typeset -g POWERLEVEL9K_ASDF_SHOW_ON_UPGLOB=
+
+ # Ruby version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_RUBY_FOREGROUND=168
+ # typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Python version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=37
+ # typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Go version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=37
+ # typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Node.js version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=70
+ # typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Rust version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=37
+ # typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # .NET Core version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=134
+ # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Flutter version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=38
+ # typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Lua version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=32
+ # typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Java version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=32
+ # typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Perl version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=67
+ # typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Erlang version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=125
+ # typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Elixir version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=129
+ # typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Postgres version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=31
+ # typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # PHP version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=99
+ # typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Haskell version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=172
+ # typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ # Julia version from asdf.
+ typeset -g POWERLEVEL9K_ASDF_JULIA_FOREGROUND=70
+ # typeset -g POWERLEVEL9K_ASDF_JULIA_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_ASDF_JULIA_SHOW_ON_UPGLOB='*.foo|*.bar'
+
+ ##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]###########
+ # NordVPN connection indicator color.
+ typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=39
+ # Hide NordVPN connection indicator when not connected.
+ typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION=
+ typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION=
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]##################
+ # Ranger shell color.
+ typeset -g POWERLEVEL9K_RANGER_FOREGROUND=178
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]#######################
+ # Nnn shell color.
+ typeset -g POWERLEVEL9K_NNN_FOREGROUND=72
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##################[ xplr: xplr shell (https://github.com/sayanarijit/xplr) ]##################
+ # xplr shell color.
+ typeset -g POWERLEVEL9K_XPLR_FOREGROUND=72
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_XPLR_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###########################[ vim_shell: vim shell indicator (:sh) ]###########################
+ # Vim shell indicator color.
+ typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=34
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]######
+ # Midnight Commander shell color.
+ typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=178
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]##
+ # Nix shell color.
+ typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=74
+
+ # Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line.
+ # typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION=
+
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##################################[ disk_usage: disk usage ]##################################
+ # Colors for different levels of disk usage.
+ typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=35
+ typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=220
+ typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=160
+ # Thresholds for different levels of disk usage (percentage points).
+ typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90
+ typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95
+ # If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent.
+ typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###########[ vi_mode: vi mode (you don't need this if you've enabled prompt_char) ]###########
+ # Text and color for normal (a.k.a. command) vi mode.
+ typeset -g POWERLEVEL9K_VI_COMMAND_MODE_STRING=NORMAL
+ typeset -g POWERLEVEL9K_VI_MODE_NORMAL_FOREGROUND=106
+ # Text and color for visual vi mode.
+ typeset -g POWERLEVEL9K_VI_VISUAL_MODE_STRING=VISUAL
+ typeset -g POWERLEVEL9K_VI_MODE_VISUAL_FOREGROUND=68
+ # Text and color for overtype (a.k.a. overwrite and replace) vi mode.
+ typeset -g POWERLEVEL9K_VI_OVERWRITE_MODE_STRING=OVERTYPE
+ typeset -g POWERLEVEL9K_VI_MODE_OVERWRITE_FOREGROUND=172
+ # Text and color for insert vi mode.
+ typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING=
+ typeset -g POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND=66
+
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ######################################[ ram: free RAM ]#######################################
+ # RAM color.
+ typeset -g POWERLEVEL9K_RAM_FOREGROUND=66
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #####################################[ swap: used swap ]######################################
+ # Swap color.
+ typeset -g POWERLEVEL9K_SWAP_FOREGROUND=96
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ######################################[ load: CPU load ]######################################
+ # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15.
+ typeset -g POWERLEVEL9K_LOAD_WHICH=5
+ # Load color when load is under 50%.
+ typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=66
+ # Load color when load is between 50% and 70%.
+ typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=178
+ # Load color when load is over 70%.
+ typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=166
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################
+ # Todo color.
+ typeset -g POWERLEVEL9K_TODO_FOREGROUND=110
+ # Hide todo when the total number of tasks is zero.
+ typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true
+ # Hide todo when the number of tasks after filtering is zero.
+ typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false
+
+ # Todo format. The following parameters are available within the expansion.
+ #
+ # - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks.
+ # - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering.
+ #
+ # These variables correspond to the last line of the output of `todo.sh -p ls`:
+ #
+ # TODO: 24 of 42 tasks shown
+ #
+ # Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT.
+ #
+ # typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT'
+
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############
+ # Timewarrior color.
+ typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=110
+ # If the tracked task is longer than 24 characters, truncate and append "…".
+ # Tip: To always display tasks without truncation, delete the following parameter.
+ # Tip: To hide task names and display just the icon when time tracking is enabled, set the
+ # value of the following parameter to "".
+ typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+…}'
+
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]##############
+ # Taskwarrior color.
+ typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=74
+
+ # Taskwarrior segment format. The following parameters are available within the expansion.
+ #
+ # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`.
+ # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`.
+ #
+ # Zero values are represented as empty parameters.
+ #
+ # The default format:
+ #
+ # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT'
+ #
+ # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT'
+
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##################################[ context: user@hostname ]##################################
+ # Context color when running with privileges.
+ typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178
+ # Context color in SSH without privileges.
+ typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=180
+ # Default context color (no privileges, no SSH).
+ typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=180
+
+ # Context format when running with privileges: bold user@hostname.
+ typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%B%n@%m'
+ # Context format when in SSH without privileges: user@hostname.
+ typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m'
+ # Default context format (no privileges, no SSH): user@hostname.
+ typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m'
+
+ # Don't show context unless running with privileges or in SSH.
+ # Tip: Remove the next line to always show context.
+ typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION=
+
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # Custom prefix.
+ # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='%246Fwith '
+
+ ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]###
+ # Python virtual environment color.
+ typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=37
+ # Don't show Python version next to the virtual environment name.
+ typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false
+ # If set to "false", won't show virtualenv if pyenv is already shown.
+ # If set to "if-different", won't show virtualenv if it's the same as pyenv.
+ typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false
+ # Separate environment name from Python version only with a space.
+ typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER=
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #####################[ anaconda: conda environment (https://conda.io/) ]######################
+ # Anaconda environment color.
+ typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=37
+
+ # Anaconda segment format. The following parameters are available within the expansion.
+ #
+ # - CONDA_PREFIX Absolute path to the active Anaconda/Miniconda environment.
+ # - CONDA_DEFAULT_ENV Name of the active Anaconda/Miniconda environment.
+ # - CONDA_PROMPT_MODIFIER Configurable prompt modifier (see below).
+ # - P9K_ANACONDA_PYTHON_VERSION Current python version (python --version).
+ #
+ # CONDA_PROMPT_MODIFIER can be configured with the following command:
+ #
+ # conda config --set env_prompt '({default_env}) '
+ #
+ # The last argument is a Python format string that can use the following variables:
+ #
+ # - prefix The same as CONDA_PREFIX.
+ # - default_env The same as CONDA_DEFAULT_ENV.
+ # - name The last segment of CONDA_PREFIX.
+ # - stacked_env Comma-separated list of names in the environment stack. The first element is
+ # always the same as default_env.
+ #
+ # Note: '({default_env}) ' is the default value of env_prompt.
+ #
+ # The default value of POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION expands to $CONDA_PROMPT_MODIFIER
+ # without the surrounding parentheses, or to the last path component of CONDA_PREFIX if the former
+ # is empty.
+ typeset -g POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION='${${${${CONDA_PROMPT_MODIFIER#\(}% }%\)}:-${CONDA_PREFIX:t}}'
+
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################
+ # Pyenv color.
+ typeset -g POWERLEVEL9K_PYENV_FOREGROUND=37
+ # Hide python version if it doesn't come from one of these sources.
+ typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global)
+ # If set to false, hide python version if it's the same as global:
+ # $(pyenv version-name) == $(pyenv global).
+ typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false
+ # If set to false, hide python version if it's equal to "system".
+ typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true
+
+ # Pyenv segment format. The following parameters are available within the expansion.
+ #
+ # - P9K_CONTENT Current pyenv environment (pyenv version-name).
+ # - P9K_PYENV_PYTHON_VERSION Current python version (python --version).
+ #
+ # The default format has the following logic:
+ #
+ # 1. Display just "$P9K_CONTENT" if it's equal to "$P9K_PYENV_PYTHON_VERSION" or
+ # starts with "$P9K_PYENV_PYTHON_VERSION/".
+ # 2. Otherwise display "$P9K_CONTENT $P9K_PYENV_PYTHON_VERSION".
+ typeset -g POWERLEVEL9K_PYENV_CONTENT_EXPANSION='${P9K_CONTENT}${${P9K_CONTENT:#$P9K_PYENV_PYTHON_VERSION(|/*)}:+ $P9K_PYENV_PYTHON_VERSION}'
+
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ################[ goenv: go environment (https://github.com/syndbg/goenv) ]################
+ # Goenv color.
+ typeset -g POWERLEVEL9K_GOENV_FOREGROUND=37
+ # Hide go version if it doesn't come from one of these sources.
+ typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global)
+ # If set to false, hide go version if it's the same as global:
+ # $(goenv version-name) == $(goenv global).
+ typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false
+ # If set to false, hide go version if it's equal to "system".
+ typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]##########
+ # Nodenv color.
+ typeset -g POWERLEVEL9K_NODENV_FOREGROUND=70
+ # Hide node version if it doesn't come from one of these sources.
+ typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global)
+ # If set to false, hide node version if it's the same as global:
+ # $(nodenv version-name) == $(nodenv global).
+ typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false
+ # If set to false, hide node version if it's equal to "system".
+ typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]###############
+ # Nvm color.
+ typeset -g POWERLEVEL9K_NVM_FOREGROUND=70
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############
+ # Nodeenv color.
+ typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=70
+ # Don't show Node version next to the environment name.
+ typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false
+ # Separate environment name from Node version only with a space.
+ typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER=
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##############################[ node_version: node.js version ]###############################
+ # Node version color.
+ typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=70
+ # Show node version only when in a directory tree containing package.json.
+ typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #######################[ go_version: go version (https://golang.org) ]########################
+ # Go version color.
+ typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=37
+ # Show go version only when in a go project subdirectory.
+ typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #################[ rust_version: rustc version (https://www.rust-lang.org) ]##################
+ # Rust version color.
+ typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=37
+ # Show rust version only when in a rust project subdirectory.
+ typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################
+ # .NET version color.
+ typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=134
+ # Show .NET version only when in a .NET project subdirectory.
+ typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #####################[ php_version: php version (https://www.php.net/) ]######################
+ # PHP version color.
+ typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=99
+ # Show PHP version only when in a PHP project subdirectory.
+ typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##########[ laravel_version: laravel php framework version (https://laravel.com/) ]###########
+ # Laravel version color.
+ typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=161
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ####################[ java_version: java version (https://www.java.com/) ]####################
+ # Java version color.
+ typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=32
+ # Show java version only when in a java project subdirectory.
+ typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true
+ # Show brief version.
+ typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]####
+ # Package color.
+ typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=117
+ # Package format. The following parameters are available within the expansion.
+ #
+ # - P9K_PACKAGE_NAME The value of `name` field in package.json.
+ # - P9K_PACKAGE_VERSION The value of `version` field in package.json.
+ #
+ # typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}'
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]##############
+ # Rbenv color.
+ typeset -g POWERLEVEL9K_RBENV_FOREGROUND=168
+ # Hide ruby version if it doesn't come from one of these sources.
+ typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global)
+ # If set to false, hide ruby version if it's the same as global:
+ # $(rbenv version-name) == $(rbenv global).
+ typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false
+ # If set to false, hide ruby version if it's equal to "system".
+ typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #######################[ rvm: ruby version from rvm (https://rvm.io) ]########################
+ # Rvm color.
+ typeset -g POWERLEVEL9K_RVM_FOREGROUND=168
+ # Don't show @gemset at the end.
+ typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false
+ # Don't show ruby- at the front.
+ typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############
+ # Fvm color.
+ typeset -g POWERLEVEL9K_FVM_FOREGROUND=38
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]###########
+ # Lua color.
+ typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=32
+ # Hide lua version if it doesn't come from one of these sources.
+ typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global)
+ # If set to false, hide lua version if it's the same as global:
+ # $(luaenv version-name) == $(luaenv global).
+ typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false
+ # If set to false, hide lua version if it's equal to "system".
+ typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################
+ # Java color.
+ typeset -g POWERLEVEL9K_JENV_FOREGROUND=32
+ # Hide java version if it doesn't come from one of these sources.
+ typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global)
+ # If set to false, hide java version if it's the same as global:
+ # $(jenv version-name) == $(jenv global).
+ typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false
+ # If set to false, hide java version if it's equal to "system".
+ typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############
+ # Perl color.
+ typeset -g POWERLEVEL9K_PLENV_FOREGROUND=67
+ # Hide perl version if it doesn't come from one of these sources.
+ typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global)
+ # If set to false, hide perl version if it's the same as global:
+ # $(plenv version-name) == $(plenv global).
+ typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false
+ # If set to false, hide perl version if it's equal to "system".
+ typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############
+ # PHP color.
+ typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=99
+ # Hide php version if it doesn't come from one of these sources.
+ typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global)
+ # If set to false, hide php version if it's the same as global:
+ # $(phpenv version-name) == $(phpenv global).
+ typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false
+ # If set to false, hide php version if it's equal to "system".
+ typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #######[ scalaenv: scala version from scalaenv (https://github.com/scalaenv/scalaenv) ]#######
+ # Scala color.
+ typeset -g POWERLEVEL9K_SCALAENV_FOREGROUND=160
+ # Hide scala version if it doesn't come from one of these sources.
+ typeset -g POWERLEVEL9K_SCALAENV_SOURCES=(shell local global)
+ # If set to false, hide scala version if it's the same as global:
+ # $(scalaenv version-name) == $(scalaenv global).
+ typeset -g POWERLEVEL9K_SCALAENV_PROMPT_ALWAYS_SHOW=false
+ # If set to false, hide scala version if it's equal to "system".
+ typeset -g POWERLEVEL9K_SCALAENV_SHOW_SYSTEM=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_SCALAENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##########[ haskell_stack: haskell version from stack (https://haskellstack.org/) ]###########
+ # Haskell color.
+ typeset -g POWERLEVEL9K_HASKELL_STACK_FOREGROUND=172
+ # Hide haskell version if it doesn't come from one of these sources.
+ #
+ # shell: version is set by STACK_YAML
+ # local: version is set by stack.yaml up the directory tree
+ # global: version is set by the implicit global project (~/.stack/global-project/stack.yaml)
+ typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local)
+ # If set to false, hide haskell version if it's the same as in the implicit global project.
+ typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ################[ terraform: terraform workspace (https://www.terraform.io) ]#################
+ # Don't show terraform workspace if it's literally "default".
+ typeset -g POWERLEVEL9K_TERRAFORM_SHOW_DEFAULT=false
+ # POWERLEVEL9K_TERRAFORM_CLASSES is an array with even number of elements. The first element
+ # in each pair defines a pattern against which the current terraform workspace gets matched.
+ # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below)
+ # that gets matched. If you unset all POWERLEVEL9K_TERRAFORM_*CONTENT_EXPANSION parameters,
+ # you'll see this value in your prompt. The second element of each pair in
+ # POWERLEVEL9K_TERRAFORM_CLASSES defines the workspace class. Patterns are tried in order. The
+ # first match wins.
+ #
+ # For example, given these settings:
+ #
+ # typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=(
+ # '*prod*' PROD
+ # '*test*' TEST
+ # '*' OTHER)
+ #
+ # If your current terraform workspace is "project_test", its class is TEST because "project_test"
+ # doesn't match the pattern '*prod*' but does match '*test*'.
+ #
+ # You can define different colors, icons and content expansions for different classes:
+ #
+ # typeset -g POWERLEVEL9K_TERRAFORM_TEST_FOREGROUND=28
+ # typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <'
+ typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=(
+ # '*prod*' PROD # These values are examples that are unlikely
+ # '*test*' TEST # to match your needs. Customize them as needed.
+ '*' OTHER)
+ typeset -g POWERLEVEL9K_TERRAFORM_OTHER_FOREGROUND=38
+ # typeset -g POWERLEVEL9K_TERRAFORM_OTHER_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #############[ terraform_version: terraform version (https://www.terraform.io) ]##############
+ # Terraform version color.
+ typeset -g POWERLEVEL9K_TERRAFORM_VERSION_FOREGROUND=38
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_TERRAFORM_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]#############
+ # Show kubecontext only when the command you are typing invokes one of these tools.
+ # Tip: Remove the next line to always show kubecontext.
+ typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito|k9s|helmfile|flux|fluxctl|stern'
+
+ # Kubernetes context classes for the purpose of using different colors, icons and expansions with
+ # different contexts.
+ #
+ # POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element
+ # in each pair defines a pattern against which the current kubernetes context gets matched.
+ # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below)
+ # that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters,
+ # you'll see this value in your prompt. The second element of each pair in
+ # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The
+ # first match wins.
+ #
+ # For example, given these settings:
+ #
+ # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=(
+ # '*prod*' PROD
+ # '*test*' TEST
+ # '*' DEFAULT)
+ #
+ # If your current kubernetes context is "deathray-testing/default", its class is TEST
+ # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'.
+ #
+ # You can define different colors, icons and content expansions for different classes:
+ #
+ # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=28
+ # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <'
+ typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=(
+ # '*prod*' PROD # These values are examples that are unlikely
+ # '*test*' TEST # to match your needs. Customize them as needed.
+ '*' DEFAULT)
+ typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=134
+ # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext
+ # segment. Parameter expansions are very flexible and fast, too. See reference:
+ # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
+ #
+ # Within the expansion the following parameters are always available:
+ #
+ # - P9K_CONTENT The content that would've been displayed if there was no content
+ # expansion defined.
+ # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the
+ # output of `kubectl config get-contexts`.
+ # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the
+ # output of `kubectl config get-contexts`.
+ # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE
+ # in the output of `kubectl config get-contexts`. If there is no
+ # namespace, the parameter is set to "default".
+ # - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the
+ # output of `kubectl config get-contexts`.
+ #
+ # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS),
+ # the following extra parameters are available:
+ #
+ # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks".
+ # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID.
+ # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone.
+ # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster.
+ #
+ # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example,
+ # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01":
+ #
+ # - P9K_KUBECONTEXT_CLOUD_NAME=gke
+ # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account
+ # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a
+ # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01
+ #
+ # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01":
+ #
+ # - P9K_KUBECONTEXT_CLOUD_NAME=eks
+ # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012
+ # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1
+ # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01
+ typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION=
+ # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME.
+ POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}'
+ # Append the current context's namespace if it's not "default".
+ POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}'
+
+ # Custom prefix.
+ # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='%246Fat '
+
+ #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]#
+ # Show aws only when the command you are typing invokes one of these tools.
+ # Tip: Remove the next line to always show aws.
+ typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi|terragrunt'
+
+ # POWERLEVEL9K_AWS_CLASSES is an array with even number of elements. The first element
+ # in each pair defines a pattern against which the current AWS profile gets matched.
+ # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below)
+ # that gets matched. If you unset all POWERLEVEL9K_AWS_*CONTENT_EXPANSION parameters,
+ # you'll see this value in your prompt. The second element of each pair in
+ # POWERLEVEL9K_AWS_CLASSES defines the profile class. Patterns are tried in order. The
+ # first match wins.
+ #
+ # For example, given these settings:
+ #
+ # typeset -g POWERLEVEL9K_AWS_CLASSES=(
+ # '*prod*' PROD
+ # '*test*' TEST
+ # '*' DEFAULT)
+ #
+ # If your current AWS profile is "company_test", its class is TEST
+ # because "company_test" doesn't match the pattern '*prod*' but does match '*test*'.
+ #
+ # You can define different colors, icons and content expansions for different classes:
+ #
+ # typeset -g POWERLEVEL9K_AWS_TEST_FOREGROUND=28
+ # typeset -g POWERLEVEL9K_AWS_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_AWS_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <'
+ typeset -g POWERLEVEL9K_AWS_CLASSES=(
+ # '*prod*' PROD # These values are examples that are unlikely
+ # '*test*' TEST # to match your needs. Customize them as needed.
+ '*' DEFAULT)
+ typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND=208
+ # typeset -g POWERLEVEL9K_AWS_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ # AWS segment format. The following parameters are available within the expansion.
+ #
+ # - P9K_AWS_PROFILE The name of the current AWS profile.
+ # - P9K_AWS_REGION The region associated with the current AWS profile.
+ typeset -g POWERLEVEL9K_AWS_CONTENT_EXPANSION='${P9K_AWS_PROFILE//\%/%%}${P9K_AWS_REGION:+ ${P9K_AWS_REGION//\%/%%}}'
+
+ #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]#
+ # AWS Elastic Beanstalk environment color.
+ typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=70
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]##########
+ # Show azure only when the command you are typing invokes one of these tools.
+ # Tip: Remove the next line to always show azure.
+ typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi|terragrunt'
+ # Azure account name color.
+ typeset -g POWERLEVEL9K_AZURE_FOREGROUND=32
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]###########
+ # Show gcloud only when the command you are typing invokes one of these tools.
+ # Tip: Remove the next line to always show gcloud.
+ typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs|gsutil'
+ # Google cloud color.
+ typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=32
+
+ # Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or
+ # POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative
+ # enough. You can use the following parameters in the expansions. Each of them corresponds to the
+ # output of `gcloud` tool.
+ #
+ # Parameter | Source
+ # -------------------------|--------------------------------------------------------------------
+ # P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)'
+ # P9K_GCLOUD_ACCOUNT | gcloud config get-value account
+ # P9K_GCLOUD_PROJECT_ID | gcloud config get-value project
+ # P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)'
+ #
+ # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurrences of '%' replaced with '%%'.
+ #
+ # Obtaining project name requires sending a request to Google servers. This can take a long time
+ # and even fail. When project name is unknown, P9K_GCLOUD_PROJECT_NAME is not set and gcloud
+ # prompt segment is in state PARTIAL. When project name gets known, P9K_GCLOUD_PROJECT_NAME gets
+ # set and gcloud prompt segment transitions to state COMPLETE.
+ #
+ # You can customize the format, icon and colors of gcloud segment separately for states PARTIAL
+ # and COMPLETE. You can also hide gcloud in state PARTIAL by setting
+ # POWERLEVEL9K_GCLOUD_PARTIAL_VISUAL_IDENTIFIER_EXPANSION and
+ # POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION to empty.
+ typeset -g POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_ID//\%/%%}'
+ typeset -g POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_NAME//\%/%%}'
+
+ # Send a request to Google (by means of `gcloud projects describe ...`) to obtain project name
+ # this often. Negative value disables periodic polling. In this mode project name is retrieved
+ # only when the current configuration, account or project id changes.
+ typeset -g POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS=60
+
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_GCLOUD_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #[ google_app_cred: google application credentials (https://cloud.google.com/docs/authentication/production) ]#
+ # Show google_app_cred only when the command you are typing invokes one of these tools.
+ # Tip: Remove the next line to always show google_app_cred.
+ typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_SHOW_ON_COMMAND='terraform|pulumi|terragrunt'
+
+ # Google application credentials classes for the purpose of using different colors, icons and
+ # expansions with different credentials.
+ #
+ # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES is an array with even number of elements. The first
+ # element in each pair defines a pattern against which the current kubernetes context gets
+ # matched. More specifically, it's P9K_CONTENT prior to the application of context expansion
+ # (see below) that gets matched. If you unset all POWERLEVEL9K_GOOGLE_APP_CRED_*CONTENT_EXPANSION
+ # parameters, you'll see this value in your prompt. The second element of each pair in
+ # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES defines the context class. Patterns are tried in order.
+ # The first match wins.
+ #
+ # For example, given these settings:
+ #
+ # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=(
+ # '*:*prod*:*' PROD
+ # '*:*test*:*' TEST
+ # '*' DEFAULT)
+ #
+ # If your current Google application credentials is "service_account deathray-testing x@y.com",
+ # its class is TEST because it doesn't match the pattern '* *prod* *' but does match '* *test* *'.
+ #
+ # You can define different colors, icons and content expansions for different classes:
+ #
+ # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_FOREGROUND=28
+ # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_CONTENT_EXPANSION='$P9K_GOOGLE_APP_CRED_PROJECT_ID'
+ typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=(
+ # '*:*prod*:*' PROD # These values are examples that are unlikely
+ # '*:*test*:*' TEST # to match your needs. Customize them as needed.
+ '*' DEFAULT)
+ typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_FOREGROUND=32
+ # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ # Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by
+ # google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference:
+ # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
+ #
+ # You can use the following parameters in the expansion. Each of them corresponds to one of the
+ # fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS.
+ #
+ # Parameter | JSON key file field
+ # ---------------------------------+---------------
+ # P9K_GOOGLE_APP_CRED_TYPE | type
+ # P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id
+ # P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email
+ #
+ # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurrences of '%' replaced by '%%'.
+ typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}'
+
+ ##############[ toolbox: toolbox name (https://github.com/containers/toolbox) ]###############
+ # Toolbox color.
+ typeset -g POWERLEVEL9K_TOOLBOX_FOREGROUND=178
+ # Don't display the name of the toolbox if it matches fedora-toolbox-*.
+ typeset -g POWERLEVEL9K_TOOLBOX_CONTENT_EXPANSION='${P9K_TOOLBOX_NAME:#fedora-toolbox-*}'
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_TOOLBOX_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # Custom prefix.
+ # typeset -g POWERLEVEL9K_TOOLBOX_PREFIX='%246Fin '
+
+ ###############################[ public_ip: public IP address ]###############################
+ # Public IP color.
+ typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=94
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ########################[ vpn_ip: virtual private network indicator ]#########################
+ # VPN IP color.
+ typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=81
+ # When on VPN, show just an icon without the IP address.
+ # Tip: To display the private IP address when on VPN, remove the next line.
+ typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION=
+ # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN
+ # to see the name of the interface.
+ typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(gpd|wg|(.*tun)|tailscale)[0-9]*'
+ # If set to true, show one segment per matching network interface. If set to false, show only
+ # one segment corresponding to the first matching network interface.
+ # Tip: If you set it to true, you'll probably want to unset POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION.
+ typeset -g POWERLEVEL9K_VPN_IP_SHOW_ALL=false
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ###########[ ip: ip address and bandwidth usage for a specified network interface ]###########
+ # IP color.
+ typeset -g POWERLEVEL9K_IP_FOREGROUND=38
+ # The following parameters are accessible within the expansion:
+ #
+ # Parameter | Meaning
+ # ----------------------+-------------------------------------------
+ # P9K_IP_IP | IP address
+ # P9K_IP_INTERFACE | network interface
+ # P9K_IP_RX_BYTES | total number of bytes received
+ # P9K_IP_TX_BYTES | total number of bytes sent
+ # P9K_IP_RX_BYTES_DELTA | number of bytes received since last prompt
+ # P9K_IP_TX_BYTES_DELTA | number of bytes sent since last prompt
+ # P9K_IP_RX_RATE | receive rate (since last prompt)
+ # P9K_IP_TX_RATE | send rate (since last prompt)
+ typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='${P9K_IP_RX_RATE:+%70F⇣$P9K_IP_RX_RATE }${P9K_IP_TX_RATE:+%215F⇡$P9K_IP_TX_RATE }%38F$P9K_IP_IP'
+ # Show information for the first network interface whose name matches this regular expression.
+ # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces.
+ typeset -g POWERLEVEL9K_IP_INTERFACE='[ew].*'
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ #########################[ proxy: system-wide http/https/ftp proxy ]##########################
+ # Proxy color.
+ typeset -g POWERLEVEL9K_PROXY_FOREGROUND=68
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ ################################[ battery: internal battery ]#################################
+ # Show battery in red when it's below this level and not connected to power supply.
+ typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20
+ typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=160
+ # Show battery in green when it's charging or fully charged.
+ typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=70
+ # Show battery in yellow when it's discharging.
+ typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=178
+ # Battery pictograms going from low to high level of charge.
+ typeset -g POWERLEVEL9K_BATTERY_STAGES='\uf58d\uf579\uf57a\uf57b\uf57c\uf57d\uf57e\uf57f\uf580\uf581\uf578'
+ # Don't show the remaining time to charge/discharge.
+ typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false
+
+ #####################################[ wifi: wifi speed ]#####################################
+ # WiFi color.
+ typeset -g POWERLEVEL9K_WIFI_FOREGROUND=68
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ # Use different colors and icons depending on signal strength ($P9K_WIFI_BARS).
+ #
+ # # Wifi colors and icons for different signal strength levels (low to high).
+ # typeset -g my_wifi_fg=(68 68 68 68 68) # <-- change these values
+ # typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values
+ #
+ # typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps'
+ # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}'
+ #
+ # The following parameters are accessible within the expansions:
+ #
+ # Parameter | Meaning
+ # ----------------------+---------------
+ # P9K_WIFI_SSID | service set identifier, a.k.a. network name
+ # P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none"; empty if unknown
+ # P9K_WIFI_LAST_TX_RATE | wireless transmit rate in megabits per second
+ # P9K_WIFI_RSSI | signal strength in dBm, from -120 to 0
+ # P9K_WIFI_NOISE | noise in dBm, from -120 to 0
+ # P9K_WIFI_BARS | signal strength in bars, from 0 to 4 (derived from P9K_WIFI_RSSI and P9K_WIFI_NOISE)
+
+ ####################################[ time: current time ]####################################
+ # Current time color.
+ typeset -g POWERLEVEL9K_TIME_FOREGROUND=66
+ # Format for the current time: 09:51:02. See `man 3 strftime`.
+ typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%I:%M:%S %p}'
+ # If set to true, time will update when you hit enter. This way prompts for the past
+ # commands will contain the start times of their commands as opposed to the default
+ # behavior where they contain the end times of their preceding commands.
+ typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false
+ # Custom icon.
+ # typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐'
+ # Custom prefix.
+ # typeset -g POWERLEVEL9K_TIME_PREFIX='%246Fat '
+
+ # Example of a user-defined prompt segment. Function prompt_example will be called on every
+ # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or
+ # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and orange text greeting the user.
+ #
+ # Type `p10k help segment` for documentation and a more sophisticated example.
+ function prompt_example() {
+ p10k segment -f 208 -i '⭐' -t 'hello, %n'
+ }
+
+ # User-defined prompt segments may optionally provide an instant_prompt_* function. Its job
+ # is to generate the prompt segment for display in instant prompt. See
+ # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt.
+ #
+ # Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function
+ # and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k
+ # will replay these calls without actually calling instant_prompt_*. It is imperative that
+ # instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this
+ # rule is not observed, the content of instant prompt will be incorrect.
+ #
+ # Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If
+ # instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt.
+ function instant_prompt_example() {
+ # Since prompt_example always makes the same `p10k segment` calls, we can call it from
+ # instant_prompt_example. This will give us the same `example` prompt segment in the instant
+ # and regular prompts.
+ prompt_example
+ }
+
+ # User-defined prompt segments can be customized the same way as built-in segments.
+ # typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=208
+ # typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐'
+
+ # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt
+ # when accepting a command line. Supported values:
+ #
+ # - off: Don't change prompt when accepting a command line.
+ # - always: Trim down prompt when accepting a command line.
+ # - same-dir: Trim down prompt when accepting a command line unless this is the first command
+ # typed after changing current working directory.
+ typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=always
+
+ # Instant prompt mode.
+ #
+ # - off: Disable instant prompt. Choose this if you've tried instant prompt and found
+ # it incompatible with your zsh configuration files.
+ # - quiet: Enable instant prompt and don't print warnings when detecting console output
+ # during zsh initialization. Choose this if you've read and understood
+ # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt.
+ # - verbose: Enable instant prompt and print a warning when detecting console output during
+ # zsh initialization. Choose this if you've never tried instant prompt, haven't
+ # seen the warning, or if you are unsure what this all means.
+ typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet
+
+ # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized.
+ # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload
+ # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you
+ # really need it.
+ typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true
+
+ # If p10k is already loaded, reload configuration.
+ # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true.
+ (( ! $+functions[p10k] )) || p10k reload
+}
+
+# Tell `p10k configure` which file it should overwrite.
+typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a}
+
+(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]}
+'builtin' 'unset' 'p10k_config_opts'
diff --git a/.local/share/git-core/templates/hooks/post-commit b/.local/share/git-core/templates/hooks/post-commit
new file mode 100644
index 00000000..10bf082f
--- /dev/null
+++ b/.local/share/git-core/templates/hooks/post-commit
@@ -0,0 +1,9 @@
+#!/bin/sh
+### git-stats hook (begin) ###
+# Copy last commit hash to clipboard on commit
+commit_hash=$(git rev-parse HEAD)
+repo_url=$(git config --get remote.origin.url)
+commit_date=$(git log -1 --format=%cd)
+commit_data="\"{ \"date\": \"$commit_date\", \"url\": \"$repo_url\", \"hash\": \"$commit_hash\" }\""
+git-stats --record "${commit_data}"
+### git-stats hook (end) ###
diff --git a/.tool-versions b/.tool-versions
index 5dd1b741..ebc18b2e 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -7,4 +7,3 @@ poetry system
python system
ruby 3.1.1
rust system
-
diff --git a/.vim/colors/betelgeuse.vim b/.vim/colors/betelgeuse.vim
index d83c6d1b..d02a6dcc 100644
--- a/.vim/colors/betelgeuse.vim
+++ b/.vim/colors/betelgeuse.vim
@@ -1,8 +1,8 @@
-
+
if &background == 'dark'
-
+
let s:guishade0 = "#161925"
let s:guishade1 = "#2f323e"
let s:guishade2 = "#474b56"
@@ -35,13 +35,13 @@
let s:ctermaccent5 = 117
let s:ctermaccent6 = 188
let s:ctermaccent7 = 175
-
- endif
-
-
+ endif
+
+
+
if &background == 'light'
-
+
let s:guishade0 = "#ffffff"
let s:guishade1 = "#e5e6e7"
let s:guishade2 = "#cccdcf"
@@ -74,9 +74,9 @@
let s:ctermaccent5 = 153
let s:ctermaccent6 = 239
let s:ctermaccent7 = 211
-
+
endif
-
+
highlight clear
syntax reset
@@ -255,4 +255,4 @@
""""""""""""
unlet s:guishade0 s:guishade1 s:guishade2 s:guishade3 s:guishade4 s:guishade5 s:guishade6 s:guishade7 s:guiaccent0 s:guiaccent1 s:guiaccent2 s:guiaccent3 s:guiaccent4 s:guiaccent5 s:guiaccent6 s:guiaccent7
- unlet s:ctermshade0 s:ctermshade1 s:ctermshade2 s:ctermshade3 s:ctermshade4 s:ctermshade5 s:ctermshade6 s:ctermshade7 s:ctermaccent0 s:ctermaccent1 s:ctermaccent2 s:ctermaccent3 s:ctermaccent4 s:ctermaccent5 s:ctermaccent6 s:ctermaccent7
\ No newline at end of file
+ unlet s:ctermshade0 s:ctermshade1 s:ctermshade2 s:ctermshade3 s:ctermshade4 s:ctermshade5 s:ctermshade6 s:ctermshade7 s:ctermaccent0 s:ctermaccent1 s:ctermaccent2 s:ctermaccent3 s:ctermaccent4 s:ctermaccent5 s:ctermaccent6 s:ctermaccent7
diff --git a/.vim/vimrc b/.vim/vimrc
new file mode 100644
index 00000000..8c73702c
--- /dev/null
+++ b/.vim/vimrc
@@ -0,0 +1,54 @@
+silent! call plug#begin()
+Plug '~/.vim/plugged/typescript-vim'
+Plug '~/.vim/plugged/vim-airline'
+Plug '~/.vim/plugged/lightline.vim'
+Plug '~/.vim/plugged/vim-javascript'
+Plug '~/.vim/plugged/vim-jsx'
+Plug '~/.vim/plugged/vim-markdown'
+Plug '~/.vim/plugged/dockerfile.vim'
+Plug '~/.vim/plugged/php.vim'
+Plug '~/.vim/plugged/python-syntax'
+Plug '~/.vim/plugged/nerdtree'
+Plug '~/.vim/plugged/vim-five'
+Plug '~/.vim/plugged/vim-prettier'
+Plug '~/.vim/plugged/vim-sensible'
+Plug '~/.vim/plugged/editorconfig-vim'
+Plug '~/.vim/plugged/vimgutter'
+Plug '~/.vim/plugged/vim-surround'
+Plug '~/.vim/plugged/vim-carbon-now-sh'
+Plug '~/.vim/plugged/vim-multiple-cursors'
+Plug '~/.vim/plugged/ale'
+Plug '~/.vim/plugged/fzf'
+Plug '~/.vim/plugged/fzf.vim'
+if executable('node')
+ Plug '~/.vim/plugged/coc.nvim'
+endif
+Plug '~/.vim/plugged/syntastic'
+Plug '~/.vim/plugged/vim-devicons'
+Plug '~/.vim/plugged/zoxide.vim'
+Plug '~/.vim/plugged/vim-go'
+Plug '~/.vim/plugged/ansible-vim', {'do': './UltiSnips/generate.sh'}
+call plug#end()
+
+syntax enable
+set background=dark
+colorscheme Betelgeuse
+" set g:lightline = { 'colorscheme': 'Betelgeuse' }
+
+" Settings for plugin https://github.com/neoclide/coc.nvim.git
+autocmd FileType json syntax match Comment +\/\/.\+$+
+
+" Settings for plugin https://github.com/vim-syntastic/syntastic.git
+set statusline+=%#warningmsg#
+set statusline+=%{SyntasticStatuslineFlag()}
+set statusline+=%*
+let g:syntastic_always_populate_loc_list = 1
+let g:syntastic_auto_loc_list = 1
+let g:syntastic_check_on_open = 1
+let g:syntastic_check_on_wq = 0
+
+" Settings for plugin https://github.com/ryanoasis/vim-devicons.git
+set encoding=UTF-8
+
+" Automatically apply with Chezmoi anytime a source file is modified
+autocmd BufWritePost ~/.local/share/chezmoi/* ! chezmoi apply --source-path "%"
diff --git a/AppData/Local/clink/oh-my-posh.lua b/AppData/Local/clink/oh-my-posh.lua
new file mode 100644
index 00000000..85a31d27
--- /dev/null
+++ b/AppData/Local/clink/oh-my-posh.lua
@@ -0,0 +1 @@
+load(io.popen('oh-my-posh init cmd'):read("*a"))()
diff --git a/Library/Application Support/tabby/plugins/package-lock.json b/Library/Application Support/tabby/plugins/package-lock.json
new file mode 100644
index 00000000..e7dd48be
--- /dev/null
+++ b/Library/Application Support/tabby/plugins/package-lock.json
@@ -0,0 +1,36 @@
+{
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "crypto-js": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
+ "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
+ },
+ "tabby-docker": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/tabby-docker/-/tabby-docker-0.2.0.tgz",
+ "integrity": "sha512-kEDZI33Xt7NnncPDhhbqREP809YevCnoVRYhzACvAkteODWorABCoKEuOrfi2I3DDwCHcMk0+fM0nCWy5C/JVg=="
+ },
+ "tabby-save-output": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/tabby-save-output/-/tabby-save-output-3.1.0.tgz",
+ "integrity": "sha512-4mGxpYSaeBzU8TkOrZudPmT3/YkT9fGXCesBp2XO9iql+2EELzkPLJUntlGYSBH0RQVRDYnl+IF8F65WPaaSxQ=="
+ },
+ "tabby-search-in-browser": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/tabby-search-in-browser/-/tabby-search-in-browser-0.0.1.tgz",
+ "integrity": "sha512-jb5UINTXBN6UR0xi+LWs7KdnE5qRV++ogy9lmkIJ9dDbBbVe7d6HKxneZcQVjQLjG+UYJNl/nElh8DPzFPMTSg=="
+ },
+ "tabby-workspace-manager": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/tabby-workspace-manager/-/tabby-workspace-manager-0.0.4.tgz",
+ "integrity": "sha512-O3etFcZxw68ZieS1q8VM01IW0M+rMyyBJpghYhz7WtNyckxfO/ir4AuXfb/kFz9ozOmI33/ff3UMY8yJjIJ6qw=="
+ },
+ "terminus-elastic-quick-cmds": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/terminus-elastic-quick-cmds/-/terminus-elastic-quick-cmds-1.1.1.tgz",
+ "integrity": "sha512-PDWQ5MKs8UuPE1O/Nk63RSz661big/uuWWaRIZFSYfdqvrUWK186xNcUFioBWOnyNVvdLI4H+mxektmW2TnHrA=="
+ }
+ }
+}
diff --git a/Library/Developer/Xcode/UserData/FontAndColorThemes/Betelgeuse Dark.dvtcolortheme b/Library/Developer/Xcode/UserData/FontAndColorThemes/Betelgeuse Dark.dvtcolortheme
new file mode 100644
index 00000000..9a5b0157
--- /dev/null
+++ b/Library/Developer/Xcode/UserData/FontAndColorThemes/Betelgeuse Dark.dvtcolortheme
@@ -0,0 +1,83 @@
+
+
+
+
+ DVTConsoleDebuggerInputTextColor
+ 0.764706 0.780392 0.819608 1
+ DVTConsoleDebuggerOutputTextColor
+ 0.572549 0.584314 0.627451 1
+ DVTConsoleDebuggerPromptTextColor
+ 0.862745 0.87451 0.894118 1
+ DVTConsoleExectuableInputTextColor
+ 0.572549 0.584314 0.627451 1
+ DVTConsoleExectuableOutputTextColor
+ 0.764706 0.780392 0.819608 1
+ DVTConsoleTextBackgroundColor
+ 0.086275 0.098039 0.145098 1
+ DVTConsoleTextInsertionPointColor
+ 0.764706 0.780392 0.819608 1
+ DVTConsoleTextSelectionColor
+ 0.184314 0.196078 0.243137 1
+ DVTDebuggerInstructionPointerColor
+ 0.443137 0.968627 0.623529 1
+ DVTSourceTextBackground
+ 0.086275 0.098039 0.145098 1
+ DVTSourceTextBlockDimBackgroundColor
+ 0.47451 0.486275 0.529412 1
+ DVTSourceTextInsertionPointColor
+ 0.764706 0.780392 0.819608 1
+ DVTSourceTextInvisiblesColor
+ 0.184314 0.196078 0.243137 1
+ DVTSourceTextSelectionColor
+ 0.184314 0.196078 0.243137 1
+ DVTSourceTextSyntaxColors
+
+ xcode.syntax.attribute
+ 0.443137 0.968627 0.623529 1
+ xcode.syntax.character
+ 0 0.756863 0.894118 1
+ xcode.syntax.comment
+ 0.278431 0.294118 0.337255 1
+ xcode.syntax.comment.doc
+ 0.376471 0.392157 0.435294 1
+ xcode.syntax.comment.doc.keyword
+ 0.47451 0.486275 0.529412 1
+ xcode.syntax.identifier.class
+ 0.976471 0.862745 0.360784 1
+ xcode.syntax.identifier.class.system
+ 0.976471 0.862745 0.360784 1
+ xcode.syntax.identifier.constant
+ 0.443137 0.968627 0.623529 1
+ xcode.syntax.identifier.constant.system
+ 0.443137 0.968627 0.623529 1
+ xcode.syntax.identifier.function
+ 0 0.756863 0.894118 1
+ xcode.syntax.identifier.function.system
+ 0 0.756863 0.894118 1
+ xcode.syntax.identifier.macro
+ 0.780392 0.301961 0.537255 1
+ xcode.syntax.identifier.macro.system
+ 0.780392 0.301961 0.537255 1
+ xcode.syntax.identifier.type
+ 0.929412 0.145098 0.305882 1
+ xcode.syntax.identifier.type.system
+ 0.862745 0.87451 0.894118 1
+ xcode.syntax.identifier.variable
+ 0.764706 0.780392 0.819608 1
+ xcode.syntax.identifier.variable.system
+ 0.764706 0.780392 0.819608 1
+ xcode.syntax.keyword
+ 0.486275 0.717647 1 1
+ xcode.syntax.number
+ 0.443137 0.968627 0.623529 1
+ xcode.syntax.plain
+ 0.666667 0.682353 0.721569 1
+ xcode.syntax.preprocessor
+ 0.764706 0.780392 0.819608 1
+ xcode.syntax.string
+ 0.443137 0.968627 0.623529 1
+ xcode.syntax.url
+ 0.486275 0.717647 1 1
+
+
+
diff --git a/Library/Developer/Xcode/UserData/FontAndColorThemes/Betelgeuse Light.dvtcolortheme b/Library/Developer/Xcode/UserData/FontAndColorThemes/Betelgeuse Light.dvtcolortheme
new file mode 100644
index 00000000..2f64afd0
--- /dev/null
+++ b/Library/Developer/Xcode/UserData/FontAndColorThemes/Betelgeuse Light.dvtcolortheme
@@ -0,0 +1,83 @@
+
+
+
+
+ DVTConsoleDebuggerInputTextColor
+ 0.298039 0.313725 0.345098 1
+ DVTConsoleDebuggerOutputTextColor
+ 0.498039 0.509804 0.533333 1
+ DVTConsoleDebuggerPromptTextColor
+ 0.862745 0.87451 0.894118 1
+ DVTConsoleExectuableInputTextColor
+ 0.498039 0.509804 0.533333 1
+ DVTConsoleExectuableOutputTextColor
+ 0.298039 0.313725 0.345098 1
+ DVTConsoleTextBackgroundColor
+ 1 1 1 1
+ DVTConsoleTextInsertionPointColor
+ 0.298039 0.313725 0.345098 1
+ DVTConsoleTextSelectionColor
+ 0.898039 0.901961 0.905882 1
+ DVTDebuggerInstructionPointerColor
+ 0.584314 1 0.764706 1
+ DVTSourceTextBackground
+ 1 1 1 1
+ DVTSourceTextBlockDimBackgroundColor
+ 0.6 0.607843 0.627451 1
+ DVTSourceTextInsertionPointColor
+ 0.298039 0.313725 0.345098 1
+ DVTSourceTextInvisiblesColor
+ 0.898039 0.901961 0.905882 1
+ DVTSourceTextSelectionColor
+ 0.898039 0.901961 0.905882 1
+ DVTSourceTextSyntaxColors
+
+ xcode.syntax.attribute
+ 0.584314 1 0.764706 1
+ xcode.syntax.character
+ 0.141176 0.898039 1 1
+ xcode.syntax.comment
+ 0.8 0.803922 0.811765 1
+ xcode.syntax.comment.doc
+ 0.698039 0.705882 0.717647 1
+ xcode.syntax.comment.doc.keyword
+ 0.6 0.607843 0.627451 1
+ xcode.syntax.identifier.class
+ 1 1 0.501961 1
+ xcode.syntax.identifier.class.system
+ 1 1 0.501961 1
+ xcode.syntax.identifier.constant
+ 0.584314 1 0.764706 1
+ xcode.syntax.identifier.constant.system
+ 0.584314 1 0.764706 1
+ xcode.syntax.identifier.function
+ 0.141176 0.898039 1 1
+ xcode.syntax.identifier.function.system
+ 0.141176 0.898039 1 1
+ xcode.syntax.identifier.macro
+ 0.921569 0.443137 0.678431 1
+ xcode.syntax.identifier.macro.system
+ 0.921569 0.443137 0.678431 1
+ xcode.syntax.identifier.type
+ 1 0.286275 0.447059 1
+ xcode.syntax.identifier.type.system
+ 0.862745 0.87451 0.894118 1
+ xcode.syntax.identifier.variable
+ 0.298039 0.313725 0.345098 1
+ xcode.syntax.identifier.variable.system
+ 0.298039 0.313725 0.345098 1
+ xcode.syntax.keyword
+ 0.627451 0.858824 1 1
+ xcode.syntax.number
+ 0.584314 1 0.764706 1
+ xcode.syntax.plain
+ 0.4 0.411765 0.439216 1
+ xcode.syntax.preprocessor
+ 0.298039 0.313725 0.345098 1
+ xcode.syntax.string
+ 0.584314 1 0.764706 1
+ xcode.syntax.url
+ 0.627451 0.858824 1 1
+
+
+
diff --git a/Library/Preferences/com.apple.Terminal.plist b/Library/Preferences/com.apple.Terminal.plist
new file mode 100644
index 00000000..a2e44596
--- /dev/null
+++ b/Library/Preferences/com.apple.Terminal.plist
@@ -0,0 +1,328 @@
+
+
+
+
+ Default Window Settings
+ Betelgeuse
+ DefaultProfilesVersion
+ 1
+ HasMigratedDefaults
+
+ NSColorPanelMode
+ 1
+ NSColorPickerPreferredRGBEntryMode
+ 2
+ NSColorPickerSlidersDefaults
+ 1
+ NSFontPanelAttributes
+ 1, 0
+ NSNavLastRootDirectory
+ /Users
+ NSNavPanelExpandedSizeForSaveMode
+ {712, 448}
+ NSSplitView Subview Frames NSColorPanelSplitView
+
+ 0.000000, 0.000000, 257.000000, 271.000000, NO, NO
+ 0.000000, 272.000000, 257.000000, 43.000000, NO, NO
+
+ NSToolbar Configuration com.apple.NSColorPanel
+
+ TB Is Shown
+ 1
+
+ NSWindow Frame NSColorPanel
+ 1295 353 257 291 0 0 1680 1025
+ NSWindow Frame NSFontPanel
+ 573 187 445 79 0 0 1680 1025
+ NSWindow Frame NSNavPanelAutosaveName
+ -14 33 328 167 0 0 1680 1025
+ NSWindow Frame TTAppPreferences
+ 663 257 667 554 0 0 1680 1025
+ NSWindow Frame TTWindow
+ 580 240 710 455 0 0 1680 1025
+ NSWindow Frame TTWindow Basic
+ 552 468 585 371 0 0 1680 1025
+ NSWindow Frame TTWindow Betelgeuse
+ 267 404 893 525 0 0 1680 1025
+ NSWindow Frame TTWindow Cipherpunk
+ 51 119 570 365 0 0 1280 777
+ NSWindow Frame TTWindow Homebrew
+ 124 412 570 365 0 0 1280 777
+ NSWindow Frame TTWindow Nord_Custom
+ 210 278 570 412 0 0 1280 777
+ NSWindow Frame TTWindow Ocean
+ 187 343 570 365 0 0 1280 777
+ NSWindow Frame TTWindow Silver Aerogel
+ 20 292 570 365 0 0 1280 777
+ NSWindow Frame TTWindow SolarizedDark_custom
+ 124 365 570 412 0 0 1280 777
+ NSWindow Frame TTWindow Solarized_Dark_Custom
+ 693 199 725 455 0 0 1680 1025
+ NSWindow Frame TTWindow themer-dark
+ 246 284 505 371 0 0 1680 1025
+ ProfileCurrentVersion
+ 2.0699999999999998
+ SecureKeyboardEntry
+
+ Startup Window Settings
+ Betelgeuse
+ TTAppPreferences Selected Tab
+ 1
+ Window Settings
+
+ Betelgeuse
+
+ ANSIBlackColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjA4NjI3NDUwOTggMC4w
+ OTgwMzkyMTU3IDAuMTQ1MDk4MDM5MgAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIBlueColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjQ4NjI3NDUwOTggMC43
+ MTc2NDcwNTg4IDEuMDAwMDAwMDAwMAAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIBrightBlackColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjE4NDMxMzcyNTUgMC4x
+ OTYwNzg0MzE0IDAuMjQzMTM3MjU0OQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIBrightBlueColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjU1Njg2Mjc0NTEgMC43
+ MzMzMzMzMzMzIDAuOTU2ODYyNzQ1MQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIBrightCyanColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjE5MjE1Njg2MjcgMC43
+ NjQ3MDU4ODI0IDAuODc0NTA5ODAzOQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIBrightGreenColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjUyNTQ5MDE5NjEgMC45
+ MjE1Njg2Mjc1IDAuNjc0NTA5ODAzOQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIBrightMagentaColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc3NjQ3MDU4ODIgMC40
+ MjM1Mjk0MTE4IDAuNjA3ODQzMTM3MwAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIBrightRedColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjg5MDE5NjA3ODQgMC4z
+ MDU4ODIzNTI5IDAuNDM1Mjk0MTE3NgAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIBrightWhiteColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc2NDcwNTg4MjQgMC43
+ ODAzOTIxNTY5IDAuODE5NjA3ODQzMQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIBrightYellowColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjkyNTQ5MDE5NjEgMC44
+ NDMxMzcyNTQ5IDAuNDc0NTA5ODAzOQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSICyanColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjAwMDAwMDAwMDAgMC43
+ NTY4NjI3NDUxIDAuODk0MTE3NjQ3MQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIGreenColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjQ0MzEzNzI1NDkgMC45
+ Njg2Mjc0NTEwIDAuNjIzNTI5NDExOAAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIMagentaColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc4MDM5MjE1NjkgMC4z
+ MDE5NjA3ODQzIDAuNTM3MjU0OTAyMAAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIRedColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjkyOTQxMTc2NDcgMC4x
+ NDUwOTgwMzkyIDAuMzA1ODgyMzUyOQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIWhiteColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjY2NjY2NjY2NjcgMC42
+ ODIzNTI5NDEyIDAuNzIxNTY4NjI3NQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ ANSIYellowColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjk3NjQ3MDU4ODIgMC44
+ NjI3NDUwOTgwIDAuMzYwNzg0MzEzNwAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ BackgroundColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjA4NjI3NDUwOTggMC4w
+ OTgwMzkyMTU3IDAuMTQ1MDk4MDM5MgAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ BoldTextColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc2NDcwNTg4MjQgMC43
+ ODAzOTIxNTY5IDAuODE5NjA3ODQzMQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ CursorColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc2NDcwNTg4MjQgMC43
+ ODAzOTIxNTY5IDAuODE5NjA3ODQzMQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ Font
+
+ YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0
+ b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRy
+ b290gAGkCwwVFlUkbnVsbNQNDg8QERITFFZOU1NpemVYTlNmRmxh
+ Z3NWTlNOYW1lViRjbGFzcyNAJgAAAAAAABAQgAKAA18QGUhhY2tO
+ ZXJkRm9udENvbXBsZXRlLUJvbGTSFxgZGlokY2xhc3NuYW1lWCRj
+ bGFzc2VzVk5TRm9udKIZG1hOU09iamVjdAgRGiQpMjdJTFFTWF5n
+ bnd+hY6QkpSwtcDJ0NMAAAAAAAABAQAAAAAAAAAcAAAAAAAAAAAA
+ AAAAAAAA3A==
+
+ SelectionColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjc4MDM5MjE1NjkgMC4z
+ MDE5NjA3ODQzIDAuNTM3MjU0OTAyMAAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ TextColor
+
+ YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFy
+ Y2hpdmVyVCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdC
+ XE5TQ29sb3JTcGFjZVYkY2xhc3NPECcwLjY2NjY2NjY2NjcgMC42
+ ODIzNTI5NDEyIDAuNzIxNTY4NjI3NQAQAYAC0hAREhNaJGNsYXNz
+ bmFtZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNL
+ ZXllZEFyY2hpdmVy0RcYVHJvb3SAAQgRGiMtMjc7QUhOW2KMjpCV
+ oKmxtL3P0tcAAAAAAAABAQAAAAAAAAAZAAAAAAAAAAAAAAAAAAAA
+ 2Q==
+
+ columnCount
+ 35
+ name
+ Betelgeuse
+ rowCount
+ 124
+ type
+ Window Settings
+
+
+
+
diff --git a/Library/VirtualBox/VirtualBox.xml b/Library/VirtualBox/VirtualBox.xml
new file mode 100644
index 00000000..f51de8de
--- /dev/null
+++ b/Library/VirtualBox/VirtualBox.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..dd61f0e8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+# Hiawatha
+
+This is a decked out dotfiles repository that leverages a handful of technologies including Chezmoi and Ansible.
+
+To use these dotfiles and provision your computer with prompts (which can be made headless with environment variables):
+
+```
+bash <(curl -sSL https://install.doctor/start)
+```
+
+All the source files are located in ~/.local/share/chezmoi/home for the dotfiles and ~/.local/share/chezmoi/system for the system files. The roles / playbooks from [Gas Station](https://gitlab.com/megabyte-labs/gas-station) are occasionally used to fill in gaps. The software installation (which happens when you run Chezmoi or the link above) determines which package manager to use to install the software using [this software map](https://gitlab.com/megabyte-labs/misc/dotfiles/-/blob/master/.local/share/chezmoi/software.yml).
+
+Many of the dotfiles (and system files) are templated. Those ones you will have to look at ~/.local/share/chezmoi to take a peek at. The static files are at the root of this repository for easy viewing.
diff --git a/sync.sh b/sync.sh
new file mode 100644
index 00000000..aed9f901
--- /dev/null
+++ b/sync.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+### Copy static files to base directory for easy viewing - source should still be modified in ~/.local/share/chezmoi/home (or ~/.local/share/chezmoi/system for system files)
+find ./.local/share/chezmoi/home -type f | while read FILE; do
+ BASENAME="$(basename "$FILE")"
+ DIRNAME="$(dirname "$FILE")"
+ if [[ "$FILE" != *'.tmpl' ]] && [[ "$BASENAME" != '.chezmoi'* ]] && [[ "$BASENAME" != 'symlink_'* ]] && [[ "$FILE" != *'gitkeep' ]] && [[ "$FILE" != *'.chezmoitemplates'* ]] && [ "$BASENAME" != 'chezmoi.txt.age' ] && [ "$FILE" != *'TODO' ]; then
+ TARGET_DIR="$(echo "$DIRNAME" | sed 's/private_//g' | sed 's/dot_/\./g' | sed 's/executable_//' | sed 's/readonly_//g' | sed 's/\/.local\/share\/chezmoi\/home//')"
+ mkdir -p "$TARGET_DIR"
+ TARGET="$(echo "$FILE" | sed 's/private_//g' | sed 's/dot_/\./g' | sed 's/executable_//' | sed 's/readonly_//g' | sed 's/\/.local\/share\/chezmoi\/home//' )"
+ cp "$FILE" "$TARGET"
+ fi
+done