initial commit

This commit is contained in:
Sergey Krylov 2026-02-23 19:52:05 +03:00
commit 51b12d0e19
413 changed files with 32056 additions and 0 deletions

BIN
Knowledges/.DS_Store vendored Normal file

Binary file not shown.

BIN
Knowledges/.obsidian/.DS_Store vendored Normal file

Binary file not shown.

3
Knowledges/.obsidian/app.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"alwaysUpdateLinks": true
}

5
Knowledges/.obsidian/appearance.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"theme": "obsidian",
"cssTheme": "Minimal",
"accentColor": ""
}

View File

@ -0,0 +1,5 @@
[
"editing-toolbar",
"obsidian-git",
"dataview"
]

33
Knowledges/.obsidian/core-plugins.json vendored Normal file
View File

@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"properties": false,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": false,
"webviewer": false,
"footnotes": false,
"bases": true
}

22
Knowledges/.obsidian/graph.json vendored Normal file
View File

@ -0,0 +1,22 @@
{
"collapse-filter": false,
"search": "",
"showTags": false,
"showAttachments": false,
"hideUnresolved": false,
"showOrphans": false,
"collapse-color-groups": true,
"colorGroups": [],
"collapse-display": false,
"showArrow": false,
"textFadeMultiplier": 0,
"nodeSizeMultiplier": 0.70472412109375,
"lineSizeMultiplier": 1.06680094401042,
"collapse-forces": false,
"centerStrength": 0,
"repelStrength": 10,
"linkStrength": 1,
"linkDistance": 250,
"scale": 0.6410942760894982,
"close": true
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,11 @@
{
"id": "dataview",
"name": "Dataview",
"version": "0.5.68",
"minAppVersion": "0.13.11",
"description": "Complex data views for the data-obsessed.",
"author": "Michael Brenan <blacksmithgu@gmail.com>",
"authorUrl": "https://github.com/blacksmithgu",
"helpUrl": "https://blacksmithgu.github.io/obsidian-dataview/",
"isDesktopOnly": false
}

View File

@ -0,0 +1,141 @@
.block-language-dataview {
overflow-y: auto;
}
/*****************/
/** Table Views **/
/*****************/
/* List View Default Styling; rendered internally as a table. */
.table-view-table {
width: 100%;
}
.table-view-table > thead > tr, .table-view-table > tbody > tr {
margin-top: 1em;
margin-bottom: 1em;
text-align: left;
}
.table-view-table > tbody > tr:hover {
background-color: var(--table-row-background-hover);
}
.table-view-table > thead > tr > th {
font-weight: 700;
font-size: larger;
border-top: none;
border-left: none;
border-right: none;
border-bottom: solid;
max-width: 100%;
}
.table-view-table > tbody > tr > td {
text-align: left;
border: none;
font-weight: 400;
max-width: 100%;
}
.table-view-table ul, .table-view-table ol {
margin-block-start: 0.2em !important;
margin-block-end: 0.2em !important;
}
/** Rendered value styling for any view. */
.dataview-result-list-root-ul {
padding: 0em !important;
margin: 0em !important;
}
.dataview-result-list-ul {
margin-block-start: 0.2em !important;
margin-block-end: 0.2em !important;
}
/** Generic grouping styling. */
.dataview.result-group {
padding-left: 8px;
}
/*******************/
/** Inline Fields **/
/*******************/
.dataview.inline-field-key {
padding-left: 8px;
padding-right: 8px;
font-family: var(--font-monospace);
background-color: var(--background-primary-alt);
color: var(--nav-item-color-selected);
}
.dataview.inline-field-value {
padding-left: 8px;
padding-right: 8px;
font-family: var(--font-monospace);
background-color: var(--background-secondary-alt);
color: var(--nav-item-color-selected);
}
.dataview.inline-field-standalone-value {
padding-left: 8px;
padding-right: 8px;
font-family: var(--font-monospace);
background-color: var(--background-secondary-alt);
color: var(--nav-item-color-selected);
}
/***************/
/** Task View **/
/***************/
.dataview.task-list-item, .dataview.task-list-basic-item {
margin-top: 3px;
margin-bottom: 3px;
transition: 0.4s;
}
.dataview.task-list-item:hover, .dataview.task-list-basic-item:hover {
background-color: var(--text-selection);
box-shadow: -40px 0 0 var(--text-selection);
cursor: pointer;
}
/*****************/
/** Error Views **/
/*****************/
div.dataview-error-box {
width: 100%;
min-height: 150px;
display: flex;
align-items: center;
justify-content: center;
border: 4px dashed var(--background-secondary);
}
.dataview-error-message {
color: var(--text-muted);
text-align: center;
}
/*************************/
/** Additional Metadata **/
/*************************/
.dataview.small-text {
font-size: smaller;
color: var(--text-muted);
margin-left: 3px;
}
.dataview.small-text::before {
content: "(";
}
.dataview.small-text::after {
content: ")";
}

View File

@ -0,0 +1,303 @@
{
"aestheticStyle": "default",
"positionStyle": "top",
"menuCommands": [
{
"id": "editing-toolbar:editor-undo",
"name": "undo editor",
"icon": "undo-glyph"
},
{
"id": "editing-toolbar:editor-redo",
"name": "redo editor",
"icon": "redo-glyph"
},
{
"id": "editing-toolbar:format-eraser",
"name": "Clear text formatting",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M889 512 l-211 211 q-26 27 -61 36 q-35 9 -70 0 q-35 -9 -61 -36 l-351 -350 q-26 -27 -35.5 -62 q-9.5 -35 0 -70 q9.5 -35 35.5 -61 l170 -170 q12 -12 29 -12 l215 0 q17 0 29 12 l311 310 q26 26 35.5 61 q9.5 35 0 70 q-9.5 35 -35.5 61 ZM831 453 q15 -15 15.5 -36.5 q0.5 -21.5 -14.5 -37.5 l-300 -298 l-181 0 l-158 158 q-15 15 -15 37 q0 22 15 38 l351 351 q16 16 38 16 q22 0 37 -16 l212 -212 ZM686 217 l-59 -59 l-317 315 l58 59 l318 -315 ZM883 81 q18 0 30.5 -12 q12.5 -12 12.5 -29 q0 -17 -12.5 -29 q-12.5 -12 -29.5 -13 l-456 0 q-17 0 -29.5 12 q-12.5 12 -12.5 29 q0 17 12 29 q12 12 29 13 l456 0 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:header2-text",
"name": "Header 2",
"icon": "header-2"
},
{
"id": "editing-toolbar:header3-text",
"name": "Header 3",
"icon": "header-3"
},
{
"id": "SubmenuCommands-header",
"name": "submenu",
"icon": "header-n",
"SubmenuCommands": [
{
"id": "editing-toolbar:header1-text",
"name": "Header 1",
"icon": "header-1"
},
{
"id": "editing-toolbar:header4-text",
"name": "Header 4",
"icon": "header-4"
},
{
"id": "editing-toolbar:header5-text",
"name": "Header 5",
"icon": "header-5"
},
{
"id": "editing-toolbar:header6-text",
"name": "Header 6",
"icon": "header-6"
}
]
},
{
"id": "editing-toolbar:editor:toggle-bold",
"name": "Toggle bold",
"icon": "bold-glyph"
},
{
"id": "editing-toolbar:editor:toggle-italics",
"name": "Toggle italics",
"icon": "italic-glyph"
},
{
"id": "editing-toolbar:editor:toggle-strikethrough",
"name": "Toggle strikethrough",
"icon": "strikethrough-glyph"
},
{
"id": "editing-toolbar:underline",
"name": "Toggle underline",
"icon": "underline-glyph"
},
{
"id": "editor:toggle-highlight",
"name": "==Toggle highlight ==",
"icon": "highlight-glyph"
},
{
"id": "SubmenuCommands-lucdf3en5",
"name": "submenu",
"icon": "edit",
"SubmenuCommands": [
{
"id": "editing-toolbar:editor-copy",
"name": " copy ",
"icon": "lucide-copy"
},
{
"id": "editing-toolbar:editor-cut",
"name": " cut ",
"icon": "lucide-scissors"
},
{
"id": "editing-toolbar:editor-paste",
"name": "paste ",
"icon": "lucide-clipboard-type"
},
{
"id": "editing-toolbar:editor:swap-line-down",
"name": "swap line down",
"icon": "lucide-corner-right-down"
},
{
"id": "editing-toolbar:editor:swap-line-up",
"name": "swap line up",
"icon": "lucide-corner-right-up"
}
]
},
{
"id": "editing-toolbar:editor:attach-file",
"name": "upload attach file",
"icon": "lucide-paperclip"
},
{
"id": "editing-toolbar:editor:insert-table",
"name": "Toggle table",
"icon": "lucide-table"
},
{
"id": "editing-toolbar:editor:cycle-list-checklist",
"name": "Toggle cycle list checklist",
"icon": "check-circle"
},
{
"id": "SubmenuCommands-luc8efull",
"name": "submenu",
"icon": "message-square",
"SubmenuCommands": [
{
"id": "editing-toolbar:editor:toggle-blockquote",
"name": "Toggle blockquote",
"icon": "lucide-text-quote"
},
{
"id": "editing-toolbar:editor:insert-callout",
"name": "Toggle Callout ",
"icon": "lucide-quote"
}
]
},
{
"id": "SubmenuCommands-mdcmder",
"name": "submenu",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M464 608 l0 -568 q0 -3 -2.5 -5.5 q-2.5 -2.5 -5.5 -2.5 l-80 0 q-3 0 -5.5 2.5 q-2.5 2.5 -2.5 5.5 l0 568 l-232 0 q-3 0 -5.5 2.5 q-2.5 2.5 -2.5 5.5 l0 80 q0 3 2.5 5.5 q2.5 2.5 5.5 2.5 l560 0 q3 0 5.5 -2.5 q2.5 -2.5 2.5 -5.5 l0 -80 q0 -3 -2.5 -5.5 q-2.5 -2.5 -5.5 -2.5 l-232 0 ZM864 696 q17 0 28.5 11.5 q11.5 11.5 11.5 28.5 q0 17 -11.5 28.5 q-11.5 11.5 -28.5 11.5 q-17 0 -28.5 -11.5 q-11.5 -11.5 -11.5 -28.5 q0 -17 11.5 -28.5 q11.5 -11.5 28.5 -11.5 ZM864 640 q-40 0 -68 28 q-28 28 -28 68 q0 40 28 68 q28 28 68 28 q40 0 68 -28 q28 -28 28 -68 q0 -40 -28 -68 q-28 -28 -68 -28 ZM576 322 l0 -63 q0 -3 2 -5 l89 -70 l-89 -70 q-2 -2 -2 -5 l0 -63 q0 -4 3.5 -5.5 q3.5 -1.5 6.5 0.5 l170 133 q4 3 4.5 8.5 q0.5 5.5 -2.5 9.5 l-2 2 l-170 133 q-3 2 -6.5 0.5 q-3.5 -1.5 -3.5 -5.5 ZM256 322 l0 -63 q0 -3 -2 -5 l-89 -70 l89 -70 q2 -2 2 -5 l0 -63 q0 -4 -3.5 -5.5 q-3.5 -1.5 -6.5 0.5 l-170 133 q-4 3 -4.5 8.5 q-0.5 5.5 2.5 9.5 l2 2 l170 133 q3 2 6.5 0.5 q3.5 -1.5 3.5 -5.5 Z\"></path></g></svg>",
"SubmenuCommands": [
{
"id": "editing-toolbar:superscript",
"name": "Toggle superscript",
"icon": "superscript-glyph"
},
{
"id": "editing-toolbar:subscript",
"name": "Toggle subscript",
"icon": "subscript-glyph"
},
{
"id": "editing-toolbar:editor:toggle-code",
"name": "inline code",
"icon": "code-glyph"
},
{
"id": "editing-toolbar:codeblock",
"name": "Toggle codeblock",
"icon": "codeblock-glyph"
},
{
"id": "editing-toolbar:editor:insert-wikilink",
"name": "insert wikilink [[]]",
"icon": "<svg width=\"15\" height=\"15\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M306 134 l91 0 q1 0 1 -8 l0 -80 q0 -8 -1 -8 l-91 0 q-1 0 -1 7 q0 -8 -5 -8 l-45 0 q-5 0 -5 8 l0 784 q0 8 5 8 l45 0 q5 0 5 -8 q0 8 1 8 l91 0 q1 0 1 -8 l0 -80 q0 -8 -1 -8 l-91 0 q-1 0 -1 8 l0 -623 q0 8 1 8 ZM139 134 l91 0 q1 0 1 -8 l0 -80 q0 -8 -1 -8 l-91 0 q-1 0 -1 7 q0 -8 -5 -8 l-45 0 q-5 0 -5 8 l0 784 q0 8 5 8 l45 0 q5 0 5 -8 q0 8 1 8 l91 0 q1 0 1 -8 l0 -80 q0 -8 -1 -8 l-91 0 q-1 0 -1 8 l0 -623 q0 8 1 8 ZM711 134 q1 0 1 -8 l0 623 q0 -8 -1 -8 l-91 0 q-1 0 -1 8 l0 80 q0 8 1 8 l91 0 q1 0 1 -8 q0 8 4 8 l46 0 q4 0 4 -8 l0 -784 q0 -8 -4 -8 l-46 0 q-4 0 -4 8 q0 -7 -1 -7 l-91 0 q-1 0 -1 8 l0 80 q0 8 1 8 l91 0 ZM878 134 q1 0 1 -8 l0 623 q0 -8 -1 -8 l-91 0 q-1 0 -1 8 l0 80 q0 8 1 8 l91 0 q1 0 1 -8 q0 8 5 8 l45 0 q4 0 4 -8 l0 -784 q0 -8 -4 -8 l-45 0 q-5 0 -5 8 q0 -7 -1 -7 l-91 0 q-1 0 -1 8 l0 80 q0 8 1 8 l91 0 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:editor:insert-embed",
"name": "insert embed ![[]]",
"icon": "note-glyph"
},
{
"id": "editing-toolbar:editor:insert-link",
"name": "insert link []()",
"icon": "link-glyph"
},
{
"id": "editing-toolbar:hrline",
"name": "Horizontal divider",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M912 424 l0 -80 q0 -3 -2.5 -5.5 q-2.5 -2.5 -5.5 -2.5 l-784 0 q-3 0 -5.5 2.5 q-2.5 2.5 -2.5 5.5 l0 80 q0 3 2.5 5.5 q2.5 2.5 5.5 2.5 l784 0 q3 0 5.5 -2.5 q2.5 -2.5 2.5 -5.5 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:editor:toggle-inline-math",
"name": "Toggle inline math",
"icon": "lucide-sigma"
},
{
"id": "editing-toolbar:editor:insert-mathblock",
"name": "Toggle MathBlock",
"icon": "lucide-sigma-square"
}
]
},
{
"id": "SubmenuCommands-list",
"name": "submenu-list",
"icon": "bullet-list-glyph",
"SubmenuCommands": [
{
"id": "editing-toolbar:editor:toggle-checklist-status",
"name": "checklist",
"icon": "checkbox-glyph"
},
{
"id": "editor:toggle-numbered-list",
"name": "numbered list",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M860 424 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-457 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l457 0 ZM860 756 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-457 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l457 0 ZM860 92 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-457 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l457 0 ZM264 136 l-3 -3 l-51 -57 l56 0 q14 0 24.5 -10 q10.5 -10 11.5 -25 l0 -1 q0 -15 -10.5 -25.5 q-10.5 -10.5 -24.5 -10.5 l-137 0 q-15 0 -25 10 q-10 10 -11 24.5 q-1 14.5 9 25.5 l63 70 l49 54 q7 7 7 16.5 q0 9.5 -7.5 16.5 q-7.5 7 -18.5 7 q-11 0 -18.5 -6.5 q-7.5 -6.5 -8.5 -16.5 l0 0 q0 -15 -10.5 -25.5 q-10.5 -10.5 -25.5 -10.5 q-15 0 -25.5 10.5 q-10.5 10.5 -10.5 25.5 q0 26 13.5 47.5 q13.5 21.5 36 34.5 q22.5 13 49 13 q26.5 0 49.5 -13 q23 -13 36 -34.5 q13 -21.5 13 -47.5 q0 -20 -7.5 -37.5 q-7.5 -17.5 -21.5 -30.5 l-1 -1 ZM173 794 q11 11 25 10.5 q14 -0.5 24.5 -10.5 q10.5 -10 10.5 -25 l0 -293 q0 -15 -10 -25.5 q-10 -10.5 -25 -10.5 q-15 0 -25.5 10 q-10.5 10 -11.5 25 l0 211 q-10 -8 -23.5 -7 q-13.5 1 -22.5 11 l-1 0 q-10 11 -9.5 25.5 q0.5 14.5 10.5 24.5 l58 54 Z\"></path></g></svg>"
},
{
"id": "editor:toggle-bullet-list",
"name": "bullet list",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M860 424 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-477 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l477 0 ZM860 756 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-477 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l477 0 ZM860 92 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-477 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l477 0 ZM176 716 l0 0 ZM112 716 q0 -27 18.5 -45.5 q18.5 -18.5 45.5 -18.5 q27 0 45.5 18.5 q18.5 18.5 18.5 45.5 q0 27 -18.5 45.5 q-18.5 18.5 -45.5 18.5 q-27 0 -45.5 -18.5 q-18.5 -18.5 -18.5 -45.5 ZM176 384 l0 0 ZM112 384 q0 -27 18.5 -45.5 q18.5 -18.5 45.5 -18.5 q27 0 45.5 18.5 q18.5 18.5 18.5 45.5 q0 27 -18.5 45.5 q-18.5 18.5 -45.5 18.5 q-27 0 -45.5 -18.5 q-18.5 -18.5 -18.5 -45.5 ZM176 52 l0 0 ZM112 52 q0 -27 18.5 -45.5 q18.5 -18.5 45.5 -18.5 q27 0 45.5 18.5 q18.5 18.5 18.5 45.5 q0 27 -18.5 45.5 q-18.5 18.5 -45.5 18.5 q-27 0 -45.5 -18.5 q-18.5 -18.5 -18.5 -45.5 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:undent-list",
"name": "unindent-list",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M872 302 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-429 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l429 0 ZM872 542 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-429 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l429 0 ZM872 784 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM872 62 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM244 534 l-123 -122 q-8 -7 -8 -18 q0 -11 8 -18 l123 -122 q8 -7 19 -7 q11 0 18.5 7.5 q7.5 7.5 7.5 18.5 l0 242 q0 11 -7.5 18.5 q-7.5 7.5 -18.5 7.5 q-11 0 -19 -7 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:indent-list",
"name": "indent list",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M872 302 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-429 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l429 0 ZM872 542 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-429 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l429 0 ZM872 784 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM872 62 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM158 534 l124 -122 q7 -7 7 -18 q0 -11 -7 -18 l-124 -122 q-7 -7 -18 -7 q-11 0 -19 7.5 q-8 7.5 -8 18.5 l0 242 q0 11 8 18.5 q8 7.5 19 7.5 q11 0 18 -7 Z\"></path></g></svg>"
}
]
},
{
"id": "SubmenuCommands-aligin",
"name": "submenu-aligin",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M724 304 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 540 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM724 776 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 68 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 Z\"></path></g></svg>",
"SubmenuCommands": [
{
"id": "editing-toolbar:justify",
"name": "<p aligin=\"justify\"></p>",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M112 736 l0 0 ZM120 736 l784 0 q8 0 8 -8 l0 -80 q0 -8 -8 -8 l-784 0 q-8 0 -8 8 l0 80 q0 8 8 8 ZM112 331 l0 0 ZM120 331 l784 0 q8 0 8 -8 l0 -80 q0 -8 -8 -8 l-784 0 q-8 0 -8 8 l0 80 q0 8 8 8 ZM112 128 l0 0 ZM120 128 l784 0 q8 0 8 -8 l0 -80 q0 -8 -8 -8 l-784 0 q-8 0 -8 8 l0 80 q0 8 8 8 ZM112 533 l0 0 ZM120 533 l784 0 q8 0 8 -8 l0 -80 q0 -8 -8 -8 l-784 0 q-8 0 -8 8 l0 80 q0 8 8 8 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:left",
"name": "<p aligin=\"left\"></p>",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M572 304 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 540 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM572 776 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 68 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:center",
"name": "<center>",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M724 304 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 540 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM724 776 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 68 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 Z\"></path></g></svg>"
},
{
"id": "editing-toolbar:right",
"name": "<p aligin=\"right\"></p>",
"icon": "<svg width=\"18\" height=\"18\" focusable=\"false\" fill=\"currentColor\" viewBox=\"0 0 1024 1024\"><g transform=\"scale(1, -1) translate(0, -896) scale(0.9, 0.9) \"><path class=\"path\" d=\"M872 304 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 540 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 ZM872 776 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-421 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l421 0 ZM872 68 q17 0 28.5 -11.5 q11.5 -11.5 11.5 -28 q0 -16.5 -11.5 -28.5 q-11.5 -12 -27.5 -12 l-721 0 q-17 0 -28.5 11.5 q-11.5 11.5 -11.5 28 q0 16.5 11.5 28.5 q11.5 12 27.5 12 l721 0 Z\"></path></g></svg>"
}
]
},
{
"id": "editing-toolbar:change-font-color",
"name": "Change font color[html]",
"icon": "<svg width=\"24\" height=\"24\" focusable=\"false\" fill=\"currentColor\"><g fill-rule=\"evenodd\"><path id=\"change-font-color-icon\" d=\"M3 18h18v3H3z\" style=\"fill:#2DC26B\"></path><path d=\"M8.7 16h-.8a.5.5 0 01-.5-.6l2.7-9c.1-.3.3-.4.5-.4h2.8c.2 0 .4.1.5.4l2.7 9a.5.5 0 01-.5.6h-.8a.5.5 0 01-.4-.4l-.7-2.2c0-.3-.3-.4-.5-.4h-3.4c-.2 0-.4.1-.5.4l-.7 2.2c0 .3-.2.4-.4.4zm2.6-7.6l-.6 2a.5.5 0 00.5.6h1.6a.5.5 0 00.5-.6l-.6-2c0-.3-.3-.4-.5-.4h-.4c-.2 0-.4.1-.5.4z\"></path></g></svg>"
},
{
"id": "editing-toolbar:change-background-color",
"name": "Change Backgroundcolor[html]",
"icon": "<svg width=\"18\" height=\"24\" viewBox=\"0 0 256 256\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"><g stroke=\"none\" stroke-width=\"1\" fill=\"currentColor\" fill-rule=\"evenodd\"><g ><g fill=\"currentColor\"><g transform=\"translate(119.502295, 137.878331) rotate(-135.000000) translate(-119.502295, -137.878331) translate(48.002295, 31.757731)\" ><path d=\"M100.946943,60.8084699 L43.7469427,60.8084699 C37.2852111,60.8084699 32.0469427,66.0467383 32.0469427,72.5084699 L32.0469427,118.70847 C32.0469427,125.170201 37.2852111,130.40847 43.7469427,130.40847 L100.946943,130.40847 C107.408674,130.40847 112.646943,125.170201 112.646943,118.70847 L112.646943,72.5084699 C112.646943,66.0467383 107.408674,60.8084699 100.946943,60.8084699 Z M93.646,79.808 L93.646,111.408 L51.046,111.408 L51.046,79.808 L93.646,79.808 Z\" fill-rule=\"nonzero\"></path><path d=\"M87.9366521,16.90916 L87.9194966,68.2000001 C87.9183543,69.4147389 86.9334998,70.399264 85.7187607,70.4 L56.9423078,70.4 C55.7272813,70.4 54.7423078,69.4150264 54.7423078,68.2 L54.7423078,39.4621057 C54.7423078,37.2523513 55.5736632,35.1234748 57.0711706,33.4985176 L76.4832996,12.4342613 C78.9534987,9.75382857 83.1289108,9.5834005 85.8093436,12.0535996 C87.1658473,13.303709 87.9372691,15.0644715 87.9366521,16.90916 Z\" fill-rule=\"evenodd\"></path><path d=\"M131.3,111.241199 L11.7,111.241199 C5.23826843,111.241199 0,116.479467 0,122.941199 L0,200.541199 C0,207.002931 5.23826843,212.241199 11.7,212.241199 L131.3,212.241199 C137.761732,212.241199 143,207.002931 143,200.541199 L143,122.941199 C143,116.479467 137.761732,111.241199 131.3,111.241199 Z M124,130.241 L124,193.241 L19,193.241 L19,130.241 L124,130.241 Z\" fill-rule=\"nonzero\"></path></g></g><path d=\"M51,218 L205,218 C211.075132,218 216,222.924868 216,229 C216,235.075132 211.075132,240 205,240 L51,240 C44.9248678,240 40,235.075132 40,229 C40,222.924868 44.9248678,218 51,218 Z\" id=\"change-background-color-icon\" style=\"fill:#FA541C\"></path></g></g></svg>"
},
{
"id": "editing-toolbar:fullscreen-focus",
"name": "Fullscreen focus mode",
"icon": "fullscreen"
},
{
"id": "editing-toolbar:workplace-fullscreen-focus",
"name": "workplace-Fullscreen ",
"icon": "exit-fullscreen"
}
],
"appendMethod": "workspace",
"shouldShowMenuOnSelect": false,
"cMenuVisibility": true,
"cMenuBottomValue": 4.25,
"cMenuNumRows": 12,
"cMenuWidth": 610,
"cMenuFontColor": "#00b050",
"cMenuBackgroundColor": "#fff88f",
"autohide": false,
"custom_bg1": "#FFB78B8C",
"custom_bg2": "#CDF4698C",
"custom_bg3": "#A0CCF68C",
"custom_bg4": "#F0A7D88C",
"custom_bg5": "#ADEFEF8C",
"custom_fc1": "#D83931",
"custom_fc2": "#DE7802",
"custom_fc3": "#245BDB",
"custom_fc4": "#6425D0",
"custom_fc5": "#646A73",
"isLoadOnMobile": false
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,11 @@
{
"id": "editing-toolbar",
"name": "Editing Toolbar",
"version": "2.4.16",
"minAppVersion": "0.14.0",
"description": "The Obsidian Editing Toolbar is modified from cmenu, which provides more powerful customization settings and has many built-in editing commands to be a MS Word-like toolbar editing experience.",
"author": "Cuman",
"authorUrl": "https://github.com/cumany/obsidian-editing-toolbar",
"fundingUrl": "https://github.com/cumany#thank-you-very-much-for-your-support",
"isDesktopOnly": false
}

View File

@ -0,0 +1,971 @@
#cMenuToolbarModalBar {
width: auto;
height: auto;
padding: 3px;
display: grid;
user-select: none;
border-radius: var(--radius-m);
position: absolute;
transition: 100ms cubic-bezier(0.92, -0.53, 0.65, 1.21);
-webkit-transition: 100ms cubic-bezier(0.92, -0.53, 0.65, 1.21);
min-width: fit-content;
justify-content: space-around;
z-index: var(--layer-modal);
}
#cMenuToolbarModalBar.cMenuToolbarFlex {
display: flex;
}
#cMenuToolbarModalBar.cMenuToolbarFlex :is(.cMenuToolbarCommandItem, button[class^=cMenuToolbarCommandsubItem]) {
min-width: 20px;
}
#cMenuToolbarModalBar .cMenuToolbarCommandItem {
margin: 2px;
border: none;
display: flex;
cursor: default;
padding: 5px 6px;
box-shadow: none;
margin-left: 3px;
margin-right: 3px;
position: relative;
border-radius: var(--radius-s);
font-size: initial !important;
background-color: var(--background-primary-alt);
height: auto;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommandsubItem]>.subitem button:hover,
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommand]:hover,
#cMenuToolbarSecond:hover {
background-color: var(--background-modifier-hover) !important;
}
/* #cMenuToolbarModalBar button.cMenuToolbarCommandItem svg {
width: 1.3em;
height: 1.3em;
} */
/*----------------------------------------------------------------
cMenuToolbar SETTINGS BUTTONS
----------------------------------------------------------------*/
.modal.mod-settings button:not(.mod-cta):not(.mod-warning).cMenuToolbarSettingsButton.cMenuToolbarSettingsButtonAdd,
button:not(.mod-cta):not(.mod-warning).cMenuToolbarSettingsButton.cMenuToolbarSettingsButtonAdd {
background-color: var(--interactive-accent);
}
.modal.mod-settings button:not(.mod-cta):not(.mod-warning).cMenuToolbarSettingsButton.cMenuToolbarSettingsButtonDelete,
button:not(.mod-cta):not(.mod-warning).cMenuToolbarSettingsButton.cMenuToolbarSettingsButtonDelete {
background-color: #989cab;
}
.modal.mod-settings button:not(.mod-cta):not(.mod-warning).cMenuToolbarSettingsButton.cMenuToolbarSettingsButtonRefresh,
button:not(.mod-cta):not(.mod-warning).cMenuToolbarSettingsButton.cMenuToolbarSettingsButtonRefresh {
background-color: var(--text-accent);
}
button.cMenuToolbarSettingsButton {
padding: 4px 14px;
border-radius: var(--radius-m);
}
/*----------------------------------------------------------------
cMenuToolbar SETTING ITEMS
----------------------------------------------------------------*/
.setting-item.cMenuToolbarCommandItem:first-child {
padding-top: 18px;
}
.cMenuToolbarCommandItem {
cursor: grab;
padding: 18px 0 18px 0;
}
.cMenuToolbarSettingsTabsContainer .sortable-fallback {
cursor: grabbing;
box-shadow: 0px 3px 32px rgb(31 38 135 / 15%);
}
.cMenuToolbarSettingsTabsContainer .sortable-grab {
cursor: grabbing !important;
}
.cMenuToolbarSettingsTabsContainer .sortable-ghost {
opacity: 0.4;
cursor: grabbing;
}
.cMenuToolbarSettingsTabsContainer .sortable-chosen {
cursor: grabbing;
padding: 18px 0 18px 18px;
background-color: var(--color-base-10, --background-primary);
}
.cMenuToolbarSettingsTabsContainer .sortable-drag {
cursor: grabbing;
box-shadow: 0px 3px 32px rgb(31 38 135 / 15%);
}
.cMenuToolbarSettingsTabsContainer {
border-top: 1px solid var(--background-modifier-border);
border-bottom: 1px solid var(--background-modifier-border);
}
/*----------------------------------------------------------------
cMenuToolbar CLASS CHANGES
----------------------------------------------------------------*/
#cMenuToolbarModalBar.cMenuToolbarDefaultAesthetic {
border: 1px solid var(--background-modifier-border);
}
#cMenuToolbarModalBar.cMenuToolbarDefaultAesthetic:not(.top) :is(.cMenuToolbarCommandItem, button[class^=cMenuToolbarCommandsubItem]) {
min-height: 28px;
}
#cMenuToolbarModalBar.cMenuToolbarDefaultAesthetic:not(.top) button[class^=cMenuToolbarCommandsubItem] {
margin: auto;
padding: 6px;
box-shadow: none;
border: none;
background-color: transparent;
place-items: center;
}
.cMenuToolbarDefaultAesthetic {
background-color: var(--color-base-10, --background-primary);
}
#cMenuToolbarModalBar.cMenuToolbarGlassAesthetic,
#cMenuToolbarModalBar.cMenuToolbarGlassAesthetic~#cMenuToolbarPopoverBar {
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
box-shadow: none;
background-color: transparent;
}
#cMenuToolbarModalBar.cMenuToolbarGlassAesthetic:not(.top) button[class^=cMenuToolbarCommandsubItem] {
margin: auto;
padding: 0px;
box-shadow: none;
border: none;
display: flex;
border-radius: var(--radius-s);
font-size: 10px;
margin-right: 0px;
position: relative;
background-color: transparent;
place-items: center;
clear: both;
max-width: 28px;
max-height: 23px;
}
/*----------------------------------------------------------------
cMenuToolbar ICONS
----------------------------------------------------------------*/
.cMenuToolbarIconPick {
line-height: normal;
vertical-align: middle;
margin-right: 8px;
}
.cMenuToolbarIconPick svg {
width: 17px;
height: 17px;
}
/*----------------------------------------------------------------
cMenuToolbar STATUS BAR MENU
----------------------------------------------------------------*/
.cMenuToolbar-statusbar-menu {
text-align: center;
width: 200px;
}
.cMenuToolbar-statusbar-menu .menu-item {
display: flex;
align-items: center;
flex-direction: row;
}
.cMenuToolbar-statusbar-menu .menu-item.settings-item {
font-size: 12px;
text-align: center;
line-height: 1;
border-radius: var(--radius-m);
height: auto;
padding: 8px 5px 0px 5px;
margin: 0 auto;
width: fit-content;
color: var(--text-faint);
}
.cMenuToolbar-statusbar-menu .menu-item.settings-item .menu-item-title {
text-align: center;
}
.cMenuToolbar-statusbar-menu .menu-item:hover,
.cMenuToolbar-statusbar-menu .menu-item .selected:hover,
.cMenuToolbar-statusbar-menu .menu-item.selected:not(.is-disabled):not(.is-label) {
background-color: transparent;
}
.cMenuToolbar-statusbar-menu .menu-item-title {
margin-right: 10px;
}
.cMenuToolbar-statusbar-menu .slider {
width: 100%;
}
.cMenuToolbar-statusbar-menu .menu-item.buttonitem {
padding-top: 10px;
padding-bottom: 4px;
height: fit-content;
}
.cMenuToolbar-statusbar-menu .menu-item.buttonitem button.cMenuToolbarSettingsButton {
margin: 0;
}
.cMenuToolbar-statusbar-menu .menu-item-icon svg path {
fill: var(--text-muted);
}
.cMenuToolbar-statusbar-menu .menu-item-icon svg {
stroke: var(--text-muted);
}
.cMenuToolbar-statusbar-menu>.menu-item:is([data-section="ButtonAdd"]) {
display: inline-flex;
padding: 0px 0px 5px 5px;
align-items: center;
}
.cMenuToolbar-statusbar-menu>.menu-item {
display: inline-flex;
padding: 0px 0px 5px 5px;
align-items: center;
}
.cMenuToolbar-statusbar-menu>.menu-item:is([data-section="ButtonAdd"]) .menu-item-icon {
text-align: center;
}
/*----------------------------------------------------------------
cMenuToolbar STATUS BAR BUTTONS
----------------------------------------------------------------*/
.cMenuToolbar-statusbar-button {
cursor: default;
display: flex;
align-items: center;
line-height: 1;
}
.cMenuToolbar-statusbar-button svg {
display: flex;
width: 1.3em;
height: 1.3em;
}
/*----------------------------------------------------------------
cMenuToolbar SUPPORT
---------------------------------------------`-------------------*/
.cDonationSection {
width: 60%;
height: 50vh;
margin: 0 auto;
text-align: center;
color: var(--text-normal);
}
#cMenuToolbarModalBar {
align-items: center;
justify-items: center;
border: none;
backdrop-filter: none;
}
#cMenuToolbarModalBar.cMenuToolbarGlassAesthetic .cMenuToolbarCommandItem {
background-color: #ffffff00;
}
#cMenuToolbarModalBar.cMenuToolbarGlassAesthetic [class^=cMenuToolbarCommandsubItem] {
background-color: #ffffff00;
}
#cMenuToolbarModalBar .cMenuToolbarCommandItem {
justify-content: center;
align-content: center;
place-items: center;
}
/* #cMenuToolbarModalBar.cMenuToolbarTinyAesthetic .cMenuToolbarCommandItem svg{
width: 1em;
height: 1em;
} */
div.modal-container.cMenuToolbar-Modal:not(.changename) .modal-bg {
background-color: transparent !important;
backdrop-filter: none !important;
position: relative;
}
.modal-container.cMenuToolbar-Modal:not(.changename) .modal {
padding: 10px 30px;
min-width: 130px;
position: absolute;
bottom: 2em;
right: 0.5em;
background-color: rgb(var(--mono-rgb-0), 0.8);
backdrop-filter: blur(4px);
}
.modal-container.cMenuToolbar-Modal .modal-title {
display: none;
}
.modal-container.cMenuToolbar-Modal .modal input[type='range'] {
width: 90%;
}
body.theme-dark .modal-container.cMenuToolbar-Modal .modal input[type='range'] {
background-color: var(--background-secondary);
}
/*tiny 样式*/
#cMenuToolbarModalBar.cMenuToolbarTinyAesthetic {
align-items: center;
justify-items: center;
border: 1px solid var(--background-modifier-border-hover);
backdrop-filter: none;
background-color: var(--background-secondary);
}
#cMenuToolbarModalBar.cMenuToolbarTinyAesthetic .cMenuToolbarCommandItem {
margin: auto;
padding: 0px;
box-shadow: none;
margin-left: 0px;
margin-right: 0px;
position: relative;
background-color: transparent;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
}
#cMenuToolbarModalBar .cMenuToolbarCommandItem {
margin: auto;
padding: 0px;
box-shadow: none;
margin-left: 4px;
margin-right: 0px;
position: relative;
background-color: transparent;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
}
:is(#cMenuToolbarModalBar).cMenuToolbarTinyAesthetic:not(.top) button[class^=cMenuToolbarCommandsubItem] {
margin: auto;
padding: 0px;
box-shadow: none;
border: none;
display: flex;
border-radius: var(--radius-s);
font-size: 10px;
margin-right: 0px;
position: relative;
background-color: transparent;
place-items: center;
clear: both;
max-width: 28px;
max-height: 18px;
}
button[class^=cMenuToolbarCommandsubItem]::after {
content: url("data:image/svg+xml,%3Csvg width='4' height='4' version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024' enable-background='new 0 0 1024 1024' xml:space='preserve'%3E%3Cpath fill='%23666' d='M13.24 80.11 l461.75 560.8 q14.56 16.02 36.41 16.02 q21.85 0 36.42 -16.02 l463.2 -560.8 q10.2 -10.19 12.38 -24.75 q2.18 -14.57 -3.64 -27.68 q-5.82 -13.11 -18.21 -20.39 q-12.39 -7.29 -26.95 -7.29 l-924.95 0 q-20.4 0 -34.23 13.11 q-13.84 13.11 -15.29 32.77 q-1.46 19.66 13.11 34.23 Z'/%3E%3C/svg%3E");
margin-left: 1px;
margin-top: 6px;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommandsubItem]>.subitem {
background-color: var(--color-base-10, --background-primary);
border-radius: var(--radius-s);
border: 1px solid var(--background-modifier-border);
position: absolute;
z-index: var(--layer-menu);
user-select: none;
transform: translateY(90%) translateX(0%);
-webkit-transform: translateY(90%) translateX(0%);
display: flex;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommandsubItem]>.subitem svg {
max-width: 1.3em;
max-height: 1.3em;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommandsubItem]>.subitem button.menu-item {
background-color: transparent;
line-height: 2em;
display: inline-flex;
box-shadow: none;
align-items: center;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommandsubItem]>.subitem .menu-item {
margin-left: 2px;
margin-right: 2px;
padding: 0px 4px 0px 4px;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommandsubItem]>.subitem {
visibility: hidden;
transition: all 0.3s linear;
-webkit-transition: all 0.3s linear;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button.cMenuToolbarCommandsubItem-font-color .triangle-icon {
position: absolute;
margin-left: 18px;
bottom: 8%;
background-size: 4px 4px;
background-image: url("data:image/svg+xml,%3Csvg width='4' height='4' version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024' enable-background='new 0 0 1024 1024' xml:space='preserve'%3E%3Cpath fill='%23666' d='M13.24 80.11 l461.75 560.8 q14.56 16.02 36.41 16.02 q21.85 0 36.42 -16.02 l463.2 -560.8 q10.2 -10.19 12.38 -24.75 q2.18 -14.57 -3.64 -27.68 q-5.82 -13.11 -18.21 -20.39 q-12.39 -7.29 -26.95 -7.29 l-924.95 0 q-20.4 0 -34.23 13.11 q-13.84 13.11 -15.29 32.77 q-1.46 19.66 13.11 34.23 Z'/%3E%3C/svg%3E");
width: 16px;
height: 20px;
background-position: center;
background-repeat: no-repeat;
min-width: unset;
border-left: 2px solid transparent;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar):not(.top) button.cMenuToolbarCommandsubItem-font-color .triangle-icon {
margin-left: 16px;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar):not(.top) button.cMenuToolbarCommandsubItem-font-color .x-color-picker-wrapper {
top: auto;
bottom: calc(100%);
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar):not(.top) button[class^=cMenuToolbarCommandsubItem]:not(.cMenuToolbarSecond)>.subitem {
bottom: calc(100% + 2.8em);
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button.cMenuToolbarCommandsubItem-font-color .subitem {
visibility: hidden;
transition: all 0.3s linear;
-webkit-transition: all 0.3s linear;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button.cMenuToolbarCommandsubItem-font-color .subitem:hover {
visibility: visible;
transition: all 0.3s linear;
-webkit-transition: all 0.3s linear;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommandsubItem]:hover>.subitem {
visibility: visible;
transition: all 0.3s linear;
-webkit-transition: all 0.3s linear;
}
/* :is(#cMenuToolbarModalBar,#cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommandsubItem] >.subitem:hover {
visibility:visible;
transition: all 0.3s linear;
-webkit-transition: all 0.3s linear;
} */
.cMenuToolbarCommandsubItem-font-color button {
background-color: transparent;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbarCommandItem .setting-item-info {
flex: 30%;
margin: 0;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbarSettingsTabsContainer_sub {
border-left: 1px solid var(--background-modifier-border);
flex-flow: column;
min-height: 45px;
display: flex;
padding: 0;
margin-left: 10px;
flex: 70%;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbarSettingsTabsContainer_sub:empty {
border: 2px dashed rgba(var(--interactive-accent-rgb), 0.5);
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbarSettingsTabsContainer_sub:empty::before {
content: "✖Drag it here";
margin: auto;
font-size: 12px;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbarSettingsTabsContainer_sub .cMenuToolbarCommandItem {
flex: auto;
margin-left: 2em;
;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbarSettingsTabsContainer_sub .setting-item-control {
flex: 0;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbarCommandSubItem>.setting-item-info {
flex: 70px;
}
.cMenuToolbarCommandSubItem>.setting-item-control {
justify-content: flex-start;
}
.modal.mod-settings button:not(.mod-cta):not(.mod-warning).cMenuToolbarSettingsButton.cMenuToolbarSettingsButtonaddsub {
background-color: var(--background-secondary-alt);
}
.setting-item button.cMenuToolbarSettingsIcon {
display: block;
transform: translateX(-30%);
-webkit-transform: translateX(-30%);
}
.setting-item button.cMenuToolbarSettingsIcon:empty::before {
content: "❗";
}
.setting-item button.cMenuToolbarSettingsIcon svg {
max-width: 1.5em;
max-height: 1.5em;
}
.modal.mod-settings button:not(.mod-cta):not(.mod-warning).cMenuToolbarSettingsIcon:hover {
background-color: var(--interactive-accent-hover);
}
.modal.mod-settings button:not(.mod-cta):not(.mod-warning).cMenuToolbarSettingsIcon {
background-color: transparent;
box-shadow: 0 1px 1px 0px var(--background-modifier-border);
}
@media screen and (min-width: 781px) {
.cMenuToolbar-Modal .wideInputPromptInputEl {
width: 40rem;
max-width: 100%;
height: 20rem;
background-color: rgb(var(--mono-rgb-0), 0.8);
}
}
.cMenuToolbarcustomIcon svg {
max-width: 1.3em;
max-height: 1.3em;
display: flex;
}
.cMenuToolbarSettingsButton svg {
max-width: 1.3em;
max-height: 1.3em;
display: flex;
}
.cmdr-page-header {
min-width: 1em;
;
}
.x-color-picker-wrapper {
right: 0px;
top: 1.8em;
min-width: 1px;
padding: 10px;
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14);
position: absolute;
width: fit-content;
font-weight: 400;
font-family: Source Sans Pro, sans-serif;
border-radius: var(--radius-s);
background-color: var(--color-base-10, --background-primary);
}
.markdown-source-view.mod-cm6 .x-color-picker-wrapper table.x-color-picker-table#x-color-picker-table {
width: unset;
border-collapse: separate;
border-spacing: 6px;
margin: auto !important;
}
.x-color-picker-wrapper table.x-color-picker-table#x-backgroundcolor-picker-table {
width: unset;
border-collapse: separate;
border-spacing: 6px;
margin: auto !important;
}
.x-color-picker-wrapper .x-color-picker-table th {
border: 0;
text-align: left;
font-weight: normal;
background: transparent !important;
color: #718096;
}
.x-color-picker-wrapper #x-color-picker-table td {
font-size: 1px;
padding: 9px;
cursor: default;
border: solid 1px var(--background-modifier-border);
}
.x-color-picker-wrapper #x-backgroundcolor-picker-table td {
font-size: 1px;
border-radius: 50%;
padding: 9px;
cursor: default;
border: solid 1px var(--background-modifier-border);
}
.x-color-picker-wrapper .x-color-picker-table tr td:hover {
filter: brightness(1.2);
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, .12), 0 6px 16px 0 rgba(0, 0, 0, .08), 0 9px 28px 8px rgba(0, 0, 0, .05);
}
/* .x-color-picker-wrapper tbody>tr:hover {
background-color: transparent !important;
} */
/**top**/
#cMenuToolbarModalBar.top {
display: flex;
flex-wrap: nowrap;
position: relative;
height: 38px;
align-items: center;
transition: all 0.2s linear;
-webkit-transition: all 0.2s linear;
}
#cMenuToolbarModalBar.top.autohide {
opacity: 0;
transition: all 0.5s linear;
-webkit-transition: all 0.5s linear;
}
#cMenuToolbarModalBar.top.autohide:hover {
opacity: 1;
transition: all 1s linear;
-webkit-transition: all 1s linear;
}
#cMenuToolbarModalBar.top :is(.cMenuToolbarCommandItem, button[class^=cMenuToolbarCommandsubItem]):not(.cMenuToolbar-Divider-Line) {
font-size: 10px;
margin-right: 0px;
clear: both;
opacity: 1;
flex-shrink: 0;
height: 26px;
padding: 0;
border: none;
background: transparent;
cursor: default;
outline: none;
box-shadow: none;
border-radius: var(--radius-s);
display: inline-flex;
justify-content: center;
align-items: center;
transition: all 0.2s linear;
-webkit-transition: all 0.2s linear;
}
/* #cMenuToolbarModalBar.top button.cMenuToolbarCommandItem:hover {
background-color: var(--interactive-hover);
} */
#cMenuToolbarPopoverBar {
padding: 0 10px;
display: inline-flex;
align-items: center;
width: fit-content;
z-index: var(--layer-popover);
background-color: var(--color-base-10, --background-primary);
background-clip: padding-box;
border-radius: var(--radius-m);
margin-left: auto;
margin-right: 25px;
transition: all 0.1s linear;
-webkit-transition: all 0.1s linear;
margin-top: 32px;
position: absolute;
right: 0;
}
#cMenuToolbarPopoverBar :is(.cMenuToolbarCommandItem, button[class^=cMenuToolbarCommandsubItem]) {
height: 26px;
margin-left: 4px;
font-size: 10px;
margin-right: 4px;
clear: both;
opacity: 1;
flex-shrink: 0;
height: 26px;
padding: 0;
border: none;
background: transparent;
cursor: default;
outline: none;
box-shadow: none;
border-radius: var(--radius-s);
display: inline-flex;
justify-content: center;
align-items: center;
transition: all 0.2s linear;
-webkit-transition: all 0.2s linear;
}
#cMenuToolbarModalBar .more-menu {
display: flex;
align-items: center;
box-shadow: none;
margin-left: 4px;
border-left: 1px inset var(--background-modifier-form-field);
height: 24px;
opacity: 0.8;
}
/*Divider-Line**/
.cMenuToolbarSettingsTabsContainer .cMenuToolbar-Divider-Line {
padding: 0;
line-height: 0px;
border-left: 200px solid rgba(var(--interactive-accent-rgb), 0.05);
border-right: 200px solid rgba(var(--interactive-accent-rgb), 0.05);
text-align: center;
background: rgba(var(--interactive-accent-rgb), 0.2);
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbar-Divider-Line .setting-item-control button:not(:last-child) {
display: none;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbar-Divider-Line .setting-item-info {
flex: 1 1 auto;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbar-Divider-Line .setting-item-control {
justify-content: flex-start;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbar-Divider-Line .setting-item-info .setting-item-name {
font-size: 12px;
text-align: right;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbar-Divider-Line .setting-item-control button:last-child {
padding: 0;
background-color: transparent !important;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbar-Divider-Line .setting-item-control button:last-child svg {
display: none;
}
.cMenuToolbarSettingsTabsContainer .cMenuToolbar-Divider-Line .setting-item-control button:last-child::before {
content: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M511.674077 66.707284c-246.52265 0-446.347744 199.835328-446.347744 446.347744s199.825095 446.356954 446.347744 446.356954c246.50423 0 446.348768-199.844537 446.348768-446.356954S758.177284 66.707284 511.674077 66.707284zM744.967424 667.159826c21.8701 21.8701 21.8701 57.310264 0 79.199807-21.8701 21.851681-57.30924 21.851681-79.198783-0.019443L511.674077 592.264045 357.56007 746.359632c-21.8701 21.8701-57.30924 21.851681-79.17934-0.019443s-21.8701-57.290821 0-79.160921L432.493713 513.065262 278.379707 358.950232c-21.8701-21.86089-21.8701-57.328683 0-79.18855 21.8701-21.87931 57.30924-21.87931 79.17934 0l154.114007 154.104797 154.095587-154.104797c21.889543-21.87931 57.32766-21.87931 79.198783-0.010233 21.8701 21.8701 21.8701 57.348126 0 79.207993L590.89128 513.065262 744.967424 667.159826z' fill='%23666666'/%3E%3C/svg%3E");
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button.cMenuToolbar-Divider-Line
{
min-width: unset;
flex-shrink: 0;
display: inline-flex;
width: 0.6px;
background-color: var(--background-modifier-border);
height: 22px;
opacity: 0.8;
margin: 0;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button[class^=cMenuToolbarCommandsubItem]>.subitem button.menu-item.cMenuToolbar-Divider-Line
{ min-width: unset;
flex-shrink: 0;
display: inline-flex;
width: 0.6px;
background-color: var(--background-modifier-border);
height: 22px;
opacity: 0.8;
margin: 0;
padding: 0;
height: auto;
}
.theme-dark :is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button.cMenuToolbar-Divider-Line {
background-color: #4f4f5188;
}
:is(#cMenuToolbarModalBar, #cMenuToolbarPopoverBar) button.cMenuToolbar-Divider-Line svg {
display: none;
}
.workspace-tabs.mod-stacked .workspace-tab-header:not(.is-active)+.workspace-leaf #cMenuToolbarModalBar {
opacity: 0;
}
:is(.cm-line, p) span[style^="background:rgba"] {
color: var(--text-normal);
}
:is(.cm-line, p) span[style^="background:#"] {
color: black;
}
.setting-item.toolbar-cta:after {
content: "";
position: absolute;
top: -10%;
width: 104%;
left: -2%;
height: 120%;
outline: 2px solid var(--text-accent);
border-radius: 1em;
pointer-events: none;
}
.setting-item.toolbar-cta {
position: relative;
}
.toolbar-pickr .pcr-last-color,
.pickr .pcr-button{
background-color: var(--pcr-color);
}
.toolbar-pickr .pcr-interaction :not(:is(input.pcr-save,.pcr-result)){
display:none;
}
.toolbar-pickr .pcr-swatches {
display:none;
}
.toolbar-pickr {
display:flex;
}
div[data-type="thino_view"] .memo-editor-wrapper:has(#cMenuToolbarModalBar)
{
padding-top:0;
padding-left:0;
padding-right:0;
}
div[data-type="thino_view"] .memo-editor-wrapper:has(#cMenuToolbarModalBar) .common-tools-wrapper
{
padding-left:16px;
padding-right:16px;
}
div[data-type="thino_view"] .memo-editor-wrapper #cMenuToolbarModalBar ~ .cm-editor{
padding-top:38px;
padding-bottom:0px;
padding-left:16px;
padding-right:16px;
}
div[data-type=thino_view] .common-editor-wrapper .common-editor-inputer:has(#cMenuToolbarModalBar)
{
min-height:118px;
}
div[data-type=thino_view] #cMenuToolbarModalBar.top
{
position:absolute!important;
width: 100%;
}
body.auto-hide-header .workspace-tab-header-container:hover + .workspace-tab-container .workspace-leaf .workspace-leaf-content>.view-header {
margin-top: 0;
transition: all 0.1s linear;
}
body.auto-hide-header .workspace-tab-header-container + .workspace-tab-container .workspace-leaf .workspace-leaf-content>.view-header:hover {
margin-top: 0;
transition: all 0.6s linear;
}
body.auto-hide-header .workspace-tab-header-container + .workspace-tab-container .workspace-leaf .workspace-leaf-content>.view-header {
margin-top: -40px;
transition: all 0.6s linear;
}

View File

@ -0,0 +1,68 @@
{
"commitMessage": "vault backup: {{date}}",
"autoCommitMessage": "vault backup: {{date}}",
"commitMessageScript": "",
"commitDateFormat": "YYYY-MM-DD HH:mm:ss",
"autoSaveInterval": 0,
"autoPushInterval": 0,
"autoPullInterval": 0,
"autoPullOnBoot": false,
"autoCommitOnlyStaged": false,
"disablePush": false,
"pullBeforePush": true,
"disablePopups": false,
"showErrorNotices": true,
"disablePopupsForNoChanges": false,
"listChangedFilesInMessageBody": false,
"showStatusBar": true,
"updateSubmodules": false,
"syncMethod": "merge",
"mergeStrategy": "none",
"customMessageOnAutoBackup": false,
"autoBackupAfterFileChange": false,
"treeStructure": false,
"refreshSourceControl": true,
"basePath": "",
"differentIntervalCommitAndPush": false,
"changedFilesInStatusBar": false,
"showedMobileNotice": true,
"refreshSourceControlTimer": 7000,
"showBranchStatusBar": true,
"setLastSaveToLastCommit": false,
"submoduleRecurseCheckout": false,
"gitDir": "",
"showFileMenu": true,
"authorInHistoryView": "full",
"dateInHistoryView": true,
"diffStyle": "split",
"hunks": {
"showSigns": false,
"hunkCommands": false,
"statusBar": "disabled"
},
"lineAuthor": {
"show": false,
"followMovement": "inactive",
"authorDisplay": "initials",
"showCommitHash": false,
"dateTimeFormatOptions": "date",
"dateTimeFormatCustomString": "YYYY-MM-DD HH:mm",
"dateTimeTimezone": "viewer-local",
"coloringMaxAge": "1y",
"colorNew": {
"r": 255,
"g": 150,
"b": 150
},
"colorOld": {
"r": 120,
"g": 160,
"b": 255
},
"textColorCss": "var(--text-muted)",
"ignoreWhitespace": false,
"gutterSpacingFallbackLength": 5,
"lastShownAuthorDisplay": "initials",
"lastShownDateTimeFormatOptions": "date"
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
{
"author": "Vinzent",
"authorUrl": "https://github.com/Vinzent03",
"id": "obsidian-git",
"name": "Git",
"description": "Integrate Git version control with automatic backup and other advanced features.",
"isDesktopOnly": false,
"fundingUrl": "https://ko-fi.com/vinzent",
"version": "2.37.1"
}

View File

@ -0,0 +1,23 @@
#!/bin/sh
PROMPT="$1"
TEMP_FILE="$OBSIDIAN_GIT_CREDENTIALS_INPUT"
cleanup() {
rm -f "$TEMP_FILE" "$TEMP_FILE.response"
}
trap cleanup EXIT
echo "$PROMPT" > "$TEMP_FILE"
while [ ! -e "$TEMP_FILE.response" ]; do
if [ ! -e "$TEMP_FILE" ]; then
echo "Trigger file got removed: Abort" >&2
exit 1
fi
sleep 0.1
done
RESPONSE=$(cat "$TEMP_FILE.response")
echo "$RESPONSE"

View File

@ -0,0 +1,705 @@
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.git-signs-gutter {
.cm-gutterElement {
/* Needed to align the sign properly for different line heigts. Such as
* when having a heading or list item.
*/
padding-top: 0 !important;
}
}
.workspace-leaf-content[data-type="git-view"] .button-border {
border: 2px solid var(--interactive-accent);
border-radius: var(--radius-s);
}
.workspace-leaf-content[data-type="git-view"] .view-content {
padding-left: 0;
padding-top: 0;
padding-right: 0;
}
.workspace-leaf-content[data-type="git-history-view"] .view-content {
padding-left: 0;
padding-top: 0;
padding-right: 0;
}
.loading {
overflow: hidden;
}
.loading > svg {
animation: 2s linear infinite loading;
transform-origin: 50% 50%;
display: inline-block;
}
.obsidian-git-center {
margin: auto;
text-align: center;
width: 50%;
}
.obsidian-git-textarea {
display: block;
margin-left: auto;
margin-right: auto;
}
.obsidian-git-disabled {
opacity: 0.5;
}
.obsidian-git-center-button {
display: block;
margin: 20px auto;
}
.tooltip.mod-left {
overflow-wrap: break-word;
}
.tooltip.mod-right {
overflow-wrap: break-word;
}
/* Limits the scrollbar to the view body */
.git-view {
display: flex;
flex-direction: column;
position: relative;
height: 100%;
}
.git-tools {
display: flex;
margin-left: auto;
}
.git-tools .type {
padding-left: var(--size-2-1);
display: flex;
align-items: center;
justify-content: center;
width: 11px;
}
.git-tools .type[data-type="M"] {
color: orange;
}
.git-tools .type[data-type="D"] {
color: red;
}
.git-tools .buttons {
display: flex;
}
.git-tools .buttons > * {
padding: 0 0;
height: auto;
}
.workspace-leaf-content[data-type="git-view"] .tree-item-self,
.workspace-leaf-content[data-type="git-history-view"] .tree-item-self {
align-items: center;
}
.workspace-leaf-content[data-type="git-view"]
.tree-item-self:hover
.clickable-icon,
.workspace-leaf-content[data-type="git-history-view"]
.tree-item-self:hover
.clickable-icon {
color: var(--icon-color-hover);
}
/* Highlight an item as active if it's diff is currently opened */
.is-active .git-tools .buttons > * {
color: var(--nav-item-color-active);
}
.git-author {
color: var(--text-accent);
}
.git-date {
color: var(--text-accent);
}
.git-ref {
color: var(--text-accent);
}
/* ====== diff2html ======
The following styles are adapted from the obsidian-version-history plugin by
@kometenstaub https://github.com/kometenstaub/obsidian-version-history-diff/blob/main/src/styles.scss
which itself is adapted from the diff2html library with the following original license:
https://github.com/rtfpessoa/diff2html/blob/master/LICENSE.md
Copyright 2014-2016 Rodrigo Fernandes https://rtfpessoa.github.io/
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.
*/
.theme-dark,
.theme-light {
--git-delete-bg: #ff475040;
--git-delete-hl: #96050a75;
--git-insert-bg: #68d36840;
--git-insert-hl: #23c02350;
--git-change-bg: #ffd55840;
--git-selected: #3572b0;
--git-delete: #c33;
--git-insert: #399839;
--git-change: #d0b44c;
--git-move: #3572b0;
}
.git-diff {
.d2h-d-none {
display: none;
}
.d2h-wrapper {
text-align: left;
border-radius: 0.25em;
overflow: auto;
}
.d2h-file-header.d2h-file-header {
background-color: var(--background-secondary);
border-bottom: 1px solid var(--background-modifier-border);
font-family:
Source Sans Pro,
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
height: 35px;
padding: 5px 10px;
}
.d2h-file-header,
.d2h-file-stats {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.d2h-file-header {
display: none;
}
.d2h-file-stats {
font-size: 14px;
margin-left: auto;
}
.d2h-lines-added {
border: 1px solid var(--color-green);
border-radius: 5px 0 0 5px;
color: var(--color-green);
padding: 2px;
text-align: right;
vertical-align: middle;
}
.d2h-lines-deleted {
border: 1px solid var(--color-red);
border-radius: 0 5px 5px 0;
color: var(--color-red);
margin-left: 1px;
padding: 2px;
text-align: left;
vertical-align: middle;
}
.d2h-file-name-wrapper {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 15px;
width: 100%;
}
.d2h-file-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--text-normal);
font-size: var(--h5-size);
}
.d2h-file-wrapper {
border: 1px solid var(--background-secondary-alt);
border-radius: 3px;
margin-bottom: 1em;
max-height: 100%;
}
.d2h-file-collapse {
-webkit-box-pack: end;
-ms-flex-pack: end;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border: 1px solid var(--background-secondary-alt);
border-radius: 3px;
cursor: pointer;
display: none;
font-size: 12px;
justify-content: flex-end;
padding: 4px 8px;
}
.d2h-file-collapse.d2h-selected {
background-color: var(--git-selected);
}
.d2h-file-collapse-input {
margin: 0 4px 0 0;
}
.d2h-diff-table {
border-collapse: collapse;
font-family: var(--font-monospace);
font-size: var(--code-size);
width: 100%;
}
.d2h-files-diff {
width: 100%;
}
.d2h-file-diff {
/*
overflow-y: scroll;
*/
border-radius: 5px;
font-size: var(--font-text-size);
line-height: var(--line-height-normal);
}
.d2h-file-side-diff {
display: inline-block;
margin-bottom: -8px;
margin-right: -4px;
overflow-x: scroll;
overflow-y: hidden;
width: 50%;
}
.d2h-code-line {
padding-left: 6em;
padding-right: 1.5em;
}
.d2h-code-line,
.d2h-code-side-line {
display: inline-block;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
width: 100%;
}
.d2h-code-side-line {
/* needed to be changed */
padding-left: 0.5em;
padding-right: 0.5em;
}
.d2h-code-line-ctn {
word-wrap: normal;
background: none;
display: inline-block;
padding: 0;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
vertical-align: middle;
width: 100%;
/* only works for line-by-line */
white-space: pre-wrap;
}
.d2h-code-line del,
.d2h-code-side-line del {
background-color: var(--git-delete-hl);
color: var(--text-normal);
}
.d2h-code-line del,
.d2h-code-line ins,
.d2h-code-side-line del,
.d2h-code-side-line ins {
border-radius: 0.2em;
display: inline-block;
margin-top: -1px;
text-decoration: none;
vertical-align: middle;
}
.d2h-code-line ins,
.d2h-code-side-line ins {
background-color: var(--git-insert-hl);
text-align: left;
}
.d2h-code-line-prefix {
word-wrap: normal;
background: none;
display: inline;
padding: 0;
white-space: pre;
}
.line-num1 {
float: left;
}
.line-num1,
.line-num2 {
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
/*
padding: 0 0.5em;
*/
text-overflow: ellipsis;
width: 2.5em;
padding-left: 0;
}
.line-num2 {
float: right;
}
.d2h-code-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-faint);
cursor: pointer;
display: inline-block;
position: absolute;
text-align: right;
width: 5.5em;
}
.d2h-code-linenumber:after {
content: "\200b";
}
.d2h-code-side-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-faint);
cursor: pointer;
overflow: hidden;
padding: 0 0.5em;
text-align: right;
text-overflow: ellipsis;
width: 4em;
/* needed to be changed */
display: table-cell;
position: relative;
}
.d2h-code-side-linenumber:after {
content: "\200b";
}
.d2h-code-side-emptyplaceholder,
.d2h-emptyplaceholder {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
}
.d2h-code-line-prefix,
.d2h-code-linenumber,
.d2h-code-side-linenumber,
.d2h-emptyplaceholder {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.d2h-code-linenumber,
.d2h-code-side-linenumber {
direction: rtl;
}
.d2h-del {
background-color: var(--git-delete-bg);
border-color: var(--git-delete-hl);
}
.d2h-ins {
background-color: var(--git-insert-bg);
border-color: var(--git-insert-hl);
}
.d2h-info {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
color: var(--text-faint);
}
.d2h-del,
.d2h-ins,
.d2h-file-diff .d2h-change {
color: var(--text-normal);
}
.d2h-file-diff .d2h-del.d2h-change {
background-color: var(--git-change-bg);
}
.d2h-file-diff .d2h-ins.d2h-change {
background-color: var(--git-insert-bg);
}
.d2h-file-list-wrapper {
a {
text-decoration: none;
cursor: default;
-webkit-user-drag: none;
}
svg {
display: none;
}
}
.d2h-file-list-header {
text-align: left;
}
.d2h-file-list-title {
display: none;
}
.d2h-file-list-line {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
text-align: left;
}
.d2h-file-list {
}
.d2h-file-list > li {
border-bottom: 1px solid var(--background-modifier-border);
margin: 0;
padding: 5px 10px;
}
.d2h-file-list > li:last-child {
border-bottom: none;
}
.d2h-file-switch {
cursor: pointer;
display: none;
font-size: 10px;
}
.d2h-icon {
fill: currentColor;
margin-right: 10px;
vertical-align: middle;
}
.d2h-deleted {
color: var(--git-delete);
}
.d2h-added {
color: var(--git-insert);
}
.d2h-changed {
color: var(--git-change);
}
.d2h-moved {
color: var(--git-move);
}
.d2h-tag {
background-color: var(--background-secondary);
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 10px;
margin-left: 5px;
padding: 0 2px;
}
.d2h-deleted-tag {
border: 1px solid var(--git-delete);
}
.d2h-added-tag {
border: 1px solid var(--git-insert);
}
.d2h-changed-tag {
border: 1px solid var(--git-change);
}
.d2h-moved-tag {
border: 1px solid var(--git-move);
}
/* needed for line-by-line*/
.d2h-diff-tbody {
position: relative;
}
}
/* ====================== Line Authoring Information ====================== */
.cm-gutterElement.obs-git-blame-gutter {
/* Add background color to spacing inbetween and around the gutter for better aesthetics */
border-width: 0px 2px 0.2px 2px;
border-style: solid;
border-color: var(--background-secondary);
background-color: var(--background-secondary);
}
.cm-gutterElement.obs-git-blame-gutter > div,
.line-author-settings-preview {
/* delegate text color to settings */
color: var(--obs-git-gutter-text);
font-family: monospace;
height: 100%; /* ensure, that age-based background color occupies entire parent */
text-align: right;
padding: 0px 6px 0px 6px;
white-space: pre; /* Keep spaces and do not collapse them. */
}
@media (max-width: 800px) {
/* hide git blame gutter not to superpose text */
.cm-gutterElement.obs-git-blame-gutter {
display: none;
}
}
.git-unified-diff-view,
.git-split-diff-view .cm-deletedLine .cm-changedText {
background-color: #ee443330;
}
.git-unified-diff-view,
.git-split-diff-view .cm-insertedLine .cm-changedText {
background-color: #22bb2230;
}
.git-obscure-prompt[git-is-obscured="true"] #git-show-password:after {
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"></path><circle cx="12" cy="12" r="3"></circle></svg>');
}
.git-obscure-prompt[git-is-obscured="false"] #git-show-password:after {
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye-off"><path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"></path><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"></path><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"></path><path d="m2 2 20 20"></path></svg>');
}
/* Override styling of Codemirror merge view "collapsed lines" indicator */
.git-split-diff-view .ͼ2 .cm-collapsedLines {
background: var(--interactive-normal);
border-radius: var(--radius-m);
color: var(--text-accent);
font-size: var(--font-small);
padding: var(--size-4-1) var(--size-4-1);
}
.git-split-diff-view .ͼ2 .cm-collapsedLines:hover {
background: var(--interactive-hover);
color: var(--text-accent-hover);
}
.git-signs-gutter {
.cm-gutterElement {
display: grid;
}
}
.git-gutter-marker:hover {
border-radius: 2px;
}
.git-gutter-marker.git-add {
background-color: var(--color-green);
justify-self: center;
height: inherit;
width: 0.2rem;
}
.git-gutter-marker.git-change {
background-color: var(--color-yellow);
justify-self: center;
height: inherit;
width: 0.2rem;
}
.git-gutter-marker.git-changedelete {
color: var(--color-yellow);
font-weight: var(--font-bold);
font-size: 1rem;
justify-self: center;
height: inherit;
}
.git-gutter-marker.git-delete {
background-color: var(--color-red);
height: 0.2rem;
width: 0.8rem;
align-self: end;
}
.git-gutter-marker.git-topdelete {
background-color: var(--color-red);
height: 0.2rem;
width: 0.8rem;
align-self: start;
}
div:hover > .git-gutter-marker.git-change {
width: 0.6rem;
}
div:hover > .git-gutter-marker.git-add {
width: 0.6rem;
}
div:hover > .git-gutter-marker.git-delete {
height: 0.6rem;
}
div:hover > .git-gutter-marker.git-topdelete {
height: 0.6rem;
}
div:hover > .git-gutter-marker.git-changedelete {
font-weight: var(--font-bold);
}
.git-gutter-marker.staged {
opacity: 0.5;
}
.git-diff {
.cm-merge-revert {
width: 4em;
}
/* Ensure that merge revert markers are positioned correctly */
.cm-merge-revert > * {
position: absolute;
background-color: var(--background-secondary);
display: flex;
}
}
/* Prevent shifting of the editor when git signs gutter is the only gutter present */
.cm-gutters.cm-gutters-before:has(> .git-signs-gutter:only-child) {
margin-inline-end: 0;
.git-signs-gutter {
margin-inline-start: -1rem;
}
}
.git-changes-status-bar-colored {
.git-add {
color: var(--color-green);
}
.git-change {
color: var(--color-yellow);
}
.git-delete {
color: var(--color-red);
}
}
.git-changes-status-bar .git-add {
margin-right: 0.3em;
}
.git-changes-status-bar .git-change {
margin-right: 0.3em;
}

View File

@ -0,0 +1,134 @@
{
"remoteType": "",
"useCustomRequestHandler": false,
"couchDB_URI": "",
"couchDB_USER": "",
"couchDB_PASSWORD": "",
"couchDB_DBNAME": "",
"liveSync": true,
"syncOnSave": false,
"syncOnStart": false,
"savingDelay": 200,
"lessInformationInLog": false,
"gcDelay": 0,
"versionUpFlash": "",
"minimumChunkSize": 20,
"longLineThreshold": 250,
"showVerboseLog": false,
"suspendFileWatching": false,
"trashInsteadDelete": true,
"periodicReplication": false,
"periodicReplicationInterval": 60,
"syncOnFileOpen": false,
"encrypt": false,
"passphrase": "",
"usePathObfuscation": false,
"doNotDeleteFolder": false,
"resolveConflictsByNewerFile": false,
"batchSave": false,
"batchSaveMinimumDelay": 5,
"batchSaveMaximumDelay": 60,
"deviceAndVaultName": "",
"usePluginSettings": false,
"showOwnPlugins": false,
"showStatusOnEditor": true,
"showStatusOnStatusbar": true,
"showOnlyIconsOnEditor": false,
"usePluginSync": false,
"autoSweepPlugins": false,
"autoSweepPluginsPeriodic": false,
"notifyPluginOrSettingUpdated": false,
"checkIntegrityOnSave": false,
"batch_size": 25,
"batches_limit": 25,
"useHistory": true,
"disableRequestURI": true,
"skipOlderFilesOnSync": true,
"checkConflictOnlyOnOpen": false,
"showMergeDialogOnlyOnActive": false,
"syncInternalFiles": false,
"syncInternalFilesBeforeReplication": false,
"syncInternalFilesIgnorePatterns": "\\/node_modules\\/, \\/\\.git\\/, \\/obsidian-livesync\\/",
"syncInternalFilesInterval": 60,
"additionalSuffixOfDatabaseName": "a381e9b5ea3f0dc1",
"ignoreVersionCheck": false,
"lastReadUpdates": 0,
"deleteMetadataOfDeletedFiles": false,
"syncIgnoreRegEx": "",
"syncOnlyRegEx": "",
"customChunkSize": 0,
"readChunksOnline": true,
"watchInternalFileChanges": true,
"automaticallyDeleteMetadataOfDeletedFiles": 0,
"disableMarkdownAutoMerge": false,
"writeDocumentsIfConflicted": false,
"useDynamicIterationCount": false,
"syncAfterMerge": false,
"configPassphraseStore": "",
"encryptedPassphrase": "",
"encryptedCouchDBConnection": "%d0bdc261736e79135fdbbde9020000008c82f98c712661655345d2c031c29caccfi4G20HgIYeV1TNk0D+91h8w1ZxwQVy59j7quZzGrf8+bxm7dqczR4s4Phk29p00flkRpxE4ZYWxEEJDbuSYDx6czoL9liSyEWeuw5N/b5NBzvmSi55r/ywMq+yhBw295sTC0FZYd2LJg2Toe8KwzLfEbbmlcBW5s/Zac4WuFFNO4JdR/rWvDhE073JFxNzwesRTycUXc0vStXooWl6Xk4/PH07vTrswVmdp0wLbYGd3M33ZtTeXfMGz/l+2/FroOnoW/WDqascCtYDBVaqxUYyWQDbrpr+nFtFyX9aP/pcW/i7c7uFYuYdpUyzP1Ma+hoa4qYTs0Q=",
"permitEmptyPassphrase": false,
"useIndexedDBAdapter": true,
"useTimeouts": false,
"writeLogToTheFile": false,
"doNotPaceReplication": false,
"hashCacheMaxCount": 300,
"hashCacheMaxAmount": 50,
"concurrencyOfReadChunksOnline": 40,
"minimumIntervalOfReadChunksOnline": 50,
"hashAlg": "xxhash64",
"suspendParseReplicationResult": false,
"doNotSuspendOnFetching": false,
"useIgnoreFiles": false,
"ignoreFiles": ".gitignore",
"syncOnEditorSave": false,
"pluginSyncExtendedSetting": {},
"syncMaxSizeInMB": 50,
"settingSyncFile": "",
"writeCredentialsForSettingSync": false,
"notifyAllSettingSyncFile": false,
"isConfigured": true,
"settingVersion": 10,
"enableCompression": false,
"accessKey": "",
"bucket": "",
"endpoint": "",
"region": "",
"secretKey": "",
"useEden": false,
"maxChunksInEden": 10,
"maxTotalLengthInEden": 1024,
"maxAgeInEden": 10,
"disableCheckingConfigMismatch": false,
"displayLanguage": "",
"enableChunkSplitterV2": false,
"disableWorkerForGeneratingChunks": false,
"processSmallFilesInUIThread": false,
"notifyThresholdOfRemoteStorageSize": 0,
"usePluginSyncV2": false,
"usePluginEtc": false,
"doNotUseFixedRevisionForChunks": true,
"showLongerLogInsideEditor": false,
"sendChunksBulk": false,
"sendChunksBulkMaxSize": 1,
"useSegmenter": false,
"useAdvancedMode": false,
"usePowerUserMode": false,
"useEdgeCaseMode": false,
"enableDebugTools": false,
"suppressNotifyHiddenFilesChange": false,
"syncMinimumInterval": 2000,
"P2P_Enabled": false,
"P2P_AutoAccepting": 0,
"P2P_AppID": "self-hosted-livesync",
"P2P_roomID": "",
"P2P_passphrase": "",
"P2P_relays": "wss://exp-relay.vrtmrz.net/",
"P2P_AutoBroadcast": false,
"P2P_AutoStart": false,
"P2P_AutoSyncPeers": "",
"P2P_AutoWatchPeers": "",
"P2P_SyncOnReplication": "",
"P2P_RebuildFrom": "",
"doctorProcessedVersion": "0.24.16"
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
{
"id": "obsidian-livesync",
"name": "Self-hosted LiveSync",
"version": "0.24.18",
"minAppVersion": "0.9.12",
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
"author": "vorotamoroz",
"authorUrl": "https://github.com/vrtmrz",
"isDesktopOnly": false
}

View File

@ -0,0 +1,439 @@
.added {
color: var(--text-on-accent);
background-color: var(--text-accent);
}
.normal {
color: var(--text-normal);
}
.deleted {
color: var(--text-on-accent);
background-color: var(--text-muted);
}
.op-scrollable {
overflow-y: scroll;
/* min-height: 280px; */
max-height: 280px;
user-select: text;
-webkit-user-select: text;
}
.op-pre {
white-space: pre-wrap;
}
.op-warn {
border: 1px solid salmon;
padding: 2px;
border-radius: 4px;
}
.op-warn::before {
content: "Warning";
font-weight: bold;
color: salmon;
position: relative;
display: block;
}
.op-warn-info {
border: 1px solid rgb(255, 209, 81);
padding: 2px;
border-radius: 4px;
}
.op-warn-info::before {
content: "Notice";
font-weight: bold;
color: rgb(255, 209, 81);
position: relative;
display: block;
}
.syncstatusbar {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
.tcenter {
text-align: center;
}
.sls-plugins-wrap {
display: flex;
flex-grow: 1;
max-height: 50vh;
overflow-y: scroll;
}
.sls-plugins-tbl {
border: 1px solid var(--background-modifier-border);
width: 100%;
max-height: 80%;
}
.divider th {
border-top: 1px solid var(--background-modifier-border);
}
.sls-header-button {
margin-left: 2em;
}
.sls-hidden {
display: none;
}
:root {
--sls-log-text: "";
}
.sls-troubleshoot-preview {
max-width: max-content;
}
.sls-troubleshoot-preview img {
max-width: 100%;
}
.sls-setting-tab {
display: none;
}
div.sls-setting-menu-btn {
color: var(--text-normal);
background-color: var(--background-secondary-alt);
border-radius: 4px 4px 0 0;
padding: 6px 10px;
cursor: pointer;
margin-right: 12px;
font-family: "Inter", sans-serif;
outline: none;
user-select: none;
flex-grow: 1;
text-align: center;
flex-shrink: 1;
}
.sls-setting-label.selected {
/* order: 1; */
flex-grow: 1;
/* width: 100%; */
}
.sls-setting-tab:hover~div.sls-setting-menu-btn,
.sls-setting-label.selected .sls-setting-tab:checked~div.sls-setting-menu-btn {
background-color: var(--interactive-accent);
color: var(--text-on-accent);
}
.sls-setting-menu-wrapper {
display: flex;
flex-direction: column;
flex-grow: 1;
position: sticky;
top: 0;
background-color: rgba(var(--background-primary), 0.3);
backdrop-filter: blur(4px);
border-radius: 4px;
z-index: 10;
}
.sls-setting-menu {
display: flex;
flex-direction: row;
overflow-x: auto;
}
body {
--sls-col-transparent: transparent;
--sls-col-warn: rgba(var(--background-modifier-error-rgb), 0.1);
--sls-col-warn-stripe1: var(--sls-col-transparent);
--sls-col-warn-stripe2: var(--sls-col-warn);
}
.sls-setting-menu-buttons {
border: 1px solid var(--sls-col-warn);
padding: 2px;
margin: 1px;
border-radius: 4px;
background-image: linear-gradient(-45deg,
var(--sls-col-warn-stripe1) 25%, var(--sls-col-warn-stripe2) 25%, var(--sls-col-warn-stripe2) 50%,
var(--sls-col-warn-stripe1) 50%, var(--sls-col-warn-stripe1) 75%, var(--sls-col-warn-stripe2) 75%, var(--sls-col-warn-stripe2));
background-size: 30px 30px;
display: flex;
flex-direction: row;
justify-content: flex-end;
padding: 0.5em 0.25em;
justify-content: center;
align-items: center;
/* transition: background-position 1s; */
animation: sls-scroll-warn 1s linear 0s infinite;
}
@keyframes sls-scroll-warn {
0% {
background-position: 0 0;
}
100% {
background-position: 30px 0;
}
}
.sls-setting-menu-buttons label {
margin-right: auto;
flex-grow: 1;
color: var(--text-warning);
}
.sls-setting-label {
flex-grow: 1;
display: inline-flex;
justify-content: center;
}
.setting-collapsed {
display: none;
}
.sls-plugins-tbl-buttons {
text-align: right;
}
.sls-plugins-tbl-buttons button {
flex-grow: 0;
padding: 6px 10px;
}
.sls-plugins-tbl-device-head {
background-color: var(--background-secondary-alt);
color: var(--text-accent);
}
.op-flex {
display: flex;
}
.op-flex input {
display: inline-flex;
flex-grow: 1;
margin-bottom: 8px;
}
.op-info {
display: inline-flex;
flex-grow: 1;
border-bottom: 1px solid var(--background-modifier-border);
width: 100%;
margin-bottom: 4px;
padding-bottom: 4px;
}
.history-added {
color: var(--text-on-accent);
background-color: var(--text-accent);
}
.history-normal {
color: var(--text-normal);
}
.history-deleted {
color: var(--text-on-accent);
background-color: var(--text-muted);
text-decoration: line-through;
}
.ob-btn-config-fix label {
margin-right: 40px;
}
.ob-btn-config-info {
border: 1px solid salmon;
padding: 2px;
margin: 1px;
border-radius: 4px;
}
.ob-btn-config-head {
padding: 2px;
margin: 1px;
border-radius: 4px;
}
.isWizard .wizardHidden {
display: none;
}
.sls-setting:not(.isWizard) .wizardOnly {
display: none;
}
.sls-item-dirty::before {
content: "✏";
}
.sls-item-dirty-help::after {
content: " ❓";
}
.sls-item-invalid-value {
background-color: rgba(var(--background-modifier-error-rgb), 0.3) !important;
}
.sls-setting-disabled input[type=text],
.sls-setting-disabled input[type=number],
.sls-setting-disabled input[type=password] {
filter: brightness(80%);
color: var(--text-muted);
}
.sls-setting-hidden {
display: none;
}
.sls-setting-obsolete {
background-image: linear-gradient(-45deg,
var(--sls-col-warn-stripe1) 25%, var(--sls-col-warn-stripe2) 25%, var(--sls-col-warn-stripe2) 50%,
var(--sls-col-warn-stripe1) 50%, var(--sls-col-warn-stripe1) 75%, var(--sls-col-warn-stripe2) 75%, var(--sls-col-warn-stripe2));
background-image: linear-gradient(-45deg,
transparent 25%, rgba(var(--background-secondary), 0.1) 25%, rgba(var(--background-secondary), 0.1) 50%, transparent 50%, transparent 75%, rgba(var(--background-secondary), 0.1) 75%, rgba(var(--background-secondary), 0.1));
background-size: 60px 60px;
}
.password-input>.setting-item-control>input {
-webkit-text-security: disc;
}
span.ls-mark-cr::after {
user-select: none;
content: "↲";
color: var(--text-muted);
font-size: 0.8em;
}
.deleted span.ls-mark-cr::after {
color: var(--text-on-accent);
}
.ls-imgdiff-wrap {
display: flex;
justify-content: center;
align-items: center;
}
.ls-imgdiff-wrap .overlay {
position: relative;
}
.ls-imgdiff-wrap .overlay .img-base {
position: relative;
top: 0;
left: 0;
}
.ls-imgdiff-wrap .overlay .img-overlay {
-webkit-filter: invert(100%) opacity(50%);
filter: invert(100%) opacity(50%);
position: absolute;
top: 0;
left: 0;
animation: ls-blink-diff 0.5s cubic-bezier(0.4, 0, 1, 1) infinite alternate;
}
@keyframes ls-blink-diff {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.livesync-status {
user-select: none;
pointer-events: none;
height: auto;
min-height: 1em;
position: absolute;
background-color: transparent;
width: 100%;
padding: 10px;
padding-right: 16px;
top: var(--header-height);
z-index: calc(var(--layer-cover) + 1);
font-variant-numeric: tabular-nums;
tab-size: 4;
text-align: right;
white-space: pre-wrap;
display: inline-block;
color: var(--text-normal);
font-size: 80%;
}
.livesync-status div {
opacity: 0.6;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
.livesync-status .livesync-status-loghistory {
text-align: left;
opacity: 0.4;
}
.livesync-status div.livesync-status-messagearea {
opacity: 0.6;
color: var(--text-on-accent);
background: var(--background-modifier-error);
-webkit-filter: unset;
filter: unset;
}
.menu-setting-poweruser-disabled .sls-setting-poweruser {
display: none;
}
.menu-setting-advanced-disabled .sls-setting-advanced {
display: none;
}
.menu-setting-edgecase-disabled .sls-setting-edgecase {
display: none;
}
.sls-setting-panel-title {
position: sticky;
}
.sls-setting-panel-title {
top: 2em;
background-color: rgba(var(--background-primary), 0.3);
backdrop-filter: blur(4px);
border-radius: 30%;
}
.sls-dialogue-note-wrapper {
display: flex;
justify-content: flex-end;
align-items: center;
}
.sls-dialogue-note-countdown {
font-size: 0.8em;
}

View File

@ -0,0 +1,8 @@
{
"name": "Minimal",
"version": "7.7.18",
"minAppVersion": "1.6.1",
"author": "@kepano",
"authorUrl": "https://twitter.com/kepano",
"fundingUrl": "https://www.buymeacoffee.com/kepano"
}

File diff suppressed because one or more lines are too long

231
Knowledges/.obsidian/workspace.json vendored Normal file
View File

@ -0,0 +1,231 @@
{
"main": {
"id": "ca9084539d3057c8",
"type": "split",
"children": [
{
"id": "bdefc74df0a6f3aa",
"type": "tabs",
"children": [
{
"id": "898cd11a388619b8",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "IT/Алгоритмы/Алгоритм Диффи — Хеллмана (DiffieHellman).md",
"mode": "source",
"source": false
},
"icon": "lucide-file",
"title": "Алгоритм Диффи — Хеллмана (DiffieHellman)"
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "e46d33cc1e1f788c",
"type": "split",
"children": [
{
"id": "b19195bb2f6c722b",
"type": "tabs",
"children": [
{
"id": "b95025b8278ca4e8",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical",
"autoReveal": false
},
"icon": "lucide-folder-closed",
"title": "Files"
}
},
{
"id": "d558f7b68df9aec7",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
},
"icon": "lucide-search",
"title": "Search"
}
},
{
"id": "54a22a44c3a03988",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {},
"icon": "lucide-bookmark",
"title": "Bookmarks"
}
}
]
}
],
"direction": "horizontal",
"width": 440.5
},
"right": {
"id": "44a01af629a7fdfc",
"type": "split",
"children": [
{
"id": "4dac830b54c8aa6f",
"type": "tabs",
"children": [
{
"id": "b56d7c6abf7fd065",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "IT/Алгоритмы/Алгоритм Диффи — Хеллмана (DiffieHellman).md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": false
},
"icon": "links-coming-in",
"title": "Backlinks for Алгоритм Диффи — Хеллмана (DiffieHellman)"
}
},
{
"id": "7f6489c394a8e4b1",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "IT/Алгоритмы/Алгоритм Диффи — Хеллмана (DiffieHellman).md",
"linksCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-going-out",
"title": "Outgoing links from Алгоритм Диффи — Хеллмана (DiffieHellman)"
}
},
{
"id": "b9d3f2689d1fda87",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-tags",
"title": "Tags"
}
},
{
"id": "d7e40b6533b3df38",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "IT/Алгоритмы/Алгоритм Диффи — Хеллмана (DiffieHellman).md",
"followCursor": false,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-list",
"title": "Outline of Алгоритм Диффи — Хеллмана (DiffieHellman)"
}
},
{
"id": "80747ccaab27e735",
"type": "leaf",
"state": {
"type": "git-view",
"state": {},
"icon": "git-pull-request",
"title": "Source Control"
}
}
],
"currentTab": 4
}
],
"direction": "horizontal",
"width": 300
},
"left-ribbon": {
"hiddenItems": {
"bases:Create new base": false,
"switcher:Open quick switcher": false,
"graph:Open graph view": false,
"canvas:Create new canvas": false,
"daily-notes:Open today's daily note": false,
"templates:Insert template": false,
"command-palette:Open command palette": false,
"obsidian-git:Open Git source control": false
}
},
"active": "898cd11a388619b8",
"lastOpenFiles": [
"Untitled.base",
"IT/Алгоритмы/Сортировки/Сортировка слиянием (Merge Sort).md",
"Туториалы/Wireguard.md",
"IT/Рефакторинг/Запахи кода/Теоретическая общность.md",
"IT/Рефакторинг/Запахи кода/Таинственное имя.md",
"IT/Рефакторинг/Запахи кода/Повторяющиеся switch.md",
"IT/Рефакторинг/Запахи кода/Расходящиеся изменения.md",
"IT/Рефакторинг/Запахи кода/Параллельные иерархии наследования.md",
"IT/Рефакторинг/Запахи кода/Неуместная близость.md",
"IT/Рефакторинг/Запахи кода/Временное поле.md",
"IT/Принципы/Принцип подстановки Лисков.md",
"IT/Принципы/Принцип открытости-закрытости.md",
"IT/Паттерны/Посетитель.md",
"IT/Паттерны/Заместитель.md",
"IT/Паттерны/Декоратор.md",
"IT/Парадигмы/ООП/Инкапсуляция.md",
"IT/Алгоритмы/Сортировки/Сортировка вставками (Insertion sort).md",
"IT/Алгоритмы/Сортировки/Быстрая сортировка (Quick sort).md",
"_assets/img/Insertion-sort-example-300px.gif",
"_assets/img/Pasted image 20250715055941.png",
"_assets/img/Merge-sort-example-300px.gif",
"IT/Алгоритмы/Сортировки/Сортировка выбором (Selection sort).md",
"Pasted image 20250715061642.png",
"IT/Книги/Стивен Скиена - Алгоритмы. Руководство по разработке.md",
"IT/Книги/Список книг.md",
"IT/Книги/Мартин Фаулер - Рефакторинг кода на JavaScript.md",
"IT/Книги/Адитья Бхаргава - Грокаем Алгоритмы.md",
"IT/Алгоритмы/Фильтры Блума (Bloom filter).md",
"IT/Untitled.md",
"IT/Рефакторинг/Методы рефакторинга/Удаление посредника.md",
"_assets/img/Pasted image 20250220082420.png",
"_assets/img/Pasted image 20250220083403.png",
"_assets/img/Pasted image 20250219082742.png",
"Untitled",
"_assets/img/Pasted image 20250219090442.png",
"_assets/img/Pasted image 20250219085909.png",
"_assets/img/Pasted image 20250219085538.png",
"Туториалы/Untitled",
"Туториалы",
"IT/Алгоритмы/Сортировки",
"_assets/gif",
"IT/Алгоритмы/Поиск",
"IT/Алгоритмы/Эффективность алгоритмов",
"IT/Парадигмы/ООП",
"IT/Парадигмы"
]
}

View File

@ -0,0 +1 @@
ssf

BIN
Knowledges/IT/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,9 @@
#алгоритмы #todo
> HyperLogLog аппроксимирует количество уникальных элементов в множе-
стве. Как и фильтры Блума, он не дает точного ответа, но выдает достаточно
близкий результат с использованием малой части памяти, которую обычно
занимает такая задача.
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,48 @@
#todo
![[Pasted image 20250124095546.png]]
> Задача является NP-полной, если она одновременно является NP-задачей и NP-трудной задачей.
## Задачи разрешимости
Задача разрешимости подразумевает ответ «да» или «нет»
## Задачи выполнимости (SAT, Satisfiability Problem)
Задача SAT всегда ищет ответ «да» или «нет», поэтому это задача разрешимости.
Характеризуется временем выполнения $O(2^n)$.
## Классы задач P и NP
Решения задачи SAT быстро проверяются, поэтому она относится к классу NP. В класс NP входят задачи, решения которых могут быть проверены за полиномиальное время. NP-задачи могут быть простыми или трудными в решении, но их решения легко проверить. Этим они отличаются от класса P.
![[Pasted image 20250124100003.png]]
Задача относится к классу P, если ее можно решить и проверить за полиномиальное время.
![[Pasted image 20250124100009.png]]
![[Pasted image 20250124100108.png]]
## Сведе́ние
Задача, которую вы не умеете решать, сводится к задаче, которую вы решать умеете
![[Pasted image 20250124100222.png]]
## NP-трудность
типы NP-трудных задач:
- задача о покрытии множества
- задача о коммивояжере
- задача SAT
Задача называется NP-трудной, если какая-либо задача из класса NP может быть сведена к этой задаче.
Все NP-задачи также могут быть сведены к любой NP-трудной задаче. Например, все задачи NP можно свести к SAT
![[Pasted image 20250124100407.png]]
## NP-полнота
![[Pasted image 20250124100520.png]]
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,35 @@
#алгоритмы
> Если вы пытаетесь выполнить классификацию чего-либо, сначала попробуйте применить алгоритм k ближайших соседей
![[Pasted image 20250123090038.png]]
Среди соседей больше апельсинов, чем грейпфрутов. Следовательно, этот
фрукт, скорее всего, является апельсином.
![[Pasted image 20250123090113.png]]
Например, расстояние между A и B вычисляется так: $\sqrt{((x_1-x_2)^2 + (y_1-y_2)^2)}$
![[Pasted image 20250123090408.png]]
Вместо вычисления расстояния в двух измерениях можно вычислить расстояние в пяти измерениях. Формула расстояния остается неизменной.
![[Pasted image 20250123090549.png]]
Метрика расстояния с пятью числами сообщает, насколько близки между собой эти наборы.
У алгоритма k-ближайших соседей есть два основных применения
- классификация - распределение по категориям;
- регреcсия - прогнозирование ответа (в числовом выражении).
«Извлечением признаков» называется преобразование элемента (например, фрукта или пользователя) в список чисел, которые могут использоваться для сравнения.
Качественный выбор признаков — важная часть успешного алгоритма k ближайших соседей.
![[Pasted image 20250123091457.png]]
Применение
- Машинное обучение (рекомендации, распознавание текста, прогнозирование)
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,10 @@
#алгоритмы #todo
1) Генерируем собственные закрытые ключи
2) Генерируется общий открытый шаблон
3) Шаблон совмещается с закрытыми ключами. В результате мы получаем открытые ключи
4) Получав открытый ключ партнера, нужно совместить его со своим закрытым ключом
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,7 @@
#алгоритмы #todo
> Если вы найдете самый большой участок, подходящий для этого размера, это
будет самый большой участок, подходящий для всей фермы.
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,87 @@
#алгоритмы
> Метод динамического программирования начинает с малых задач, а затем переходит к большой задаче. Вы решаете подзадачи, которые помогут в решении большой задачи.
- Динамическое программирование применяется для оптимизации какой-либо характеристики при заданных ограничениях. В задаче о рюкзаке требуется максимизировать стоимость отобранных предметов с ограничениями по емкости рюкзака.
- Динамическое программирование работает только в том случае, если каждая подзадача автономна, то есть не зависит от других подзадач.
Общий вид решения
- в каждом решении из области динамического программирования строится таблица
- значения ячеек таблицы обычно соответствуют оптимизируемой характеристике
- каждая ячейка представляет подзадачу,
## Самая длинная общая подстрока
```javascript
const createMatrix = (row, col) => {
const arr = Array(row).fill(Array(col).fill(0));
return JSON.parse(JSON.stringify(arr));
}
const maxCommonSubstring = (str1, str2) => {
const matrix = createMatrix(str1.length, str2.length);
let maxSize = 0;
let endIndex = 0;
for (let i = 0; i < str1.length; i++) {
for (let j = 0; j < str2.length; j++) {
if (str1[i] !== str2[j]) {
continue
}
matrix[i][j] = (i && j) > 0 ? matrix[i - 1][j - 1] + 1 : 1;
if (matrix[i][j] >= maxSize) {
maxSize = matrix[i][j];
endIndex = j + 1;
}
}
}
return str1.slice(endIndex - maxSize, endIndex);
}
maxCommonSubstring('fish', 'hish'); // 'ish'
maxCommonSubstring('fish', 'fista'); // 'fis'
maxCommonSubstring('fish', 'fista'); // 'is'
```
## Самая длинная общая подпоследовательность
```javascript
const createMatrix = (row, col) => {
const arr = Array(row).fill(Array(col).fill(0));
return JSON.parse(JSON.stringify(arr));
}
const maxCommonSubsequence = (str1, str2) => {
const matrix = createMatrix(str1.length, str2.length);
for (let i = 0; i < str1.length; i++) {
for (let j = 0; j < str2.length; j++) {
if (str1[i] === str2[j]) {
matrix[i][j] = (i && j) > 0 ? matrix[i - 1][j - 1] + 1 : 1;
} else {
const left = i > 0 ? matrix[i - 1][j] : 0;
const up = j > 0 ? matrix[i][j - 1] : 0
matrix[i][j] = Math.max(left, up);
}
}
}
return matrix[str1.length - 1][str2.length - 1]
}
maxCommonSubsequence('fort', 'fosh'); // 2
maxCommonSubsequence('fish', 'fosh'); // 3
```
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,88 @@
#алгоритмы #сжатие
> Код Хаффмана — хороший пример использования бинарных деревьев. Он также лежит в основе алгоритмов сжатия текста
```
00000000: 01110100 01101001 01101100 01110100
tilt
```
В кодировке `ISO-8859-1`
|Символ | Двоичное представление | Десятичное представление |
| ----- | ---------------------- | ------------------------ |
| t | 01110100 | 116 |
| i | 01101001 | 105 |
| l | 01101100 | 108 |
Здесь в игру вступает сжатие. Для слова `tilt` не нужны все 256 возможных
букв, достаточно трех. Таким образом, для представления буквы не тре-
буется 8 бит, можно обойтись всего двумя. Можно было бы определить
собственную 2-битную кодировку для этих трех букв:
|Символ | Двоичное представление | Десятичное представление |
| ----- | ---------------------- | ------------------------ |
| t | 00 | 0 |
| i | 01 | 1 |
| l | 10 | 2 |
Хаффмана: он ищет повторяющиеся символы и использует для их представления
менее 8 бит. В результате происходит сжатие данных. Код Хаффмана генерирует дерево. Буквы помещаются только в листовых узлах. И от корня к каждому листовому узлу существует уникальный путь — это одно из свойств деревьев. Таким образом, можно гарантировать, что наложения не будет. Это свойство также гарантирует, что каждой букве соответствует только один код.
В таком случае можно записать `tilt` в новой кодировке: `00011000` (для удобства можно разделить последовательность, добавив в нее пробелы: `00 01 10 00`)
![[Pasted image 20250114092202.png]]
По этому дереву можно узнать код каждой буквы. Начиная с корневого
узла, найдите путь вниз до буквы *L*. Каждый раз, когда на этом пути выбирается левая ветвь, к коду добавляется 0, а когда выбирается правая ветвь — 1.
Когда вы доберетесь до буквы, продвижение по дереву остановится. Таким
образом, букве *L* будет соответствовать код `01`.
Дерево определяет три кода:
```
i = 00
l = 01
t = 1
```
В отличие от ISO-8859-1, в кодировке Хаффмана коды не обязательно должны иметь одинаковую длину
***
На этот раз сжатие применяется к фразе «paranoid android»
![[Pasted image 20250114092554.png]]
|Символ | Двоичное представление |
| ----- | ---------------------- |
| P | 0001 |
| O | 001 |
| A | 010 |
| R | 011 |
| D | 10 |
| I | 110 |
| N | 111 |
| '_' | 0000 |
Так как длина кода изменяется, разбить его на фрагменты невозможно, приходится перебирать цифры по одной, словно просматривая пленку с цифрами.
Длины кодов могут изменяться, поэтому декодирование должно выполняться по-другому.
Такая схема требует больших усилий по сравнению с разделением на блоки.
С другой стороны, у нее есть одно большое преимущество. Обратите вни-
мание: у букв, встречающихся чаще, коды более короткие. D встречается
в тексте три раза, поэтому ее код состоит всего из двух цифр — в отличие от
буквы I, встречающейся два раза, и буквы P, которая встречается всего один
раз. Вместо того чтобы кодировать все 4 битами, мы применяем повышен-
ное сжатие для часто используемых букв. В длинном тексте это обеспечит
большой выигрыш!
Связанные темы:
- [[Бинарное дерево (Binary tree)]]
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,7 @@
#алгоритмы #todo
> Линейная регрессия выстраивает линию из заданной группы точек, а затем использует эту линию для вычисления прогнозов. Линейная регрессия уже давно применяется в статистике, а теперь и в машинном обучении, поскольку это метод, с которого легко начинать. Линейная регрессия полезна, если значения непрерывны. Если вам нужно сделать прогноз, проще всего использовать именно линейную регрессию.
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,5 @@
#алгоритмы #todo
> Линейное программирование используется для максимизации некоторой характеристики при заданных ограничениях
В линейном программировании используется симплекс-метод.

View File

@ -0,0 +1,7 @@
#алгоритмы #todo
> При незначительном изменении строки Simhash генерирует хеш-код, который почти не отличается от исходного. Это позволяет сравнивать хеш-коды и определять, насколько похожи две строки.
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,6 @@
#алгоритмы #todo
> Чтобы алгоритм заработал быстрее, необходимо преобразовать его в форму, подходящую для параллельного выполнения сразу на всех ядрах!
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1 @@
#алгоритмы #поиск #todo

View File

@ -0,0 +1,125 @@
#алгоритмы #поиск
![[dijkstra.gif]]
> В алгоритме Дейкстры каждому сегменту присваивается число (вес), а алгоритм Дейкстры находит путь с наименьшим суммарным весом
![[Pasted image 20250116202010.png]]
Алгоритм Дейкстры работает только с графами, в которых нет циклов, где
все ребра неотрицательны
Cостоит из четырех шагов:
1. Найти узел с наименьшей стоимостью (то есть узел, до которого можно добраться за минимальное время)
2. Обновить стоимости соседей этого узла
3. Повторять, пока это не будет сделано для всех узлов графа
4. Вычислить итоговый путь
![[Pasted image 20250116203308.png]]
Для реализации понадобятся три хеш-таблицы: граф, родители, стоимости. Хеш таблицы стоимостей и родителей будут обновляться по ходу работы алгоритма.
![[Pasted image 20250116203221.png]]
Существует более эффективный вариант этого алгоритма. Он использует структуру данных, называемую очередью с приоритетом. Эта очередь строится на основе другой структуры данных — кучи.
```javascript
const findLowestCostNode = (costs, processed) => {
let lowestCost = Infinity;
let lowestCostNode = null;
Object.entries(costs).forEach(([node, cost]) => {
if (!processed.includes(node) && cost < lowestCost) {
lowestCost = cost;
lowestCostNode = node;
}
});
return lowestCostNode;
};
const dejsktra = (graph, [from, to]) => {
const costs = {
[to]: Infinity,
...graph[from],
};
const parents = {};
Object.keys(graph[from]).forEach(key => parents[key] = from);
const processed = [];
let lowestCostNode = from;
while(lowestCostNode) {
const neighbours = graph[lowestCostNode] || {};
Object.keys(neighbours).forEach(neighbour => {
let cost = costs[lowestCostNode] + neighbours[neighbour];
if (!costs[neighbour]) {
costs[neighbour] = Infinity;
}
if (cost < costs[neighbour]) {
costs[neighbour] = cost;
parents[neighbour] = lowestCostNode;
}
})
processed.push(lowestCostNode);
lowestCostNode = findLowestCostNode(costs, processed);
}
const path = [to];
let parent = parents[to];
while (parent) {
path.push(parent);
parent = parents[parent];
}
return {
value: costs[to],
path: path.reverse()
}
};
const testGraph = {
a: { b: 2, f: 6 },
b: { c: 4 },
c: { d: 8, g: 6 },
d: { h: 3 },
e: { b: 1, g: 5, },
f: { e: 1, g: 7 },
g: { d: 2, h: 4, j: 2,},
h: { j: 1 },
};
const complexGraph = {
a: { b: 4, c: 2, d: 7 },
b: { e: 3, f: 1, g: 5 },
c: { f: 4, h: 2 },
d: { h: 6, i: 3 },
e: { j: 2, k: 4 },
f: { j: 5, l: 2 },
g: { k: 3, m: 4 },
h: { l: 5, n: 2 },
i: { n: 4, o: 3 },
j: { m: 1, n: 6 },
k: { n: 2, o: 5 },
l: { o: 4 },
m: { o: 3 },
n: { o: 2 },
o: {}
};
console.log(dejsktra(testGraph, ['a', 'j'])); // { value: 14, path: [ 'a', 'b', 'c', 'g', 'j' ] }
console.log(dejsktra(complexGraph, ['a', 'o'])); // { value: 8, path: [ 'a', 'c', 'h', 'n', 'o' ] }
```
Связаные темы:
- [[Граф (Graph)]]
- [[Поиск в ширину (Breadth-first search)]]
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,46 @@
#алгоритмы #поиск
![[binary-and-linear-search-animations.gif]]
Эффективность $O(n) = \log_2(n)$
> Бинарный поиск это алгоритм на входе он получает отсортированный
список элементов. Если элемент, который вы ищете, присутствует в списке, то бинарный поиск возвращает ту позицию, в которой он был найден. В противном случае бинарный поиск возвращает null.
При бинарном поиске каждый раз исключается половина. В общем
случае для списка из `n` элементов бинарный поиск выполняется за $\log_{2}(n)$ шагов, тогда как простой поиск будет выполнен за `n` шагов.
## Пример
```javascript
const binarySearch = (list, item) => {
let startIndex = 0;
let endIndex = list.length - 1;
while (startIndex <= endIndex) {
let midIndex = Math.floor((startIndex + endIndex) / 2);
const candidate = list[midIndex];
if (candidate === item) {
console.log(`Item ${item} found at index ${midIndex}`);
return midIndex;
}
if (candidate > item) {
endIndex = midIndex - 1;
} else {
startIndex = midIndex + 1;
}
};
console.log(`Not found "${item}"`);
return null;
};
const list = [10, 20, 30, 50, 80, 100, 500];
binarySearch(list, 20); // 1
binarySearch(list, 40); // null
```
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,42 @@
>Бинарный поиск это алгоритм на входе он получает отсортированный
список элементов. Если элемент, который вы ищете, присутствует в списке, то бинарный поиск возвращает ту позицию, в которой он был найден. В противном случае бинарный поиск возвращает null.
При бинарном поиске каждый раз исключается половина. В общем
случае для списка из `n` элементов бинарный поиск выполняется за $\log_{2}(n)$ шагов, тогда как простой поиск будет выполнен за `n` шагов.
Эффективность алгоритма $O(n) = \log_2(n)$
## Пример
```javascript
const binarySearch = (list, item) => {
let startIndex = 0;
let endIndex = list.length - 1;
while (startIndex <= endIndex) {
let midIndex = Math.floor((startIndex + endIndex) / 2);
const candidate = list[midIndex];
if (candidate === item) {
console.log(`Item ${item} found at index ${midIndex}`);
return midIndex;
}
if (candidate > item) {
endIndex = midIndex - 1;
} else {
startIndex = midIndex + 1;
}
};
console.log(`Not found "${item}"`);
return null;
};
const list = [10, 20, 30, 50, 80, 100, 500];
binarySearch(list, 20); // 1
binarySearch(list, 40); // null
```
![[binary-and-linear-search-animations.gif]]

View File

@ -0,0 +1,21 @@
#алгоритмы #поиск
> Жадный алгоритм прост: на каждом шаге он выбирает оптимальный вариант. В технической терминологии: на каждом шаге выбирается локально-оптимальное решение, а в итоге вы получаете глобально-оптимальное решение.
Жадная стратегия не дает оптимального решения. Впрочем, результат не так уж далек от оптимума. В некоторых случаях достаточно алгоритма, способного решить задачу достаточно хорошо. И в таких областях жадные алгоритмы работают отлично, потому что они просто реализуются, а полученное решение обычно близко к оптимуму.
### Приближенные алгоритмы
Когда вычисление точного решения занимает слишком много времени, применяется приближенный алгоритм. Эффективность приближенного алгоритма оценивается по:
- быстроте;
- близости полученного решения к оптимальному.
Жадные алгоритмы хороши не только тем, что они обычно легко формулируются, но и тем, что простота обычно оборачивается скоростью выполнения. В данном случае жадный алгоритм выполняется за время $O(n^2)$
Жадный алгоритм не всегда даст точный ответ, но он очень быстр. Задача о покрытии множеств относится к NP-трудным задачам.
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,17 @@
#алгоритмы
![[DFS.gif]]
Поиск в глубину тоже работает с графом и представляет собой алгоритм
обхода дерева. При обнаружении папки он сразу заходит в нее, вместо того
чтобы добавлять ее в очередь.
Поиск в глубину не может использоваться для нахождения кратчайшего пути!
Он может сначала нужны элемент на третем уровне вложенности, хотя есть подходящий элемент ближе.
Связанные темы:
- [[Граф (Graph)]]
- [[Поиск в ширину (Breadth-first search)]]
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,78 @@
#алгоритмы #поиск
![[0_HN6Tr71sgf1qR70n.gif]]
Эффективность $O(n) = n$
> Поиск в ширину работает с графами, позволяет найти кратчайшее расстояние между двумя объектами. Поиск в ширину является алгоритмом обхода; это значит, что он посещает каждый узел дерева («обходит» его). Этот алгоритм находит путь с минимальным количеством сегментов.
>
> Отвечает на вопросы 2 типов:
> - существует ли путь от узла А к узлу В?
> - как выглядит кратчайший путь от узла А к узлу В?
Связи первого уровня предпочтительнее связей второго уровня, связи второго уровня предпочтительнее связей третьего уровня и т.д. Отсюда следует, что поиск по узлам второго уровня не должен производиться, пока вы не будете полностью уверены в том, что среди связей первого уровня нет ни подходящего элемента.
Также можно объяснить это иначе: связи первого уровня добавляются в [[Очередь (Queue)]] поиска раньше связей второго уровня.
### Эффективность
Если поиск искомого был выполнен по всей сети, значит, вы прошли
по каждому ребру. Таким образом, время выполнения составляет как минимум $О(количество\_ребер)$.
Также в программе должна храниться очередь поиска. Добавление одного
элемента в очередь выполняется за постоянное время: $О(1)$ . Выполнение
операции для каждого человека потребует суммарного времени $О(количество\_элементов)$.
Поиск в ширину выполняется за время $О(количество\_элементов+количество\_ребер)$, что обычно записывается в форме $O(V+E)$, где ($V$-количество вершин , $Е$ - количество ребер).
```javascript
const breadthFirstSearch = (graph, start, end) => {
const queue = graph[start];
const checked = [];
let lastLevelElement = queue[queue.length - 1];
let level = 1;
while (queue.length) {
const candidate = queue.shift();
if (candidate === end) {
return level;
}
if (checked.includes(candidate)) {
continue;
}
queue.push(...(graph[candidate] || []));
if (candidate === lastLevelElement) {
lastLevelElement = queue[queue.length - 1];
level += 1;
}
}
return -1;
}
const graph = {
a: ['b', 'c', 'd'],
b: ['e', 'f'],
d: ['e', 'g'],
c: ['j', 'k']
}
breadthFirstSearch(graph, 'a', 'g'); // 2
breadthFirstSearch(graph, 'a', 'm'); // -1
```
![[Pasted image 20250113103049.png]]
Связаные темы:
- [[Граф (Graph)]]
- [[Очередь (Queue)]]
- [[Поиск в глубину (Deep-first search)]]
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,33 @@
#алгоритмы #поиск
![[linear_search.gif]]
Эффективность: $O(n) = n$
> Последовательно проверяется каждый элемент массива
## Пример
```javascript
const simpleSearch = (list, item) => {
for (let i = 0; i <= list.length; i++) {
const candidate = list[i];
if (candidate === item) {
console.log(`Item ${item} found at index ${i}`);
return i;
}
}
console.log(`Not found "${item}"`);
return null;
};
const list = [10, 20, 30, 50, 80, 100, 500];
simpleSearch(list, 20); // 1
simpleSearch(list, 40); // null
```
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,27 @@
> Последовательно проверяется каждый элемент массива
Эффективность: $O(n) = n$
## Пример
```javascript
const simpleSearch = (list, item) => {
for (let i = 0; i <= list.length; i++) {
const candidate = list[i];
if (candidate === item) {
console.log(`Item ${item} found at index ${i}`);
return i;
}
}
console.log(`Not found "${item}"`);
return null;
};
const list = [10, 20, 30, 50, 80, 100, 500];
simpleSearch(list, 20); // 1
simpleSearch(list, 40); // null
```

View File

@ -0,0 +1,7 @@
#алгоритмы #todo
> Если у вас есть коктейль, преобразование Фурье сообщает, из каких ингредиентов он состоит. Или для заданной песни преобразование разделяет ее на отдельные частоты.
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,11 @@
#алгоритмы
![[Pasted image 20250109093218.png]]
>Решение задачи методом «разделяй и властвуй» состоит из двух шагов:
>1. Сначала определяется базовый случай. Это должен быть простейший случай из всех возможных.
>2. Задача делится или сокращается до тех пор, пока не будет сведена к базовому случаю.
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,8 @@
#алгоритмы #todo
> Распределенные алгоритмы хорошо работают в ситуациях, когда нужно выполнить большой объем работы за максимально короткое время.
Компания Google популяризировала распределенный алгоритм, который называется MapReduce. Предположим, имеется таблица с миллиардами или триллионами записей и к ней нужно сделать сложный запрос SQL. В MySQL это сделать не удастся, потому что MySQL начнет «тормозить» уже после нескольких миллиардов записей. Используйте MapReduce!
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,24 @@
#алгоритмы
>Рекурсией называется вызов функцией самой себя
```javascript
const counter = (val) => {
if (val < 1) {
return;
}
console.log(val);
counter(val - 1);
}
counter(5);
```
Каждая рекурсивная функция состоит из двух частей: базового случая и рекурсивного случая.
![[Pasted image 20250108124636.png]]
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,62 @@
#алгоритмы #сортировка
![[Sorting_quicksort_anim.gif]]
**Лучшая/Средняя эффективность** $O(n) = O(n*log_2{n})$
**Худшая эффективность** $O(n) = O(n^2)$
> Быстрая сортировка относится к алгоритмам сортировки. Она работает намного быстрее сортировки выбором и часто применяется в реальных программах. Основана на стратегии «[[Разделяй и властвуй (Divide and conquer)]]».
Последовательность:
1) Выбрать опорный элемент
2) Разделить массив на два подмассива: элементы, меньшие опорного,
и элементы, большие опорного.
3) Рекурсивно применить быструю сортировку к двум подмассивам.
Быстродействие быстрой сортировки сильно зависит от выбора опорного
элемента. Предположим, опорным всегда выбирается первый элемент, а быстрая
сортировка применяется к уже отсортированному массиву. Быстрая
сортировка не проверяет, отсортирован входной массив или нет, и все равно
пытается его отсортировать.
В худшем случае существуют $O(n)$ уровней, поэтому алгоритм займет время
$O(n) * O(n)=O(n^2)$
![[Pasted image 20250109093218.png]]
```javascript
function quickSort(array) {
if (array.length <= 1) {
return array;
}
const middleIndex = Math.ceil(array.length / 2);
const left = [];
const right = [];
for (let i = 0; i < array.length; i++) {
if (i === middleIndex) {
continue
}
if (array[i] < array[middleIndex]) {
left.push(array[i])
} else {
right.push(array[i])
}
}
return [
...quickSort(left),
array[middleIndex],
...quickSort(right),
]
}
```
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]
- [[Стивен Скиена - Алгоритмы. Руководство по разработке]]

View File

@ -0,0 +1,24 @@
#алгоритмы #сортировка
![[Insertion-sort-example-300px.gif]]
Эффективность $O(n) = O(n*log(n))$
>Выбираем следующий элемент из неотсортированного списка и вставляем его в должную позицию в отсортированном списке.
```javascript
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) {
let j = i;
while (j > 0 && arr[j] < arr[j - 1]) {
[arr[j], arr[j - 1]] = [arr[j - 1], arr[j]];
j--;
}
}
return arr;
}
```
Источники:
- [[Стивен Скиена - Алгоритмы. Руководство по разработке]]

View File

@ -0,0 +1,78 @@
#алгоритмы #сортировка
![[1_5WXRN62ddiM_Gcf4GDdCZg.gif]]
Эффективность $O(n) = O(n^2)$
> Пройти по списку и найти наибольший элемент, этот элемент добавляется
в новый список. Потом то же самое происходит со следующим элементом.
## Вариант с циклом
```javascript
const findSmallestIndex = (arr) => {
let smallestValue = arr[0];
let smallestIndex = 0;
for (let i = 1; i < arr.length; i++) {
const candidate = arr[i];
if (candidate < smallestValue) {
smallestIndex = i;
smallestValue = candidate
}
}
return smallestIndex;
}
const selectionSort = (arr) => {
const result = [];
const copyArr = [...arr];
for (let i = 0; i < arr.length; i++) {
const smallestIndex = findSmallestIndex(copyArr);
const smallestValue = copyArr.splice(smallestIndex, 1)[0];
result.push(smallestValue);
}
return result;
}
const array = [2, 4, 5, 1, 6, 3];
const sorted = selectionSort(array);
```
## Вариант с рекурсией
```javascript
const findSmallestIndex = (arr) => {
let smallestValue = arr[0];
let smallestIndex = 0;
for (let i = 1; i < arr.length; i++) {
const candidate = arr[i];
if (candidate < smallestValue) {
smallestIndex = i;
smallestValue = candidate
}
}
return smallestIndex;
}
const recursiveSelectionSort = array => {
if (!array.length) return [];
const copyArr = [...array];
const smallestIndex = findSmallestIndex(copyArr);
return [
...copyArr.splice(smallestIndex, 1),
...recursiveSelectionSort(copyArr),
];
};
const array = [2, 4, 5, 1, 6, 3];
const sorted = recursiveSelectionSort(array);
```
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,49 @@
#алгоритмы #сортировка
![[Merge-sort-example-300px.gif]]
Эффективность $O(n) = O(n*log(n))$
>Сортируемые элементы разбиваются на две группы, каждая из этих меньших групп сортируется рекурсивно, после чего оба отсортированных списка сливаются воедино и их элементы чередуются, образуя полностью отсортированный общий список.
```javascript
function mergeSort(arr) {
// Базовый случай: массив из 0 или 1 элемента уже отсортирован
if (arr.length <= 1) {
return arr;
}
// Разделяем массив пополам
const middle = Math.floor(arr.length / 2);
const left = arr.slice(0, middle);
const right = arr.slice(middle);
// Рекурсивно сортируем обе части и объединяем их
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
const result = [];
let i = 0;
let j = 0;
// Сравниваем элементы из левой и правой части и добавляем наименьший
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
result.push(left[i]);
i++;
} else {
result.push(right[j]);
j++;
}
}
// Добавляем оставшиеся элементы (если есть)
return result
.concat(left.slice(i))
.concat(right.slice(j));
}
```
Источники
- [[Стивен Скиена - Алгоритмы. Руководство по разработке]]

View File

@ -0,0 +1,10 @@
#алгоритмы #todo
> Использует вероятностные структуры данных. Они дают ответ, который может оказаться ложным, но с большой вероятностью является правильным
Фильтр Блума дает ответ, правильный с высокой вероятностью:
- возможны ложноположительные срабатывания. Фильтр скажет: «Этот сайт уже обрабатывался», хотя этого не было;
- ложноотрицательные срабатывания исключены. Если фильтр утверждает, что сайт не обрабатывался, вы можете быть в этом уверены.
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,18 @@
#алгоритмы
> Специальная нотация «О-большое> описывает скорость работы алгоритма в худшем случае. О-большое не сообщает скорость в секундах, а позволяет сравнить количество операций. Оно указывает, насколько быстро возрастает время выполнения алгоритма.
- $O(log(n))$, или логарифмическое время . Пример: [[Бинарный поиск (Binary search)]].
- $O(n)$, или линейное время. Пример: [[Простой поиск (Linear search)]].
- $O(n * log(n))$. Пример: эффективные алгоритмы сортировки (быстрая
сортировка)
- $О(n^2)$. Пример: медленные алгоритмы сортировки (сортировка выбором)
- $О(n!)$. Пример: очень медленные алгоритмы (задача о коммивояжере).
![[Pasted image 20250106153135.png]]
Источники:
- [[Адитья Бхаргава - Грокаем Алгоритмы]]

View File

@ -0,0 +1,13 @@
> Специальная нотация «О-большое> описывает скорость работы алгоритма в худшем случае. О-большое не сообщает скорость в секундах, а позволяет сравнить количество операций. Оно указывает, насколько быстро возрастает время выполнения алгоритма.
- $O(log(n))$, или логарифмическое время . Пример: [[Бинарный поиск]].
- $O(n)$, или линейное время. Пример: [[Простой поиск]].
- $O(n * log(n))$. Пример: эффективные алгоритмы сортировки (быстрая
сортировка)
- $О(n^2)$. Пример: медленные алгоритмы сортировки (сортировка выбором)
- $О(n!)$. Пример: очень медленные алгоритмы (задача о коммивояжере).
![[Pasted image 20250106153135.png]]

View File

@ -0,0 +1,3 @@
#книги
![[Pasted image 20250110093033.png]]

View File

@ -0,0 +1,3 @@
#книги
![[Pasted image 20241113230057.png]]

View File

@ -0,0 +1,5 @@
#книги
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]
- [[Адитья Бхаргава - Грокаем Алгоритмы]]
- [[Стивен Скиена - Алгоритмы. Руководство по разработке]]

View File

@ -0,0 +1,3 @@
#книги
![[Pasted image 20250715055941.png]]

View File

@ -0,0 +1 @@
#ооп #todo

View File

@ -0,0 +1 @@
#паттерны_ооп #todo

View File

@ -0,0 +1 @@
#паттерны_ооп #todo

View File

@ -0,0 +1 @@
#паттерны_ооп #todo

View File

@ -0,0 +1 @@
#паттерны_ооп #todo

Binary file not shown.

View File

@ -0,0 +1,32 @@
#рефакторинг апахи_кода
![[Pasted image 20241113230434.png]]
> Одним из больших преимуществ использования классов является возможность подстановки, позволяющая в случае необходимости подставлять один класс вместо другого. Но это работает, только если их интерфейсы одинаковы
### **Признак**
- Два класса выполняют одинаковые функции, но имеют разные названия методов
### **Причины появления**
- Программист, который создал один из классов, скорей всего, не знал о том, что в программе уже существует аналогичный по функциям класс
### **Рефакторинги**
- [[Изменение объявления функции (Change Function Declaration)]]
- [[Перенос функции (Move Function)]]
- [[Извлечение суперкласса (Extract Superclass)]]
![[Pasted image 20241113230521.png]]
### **Результат**
- Вы избавляетесь от ненужного дублирования кода, и, таким образом, уменьшаете его размер
- Повышается читабельность кода, улучшается его понимание. Вам больше не придется гадать, зачем создавался второй класс, выполняющий точно такие же функции, как и первый
### **Не стоит трогать, если...**
-Иногда объединить классы оказывается невозможно либо настолько сложно, что смысла заниматься этой работой нет. Один из примеров — альтернативные классы находятся в двух разных библиотеках, каждая из которых имеет свою версию класса
### **Ссылки**
- https://refactoring.guru/ru/smells/alternative-classes-with-different-interfaces
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,30 @@
#рефакторинг апахи_кода
![[Pasted image 20241113223522.png]]
> Когда класс пытается взять на себя слишком многое, это часто проявляется в чрезмерном количестве полей. А отсюда недалеко и до дублирования кода.
> Как и класс с большим количеством переменных экземпляра, класс со слиш­ ком большим количеством кода создает предпосылки для дублирования кода, ха­ оса и гибели. Простейшее решение (а мы уже не раз говорили, что предпочитаем простые решения) — это устранение избыточности в самом классе. Если у вас есть пять методов по сотне строк и с большим количеством дублируемого кода, возможно, их можно заменить пятью методами по десять и еще десятком двух­ строчных методов, выделенных из исходных.
> Часто лучшей подсказкой для разделения являются клиенты такого класса. Посмотрите, используют ли клиенты подмножество функций класса. Каждое та­ кое подмножество является возможным отдельным классом
### **Признаки**
- Класс содержит множество полей/методов/строк кода.
### **Причины появления**
- Как и в случае с длинными методами, чаще всего программисту ментально проще добавить фичу в существующий класс, чем создать новый класс для этой фичи
![[Pasted image 20241113224408.png]]
### **Рефакторинги**
- [[Извлечение класса (Extract Class)]]
- [[Извлечение суперкласса (Extract Superclass)]]
- [[Замена кода типа подклассами (Replace Type Code with Subclasses)]]
![[Pasted image 20241113224452.png]]
### **Результаты**
- Рефакторинг таких классов избавит разработчиков от необходимости запоминать чрезмерное количество имеющихся у класса атрибутов
- Во многих случаях разделение больших классов на части позволяет избежать дублирования кода и функциональности
### **Ссылки**
- https://refactoring.guru/ru/smells/large-class
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,13 @@
#рефакторинг апахи_кода
> Программисты любят высокие крепкие стены между своими модулями и горько жалуются на то, что обмен данными в обход этих стен слишком сильно увеличивает связи. Чтобы заставить программу работать, некоторый обмен необходим, но нам нужно свести его к минимуму и держать под контролем.
### **Рефакторинги**
- [[Перенос функции (Move Function)]]
- [[Перенос поля (Move Field)]]
- [[Сокрытие делегата (Hide Delegate)]]
- [[Замена подкласса делегатом (Replace Subclass with Delegate)]]
- [[Замена суперкласса делегатом (Replace Superclass with Delegate)]]
### **Ссылки**
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,29 @@
#рефакторинг апахи_кода
![[Pasted image 20241112230602.png]]
> Иногда выясняется, что в некотором классе поле устанавливается только в определенных обстоятельствах. Такой код труден для понимания, поскольку вы ожидаете, что объекту нужны все его поля. Можно сломать голову, пытаясь по­нять, для чего нужна некоторая переменная, если найти, где она используется, никак не удается.
### **Признаки**
Временные поля — это поля, которые нужны объекту только при определённых обстоятельствах. Только тогда они заполняются какими-то значениями, оставаясь пустыми в остальное время
### **Причины появления**
Зачастую временные поля создаются для использования в алгоритме, который требует большого числа входных данных. Так, вместо создания большого числа параметров в таком методе, программист решает создать для этих данных поля в классе. Эти поля используются только в данном алгоритме, а в остальное время простаивают.
Такой код очень трудно понять. Вы ожидаете увидеть данные в полях объекта, а они почему-то пустуют почти все время.
![[Pasted image 20241112230612.png]]
### **Рефакторинги**
- [[Извлечение класса (Extract Class)]]
- [[Перенос функции (Move Function)]]
- [[Введение частного случая (Introduce Special Case)]]
![[Pasted image 20241112230618.png]]
### **Результат**
- Улучшает понятность и организацию кода
### **Ссылки**
- [https://refactoring.guru/ru/smells/temporary-field](https://refactoring.guru/ru/smells/temporary-field)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,9 @@
#рефакторинг апахи_кода
> Проблема глобальных данных заключается в том, что они могут быть изменены из любого места кодовой базы, и нет никакого механизма, чтобы определить, какой именно фрагмент их изменил. Это дальнодей­ ствие приводит к ошибкам, источник которых крайне трудно выявить. Наиболее очевидной формой глобальных данных являются глобальные переменные, но та же проблема возникает и при использовании переменных класса и синглтонов
### **Рефакторинги**
- [[Инкапсуляция переменной (Encapsulate Variable)]]
### **Ссылки**
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,34 @@
#рефакторинг апахи_кода
![[Pasted image 20241112225311.png]]
> Данные — как дети: они любят сбиваться в тесные группы. Часто можно видеть, как одни и те же три-четыре элемента данных встречаются во множестве мест: поля в паре классов, параметры в нескольких методах. Данные, встречающиеся совместно, имеет смысл превращать в отдельный класс
### **Признаки**
- В разных частях кода встречаются одинаковые группы переменных (например, параметры подключения к базе данных). Такие группы следует превращать в самостоятельные классы.
### **Причины появления**
- Следствие плохой структурированности программы или программирования методом копирования-вставки
![[Pasted image 20241112225320.png]]
### **Рефакторинги**
- [[Извлечение класса (Extract Class)]]
- [[Введение объекта параметра (Introduce Parameter Object)]]
- [[Сохранение всего объекта (Preserve Whole Object)]]
![[Pasted image 20241112225331.png]]
### **Результат**
- Улучшает понимание и организацию кода
- Операции над определёнными данными теперь собраны в одном месте, и их не надо искать по всему коду
- Уменьшает размер кода
### **Не стоит трогать, если...**
- Передача всего объекта в параметрах метода вместо передачи его значений (элементарных типов) может создать нежелательную зависимость между двумя классами.
### **Ссылки**
- [https://refactoring.guru/ru/smells/data-clumps](https://refactoring.guru/ru/smells/data-clumps)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,39 @@
#рефакторинг апахи_кода
![[Pasted image 20241112222453.png]]
> Программы, использующие короткие функции, живут долго и счастливо. Работая с такой программой на протяжении нескольких лет, вы понимаете, какую ценность представляют собой маленькие функции. Все выгоды, которые дает косвенность — понятность, совместное использование и выбор, — поддер­живаются именно маленькими функциями.
> Еще на заре программирования было ясно, что чем длиннее функция, тем труднее понять, как она работает
> Эвристическое правило, которому мы следуем, гласит, что если возни­кает необходимость что-то прокомментировать, то пора писать функцию. В этой функции содержится код, который требовал комментариев, но ее название от­ражает его назначение, а не способ решения им задачи
### **Признаки**
- Метод содержит слишком большое число строк кода. Длина метода более десяти строк должна начинать вас беспокоить
### **Причины появления**
- В метод всё время что-то добавляется, но ничего не выносится. Так как писать код намного проще, чем читать
- Человеку зачастую ментально сложнее создать новый метод, чем дописать что-то в уже существующий: «Как же, мне нужно добавить всего две строки, не буду же я создавать для этого целый метод»
![[Pasted image 20241112222556.png]]
Если ощущается необходимость что-то прокомментировать внутри метода, этот код лучше выделить в новый метод. Даже одну строку имеет смысл выделить в метод, если она нуждается в разъяснениях. К тому же, если у метода хорошее название, то не нужно будет смотреть в его код, чтобы понять, что он делает.
### **Рефакторинги**
- [[Извлечение функции (Extract Function)]]
- [[Замена временной переменной запросом (Replace Temp with Query)]]
- [[Замена функции командой (Replace Function with Command)]]
### **Результат**
- Из всех видов объектного кода дольше всего выживают классы с короткими методами. Чем длиннее ваш метод или функция, тем труднее будет её понять и поддерживать.
- В длинных методах зачастую можно обнаружить «залежи» дублирования кода.
![[Pasted image 20241112222648.png]]
### **Производительность**
Многие волнуются, что увеличение числа методов может плохо сказаться на производительности. В абсолютном большинстве случаев, это не является реальной проблемой, так что **просто перестаньте об этом думать.**
Имея чистый и понятный код, вы с большей вероятностью натолкнётесь на отличный способ реструктуризировать код программы и увеличить реальную производительность, если такая надобность вообще будет.
### **Ссылки**
- [https://refactoring.guru/ru/smells/long-method](https://refactoring.guru/ru/smells/long-method)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,32 @@
#рефакторинг апахи_кода
![[Pasted image 20241112223051.png]]
> В длинных списках параметров трудно разобраться. Они зачастую противоречивы и сложны в применении, а кроме того, их приходится вечно изменять по мере возникновения необходимости в новых данных.
### **Признаки**
- Количество параметров метода больше трёх-четырёх
### **Причины появления**
- После объединения нескольких вариантов алгоритмов в одном методе. В этом случае может быть создан длинный список параметров, контролирующих то, какая из вариаций будет выполнена и как
- Попытка уменьшить связанность между классами
![[Pasted image 20241112223143.png]]
### **Рефакторинги**
- [[Замена параметра запросом (Replace Parameter with Query)]]
- [[Сохранение всего объекта (Preserve Whole Object)]]
- [[Введение объекта параметра (Introduce Parameter Object)]]
- [[Удаление аргумента-флага (Remove Flag Argument)]]
- [[Объединение функций в класс (Combine Functions into Class)]]
### **Результат**
- Повышает читабельность кода, уменьшает его размер
- В процессе рефакторинга может обнаружится дублирование кода, которое ранее было незаметно.
### **Не стоит трогать, если...**
- Не стоит избавляться от параметров, если при этом появляется нежелательная связанность между классами.
### **Ссылки**
- [https://refactoring.guru/ru/smells/long-parameter-list](https://refactoring.guru/ru/smells/long-parameter-list)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,36 @@
#рефакторинг апахи_кода
![[Pasted image 20241112221124.png]]
> Увидев одинаковые структуры кода в нескольких местах, можно быть уверен­ным, что если их удастся объединить, то программа от этого только выиграет. Дублирование означает, что каждый раз, когда вы читаете такие копии, вам необ­ходимо внимательно проверять — нет ли между ними какой-либо разницы. Если вам нужно изменить дублированный код, вы должны найти и исправить каждую копию.
### **Признаки**
- Два фрагмента кода выглядят почти одинаковыми.
### **Причины появления**
- В проекте работает несколько человек, и не знают, что коллега уже написал похожий код, который можно использовать вместо написания своего
- Косвенное дублирование - когда конкретные участки кода отличаются внешне, хотя и выполняют одну и ту же задачу. Такое дублирование бывает довольно сложно обнаружить и исправить
- Намеренно, в спешке, когда поджимают сроки
- Программист просто слишком ленив, чтобы избавить код от дублирования
![[Pasted image 20241112221307.png]]
### **Рефакторинги**
- [[Извлечение функции (Extract Function)]]
- [[Перемещение инструкций (Slide Statements)]]
- [[Подъем метода (Pull Up Method)]]
### **Результат**
- Объединение дублирующего кода позволяет улучшить структуру кода и уменьшить его объём
- Упрощение и удешевление поддержки кода в будущем
![[Pasted image 20241112221342.png]]
### **Не стоит трогать, если...**
- В очень редких случаях объединение двух одинаковых участков кода может сделать код менее очевидным и понятным.
### **Ссылки**
- [https://refactoring.guru/ru/smells/duplicate-code](https://refactoring.guru/ru/smells/duplicate-code)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,35 @@
#рефакторинг апахи_кода
![[Pasted image 20241112224937.png]]
> Когда мы делим программы на модули, мы пытаемся разделить код на такие зоны, чтобы максимизировать взаимодействие внутри зоны и минимизировать взаимодействие между зонами. Классический пример — когда функция в одном модуле тратит больше времени на общение с функциями или данными внутри другого модуля, чем в своем собственном.
> Функция четко хочет быть поближе к данным.
### **Признаки**
- Метод обращается к данным другого объекта чаще, чем к собственным данным
### **Причины появления**
- После перемещения каких-то полей в класс данных. В этом случае операции с данными, возможно, также следует переместить в этот класс.
![[Pasted image 20241112224947.png]]
### **Рефакторинги**
То, что изменяется одновременно, нужно хранить в одном месте. Обычно данные и функции, использующие эти данные, также изменяются вместе (хотя бывают исключения).
- [[Перенос функции (Move Function)]]
- [[Извлечение функции (Extract Function)]]
- [[Перенос функции (Move Function)]]
![[Pasted image 20241112224955.png]]
### **Результат**
- Уменьшение дублирования кода (если код работы с данными переехал в одно общее место)
- Улучшение организации кода (так как методы работы с данными находятся возле этих данных)
### **Не стоит трогать, если...**
- Бывают случаи, когда поведение намеренно отделяется от класса, содержащего данные. Чаще всего это делают для того, чтобы иметь возможность динамически менять это поведение (паттерны **[[Стратегия]]**, **[[Посетитель]]** и т. д.).
### **Ссылки**
- [https://refactoring.guru/ru/smells/feature-envy](https://refactoring.guru/ru/smells/feature-envy)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,13 @@
#рефакторинг апахи_кода
> Изменения в данных часто могут вести к неожиданным последствиям и хитрым ошибкам. Я могу обновить некоторые данные в одном месте, не зная, что другая часть программного обеспечения ожидает какие-то другие данные и теперь терпит неудачу. Такой сбой особенно трудно обнаружить, если он происходит только в редких условиях. По этой причине целая школа разработки программного обеспечения (функциональное программирование) основана на идее, что данные никогда не должны изменяться, и что обновление структуры данных всегда должно возвращать новую копию структуры с изменениями, оставляя старые данные нетронутыми.
### **Рефакторинги**
- [[Инкапсуляция переменной (Encapsulate Variable)]]
- [[Расщепление переменной (Split Variable)]]
- [[Перемещение инструкций (Slide Statements)]]
- [[Отделение запроса от модификатора (Separate Query from Modifier)]]
- [[Замена вычисленной переменной запросом (Replace Derived Variable with Query)]]
### **Ссылки**
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,29 @@
#рефакторинг апахи_кода
![[Pasted image 20241113230738.png]]
> Такие классы содержат поля, методы для получения и установки значений этих полей и ничего больше. Это молчаливые хранилища данных, которыми другие классы наверняка манипулируют излишне детально.
> Классы данных часто являются признаком размещения поведения в неправильном месте; это означает, что вы можете добиться большего прогресса, переместив его из клиента в сам класс данных. Но есть исключения, и одно из них — запись, которая используется как результат отдельного вызова функции. Ключевой характеристикой такой записи результатов является то, что она неизменяема (по крайней мере на практике). Неизменяемые поля не нужно инкапсулировать, а информация, полученная из неизменяемых данных, может быть представлена в виде полей, а не как методы доступа.
### **Признаки**
Классы данных — это классы, которые содержат только поля и простейшие методы для доступа к ним (геттеры и сеттеры). Это просто контейнеры для данных, используемые другими классами. Эти классы не содержат никакой дополнительной функциональности и не могут самостоятельно работать с данными, которыми владеют
### **Причины появления**
Это нормально, когда класс в начале своей жизни содержит всего лишь несколько публичных полей (а может даже и парочку геттеров/сеттеров). Тем не менее, настоящая сила объектов заключается в том, что они могут хранить типы поведения или операции над собственными данными.
![[Pasted image 20241113231226.png]]
### **Рефакторинги**
- Инкапсуляция записи
- Удаление метода установки значения
- Перенос функции
- Извлечение функции
- Разделение этапа
### **Результат**
- Улучшает понимание и организацию кода. Операции над определёнными данными теперь собраны в одном месте, их не надо искать по всему коду
- Может вскрыть факты дублирования клиентского кода
### **Ссылки**
- https://refactoring.guru/ru/smells/data-class
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,33 @@
#рефакторинг апахи_кода
![[Pasted image 20241114072528.png]]
> Комментарии приводят нас к плохому коду, издающему всевозможные дурные запахи, о которых мы писали в этой главе. Первым действием должно быть удаление этих запахов с помощью рефакторинга. После этого комментарии часто оказываются ненужными.
> Почувствовав необходимость написать комментарий, попробуйте сначала изменить структуру кода так, чтобы любые комментарии стали ненужными.
> Комментарии полезны, когда вы не знаете, что делать. Помимо описания про­ исходящего, комментарии могут отмечать те места, в которых вы не уверены. Комментарии — хорошее место пояснить, почему вы поступаете именно так. Эта информация пригодится тем, кто будет работать с вашим кодом в будущем.
### **Признаки**
- Метод содержит множество поясняющих комментариев
### **Причины появления**
- Зачастую комментарии создаются с хорошими намерениями, когда автор и сам понимает, что его код недостаточно очевиден и понятен. В таких случаях комментарии играют роль «дезодоранта», т.е. пытаются заглушить «дурной запах» недостаточно проработанного кода
- Самый лучший комментарий — это хорошее название метода или класса
### **Рефакторинги**
- [[Извлечение функции (Extract Function)]]
- [[Изменение объявления функции (Change Function Declaration)]]
- [[Введение утверждения (Introduce Assertion)]]
![[Pasted image 20241114072633.png]]
### **Результат**
- Код становится более очевидным и понятным
### **Не стоит трогать, если...**
Иногда комментарии бывают полезными:
- Те, которые объясняют **почему** что-то выполняется именно таким образом.
- Те, которые объясняют сложные алгоритмы (когда все иные средства упростить алгоритм уже были испробованы).
### **Ссылки**
- https://refactoring.guru/ru/smells/comments
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,31 @@
#рефакторинг апахи_кода
![[Pasted image 20241112225933.png]]
> Иногда это функция, кото­рая должна была вырасти и стать важной и востребованной позже, но которая так и не осуществила свои мечты. Иногда это класс, который раньше был нужен, но оказался уменьшен с помощью рефакторинга. В любом случае, такие элемен­ты программы должны умереть с достоинством
### **Признаки**
- Класс не делает достаточно много, чтобы уделять ему достаточно внимания, он должен быть уничтожен
### **Причины появления**
- Класс был задуман как полнофункциональный, но в результате рефакторинга ужался до неприличных размеров
- Класс создавался в расчёте на некие будущие разработки, до которых руки так и не дошли
### **Рефакторинги**
- [[Встраивание функции (Inline Function)]]
- [[Встраивание класса (Inline Class)]]
- [[Свертывание иерархии (Collapse Hierarchy)]]
![[Pasted image 20241112225940.png]]
### **Результат**
- Уменьшение размера кода
- Упрощение поддержки
### **Не стоит трогать, если...**
- Иногда енивый класс_ бывает создан для того, чтобы явно очертить какие-то намерения. В этом случае, стоит соблюдать баланс понятности кода и его простоты
### **Ссылки**
- [https://refactoring.guru/ru/smells/lazy-class](https://refactoring.guru/ru/smells/lazy-class)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,23 @@
#рефакторинг апахи_кода
![[Pasted image 20241114075108.png]]
### **Признаки**
- Переменная, параметр, поле, метод или класс больше не используются (чаще всего потому, что устарели)
### **Причины появления**
- Когда требования к программному продукту изменились, либо были внесены какие-то корректировки, но чистка старого кода так и не была проведена
- Мёртвый код можно обнаружить и в сложном условном коде, где одна из веток никогда не может быть исполнена (в виду ошибки или другого стечения обстоятельств)
![[Pasted image 20241114075243.png]]
### **Рефакторинги**
- [[Встраивание класса (Inline Class)]]
- [[Удаление неработающего кода (Remove Dead Code)]]
### **Результат**
- Уменьшает размер кода
- Упрощает его поддержку
### **Ссылки**
- https://refactoring.guru/ru/smells/dead-code

View File

@ -0,0 +1,24 @@
#рефакторинг апахи_кода
![[Pasted image 20241114075511.png]]
### **Признаки**
- Один класс использует служебные поля и методы другого класса.
### **Причины появления**
- Смотрите внимательно за классами, которые проводят слишком много времени вместе. Хорошие классы должны знать друг о друге как можно меньше. Такие классы легче поддерживать и повторно использовать
![[Pasted image 20241114075625.png]]
### **Рефакторинги**
- [[Перемещение инструкций (Slide Statements)]]
- [[Сокрытие делегата (Hide Delegate)]]
![[Pasted image 20241114075737.png]]
### **Результат**
- Улучшает организацию кода
- Упрощает техническую поддержку и повторное использование кода
### **Ссылки**
- https://refactoring.guru/ru/smells/inappropriate-intimacy

View File

@ -0,0 +1,35 @@
#рефакторинг апахи_кода
![[Pasted image 20241112225511.png]]
> Большинство сред программирования основаны на широком применении набора примитивных типов: целых чисел, чисел с плавающей точкой и строк. Встречается немало программистов, которые не хотят создавать свои собственные фундаментальные типы, полезные для их предметной области, — например денежные единицы, координаты или диапазоны. И потому приходится встре­чаться с расчетами, которые рассматривают денежные суммы как простые числа; с вычислениями физических величин, которые игнорируют единицы измерений и добавляют дюймы к миллиметрам.
> Строки являются особенно яркими источниками запаха этого вида: номер телефона — это нечто большее, чем просто набор символов. Если даже такой тип не делает ничего иного — он по крайней мере включает согласованную логику отображения в пользовательском интерфейсе. Представление таких типов в виде строк является настолько распространенным запахом, что некоторые называют их “строково типизированными” переменными.
### **Признаки**
- Использование элементарных типов вместо маленьких объектов для небольших задач (например, валюта, диапазоны, специальные строки для телефонных номеров и т. п.)
- Использование констант для кодирования какой-то информации (например, константа `USER_ADMIN_ROLE = 1` для обозначения пользователей с ролью администратора)
- Использование строковых констант в качестве названий полей в массивах
### **Причины появления**
- Программисту понадобилось поле для хранения каких-то данных. Он подумал, что создать поле элементарного типа куда проще, чем заводить новый класс
- Примитивные типы нередко используются для «симуляции» типов. Это когда вместо отдельного типа данных вы имеете набор чисел или строк, который составляет список допустимых значений для какой-то сущности. Зачастую этим конкретным числам и строкам даются понятные имена с помощью констант, что и является причиной их широкого распространения
![[Pasted image 20241112225523.png]]
### **Рефакторинги**
- [[Замена примитива объектом (Replace Primitive with Object)]]
- [[Замена кода типа подклассами (Replace Type Code with Subclasses)]]
- [[Извлечение класса (Extract Class)]]
- [[Введение объекта параметра (Introduce Parameter Object)]]
![[Pasted image 20241112225530.png]]
### **Результат**
- Повышает гибкость кода ввиду использования объектов вместо примитивных типов
- Улучшает понимание и организацию кода
- Операции над определёнными данными теперь собраны в одном месте, и их не надо искать по всему коду. Теперь не нужно догадываться, зачем созданы все эти странные константы и почему поля содержатся в массиве
- Может вскрыть факты дублирования кода
### **Ссылки**
- [https://refactoring.guru/ru/smells/primitive-obsession](https://refactoring.guru/ru/smells/primitive-obsession)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,31 @@
#рефакторинг апахи_кода
![[Pasted image 20241114071602.png]]
> Подклассам полагается наследовать методы и данные своих родителей. Но что делать, если это наследство им не нравится или не требуется? И получив все эти дары, они пользуются только малой их частью.
> Обычно это означает неправильно продуманную иерархию.
> В родительском классе должна содержаться только та функциональность, которая используется. Часто вы можете встретить совет делать все суперклассы абстрактными.
### **Признаки**
- Если подкласс использует лишь малую часть унаследованных методов и свойств суперкласса, это является признаком неправильной иерархии. При этом ненужные методы могут просто не использоваться либо быть переопределёнными и выбрасывать исключения
### **Причины появления**
- Кто-то создал наследование между классами только из побуждений повторного использования кода, находящегося в суперклассе. При этом суперкласс и подкласс могут являться совершенно различными сущностями.
![[Pasted image 20241114071816.png]]
### **Рефакторинги**
- [[Опускание метода (Push Down Method)]]
- [[Опускание поля (Push Down Field)]]
- [[Замена подкласса делегатом (Replace Subclass with Delegate)]]
- [[Замена суперкласса делегатом (Replace Superclass with Delegate)]]
![[Pasted image 20241114071837.png]]
### **Результат**
- Улучшает понимание и организацию кода. Теперь вы не будете тратить время на догадки о том, почему класс `Стул` унаследован от класса `Животное` (несмотря на то, что оба имеют четыре ноги).
### **Ссылки**
- https://refactoring.guru/ru/smells/refused-bequest
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,26 @@
#рефакторинг апахи_кода
![[Pasted image 20241114073259.png]]
### **Признаки**
- Всякий раз при создании подкласса какого-то класса приходится создавать ещё один подкласс для другого класса
### **Причины появления**
- Пока иерархия была небольшая, всё было хорошо. Но с появлением новых классов вносить изменения становилось всё сложнее и сложнее
### **Рефакторинги**
- [[Перенос поля (Move Field)]]
- [[Перенос функции (Move Function)]]
![[Pasted image 20241114073424.png]]
### **Результат**
- Уменьшает дублирования кода
- Может улучшить организацию кода
### **Не стоит трогать, если...**
- Иногда наличие паралельной иерархии — это необходимое зло, без которого устройство программы было бы еще хуже. Если вы обнаружите, что ваши попытки устранить дублирование приводят к еще большему ухудшению организации кода, то... остановите рефакторинг, откатите все внесенные изменения, выпейте чаю и начните привыкать к этому коду
### **Ссылки**
- https://refactoring.guru/ru/smells/parallel-inheritance-hierarchies

View File

@ -0,0 +1,29 @@
#рефакторинг апахи_кода
![[Pasted image 20241112225742.png]]
> Инструкция switch — вовсе не красный флаг.
> Когда одна и та же условная логика (либо в switch/case, либо в каскаде if/else) появляется в разных местах, проблема состоит в том, что всякий раз, когда вы добавляете ветвь, вы должны найти все инструкции switch и обновить их. Полиморфизм обеспечивает элегантное оружие против темных сил такого повторения.
### **Признаки**
- У вас есть сложный оператор `switch` или последовательность `if`-ов
### **Причины появления**
Одним из очевидных признаков объектно-ориентированного кода служит сравнительно редкое использование операторов типа switch или case. Часто один и тот же блок switch оказывается разбросанным по разным местам программы. При добавлении в него нового варианта приходится искать все эти блоки switch и модифицировать их.
Как правило, заметив блок switch, следует подумать о полиморфизме.
### **Рефакторинги**
- [[Замена условной инструкции полиморфизмом (Replace Conditional with Polymorphism)]]
![[Pasted image 20241112225751.png]]
### **Результат**
- Улучшает организацию кода
### **Не стоит трогать, если...**
- Когда оператор `switch` выполняет простые действия, нет никакого смысла что-то менять в коде
- Зачастую оператор switch используется в фабричных паттернах проектирования (**Фабричный метод**, **Абстрактная фабрика**) для выбора создаваемого класса.
### **Ссылки**
- [https://refactoring.guru/ru/smells/switch-statements](https://refactoring.guru/ru/smells/switch-statements)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,35 @@
#рефакторинг апахи_кода
![[Pasted image 20241112231226.png]]
> Одной из основных характеристик объектов является инкапсуляция — сокрытие внутренних деталей реализации от внешнего мира. Инкапсуляции ча­сто сопутствует делегирование. Например, вы договариваетесь с директором о встрече. Он делегирует это сообщение своему календарю и дает вам ответ. Все хорошо и правильно. Совершенно не важно, использует ли директор ежедневник, электронное устройство или своего секретаря, чтобы вести расписание личных встреч.
> Однако такой подход может завести слишком далеко. Например, мы просмат­риваем интерфейс класса и обнаруживаем, что половина методов делегирует обработку другому классу.
### **Признаки**
Если класс выполняет одно действие — делегирует работу другому классу — стоит задуматься, зачем он вообще существует.
### **Причины появления**
- Данный запах может быть результатом фанатичной борьбы с **[[Цепочки сообщений]]**.
- Вся полезная нагрузка класса постепенно перемещается в другие классы, в результате кроме делегирующих методов в нем ничего не остается.
### **Рефакторинги**
- Удаление посредника
- Встраивание функции
- Замена суперкласса делегатом
- Замена подкласса делегатом
![[Pasted image 20241112231241.png]]
### **Результат**
- Уменьшение размера кода.
### **Не стоит трогать, если...**
Не удаляйте посредников, которые были созданы осознанно:
- Посредник мог быть введён для избавления от нежелательной зависимости между классами.
- Некоторые паттерны проектирования намеренно создают посредников (например, **[[Заместитель]]** или **[[Декоратор]]**)
### Ссылки
- [https://refactoring.guru/ru/smells/middle-man](https://refactoring.guru/ru/smells/middle-man)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,29 @@
#рефакторинг апахи_кода
![[Pasted image 20241112224346.png]]
> Планируя изменение, мы хотим иметь возможность перейти в определенную точку программы и внести изменения именно в ней.
> Расходящиеся изменения имеют место тогда, когда один модуль часто изменяется различными путями по разным причинам. Взаимодействие с базой данных и обработка финансов имеют разные контексты, так что можно облегчить свою программистскую жизнь, перемещая эти контексты в разные модули. Таким образом, когда требуется изменение в одном контексте, следует разобраться только с ним одним и игнорировать другой. Мы всегда считали это важным, но теперь, когда наш мозг с возрастом уменьшается в размерах, этот подход становится просто необходимым
### **Признаки**
- При внесении изменений в класс приходится изменять большое число различных методов. Например, для добавления нового вида товара вам нужно изменить методы поиска, отображения и заказа товаров.
### **Причины появления**
- Следствие плохой структурированности программы или программирования методом копирования-вставки
![[Pasted image 20241112224448.png]]
### **Рефакторинги**
- [[Разделение этапа (Split Phase)]]
- [[Перенос функции (Move Function)]]
- [[Извлечение функции (Extract Function)]]
- [[Извлечение класса (Extract Class)]]
### **Результат**
- Улучшает организацию кода
- Уменьшает дублирование кода
- Упрощает поддержку
### **Ссылки**
- [https://refactoring.guru/ru/smells/divergent-change](https://refactoring.guru/ru/smells/divergent-change)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,33 @@
#рефакторинг апахи_кода
![[Pasted image 20241112224740.png]]
> “Стрельба дробью” подобна расходящимся изменениям, но представляет со­бой их противоположность. Унюхать ее можно, когда при выполнении любых из­менений приходится вносить множество мелких модификаций в большое число различных модулей. Когда изменения разбросаны повсюду, их трудно искать и можно пропустить важное изменение.
### **Признаки**
- При выполнении любых модификаций приходится вносить множество мелких изменений в большое число классов
### **Причины появления**
- Одна обязанность была разделена среди множества классов
![[Pasted image 20241112224755.png]]
### **Рефакторинги**
- [[Перенос функции (Move Function)]]
- [[Перенос поля (Move Field)]]
- [[Объединение функций в класс (Combine Functions into Class)]]
- [[Разделение этапа (Split Phase)]]
- [[Встраивание функции (Inline Function)]]
- [[Встраивание класса (Inline Class)]]
![[Pasted image 20241112224804.png]]
### **Результат**
- Улучшает организацию кода
- Уменьшает дублирование кода
- Упрощает поддержку.
### **Ссылки**
- [https://refactoring.guru/ru/smells/shotgun-surgery](https://refactoring.guru/ru/smells/shotgun-surgery)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,12 @@
#рефакторинг апахи_кода
> Люди часто боятся переименовывать вещи, думая, что это не стоит затрачиваемого труда, но на самом деле хорошее имя может сэко­номить часы озадаченного непонимания в будущем.
> Переименование — это не просто упражнение по смене имен. Когда вы не мо­жете придумать хорошее название для чего-то, это часто является признаком бо­ лее глубокого проектного недуга. Недоумение по поводу хитрого названия часто в конечном итоге ведет к значительным упрощениям нашего кода.
### **Рефакторинги**:
- [[Изменение объявления функции (Change Function Declaration)]]
- [[Переименование переменной (Rename Variable)]]
- [[Переименование поля (Rename Field)]]
### **Ссылки**
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,32 @@
#рефакторинг апахи_кода
![[Pasted image 20241112230403.png]]
> Воз­никает, когда говорят о том, что в будущем, наверное, потребуется возможность делать то или иное, и хотят обеспечить набор механизмов для работы с вещами, которые пока что не нужны. Получающуюся в результате программу труднее по­нимать и сопровождать. Если бы все эти механизмы использовались, их наличие было бы оправданным, а без этого они только мешают, так что лучше от них из­бавиться.
### **Признаки**
- Класс, метод, поле или параметр не используются
### **Причины появления**
Иногда код создаётся «про запас», чтобы поддерживать какой-то возможный будущий функционал, который в итоге так и не реализуется. В результате этот код становится труднее понимать и сопровождать.
### **Рефакторинги**
- [[Свертывание иерархии (Collapse Hierarchy)]]
- [[Встраивание функции (Inline Function)]]
- [[Встраивание класса (Inline Class)]]
- [[Удаление неработающего кода (Remove Dead Code)]]
![[Pasted image 20241112230411.png]]
### **Результат**
- Уменьшение размера кода
- Упрощение поддержки
### **Не стоит трогать, если...**
- В случаях, когда вы работаете над фреймворком, создание функциональности, не используемой самим фреймворком, вполне оправдано. Главное, чтобы она была полезна пользователям фреймворка
- Перед удалением элементов, стоит удостовериться, не используются ли они в юнит-тестах. Такое бывает, если в тестах необходим способ получения какой-то служебной информации класса или осуществления каких-то специальных тестовых действий
### **Ссылки**
- [https://refactoring.guru/ru/smells/speculative-generality](https://refactoring.guru/ru/smells/speculative-generality)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,32 @@
#рефакторинг апахи_кода
![[Pasted image 20241112230900.png]]
> Цепочки сообщений возникают, когда клиент запрашивает у одного объекта другой, у того клиент в свою очередь запрашивает еще один объект, у которого запрашивается еще один... и т. д. Это может выглядеть как длинный ряд методов типа `getThis` или как последовательность временных переменных. Такие после­довательности вызовов означают, что клиент связан со структурой классов, и лю­бые изменения промежуточных связей приводят к необходимости модификации клиента.
### **Признаки**
- Вы видите в коде цепочки вызовов вроде такой $a->b()->c()->d()
### **Причины появления**
Цепочка вызовов появляется тогда, когда клиент запрашивает у одного объекта другой, в свою очередь этот объект запрашивает ещё один и т. д. Такие последовательности вызовов означают, что клиент связан с навигацией по структуре классов. Любые изменения промежуточных связей означают необходимость модификации клиента.
![[Pasted image 20241112230908.png]]
### **Рефакторинги**
- [[Сокрытие делегата (Hide Delegate)]]
- [[Извлечение функции (Extract Function)]]
- [[Перенос функции (Move Function)]]
![[Pasted image 20241112230914.png]]
### **Результат**
- Может уменьшить связность между классами цепочки
- Может уменьшить размер кода
### **Не стоит трогать, если...**
- Если вы перестараетесь в процессе сокрытия делегирования, в коде будет довольно сложно понять, где именно осуществляется конкретная работа. Другими словами, появится запах **[[Посредник]]**
### **Ссылки**
- [https://refactoring.guru/ru/smells/message-chains](https://refactoring.guru/ru/smells/message-chains)
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,9 @@
#рефакторинг апахи_кода
> Конвейерные операции, такие как фильтрация и отображение, помогают быстрее увидеть элементы, включенные в обработку, и выяснить, что именно с ними происходит
### **Рефакторинги**
- [[Замена цикла конвейером (Replace Loop with Pipeline)]]
### **Ссылки**
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,37 @@
#рефакторинг етоды_рефакторинга
![[Pasted image 20241118073905.png]]
### **Проблема**
В методах встречается повторяющаяся группа параметров.
![[Pasted image 20241118074053.png]]
### **Решение**
Замените эти параметры объектом
![[Pasted image 20241118074106.png]]
### **Причины рефакторинга**
Одинаковые группы параметров зачастую встречаются не в единственном методе. Это приводит к дублированию кода, как самих параметров, так и частых операций над ними. Как только вы сведёте параметры в одном классе, вы сможете переместить туда и методы обработки этих данных, очистив от этого кода другие методы
### **Достоинства**
- Улучшает читабельность кода. Вместо пачки разнообразных параметров вы видите один объект с понятным названием.
- Одинаковые группы параметров тут и там создают особый род дублирования кода, при котором вроде бы не происходит вызова идентичного кода, но все время встречаются одинаковые группы параметров и аргументов.
### **Недостатки**
- Если вы переместили в новый класс только данные и не планируете перемещать в него никакие поведения и операции над этими данными, это может попахивать [[Классы данных]]
### **Порядок рефакторинга**
1. Создайте новый класс, который будет представлять вашу группу параметров. Сделайте так, чтобы данные объектов этого класса нельзя было изменить после создания
2. В методе, к которому применяем рефакторинг, добавьте новый параметр, в котором будет передаваться ваш объект-параметр. Во всех вызовах метода передавайте в этот параметр объект, создаваемый из старых параметров метода
3. Теперь начинайте по одному удалять старые параметры из метода, заменяя их в коде полями объекта-параметра. Тестируйте программу после каждой замены параметра
4. По окончанию оцените, есть ли возможность и смысл перенести какую-то часть метода (а иногда и весь метод) в класс объекта-параметра
### **Борется с запахом**
- [[Длинный список параметров]]
- [[Группы данных]]
- [[Одержимость примитивами]]
- [[Длинная функция]]
### **Ссылки**
- https://refactoring.guru/ru/introduce-parameter-object
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

View File

@ -0,0 +1,62 @@
#рефакторинг етоды_рефакторинга
![[Pasted image 20250207090935.png]]
### **Проблема**
Корректная работа участка кода предполагает наличие каких-то определённых условий или значений.
```typescript
getExpenseLimit(): number {
// Should have either expense limit or
// a primary project.
return (expenseLimit != NULL_EXPENSE) ?
expenseLimit:
primaryProject.getMemberExpenseLimit();
}
```
### **Решение**
Замените эти предположения конкретными проверками.
```typescript
getExpenseLimit(): number {
// TypeScript and JS doesn't have built-in assertions, so we'll use
// good-old console.error(). You can always extract this into a
// designated assertion function.
if (!(expenseLimit != NULL_EXPENSE ||
(typeof primaryProject !== 'undefined' && primaryProject))) {
console.error("Assertion failed: getExpenseLimit()");
}
return (expenseLimit != NULL_EXPENSE) ?
expenseLimit:
primaryProject.getMemberExpenseLimit();
}
```
### **Причины рефакторинга**
Участок кода создает предположения о чем-то (например, о текущем состоянии объекта, значении параметра или локальной переменной). Обычно это предположение никогда не будет нарушено разве что при наличии какой-то ошибки.
Сделайте эти предположения явными, добавив соответствующие проверки. Как и подсказки типов в параметрах методов, эти проверки могут играть роль живой документации кода.
Хорошим признаком того, что нужна проверка каких-то условий, являются комментарии в коде. Если вы видите комментарии, описывающие условия, при которых метод корректно работает, значит здесь неплохо было бы вставить проверку-утверждение этих условий.
### **Достоинства**
- Если какое-то предположение неверно и в результате код производит также неверный результат, лучше сразу остановить выполнение, пока это не привело к фатальным последствиям и порче данных. Кроме того, это означает, что вы упустили написание какого-то теста в наборе тестов вашей программы.
### **Недостатки**
- Иногда вместо простой проверки лучше вставить исключение. При этом вы можете выбрать необходимый класс исключения и дать остальному коду возможность корректно его обработать.
- В каких случаях исключение лучше простой проверки? Если к нему может привести деятельность пользователя или системы, и вы можете обработать это исключение. С другой стороны, обычные безымянные необрабатываемые исключения равносильны простым проверкам — вы их не обрабатываете, они могут быть вызваны только как результат бага в программе, который никогда не должен был возникнуть.
### **Порядок рефакторинга**
Когда вы видите, что предполагается какое-то условие, добавьте проверку этого условия, чтобы проверить его наверняка.
Добавление проверки не должно изменять поведение программы.
Не перебарщивайте с использованием проверок для всего, что только можно, на выбранном участке кода. Нужно проверять лишь те условия, без которых код перестанет корректно работать. Если ваш код нормально работает, в том числе, в случае, когда проверка не проходит успешно, такую проверку можно убрать.
### **Борется с запахом**
- [[Комментарии]]
### **Ссылки**
- https://refactoring.guru/ru/introduce-assertion
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]

Some files were not shown because too many files have changed in this diff Show More